]> git.openstreetmap.org Git - rails.git/blob - vendor/assets/iD/iD.js
Merge branch 'master' into moderation
[rails.git] / vendor / assets / iD / iD.js
1 (function () {
2 var version = "4.13.0";
3
4 function d3_ascending(a, b) {
5   return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
6 }
7
8 function d3_bisector(compare) {
9   if (compare.length === 1) compare = ascendingComparator(compare);
10   return {
11     left: function(a, x, lo, hi) {
12       if (lo == null) lo = 0;
13       if (hi == null) hi = a.length;
14       while (lo < hi) {
15         var mid = lo + hi >>> 1;
16         if (compare(a[mid], x) < 0) lo = mid + 1;
17         else hi = mid;
18       }
19       return lo;
20     },
21     right: function(a, x, lo, hi) {
22       if (lo == null) lo = 0;
23       if (hi == null) hi = a.length;
24       while (lo < hi) {
25         var mid = lo + hi >>> 1;
26         if (compare(a[mid], x) > 0) hi = mid;
27         else lo = mid + 1;
28       }
29       return lo;
30     }
31   };
32 }
33
34 function ascendingComparator(f) {
35   return function(d, x) {
36     return d3_ascending(f(d), x);
37   };
38 }
39
40 var ascendingBisect = d3_bisector(d3_ascending);
41 var bisectRight = ascendingBisect.right;
42 var bisectLeft = ascendingBisect.left;
43
44 function pairs(array, f) {
45   if (f == null) f = pair;
46   var i = 0, n = array.length - 1, p = array[0], pairs = new Array(n < 0 ? 0 : n);
47   while (i < n) pairs[i] = f(p, p = array[++i]);
48   return pairs;
49 }
50
51 function pair(a, b) {
52   return [a, b];
53 }
54
55 function cross(values0, values1, reduce) {
56   var n0 = values0.length,
57       n1 = values1.length,
58       values = new Array(n0 * n1),
59       i0,
60       i1,
61       i,
62       value0;
63
64   if (reduce == null) reduce = pair;
65
66   for (i0 = i = 0; i0 < n0; ++i0) {
67     for (value0 = values0[i0], i1 = 0; i1 < n1; ++i1, ++i) {
68       values[i] = reduce(value0, values1[i1]);
69     }
70   }
71
72   return values;
73 }
74
75 function d3_descending(a, b) {
76   return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
77 }
78
79 function number(x) {
80   return x === null ? NaN : +x;
81 }
82
83 function variance(values, valueof) {
84   var n = values.length,
85       m = 0,
86       i = -1,
87       mean = 0,
88       value,
89       delta,
90       sum = 0;
91
92   if (valueof == null) {
93     while (++i < n) {
94       if (!isNaN(value = number(values[i]))) {
95         delta = value - mean;
96         mean += delta / ++m;
97         sum += delta * (value - mean);
98       }
99     }
100   }
101
102   else {
103     while (++i < n) {
104       if (!isNaN(value = number(valueof(values[i], i, values)))) {
105         delta = value - mean;
106         mean += delta / ++m;
107         sum += delta * (value - mean);
108       }
109     }
110   }
111
112   if (m > 1) return sum / (m - 1);
113 }
114
115 function deviation(array, f) {
116   var v = variance(array, f);
117   return v ? Math.sqrt(v) : v;
118 }
119
120 function extent(values, valueof) {
121   var n = values.length,
122       i = -1,
123       value,
124       min,
125       max;
126
127   if (valueof == null) {
128     while (++i < n) { // Find the first comparable value.
129       if ((value = values[i]) != null && value >= value) {
130         min = max = value;
131         while (++i < n) { // Compare the remaining values.
132           if ((value = values[i]) != null) {
133             if (min > value) min = value;
134             if (max < value) max = value;
135           }
136         }
137       }
138     }
139   }
140
141   else {
142     while (++i < n) { // Find the first comparable value.
143       if ((value = valueof(values[i], i, values)) != null && value >= value) {
144         min = max = value;
145         while (++i < n) { // Compare the remaining values.
146           if ((value = valueof(values[i], i, values)) != null) {
147             if (min > value) min = value;
148             if (max < value) max = value;
149           }
150         }
151       }
152     }
153   }
154
155   return [min, max];
156 }
157
158 var array = Array.prototype;
159
160 var slice = array.slice;
161 var map = array.map;
162
163 function constant(x) {
164   return function() {
165     return x;
166   };
167 }
168
169 function identity(x) {
170   return x;
171 }
172
173 function d3_range(start, stop, step) {
174   start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step;
175
176   var i = -1,
177       n = Math.max(0, Math.ceil((stop - start) / step)) | 0,
178       range = new Array(n);
179
180   while (++i < n) {
181     range[i] = start + i * step;
182   }
183
184   return range;
185 }
186
187 var e10 = Math.sqrt(50);
188 var e5 = Math.sqrt(10);
189 var e2 = Math.sqrt(2);
190
191 function ticks(start, stop, count) {
192   var reverse,
193       i = -1,
194       n,
195       ticks,
196       step;
197
198   stop = +stop, start = +start, count = +count;
199   if (start === stop && count > 0) return [start];
200   if (reverse = stop < start) n = start, start = stop, stop = n;
201   if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return [];
202
203   if (step > 0) {
204     start = Math.ceil(start / step);
205     stop = Math.floor(stop / step);
206     ticks = new Array(n = Math.ceil(stop - start + 1));
207     while (++i < n) ticks[i] = (start + i) * step;
208   } else {
209     start = Math.floor(start * step);
210     stop = Math.ceil(stop * step);
211     ticks = new Array(n = Math.ceil(start - stop + 1));
212     while (++i < n) ticks[i] = (start - i) / step;
213   }
214
215   if (reverse) ticks.reverse();
216
217   return ticks;
218 }
219
220 function tickIncrement(start, stop, count) {
221   var step = (stop - start) / Math.max(0, count),
222       power = Math.floor(Math.log(step) / Math.LN10),
223       error = step / Math.pow(10, power);
224   return power >= 0
225       ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power)
226       : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1);
227 }
228
229 function tickStep(start, stop, count) {
230   var step0 = Math.abs(stop - start) / Math.max(0, count),
231       step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)),
232       error = step0 / step1;
233   if (error >= e10) step1 *= 10;
234   else if (error >= e5) step1 *= 5;
235   else if (error >= e2) step1 *= 2;
236   return stop < start ? -step1 : step1;
237 }
238
239 function sturges(values) {
240   return Math.ceil(Math.log(values.length) / Math.LN2) + 1;
241 }
242
243 function histogram() {
244   var value = identity,
245       domain = extent,
246       threshold = sturges;
247
248   function histogram(data) {
249     var i,
250         n = data.length,
251         x,
252         values = new Array(n);
253
254     for (i = 0; i < n; ++i) {
255       values[i] = value(data[i], i, data);
256     }
257
258     var xz = domain(values),
259         x0 = xz[0],
260         x1 = xz[1],
261         tz = threshold(values, x0, x1);
262
263     // Convert number of thresholds into uniform thresholds.
264     if (!Array.isArray(tz)) {
265       tz = tickStep(x0, x1, tz);
266       tz = d3_range(Math.ceil(x0 / tz) * tz, Math.floor(x1 / tz) * tz, tz); // exclusive
267     }
268
269     // Remove any thresholds outside the domain.
270     var m = tz.length;
271     while (tz[0] <= x0) tz.shift(), --m;
272     while (tz[m - 1] > x1) tz.pop(), --m;
273
274     var bins = new Array(m + 1),
275         bin;
276
277     // Initialize bins.
278     for (i = 0; i <= m; ++i) {
279       bin = bins[i] = [];
280       bin.x0 = i > 0 ? tz[i - 1] : x0;
281       bin.x1 = i < m ? tz[i] : x1;
282     }
283
284     // Assign data to bins by value, ignoring any outside the domain.
285     for (i = 0; i < n; ++i) {
286       x = values[i];
287       if (x0 <= x && x <= x1) {
288         bins[bisectRight(tz, x, 0, m)].push(data[i]);
289       }
290     }
291
292     return bins;
293   }
294
295   histogram.value = function(_) {
296     return arguments.length ? (value = typeof _ === "function" ? _ : constant(_), histogram) : value;
297   };
298
299   histogram.domain = function(_) {
300     return arguments.length ? (domain = typeof _ === "function" ? _ : constant([_[0], _[1]]), histogram) : domain;
301   };
302
303   histogram.thresholds = function(_) {
304     return arguments.length ? (threshold = typeof _ === "function" ? _ : Array.isArray(_) ? constant(slice.call(_)) : constant(_), histogram) : threshold;
305   };
306
307   return histogram;
308 }
309
310 function threshold(values, p, valueof) {
311   if (valueof == null) valueof = number;
312   if (!(n = values.length)) return;
313   if ((p = +p) <= 0 || n < 2) return +valueof(values[0], 0, values);
314   if (p >= 1) return +valueof(values[n - 1], n - 1, values);
315   var n,
316       i = (n - 1) * p,
317       i0 = Math.floor(i),
318       value0 = +valueof(values[i0], i0, values),
319       value1 = +valueof(values[i0 + 1], i0 + 1, values);
320   return value0 + (value1 - value0) * (i - i0);
321 }
322
323 function freedmanDiaconis(values, min, max) {
324   values = map.call(values, number).sort(d3_ascending);
325   return Math.ceil((max - min) / (2 * (threshold(values, 0.75) - threshold(values, 0.25)) * Math.pow(values.length, -1 / 3)));
326 }
327
328 function scott(values, min, max) {
329   return Math.ceil((max - min) / (3.5 * deviation(values) * Math.pow(values.length, -1 / 3)));
330 }
331
332 function max(values, valueof) {
333   var n = values.length,
334       i = -1,
335       value,
336       max;
337
338   if (valueof == null) {
339     while (++i < n) { // Find the first comparable value.
340       if ((value = values[i]) != null && value >= value) {
341         max = value;
342         while (++i < n) { // Compare the remaining values.
343           if ((value = values[i]) != null && value > max) {
344             max = value;
345           }
346         }
347       }
348     }
349   }
350
351   else {
352     while (++i < n) { // Find the first comparable value.
353       if ((value = valueof(values[i], i, values)) != null && value >= value) {
354         max = value;
355         while (++i < n) { // Compare the remaining values.
356           if ((value = valueof(values[i], i, values)) != null && value > max) {
357             max = value;
358           }
359         }
360       }
361     }
362   }
363
364   return max;
365 }
366
367 function mean(values, valueof) {
368   var n = values.length,
369       m = n,
370       i = -1,
371       value,
372       sum = 0;
373
374   if (valueof == null) {
375     while (++i < n) {
376       if (!isNaN(value = number(values[i]))) sum += value;
377       else --m;
378     }
379   }
380
381   else {
382     while (++i < n) {
383       if (!isNaN(value = number(valueof(values[i], i, values)))) sum += value;
384       else --m;
385     }
386   }
387
388   if (m) return sum / m;
389 }
390
391 function d3_median(values, valueof) {
392   var n = values.length,
393       i = -1,
394       value,
395       numbers = [];
396
397   if (valueof == null) {
398     while (++i < n) {
399       if (!isNaN(value = number(values[i]))) {
400         numbers.push(value);
401       }
402     }
403   }
404
405   else {
406     while (++i < n) {
407       if (!isNaN(value = number(valueof(values[i], i, values)))) {
408         numbers.push(value);
409       }
410     }
411   }
412
413   return threshold(numbers.sort(d3_ascending), 0.5);
414 }
415
416 function merge(arrays) {
417   var n = arrays.length,
418       m,
419       i = -1,
420       j = 0,
421       merged,
422       array;
423
424   while (++i < n) j += arrays[i].length;
425   merged = new Array(j);
426
427   while (--n >= 0) {
428     array = arrays[n];
429     m = array.length;
430     while (--m >= 0) {
431       merged[--j] = array[m];
432     }
433   }
434
435   return merged;
436 }
437
438 function min(values, valueof) {
439   var n = values.length,
440       i = -1,
441       value,
442       min;
443
444   if (valueof == null) {
445     while (++i < n) { // Find the first comparable value.
446       if ((value = values[i]) != null && value >= value) {
447         min = value;
448         while (++i < n) { // Compare the remaining values.
449           if ((value = values[i]) != null && min > value) {
450             min = value;
451           }
452         }
453       }
454     }
455   }
456
457   else {
458     while (++i < n) { // Find the first comparable value.
459       if ((value = valueof(values[i], i, values)) != null && value >= value) {
460         min = value;
461         while (++i < n) { // Compare the remaining values.
462           if ((value = valueof(values[i], i, values)) != null && min > value) {
463             min = value;
464           }
465         }
466       }
467     }
468   }
469
470   return min;
471 }
472
473 function permute(array, indexes) {
474   var i = indexes.length, permutes = new Array(i);
475   while (i--) permutes[i] = array[indexes[i]];
476   return permutes;
477 }
478
479 function scan(values, compare) {
480   if (!(n = values.length)) return;
481   var n,
482       i = 0,
483       j = 0,
484       xi,
485       xj = values[j];
486
487   if (compare == null) compare = d3_ascending;
488
489   while (++i < n) {
490     if (compare(xi = values[i], xj) < 0 || compare(xj, xj) !== 0) {
491       xj = xi, j = i;
492     }
493   }
494
495   if (compare(xj, xj) === 0) return j;
496 }
497
498 function shuffle(array, i0, i1) {
499   var m = (i1 == null ? array.length : i1) - (i0 = i0 == null ? 0 : +i0),
500       t,
501       i;
502
503   while (m) {
504     i = Math.random() * m-- | 0;
505     t = array[m + i0];
506     array[m + i0] = array[i + i0];
507     array[i + i0] = t;
508   }
509
510   return array;
511 }
512
513 function sum(values, valueof) {
514   var n = values.length,
515       i = -1,
516       value,
517       sum = 0;
518
519   if (valueof == null) {
520     while (++i < n) {
521       if (value = +values[i]) sum += value; // Note: zero and null are equivalent.
522     }
523   }
524
525   else {
526     while (++i < n) {
527       if (value = +valueof(values[i], i, values)) sum += value;
528     }
529   }
530
531   return sum;
532 }
533
534 function transpose(matrix) {
535   if (!(n = matrix.length)) return [];
536   for (var i = -1, m = min(matrix, length), transpose = new Array(m); ++i < m;) {
537     for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n;) {
538       row[j] = matrix[j][i];
539     }
540   }
541   return transpose;
542 }
543
544 function length(d) {
545   return d.length;
546 }
547
548 function zip() {
549   return transpose(arguments);
550 }
551
552 var slice$1 = Array.prototype.slice;
553
554 function identity$1(x) {
555   return x;
556 }
557
558 var top = 1;
559 var right = 2;
560 var bottom = 3;
561 var left = 4;
562 var epsilon = 1e-6;
563
564 function translateX(x) {
565   return "translate(" + (x + 0.5) + ",0)";
566 }
567
568 function translateY(y) {
569   return "translate(0," + (y + 0.5) + ")";
570 }
571
572 function number$1(scale) {
573   return function(d) {
574     return +scale(d);
575   };
576 }
577
578 function center(scale) {
579   var offset = Math.max(0, scale.bandwidth() - 1) / 2; // Adjust for 0.5px offset.
580   if (scale.round()) offset = Math.round(offset);
581   return function(d) {
582     return +scale(d) + offset;
583   };
584 }
585
586 function entering() {
587   return !this.__axis;
588 }
589
590 function axis(orient, scale) {
591   var tickArguments = [],
592       tickValues = null,
593       tickFormat = null,
594       tickSizeInner = 6,
595       tickSizeOuter = 6,
596       tickPadding = 3,
597       k = orient === top || orient === left ? -1 : 1,
598       x = orient === left || orient === right ? "x" : "y",
599       transform = orient === top || orient === bottom ? translateX : translateY;
600
601   function axis(context) {
602     var values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : tickValues,
603         format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity$1) : tickFormat,
604         spacing = Math.max(tickSizeInner, 0) + tickPadding,
605         range = scale.range(),
606         range0 = +range[0] + 0.5,
607         range1 = +range[range.length - 1] + 0.5,
608         position = (scale.bandwidth ? center : number$1)(scale.copy()),
609         selection = context.selection ? context.selection() : context,
610         path = selection.selectAll(".domain").data([null]),
611         tick = selection.selectAll(".tick").data(values, scale).order(),
612         tickExit = tick.exit(),
613         tickEnter = tick.enter().append("g").attr("class", "tick"),
614         line = tick.select("line"),
615         text = tick.select("text");
616
617     path = path.merge(path.enter().insert("path", ".tick")
618         .attr("class", "domain")
619         .attr("stroke", "#000"));
620
621     tick = tick.merge(tickEnter);
622
623     line = line.merge(tickEnter.append("line")
624         .attr("stroke", "#000")
625         .attr(x + "2", k * tickSizeInner));
626
627     text = text.merge(tickEnter.append("text")
628         .attr("fill", "#000")
629         .attr(x, k * spacing)
630         .attr("dy", orient === top ? "0em" : orient === bottom ? "0.71em" : "0.32em"));
631
632     if (context !== selection) {
633       path = path.transition(context);
634       tick = tick.transition(context);
635       line = line.transition(context);
636       text = text.transition(context);
637
638       tickExit = tickExit.transition(context)
639           .attr("opacity", epsilon)
640           .attr("transform", function(d) { return isFinite(d = position(d)) ? transform(d) : this.getAttribute("transform"); });
641
642       tickEnter
643           .attr("opacity", epsilon)
644           .attr("transform", function(d) { var p = this.parentNode.__axis; return transform(p && isFinite(p = p(d)) ? p : position(d)); });
645     }
646
647     tickExit.remove();
648
649     path
650         .attr("d", orient === left || orient == right
651             ? "M" + k * tickSizeOuter + "," + range0 + "H0.5V" + range1 + "H" + k * tickSizeOuter
652             : "M" + range0 + "," + k * tickSizeOuter + "V0.5H" + range1 + "V" + k * tickSizeOuter);
653
654     tick
655         .attr("opacity", 1)
656         .attr("transform", function(d) { return transform(position(d)); });
657
658     line
659         .attr(x + "2", k * tickSizeInner);
660
661     text
662         .attr(x, k * spacing)
663         .text(format);
664
665     selection.filter(entering)
666         .attr("fill", "none")
667         .attr("font-size", 10)
668         .attr("font-family", "sans-serif")
669         .attr("text-anchor", orient === right ? "start" : orient === left ? "end" : "middle");
670
671     selection
672         .each(function() { this.__axis = position; });
673   }
674
675   axis.scale = function(_) {
676     return arguments.length ? (scale = _, axis) : scale;
677   };
678
679   axis.ticks = function() {
680     return tickArguments = slice$1.call(arguments), axis;
681   };
682
683   axis.tickArguments = function(_) {
684     return arguments.length ? (tickArguments = _ == null ? [] : slice$1.call(_), axis) : tickArguments.slice();
685   };
686
687   axis.tickValues = function(_) {
688     return arguments.length ? (tickValues = _ == null ? null : slice$1.call(_), axis) : tickValues && tickValues.slice();
689   };
690
691   axis.tickFormat = function(_) {
692     return arguments.length ? (tickFormat = _, axis) : tickFormat;
693   };
694
695   axis.tickSize = function(_) {
696     return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner;
697   };
698
699   axis.tickSizeInner = function(_) {
700     return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner;
701   };
702
703   axis.tickSizeOuter = function(_) {
704     return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter;
705   };
706
707   axis.tickPadding = function(_) {
708     return arguments.length ? (tickPadding = +_, axis) : tickPadding;
709   };
710
711   return axis;
712 }
713
714 function axisTop(scale) {
715   return axis(top, scale);
716 }
717
718 function axisRight(scale) {
719   return axis(right, scale);
720 }
721
722 function axisBottom(scale) {
723   return axis(bottom, scale);
724 }
725
726 function axisLeft(scale) {
727   return axis(left, scale);
728 }
729
730 var noop = {value: function() {}};
731
732 function dispatch() {
733   for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {
734     if (!(t = arguments[i] + "") || (t in _)) throw new Error("illegal type: " + t);
735     _[t] = [];
736   }
737   return new Dispatch(_);
738 }
739
740 function Dispatch(_) {
741   this._ = _;
742 }
743
744 function parseTypenames(typenames, types) {
745   return typenames.trim().split(/^|\s+/).map(function(t) {
746     var name = "", i = t.indexOf(".");
747     if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
748     if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t);
749     return {type: t, name: name};
750   });
751 }
752
753 Dispatch.prototype = dispatch.prototype = {
754   constructor: Dispatch,
755   on: function(typename, callback) {
756     var _ = this._,
757         T = parseTypenames(typename + "", _),
758         t,
759         i = -1,
760         n = T.length;
761
762     // If no callback was specified, return the callback of the given type and name.
763     if (arguments.length < 2) {
764       while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;
765       return;
766     }
767
768     // If a type was specified, set the callback for the given type and name.
769     // Otherwise, if a null callback was specified, remove callbacks of the given name.
770     if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback);
771     while (++i < n) {
772       if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback);
773       else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null);
774     }
775
776     return this;
777   },
778   copy: function() {
779     var copy = {}, _ = this._;
780     for (var t in _) copy[t] = _[t].slice();
781     return new Dispatch(copy);
782   },
783   call: function(type, that) {
784     if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2];
785     if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
786     for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
787   },
788   apply: function(type, that, args) {
789     if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
790     for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
791   }
792 };
793
794 function get(type, name) {
795   for (var i = 0, n = type.length, c; i < n; ++i) {
796     if ((c = type[i]).name === name) {
797       return c.value;
798     }
799   }
800 }
801
802 function set(type, name, callback) {
803   for (var i = 0, n = type.length; i < n; ++i) {
804     if (type[i].name === name) {
805       type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1));
806       break;
807     }
808   }
809   if (callback != null) type.push({name: name, value: callback});
810   return type;
811 }
812
813 var xhtml = "http://www.w3.org/1999/xhtml";
814
815 var namespaces = {
816   svg: "http://www.w3.org/2000/svg",
817   xhtml: xhtml,
818   xlink: "http://www.w3.org/1999/xlink",
819   xml: "http://www.w3.org/XML/1998/namespace",
820   xmlns: "http://www.w3.org/2000/xmlns/"
821 };
822
823 function namespace(name) {
824   var prefix = name += "", i = prefix.indexOf(":");
825   if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1);
826   return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name;
827 }
828
829 function creatorInherit(name) {
830   return function() {
831     var document = this.ownerDocument,
832         uri = this.namespaceURI;
833     return uri === xhtml && document.documentElement.namespaceURI === xhtml
834         ? document.createElement(name)
835         : document.createElementNS(uri, name);
836   };
837 }
838
839 function creatorFixed(fullname) {
840   return function() {
841     return this.ownerDocument.createElementNS(fullname.space, fullname.local);
842   };
843 }
844
845 function creator(name) {
846   var fullname = namespace(name);
847   return (fullname.local
848       ? creatorFixed
849       : creatorInherit)(fullname);
850 }
851
852 function none() {}
853
854 function selector(selector) {
855   return selector == null ? none : function() {
856     return this.querySelector(selector);
857   };
858 }
859
860 function selection_select(select) {
861   if (typeof select !== "function") select = selector(select);
862
863   for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
864     for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
865       if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {
866         if ("__data__" in node) subnode.__data__ = node.__data__;
867         subgroup[i] = subnode;
868       }
869     }
870   }
871
872   return new Selection(subgroups, this._parents);
873 }
874
875 function empty() {
876   return [];
877 }
878
879 function selectorAll(selector) {
880   return selector == null ? empty : function() {
881     return this.querySelectorAll(selector);
882   };
883 }
884
885 function selection_selectAll(select) {
886   if (typeof select !== "function") select = selectorAll(select);
887
888   for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
889     for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
890       if (node = group[i]) {
891         subgroups.push(select.call(node, node.__data__, i, group));
892         parents.push(node);
893       }
894     }
895   }
896
897   return new Selection(subgroups, parents);
898 }
899
900 var matcher = function(selector) {
901   return function() {
902     return this.matches(selector);
903   };
904 };
905
906 if (typeof document !== "undefined") {
907   var element = document.documentElement;
908   if (!element.matches) {
909     var vendorMatches = element.webkitMatchesSelector
910         || element.msMatchesSelector
911         || element.mozMatchesSelector
912         || element.oMatchesSelector;
913     matcher = function(selector) {
914       return function() {
915         return vendorMatches.call(this, selector);
916       };
917     };
918   }
919 }
920
921 var matcher$1 = matcher;
922
923 function selection_filter(match) {
924   if (typeof match !== "function") match = matcher$1(match);
925
926   for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
927     for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
928       if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
929         subgroup.push(node);
930       }
931     }
932   }
933
934   return new Selection(subgroups, this._parents);
935 }
936
937 function sparse(update) {
938   return new Array(update.length);
939 }
940
941 function selection_enter() {
942   return new Selection(this._enter || this._groups.map(sparse), this._parents);
943 }
944
945 function EnterNode(parent, datum) {
946   this.ownerDocument = parent.ownerDocument;
947   this.namespaceURI = parent.namespaceURI;
948   this._next = null;
949   this._parent = parent;
950   this.__data__ = datum;
951 }
952
953 EnterNode.prototype = {
954   constructor: EnterNode,
955   appendChild: function(child) { return this._parent.insertBefore(child, this._next); },
956   insertBefore: function(child, next) { return this._parent.insertBefore(child, next); },
957   querySelector: function(selector) { return this._parent.querySelector(selector); },
958   querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); }
959 };
960
961 function constant$1(x) {
962   return function() {
963     return x;
964   };
965 }
966
967 var keyPrefix = "$"; // Protect against keys like “__proto__”.
968
969 function bindIndex(parent, group, enter, update, exit, data) {
970   var i = 0,
971       node,
972       groupLength = group.length,
973       dataLength = data.length;
974
975   // Put any non-null nodes that fit into update.
976   // Put any null nodes into enter.
977   // Put any remaining data into enter.
978   for (; i < dataLength; ++i) {
979     if (node = group[i]) {
980       node.__data__ = data[i];
981       update[i] = node;
982     } else {
983       enter[i] = new EnterNode(parent, data[i]);
984     }
985   }
986
987   // Put any non-null nodes that don’t fit into exit.
988   for (; i < groupLength; ++i) {
989     if (node = group[i]) {
990       exit[i] = node;
991     }
992   }
993 }
994
995 function bindKey(parent, group, enter, update, exit, data, key) {
996   var i,
997       node,
998       nodeByKeyValue = {},
999       groupLength = group.length,
1000       dataLength = data.length,
1001       keyValues = new Array(groupLength),
1002       keyValue;
1003
1004   // Compute the key for each node.
1005   // If multiple nodes have the same key, the duplicates are added to exit.
1006   for (i = 0; i < groupLength; ++i) {
1007     if (node = group[i]) {
1008       keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group);
1009       if (keyValue in nodeByKeyValue) {
1010         exit[i] = node;
1011       } else {
1012         nodeByKeyValue[keyValue] = node;
1013       }
1014     }
1015   }
1016
1017   // Compute the key for each datum.
1018   // If there a node associated with this key, join and add it to update.
1019   // If there is not (or the key is a duplicate), add it to enter.
1020   for (i = 0; i < dataLength; ++i) {
1021     keyValue = keyPrefix + key.call(parent, data[i], i, data);
1022     if (node = nodeByKeyValue[keyValue]) {
1023       update[i] = node;
1024       node.__data__ = data[i];
1025       nodeByKeyValue[keyValue] = null;
1026     } else {
1027       enter[i] = new EnterNode(parent, data[i]);
1028     }
1029   }
1030
1031   // Add any remaining nodes that were not bound to data to exit.
1032   for (i = 0; i < groupLength; ++i) {
1033     if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) {
1034       exit[i] = node;
1035     }
1036   }
1037 }
1038
1039 function selection_data(value, key) {
1040   if (!value) {
1041     data = new Array(this.size()), j = -1;
1042     this.each(function(d) { data[++j] = d; });
1043     return data;
1044   }
1045
1046   var bind = key ? bindKey : bindIndex,
1047       parents = this._parents,
1048       groups = this._groups;
1049
1050   if (typeof value !== "function") value = constant$1(value);
1051
1052   for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {
1053     var parent = parents[j],
1054         group = groups[j],
1055         groupLength = group.length,
1056         data = value.call(parent, parent && parent.__data__, j, parents),
1057         dataLength = data.length,
1058         enterGroup = enter[j] = new Array(dataLength),
1059         updateGroup = update[j] = new Array(dataLength),
1060         exitGroup = exit[j] = new Array(groupLength);
1061
1062     bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);
1063
1064     // Now connect the enter nodes to their following update node, such that
1065     // appendChild can insert the materialized enter node before this node,
1066     // rather than at the end of the parent node.
1067     for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {
1068       if (previous = enterGroup[i0]) {
1069         if (i0 >= i1) i1 = i0 + 1;
1070         while (!(next = updateGroup[i1]) && ++i1 < dataLength);
1071         previous._next = next || null;
1072       }
1073     }
1074   }
1075
1076   update = new Selection(update, parents);
1077   update._enter = enter;
1078   update._exit = exit;
1079   return update;
1080 }
1081
1082 function selection_exit() {
1083   return new Selection(this._exit || this._groups.map(sparse), this._parents);
1084 }
1085
1086 function selection_merge(selection$$1) {
1087
1088   for (var groups0 = this._groups, groups1 = selection$$1._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {
1089     for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
1090       if (node = group0[i] || group1[i]) {
1091         merge[i] = node;
1092       }
1093     }
1094   }
1095
1096   for (; j < m0; ++j) {
1097     merges[j] = groups0[j];
1098   }
1099
1100   return new Selection(merges, this._parents);
1101 }
1102
1103 function selection_order() {
1104
1105   for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) {
1106     for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) {
1107       if (node = group[i]) {
1108         if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next);
1109         next = node;
1110       }
1111     }
1112   }
1113
1114   return this;
1115 }
1116
1117 function selection_sort(compare) {
1118   if (!compare) compare = ascending;
1119
1120   function compareNode(a, b) {
1121     return a && b ? compare(a.__data__, b.__data__) : !a - !b;
1122   }
1123
1124   for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {
1125     for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) {
1126       if (node = group[i]) {
1127         sortgroup[i] = node;
1128       }
1129     }
1130     sortgroup.sort(compareNode);
1131   }
1132
1133   return new Selection(sortgroups, this._parents).order();
1134 }
1135
1136 function ascending(a, b) {
1137   return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
1138 }
1139
1140 function selection_call() {
1141   var callback = arguments[0];
1142   arguments[0] = this;
1143   callback.apply(null, arguments);
1144   return this;
1145 }
1146
1147 function selection_nodes() {
1148   var nodes = new Array(this.size()), i = -1;
1149   this.each(function() { nodes[++i] = this; });
1150   return nodes;
1151 }
1152
1153 function selection_node() {
1154
1155   for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
1156     for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {
1157       var node = group[i];
1158       if (node) return node;
1159     }
1160   }
1161
1162   return null;
1163 }
1164
1165 function selection_size() {
1166   var size = 0;
1167   this.each(function() { ++size; });
1168   return size;
1169 }
1170
1171 function selection_empty() {
1172   return !this.node();
1173 }
1174
1175 function selection_each(callback) {
1176
1177   for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
1178     for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {
1179       if (node = group[i]) callback.call(node, node.__data__, i, group);
1180     }
1181   }
1182
1183   return this;
1184 }
1185
1186 function attrRemove(name) {
1187   return function() {
1188     this.removeAttribute(name);
1189   };
1190 }
1191
1192 function attrRemoveNS(fullname) {
1193   return function() {
1194     this.removeAttributeNS(fullname.space, fullname.local);
1195   };
1196 }
1197
1198 function attrConstant(name, value) {
1199   return function() {
1200     this.setAttribute(name, value);
1201   };
1202 }
1203
1204 function attrConstantNS(fullname, value) {
1205   return function() {
1206     this.setAttributeNS(fullname.space, fullname.local, value);
1207   };
1208 }
1209
1210 function attrFunction(name, value) {
1211   return function() {
1212     var v = value.apply(this, arguments);
1213     if (v == null) this.removeAttribute(name);
1214     else this.setAttribute(name, v);
1215   };
1216 }
1217
1218 function attrFunctionNS(fullname, value) {
1219   return function() {
1220     var v = value.apply(this, arguments);
1221     if (v == null) this.removeAttributeNS(fullname.space, fullname.local);
1222     else this.setAttributeNS(fullname.space, fullname.local, v);
1223   };
1224 }
1225
1226 function selection_attr(name, value) {
1227   var fullname = namespace(name);
1228
1229   if (arguments.length < 2) {
1230     var node = this.node();
1231     return fullname.local
1232         ? node.getAttributeNS(fullname.space, fullname.local)
1233         : node.getAttribute(fullname);
1234   }
1235
1236   return this.each((value == null
1237       ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function"
1238       ? (fullname.local ? attrFunctionNS : attrFunction)
1239       : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value));
1240 }
1241
1242 function defaultView(node) {
1243   return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node
1244       || (node.document && node) // node is a Window
1245       || node.defaultView; // node is a Document
1246 }
1247
1248 function styleRemove(name) {
1249   return function() {
1250     this.style.removeProperty(name);
1251   };
1252 }
1253
1254 function styleConstant(name, value, priority) {
1255   return function() {
1256     this.style.setProperty(name, value, priority);
1257   };
1258 }
1259
1260 function styleFunction(name, value, priority) {
1261   return function() {
1262     var v = value.apply(this, arguments);
1263     if (v == null) this.style.removeProperty(name);
1264     else this.style.setProperty(name, v, priority);
1265   };
1266 }
1267
1268 function selection_style(name, value, priority) {
1269   return arguments.length > 1
1270       ? this.each((value == null
1271             ? styleRemove : typeof value === "function"
1272             ? styleFunction
1273             : styleConstant)(name, value, priority == null ? "" : priority))
1274       : styleValue(this.node(), name);
1275 }
1276
1277 function styleValue(node, name) {
1278   return node.style.getPropertyValue(name)
1279       || defaultView(node).getComputedStyle(node, null).getPropertyValue(name);
1280 }
1281
1282 function propertyRemove(name) {
1283   return function() {
1284     delete this[name];
1285   };
1286 }
1287
1288 function propertyConstant(name, value) {
1289   return function() {
1290     this[name] = value;
1291   };
1292 }
1293
1294 function propertyFunction(name, value) {
1295   return function() {
1296     var v = value.apply(this, arguments);
1297     if (v == null) delete this[name];
1298     else this[name] = v;
1299   };
1300 }
1301
1302 function selection_property(name, value) {
1303   return arguments.length > 1
1304       ? this.each((value == null
1305           ? propertyRemove : typeof value === "function"
1306           ? propertyFunction
1307           : propertyConstant)(name, value))
1308       : this.node()[name];
1309 }
1310
1311 function classArray(string) {
1312   return string.trim().split(/^|\s+/);
1313 }
1314
1315 function classList(node) {
1316   return node.classList || new ClassList(node);
1317 }
1318
1319 function ClassList(node) {
1320   this._node = node;
1321   this._names = classArray(node.getAttribute("class") || "");
1322 }
1323
1324 ClassList.prototype = {
1325   add: function(name) {
1326     var i = this._names.indexOf(name);
1327     if (i < 0) {
1328       this._names.push(name);
1329       this._node.setAttribute("class", this._names.join(" "));
1330     }
1331   },
1332   remove: function(name) {
1333     var i = this._names.indexOf(name);
1334     if (i >= 0) {
1335       this._names.splice(i, 1);
1336       this._node.setAttribute("class", this._names.join(" "));
1337     }
1338   },
1339   contains: function(name) {
1340     return this._names.indexOf(name) >= 0;
1341   }
1342 };
1343
1344 function classedAdd(node, names) {
1345   var list = classList(node), i = -1, n = names.length;
1346   while (++i < n) list.add(names[i]);
1347 }
1348
1349 function classedRemove(node, names) {
1350   var list = classList(node), i = -1, n = names.length;
1351   while (++i < n) list.remove(names[i]);
1352 }
1353
1354 function classedTrue(names) {
1355   return function() {
1356     classedAdd(this, names);
1357   };
1358 }
1359
1360 function classedFalse(names) {
1361   return function() {
1362     classedRemove(this, names);
1363   };
1364 }
1365
1366 function classedFunction(names, value) {
1367   return function() {
1368     (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);
1369   };
1370 }
1371
1372 function selection_classed(name, value) {
1373   var names = classArray(name + "");
1374
1375   if (arguments.length < 2) {
1376     var list = classList(this.node()), i = -1, n = names.length;
1377     while (++i < n) if (!list.contains(names[i])) return false;
1378     return true;
1379   }
1380
1381   return this.each((typeof value === "function"
1382       ? classedFunction : value
1383       ? classedTrue
1384       : classedFalse)(names, value));
1385 }
1386
1387 function textRemove() {
1388   this.textContent = "";
1389 }
1390
1391 function textConstant(value) {
1392   return function() {
1393     this.textContent = value;
1394   };
1395 }
1396
1397 function textFunction(value) {
1398   return function() {
1399     var v = value.apply(this, arguments);
1400     this.textContent = v == null ? "" : v;
1401   };
1402 }
1403
1404 function selection_text(value) {
1405   return arguments.length
1406       ? this.each(value == null
1407           ? textRemove : (typeof value === "function"
1408           ? textFunction
1409           : textConstant)(value))
1410       : this.node().textContent;
1411 }
1412
1413 function htmlRemove() {
1414   this.innerHTML = "";
1415 }
1416
1417 function htmlConstant(value) {
1418   return function() {
1419     this.innerHTML = value;
1420   };
1421 }
1422
1423 function htmlFunction(value) {
1424   return function() {
1425     var v = value.apply(this, arguments);
1426     this.innerHTML = v == null ? "" : v;
1427   };
1428 }
1429
1430 function selection_html(value) {
1431   return arguments.length
1432       ? this.each(value == null
1433           ? htmlRemove : (typeof value === "function"
1434           ? htmlFunction
1435           : htmlConstant)(value))
1436       : this.node().innerHTML;
1437 }
1438
1439 function raise() {
1440   if (this.nextSibling) this.parentNode.appendChild(this);
1441 }
1442
1443 function selection_raise() {
1444   return this.each(raise);
1445 }
1446
1447 function lower() {
1448   if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild);
1449 }
1450
1451 function selection_lower() {
1452   return this.each(lower);
1453 }
1454
1455 function selection_append(name) {
1456   var create = typeof name === "function" ? name : creator(name);
1457   return this.select(function() {
1458     return this.appendChild(create.apply(this, arguments));
1459   });
1460 }
1461
1462 function constantNull() {
1463   return null;
1464 }
1465
1466 function selection_insert(name, before) {
1467   var create = typeof name === "function" ? name : creator(name),
1468       select = before == null ? constantNull : typeof before === "function" ? before : selector(before);
1469   return this.select(function() {
1470     return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null);
1471   });
1472 }
1473
1474 function remove() {
1475   var parent = this.parentNode;
1476   if (parent) parent.removeChild(this);
1477 }
1478
1479 function selection_remove() {
1480   return this.each(remove);
1481 }
1482
1483 function selection_cloneShallow() {
1484   return this.parentNode.insertBefore(this.cloneNode(false), this.nextSibling);
1485 }
1486
1487 function selection_cloneDeep() {
1488   return this.parentNode.insertBefore(this.cloneNode(true), this.nextSibling);
1489 }
1490
1491 function selection_clone(deep) {
1492   return this.select(deep ? selection_cloneDeep : selection_cloneShallow);
1493 }
1494
1495 function selection_datum(value) {
1496   return arguments.length
1497       ? this.property("__data__", value)
1498       : this.node().__data__;
1499 }
1500
1501 var filterEvents = {};
1502
1503 var event = null;
1504
1505 if (typeof document !== "undefined") {
1506   var element$1 = document.documentElement;
1507   if (!("onmouseenter" in element$1)) {
1508     filterEvents = {mouseenter: "mouseover", mouseleave: "mouseout"};
1509   }
1510 }
1511
1512 function filterContextListener(listener, index, group) {
1513   listener = contextListener(listener, index, group);
1514   return function(event) {
1515     var related = event.relatedTarget;
1516     if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) {
1517       listener.call(this, event);
1518     }
1519   };
1520 }
1521
1522 function contextListener(listener, index, group) {
1523   return function(event1) {
1524     var event0 = event; // Events can be reentrant (e.g., focus).
1525     event = event1;
1526     try {
1527       listener.call(this, this.__data__, index, group);
1528     } finally {
1529       event = event0;
1530     }
1531   };
1532 }
1533
1534 function parseTypenames$1(typenames) {
1535   return typenames.trim().split(/^|\s+/).map(function(t) {
1536     var name = "", i = t.indexOf(".");
1537     if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
1538     return {type: t, name: name};
1539   });
1540 }
1541
1542 function onRemove(typename) {
1543   return function() {
1544     var on = this.__on;
1545     if (!on) return;
1546     for (var j = 0, i = -1, m = on.length, o; j < m; ++j) {
1547       if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) {
1548         this.removeEventListener(o.type, o.listener, o.capture);
1549       } else {
1550         on[++i] = o;
1551       }
1552     }
1553     if (++i) on.length = i;
1554     else delete this.__on;
1555   };
1556 }
1557
1558 function onAdd(typename, value, capture) {
1559   var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener;
1560   return function(d, i, group) {
1561     var on = this.__on, o, listener = wrap(value, i, group);
1562     if (on) for (var j = 0, m = on.length; j < m; ++j) {
1563       if ((o = on[j]).type === typename.type && o.name === typename.name) {
1564         this.removeEventListener(o.type, o.listener, o.capture);
1565         this.addEventListener(o.type, o.listener = listener, o.capture = capture);
1566         o.value = value;
1567         return;
1568       }
1569     }
1570     this.addEventListener(typename.type, listener, capture);
1571     o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture};
1572     if (!on) this.__on = [o];
1573     else on.push(o);
1574   };
1575 }
1576
1577 function selection_on(typename, value, capture) {
1578   var typenames = parseTypenames$1(typename + ""), i, n = typenames.length, t;
1579
1580   if (arguments.length < 2) {
1581     var on = this.node().__on;
1582     if (on) for (var j = 0, m = on.length, o; j < m; ++j) {
1583       for (i = 0, o = on[j]; i < n; ++i) {
1584         if ((t = typenames[i]).type === o.type && t.name === o.name) {
1585           return o.value;
1586         }
1587       }
1588     }
1589     return;
1590   }
1591
1592   on = value ? onAdd : onRemove;
1593   if (capture == null) capture = false;
1594   for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture));
1595   return this;
1596 }
1597
1598 function customEvent(event1, listener, that, args) {
1599   var event0 = event;
1600   event1.sourceEvent = event;
1601   event = event1;
1602   try {
1603     return listener.apply(that, args);
1604   } finally {
1605     event = event0;
1606   }
1607 }
1608
1609 function dispatchEvent(node, type, params) {
1610   var window = defaultView(node),
1611       event = window.CustomEvent;
1612
1613   if (typeof event === "function") {
1614     event = new event(type, params);
1615   } else {
1616     event = window.document.createEvent("Event");
1617     if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;
1618     else event.initEvent(type, false, false);
1619   }
1620
1621   node.dispatchEvent(event);
1622 }
1623
1624 function dispatchConstant(type, params) {
1625   return function() {
1626     return dispatchEvent(this, type, params);
1627   };
1628 }
1629
1630 function dispatchFunction(type, params) {
1631   return function() {
1632     return dispatchEvent(this, type, params.apply(this, arguments));
1633   };
1634 }
1635
1636 function selection_dispatch(type, params) {
1637   return this.each((typeof params === "function"
1638       ? dispatchFunction
1639       : dispatchConstant)(type, params));
1640 }
1641
1642 var root = [null];
1643
1644 function Selection(groups, parents) {
1645   this._groups = groups;
1646   this._parents = parents;
1647 }
1648
1649 function selection() {
1650   return new Selection([[document.documentElement]], root);
1651 }
1652
1653 Selection.prototype = selection.prototype = {
1654   constructor: Selection,
1655   select: selection_select,
1656   selectAll: selection_selectAll,
1657   filter: selection_filter,
1658   data: selection_data,
1659   enter: selection_enter,
1660   exit: selection_exit,
1661   merge: selection_merge,
1662   order: selection_order,
1663   sort: selection_sort,
1664   call: selection_call,
1665   nodes: selection_nodes,
1666   node: selection_node,
1667   size: selection_size,
1668   empty: selection_empty,
1669   each: selection_each,
1670   attr: selection_attr,
1671   style: selection_style,
1672   property: selection_property,
1673   classed: selection_classed,
1674   text: selection_text,
1675   html: selection_html,
1676   raise: selection_raise,
1677   lower: selection_lower,
1678   append: selection_append,
1679   insert: selection_insert,
1680   remove: selection_remove,
1681   clone: selection_clone,
1682   datum: selection_datum,
1683   on: selection_on,
1684   dispatch: selection_dispatch
1685 };
1686
1687 function d3_select(selector) {
1688   return typeof selector === "string"
1689       ? new Selection([[document.querySelector(selector)]], [document.documentElement])
1690       : new Selection([[selector]], root);
1691 }
1692
1693 function create(name) {
1694   return d3_select(creator(name).call(document.documentElement));
1695 }
1696
1697 var nextId = 0;
1698
1699 function local() {
1700   return new Local;
1701 }
1702
1703 function Local() {
1704   this._ = "@" + (++nextId).toString(36);
1705 }
1706
1707 Local.prototype = local.prototype = {
1708   constructor: Local,
1709   get: function(node) {
1710     var id = this._;
1711     while (!(id in node)) if (!(node = node.parentNode)) return;
1712     return node[id];
1713   },
1714   set: function(node, value) {
1715     return node[this._] = value;
1716   },
1717   remove: function(node) {
1718     return this._ in node && delete node[this._];
1719   },
1720   toString: function() {
1721     return this._;
1722   }
1723 };
1724
1725 function sourceEvent() {
1726   var current = event, source;
1727   while (source = current.sourceEvent) current = source;
1728   return current;
1729 }
1730
1731 function point(node, event) {
1732   var svg = node.ownerSVGElement || node;
1733
1734   if (svg.createSVGPoint) {
1735     var point = svg.createSVGPoint();
1736     point.x = event.clientX, point.y = event.clientY;
1737     point = point.matrixTransform(node.getScreenCTM().inverse());
1738     return [point.x, point.y];
1739   }
1740
1741   var rect = node.getBoundingClientRect();
1742   return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];
1743 }
1744
1745 function d3_mouse(node) {
1746   var event = sourceEvent();
1747   if (event.changedTouches) event = event.changedTouches[0];
1748   return point(node, event);
1749 }
1750
1751 function d3_selectAll(selector) {
1752   return typeof selector === "string"
1753       ? new Selection([document.querySelectorAll(selector)], [document.documentElement])
1754       : new Selection([selector == null ? [] : selector], root);
1755 }
1756
1757 function touch(node, touches, identifier) {
1758   if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches;
1759
1760   for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) {
1761     if ((touch = touches[i]).identifier === identifier) {
1762       return point(node, touch);
1763     }
1764   }
1765
1766   return null;
1767 }
1768
1769 function d3_touches(node, touches) {
1770   if (touches == null) touches = sourceEvent().touches;
1771
1772   for (var i = 0, n = touches ? touches.length : 0, points = new Array(n); i < n; ++i) {
1773     points[i] = point(node, touches[i]);
1774   }
1775
1776   return points;
1777 }
1778
1779 function nopropagation() {
1780   event.stopImmediatePropagation();
1781 }
1782
1783 function noevent() {
1784   event.preventDefault();
1785   event.stopImmediatePropagation();
1786 }
1787
1788 function dragDisable(view) {
1789   var root = view.document.documentElement,
1790       selection = d3_select(view).on("dragstart.drag", noevent, true);
1791   if ("onselectstart" in root) {
1792     selection.on("selectstart.drag", noevent, true);
1793   } else {
1794     root.__noselect = root.style.MozUserSelect;
1795     root.style.MozUserSelect = "none";
1796   }
1797 }
1798
1799 function yesdrag(view, noclick) {
1800   var root = view.document.documentElement,
1801       selection = d3_select(view).on("dragstart.drag", null);
1802   if (noclick) {
1803     selection.on("click.drag", noevent, true);
1804     setTimeout(function() { selection.on("click.drag", null); }, 0);
1805   }
1806   if ("onselectstart" in root) {
1807     selection.on("selectstart.drag", null);
1808   } else {
1809     root.style.MozUserSelect = root.__noselect;
1810     delete root.__noselect;
1811   }
1812 }
1813
1814 function constant$2(x) {
1815   return function() {
1816     return x;
1817   };
1818 }
1819
1820 function DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch) {
1821   this.target = target;
1822   this.type = type;
1823   this.subject = subject;
1824   this.identifier = id;
1825   this.active = active;
1826   this.x = x;
1827   this.y = y;
1828   this.dx = dx;
1829   this.dy = dy;
1830   this._ = dispatch;
1831 }
1832
1833 DragEvent.prototype.on = function() {
1834   var value = this._.on.apply(this._, arguments);
1835   return value === this._ ? this : value;
1836 };
1837
1838 // Ignore right-click, since that should open the context menu.
1839 function defaultFilter() {
1840   return !event.button;
1841 }
1842
1843 function defaultContainer() {
1844   return this.parentNode;
1845 }
1846
1847 function defaultSubject(d) {
1848   return d == null ? {x: event.x, y: event.y} : d;
1849 }
1850
1851 function defaultTouchable() {
1852   return "ontouchstart" in this;
1853 }
1854
1855 function drag() {
1856   var filter = defaultFilter,
1857       container = defaultContainer,
1858       subject = defaultSubject,
1859       touchable = defaultTouchable,
1860       gestures = {},
1861       listeners = dispatch("start", "drag", "end"),
1862       active = 0,
1863       mousedownx,
1864       mousedowny,
1865       mousemoving,
1866       touchending,
1867       clickDistance2 = 0;
1868
1869   function drag(selection) {
1870     selection
1871         .on("mousedown.drag", mousedowned)
1872       .filter(touchable)
1873         .on("touchstart.drag", touchstarted)
1874         .on("touchmove.drag", touchmoved)
1875         .on("touchend.drag touchcancel.drag", touchended)
1876         .style("touch-action", "none")
1877         .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
1878   }
1879
1880   function mousedowned() {
1881     if (touchending || !filter.apply(this, arguments)) return;
1882     var gesture = beforestart("mouse", container.apply(this, arguments), d3_mouse, this, arguments);
1883     if (!gesture) return;
1884     d3_select(event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true);
1885     dragDisable(event.view);
1886     nopropagation();
1887     mousemoving = false;
1888     mousedownx = event.clientX;
1889     mousedowny = event.clientY;
1890     gesture("start");
1891   }
1892
1893   function mousemoved() {
1894     noevent();
1895     if (!mousemoving) {
1896       var dx = event.clientX - mousedownx, dy = event.clientY - mousedowny;
1897       mousemoving = dx * dx + dy * dy > clickDistance2;
1898     }
1899     gestures.mouse("drag");
1900   }
1901
1902   function mouseupped() {
1903     d3_select(event.view).on("mousemove.drag mouseup.drag", null);
1904     yesdrag(event.view, mousemoving);
1905     noevent();
1906     gestures.mouse("end");
1907   }
1908
1909   function touchstarted() {
1910     if (!filter.apply(this, arguments)) return;
1911     var touches = event.changedTouches,
1912         c = container.apply(this, arguments),
1913         n = touches.length, i, gesture;
1914
1915     for (i = 0; i < n; ++i) {
1916       if (gesture = beforestart(touches[i].identifier, c, touch, this, arguments)) {
1917         nopropagation();
1918         gesture("start");
1919       }
1920     }
1921   }
1922
1923   function touchmoved() {
1924     var touches = event.changedTouches,
1925         n = touches.length, i, gesture;
1926
1927     for (i = 0; i < n; ++i) {
1928       if (gesture = gestures[touches[i].identifier]) {
1929         noevent();
1930         gesture("drag");
1931       }
1932     }
1933   }
1934
1935   function touchended() {
1936     var touches = event.changedTouches,
1937         n = touches.length, i, gesture;
1938
1939     if (touchending) clearTimeout(touchending);
1940     touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
1941     for (i = 0; i < n; ++i) {
1942       if (gesture = gestures[touches[i].identifier]) {
1943         nopropagation();
1944         gesture("end");
1945       }
1946     }
1947   }
1948
1949   function beforestart(id, container, point, that, args) {
1950     var p = point(container, id), s, dx, dy,
1951         sublisteners = listeners.copy();
1952
1953     if (!customEvent(new DragEvent(drag, "beforestart", s, id, active, p[0], p[1], 0, 0, sublisteners), function() {
1954       if ((event.subject = s = subject.apply(that, args)) == null) return false;
1955       dx = s.x - p[0] || 0;
1956       dy = s.y - p[1] || 0;
1957       return true;
1958     })) return;
1959
1960     return function gesture(type) {
1961       var p0 = p, n;
1962       switch (type) {
1963         case "start": gestures[id] = gesture, n = active++; break;
1964         case "end": delete gestures[id], --active; // nobreak
1965         case "drag": p = point(container, id), n = active; break;
1966       }
1967       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]);
1968     };
1969   }
1970
1971   drag.filter = function(_) {
1972     return arguments.length ? (filter = typeof _ === "function" ? _ : constant$2(!!_), drag) : filter;
1973   };
1974
1975   drag.container = function(_) {
1976     return arguments.length ? (container = typeof _ === "function" ? _ : constant$2(_), drag) : container;
1977   };
1978
1979   drag.subject = function(_) {
1980     return arguments.length ? (subject = typeof _ === "function" ? _ : constant$2(_), drag) : subject;
1981   };
1982
1983   drag.touchable = function(_) {
1984     return arguments.length ? (touchable = typeof _ === "function" ? _ : constant$2(!!_), drag) : touchable;
1985   };
1986
1987   drag.on = function() {
1988     var value = listeners.on.apply(listeners, arguments);
1989     return value === listeners ? drag : value;
1990   };
1991
1992   drag.clickDistance = function(_) {
1993     return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2);
1994   };
1995
1996   return drag;
1997 }
1998
1999 function define(constructor, factory, prototype) {
2000   constructor.prototype = factory.prototype = prototype;
2001   prototype.constructor = constructor;
2002 }
2003
2004 function extend(parent, definition) {
2005   var prototype = Object.create(parent.prototype);
2006   for (var key in definition) prototype[key] = definition[key];
2007   return prototype;
2008 }
2009
2010 function Color() {}
2011
2012 var darker = 0.7;
2013 var brighter = 1 / darker;
2014
2015 var reI = "\\s*([+-]?\\d+)\\s*";
2016 var reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*";
2017 var reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*";
2018 var reHex3 = /^#([0-9a-f]{3})$/;
2019 var reHex6 = /^#([0-9a-f]{6})$/;
2020 var reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$");
2021 var reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$");
2022 var reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$");
2023 var reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$");
2024 var reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$");
2025 var reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$");
2026
2027 var named = {
2028   aliceblue: 0xf0f8ff,
2029   antiquewhite: 0xfaebd7,
2030   aqua: 0x00ffff,
2031   aquamarine: 0x7fffd4,
2032   azure: 0xf0ffff,
2033   beige: 0xf5f5dc,
2034   bisque: 0xffe4c4,
2035   black: 0x000000,
2036   blanchedalmond: 0xffebcd,
2037   blue: 0x0000ff,
2038   blueviolet: 0x8a2be2,
2039   brown: 0xa52a2a,
2040   burlywood: 0xdeb887,
2041   cadetblue: 0x5f9ea0,
2042   chartreuse: 0x7fff00,
2043   chocolate: 0xd2691e,
2044   coral: 0xff7f50,
2045   cornflowerblue: 0x6495ed,
2046   cornsilk: 0xfff8dc,
2047   crimson: 0xdc143c,
2048   cyan: 0x00ffff,
2049   darkblue: 0x00008b,
2050   darkcyan: 0x008b8b,
2051   darkgoldenrod: 0xb8860b,
2052   darkgray: 0xa9a9a9,
2053   darkgreen: 0x006400,
2054   darkgrey: 0xa9a9a9,
2055   darkkhaki: 0xbdb76b,
2056   darkmagenta: 0x8b008b,
2057   darkolivegreen: 0x556b2f,
2058   darkorange: 0xff8c00,
2059   darkorchid: 0x9932cc,
2060   darkred: 0x8b0000,
2061   darksalmon: 0xe9967a,
2062   darkseagreen: 0x8fbc8f,
2063   darkslateblue: 0x483d8b,
2064   darkslategray: 0x2f4f4f,
2065   darkslategrey: 0x2f4f4f,
2066   darkturquoise: 0x00ced1,
2067   darkviolet: 0x9400d3,
2068   deeppink: 0xff1493,
2069   deepskyblue: 0x00bfff,
2070   dimgray: 0x696969,
2071   dimgrey: 0x696969,
2072   dodgerblue: 0x1e90ff,
2073   firebrick: 0xb22222,
2074   floralwhite: 0xfffaf0,
2075   forestgreen: 0x228b22,
2076   fuchsia: 0xff00ff,
2077   gainsboro: 0xdcdcdc,
2078   ghostwhite: 0xf8f8ff,
2079   gold: 0xffd700,
2080   goldenrod: 0xdaa520,
2081   gray: 0x808080,
2082   green: 0x008000,
2083   greenyellow: 0xadff2f,
2084   grey: 0x808080,
2085   honeydew: 0xf0fff0,
2086   hotpink: 0xff69b4,
2087   indianred: 0xcd5c5c,
2088   indigo: 0x4b0082,
2089   ivory: 0xfffff0,
2090   khaki: 0xf0e68c,
2091   lavender: 0xe6e6fa,
2092   lavenderblush: 0xfff0f5,
2093   lawngreen: 0x7cfc00,
2094   lemonchiffon: 0xfffacd,
2095   lightblue: 0xadd8e6,
2096   lightcoral: 0xf08080,
2097   lightcyan: 0xe0ffff,
2098   lightgoldenrodyellow: 0xfafad2,
2099   lightgray: 0xd3d3d3,
2100   lightgreen: 0x90ee90,
2101   lightgrey: 0xd3d3d3,
2102   lightpink: 0xffb6c1,
2103   lightsalmon: 0xffa07a,
2104   lightseagreen: 0x20b2aa,
2105   lightskyblue: 0x87cefa,
2106   lightslategray: 0x778899,
2107   lightslategrey: 0x778899,
2108   lightsteelblue: 0xb0c4de,
2109   lightyellow: 0xffffe0,
2110   lime: 0x00ff00,
2111   limegreen: 0x32cd32,
2112   linen: 0xfaf0e6,
2113   magenta: 0xff00ff,
2114   maroon: 0x800000,
2115   mediumaquamarine: 0x66cdaa,
2116   mediumblue: 0x0000cd,
2117   mediumorchid: 0xba55d3,
2118   mediumpurple: 0x9370db,
2119   mediumseagreen: 0x3cb371,
2120   mediumslateblue: 0x7b68ee,
2121   mediumspringgreen: 0x00fa9a,
2122   mediumturquoise: 0x48d1cc,
2123   mediumvioletred: 0xc71585,
2124   midnightblue: 0x191970,
2125   mintcream: 0xf5fffa,
2126   mistyrose: 0xffe4e1,
2127   moccasin: 0xffe4b5,
2128   navajowhite: 0xffdead,
2129   navy: 0x000080,
2130   oldlace: 0xfdf5e6,
2131   olive: 0x808000,
2132   olivedrab: 0x6b8e23,
2133   orange: 0xffa500,
2134   orangered: 0xff4500,
2135   orchid: 0xda70d6,
2136   palegoldenrod: 0xeee8aa,
2137   palegreen: 0x98fb98,
2138   paleturquoise: 0xafeeee,
2139   palevioletred: 0xdb7093,
2140   papayawhip: 0xffefd5,
2141   peachpuff: 0xffdab9,
2142   peru: 0xcd853f,
2143   pink: 0xffc0cb,
2144   plum: 0xdda0dd,
2145   powderblue: 0xb0e0e6,
2146   purple: 0x800080,
2147   rebeccapurple: 0x663399,
2148   red: 0xff0000,
2149   rosybrown: 0xbc8f8f,
2150   royalblue: 0x4169e1,
2151   saddlebrown: 0x8b4513,
2152   salmon: 0xfa8072,
2153   sandybrown: 0xf4a460,
2154   seagreen: 0x2e8b57,
2155   seashell: 0xfff5ee,
2156   sienna: 0xa0522d,
2157   silver: 0xc0c0c0,
2158   skyblue: 0x87ceeb,
2159   slateblue: 0x6a5acd,
2160   slategray: 0x708090,
2161   slategrey: 0x708090,
2162   snow: 0xfffafa,
2163   springgreen: 0x00ff7f,
2164   steelblue: 0x4682b4,
2165   tan: 0xd2b48c,
2166   teal: 0x008080,
2167   thistle: 0xd8bfd8,
2168   tomato: 0xff6347,
2169   turquoise: 0x40e0d0,
2170   violet: 0xee82ee,
2171   wheat: 0xf5deb3,
2172   white: 0xffffff,
2173   whitesmoke: 0xf5f5f5,
2174   yellow: 0xffff00,
2175   yellowgreen: 0x9acd32
2176 };
2177
2178 define(Color, color, {
2179   displayable: function() {
2180     return this.rgb().displayable();
2181   },
2182   toString: function() {
2183     return this.rgb() + "";
2184   }
2185 });
2186
2187 function color(format) {
2188   var m;
2189   format = (format + "").trim().toLowerCase();
2190   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
2191       : (m = reHex6.exec(format)) ? rgbn(parseInt(m[1], 16)) // #ff0000
2192       : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)
2193       : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)
2194       : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)
2195       : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)
2196       : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)
2197       : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)
2198       : named.hasOwnProperty(format) ? rgbn(named[format])
2199       : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0)
2200       : null;
2201 }
2202
2203 function rgbn(n) {
2204   return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);
2205 }
2206
2207 function rgba(r, g, b, a) {
2208   if (a <= 0) r = g = b = NaN;
2209   return new Rgb(r, g, b, a);
2210 }
2211
2212 function rgbConvert(o) {
2213   if (!(o instanceof Color)) o = color(o);
2214   if (!o) return new Rgb;
2215   o = o.rgb();
2216   return new Rgb(o.r, o.g, o.b, o.opacity);
2217 }
2218
2219 function rgb(r, g, b, opacity) {
2220   return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);
2221 }
2222
2223 function Rgb(r, g, b, opacity) {
2224   this.r = +r;
2225   this.g = +g;
2226   this.b = +b;
2227   this.opacity = +opacity;
2228 }
2229
2230 define(Rgb, rgb, extend(Color, {
2231   brighter: function(k) {
2232     k = k == null ? brighter : Math.pow(brighter, k);
2233     return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
2234   },
2235   darker: function(k) {
2236     k = k == null ? darker : Math.pow(darker, k);
2237     return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
2238   },
2239   rgb: function() {
2240     return this;
2241   },
2242   displayable: function() {
2243     return (0 <= this.r && this.r <= 255)
2244         && (0 <= this.g && this.g <= 255)
2245         && (0 <= this.b && this.b <= 255)
2246         && (0 <= this.opacity && this.opacity <= 1);
2247   },
2248   toString: function() {
2249     var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));
2250     return (a === 1 ? "rgb(" : "rgba(")
2251         + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", "
2252         + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", "
2253         + Math.max(0, Math.min(255, Math.round(this.b) || 0))
2254         + (a === 1 ? ")" : ", " + a + ")");
2255   }
2256 }));
2257
2258 function hsla(h, s, l, a) {
2259   if (a <= 0) h = s = l = NaN;
2260   else if (l <= 0 || l >= 1) h = s = NaN;
2261   else if (s <= 0) h = NaN;
2262   return new Hsl(h, s, l, a);
2263 }
2264
2265 function hslConvert(o) {
2266   if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);
2267   if (!(o instanceof Color)) o = color(o);
2268   if (!o) return new Hsl;
2269   if (o instanceof Hsl) return o;
2270   o = o.rgb();
2271   var r = o.r / 255,
2272       g = o.g / 255,
2273       b = o.b / 255,
2274       min = Math.min(r, g, b),
2275       max = Math.max(r, g, b),
2276       h = NaN,
2277       s = max - min,
2278       l = (max + min) / 2;
2279   if (s) {
2280     if (r === max) h = (g - b) / s + (g < b) * 6;
2281     else if (g === max) h = (b - r) / s + 2;
2282     else h = (r - g) / s + 4;
2283     s /= l < 0.5 ? max + min : 2 - max - min;
2284     h *= 60;
2285   } else {
2286     s = l > 0 && l < 1 ? 0 : h;
2287   }
2288   return new Hsl(h, s, l, o.opacity);
2289 }
2290
2291 function hsl(h, s, l, opacity) {
2292   return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);
2293 }
2294
2295 function Hsl(h, s, l, opacity) {
2296   this.h = +h;
2297   this.s = +s;
2298   this.l = +l;
2299   this.opacity = +opacity;
2300 }
2301
2302 define(Hsl, hsl, extend(Color, {
2303   brighter: function(k) {
2304     k = k == null ? brighter : Math.pow(brighter, k);
2305     return new Hsl(this.h, this.s, this.l * k, this.opacity);
2306   },
2307   darker: function(k) {
2308     k = k == null ? darker : Math.pow(darker, k);
2309     return new Hsl(this.h, this.s, this.l * k, this.opacity);
2310   },
2311   rgb: function() {
2312     var h = this.h % 360 + (this.h < 0) * 360,
2313         s = isNaN(h) || isNaN(this.s) ? 0 : this.s,
2314         l = this.l,
2315         m2 = l + (l < 0.5 ? l : 1 - l) * s,
2316         m1 = 2 * l - m2;
2317     return new Rgb(
2318       hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),
2319       hsl2rgb(h, m1, m2),
2320       hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),
2321       this.opacity
2322     );
2323   },
2324   displayable: function() {
2325     return (0 <= this.s && this.s <= 1 || isNaN(this.s))
2326         && (0 <= this.l && this.l <= 1)
2327         && (0 <= this.opacity && this.opacity <= 1);
2328   }
2329 }));
2330
2331 /* From FvD 13.37, CSS Color Module Level 3 */
2332 function hsl2rgb(h, m1, m2) {
2333   return (h < 60 ? m1 + (m2 - m1) * h / 60
2334       : h < 180 ? m2
2335       : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60
2336       : m1) * 255;
2337 }
2338
2339 var deg2rad = Math.PI / 180;
2340 var rad2deg = 180 / Math.PI;
2341
2342 var Kn = 18;
2343 var Xn = 0.950470;
2344 var Yn = 1;
2345 var Zn = 1.088830;
2346 var t0 = 4 / 29;
2347 var t1 = 6 / 29;
2348 var t2 = 3 * t1 * t1;
2349 var t3 = t1 * t1 * t1;
2350
2351 function labConvert(o) {
2352   if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity);
2353   if (o instanceof Hcl) {
2354     var h = o.h * deg2rad;
2355     return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity);
2356   }
2357   if (!(o instanceof Rgb)) o = rgbConvert(o);
2358   var b = rgb2xyz(o.r),
2359       a = rgb2xyz(o.g),
2360       l = rgb2xyz(o.b),
2361       x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn),
2362       y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.0721750 * l) / Yn),
2363       z = xyz2lab((0.0193339 * b + 0.1191920 * a + 0.9503041 * l) / Zn);
2364   return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity);
2365 }
2366
2367 function lab(l, a, b, opacity) {
2368   return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity);
2369 }
2370
2371 function Lab(l, a, b, opacity) {
2372   this.l = +l;
2373   this.a = +a;
2374   this.b = +b;
2375   this.opacity = +opacity;
2376 }
2377
2378 define(Lab, lab, extend(Color, {
2379   brighter: function(k) {
2380     return new Lab(this.l + Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);
2381   },
2382   darker: function(k) {
2383     return new Lab(this.l - Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);
2384   },
2385   rgb: function() {
2386     var y = (this.l + 16) / 116,
2387         x = isNaN(this.a) ? y : y + this.a / 500,
2388         z = isNaN(this.b) ? y : y - this.b / 200;
2389     y = Yn * lab2xyz(y);
2390     x = Xn * lab2xyz(x);
2391     z = Zn * lab2xyz(z);
2392     return new Rgb(
2393       xyz2rgb( 3.2404542 * x - 1.5371385 * y - 0.4985314 * z), // D65 -> sRGB
2394       xyz2rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z),
2395       xyz2rgb( 0.0556434 * x - 0.2040259 * y + 1.0572252 * z),
2396       this.opacity
2397     );
2398   }
2399 }));
2400
2401 function xyz2lab(t) {
2402   return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0;
2403 }
2404
2405 function lab2xyz(t) {
2406   return t > t1 ? t * t * t : t2 * (t - t0);
2407 }
2408
2409 function xyz2rgb(x) {
2410   return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055);
2411 }
2412
2413 function rgb2xyz(x) {
2414   return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
2415 }
2416
2417 function hclConvert(o) {
2418   if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity);
2419   if (!(o instanceof Lab)) o = labConvert(o);
2420   var h = Math.atan2(o.b, o.a) * rad2deg;
2421   return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity);
2422 }
2423
2424 function hcl(h, c, l, opacity) {
2425   return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity);
2426 }
2427
2428 function Hcl(h, c, l, opacity) {
2429   this.h = +h;
2430   this.c = +c;
2431   this.l = +l;
2432   this.opacity = +opacity;
2433 }
2434
2435 define(Hcl, hcl, extend(Color, {
2436   brighter: function(k) {
2437     return new Hcl(this.h, this.c, this.l + Kn * (k == null ? 1 : k), this.opacity);
2438   },
2439   darker: function(k) {
2440     return new Hcl(this.h, this.c, this.l - Kn * (k == null ? 1 : k), this.opacity);
2441   },
2442   rgb: function() {
2443     return labConvert(this).rgb();
2444   }
2445 }));
2446
2447 var A = -0.14861;
2448 var B = +1.78277;
2449 var C = -0.29227;
2450 var D = -0.90649;
2451 var E = +1.97294;
2452 var ED = E * D;
2453 var EB = E * B;
2454 var BC_DA = B * C - D * A;
2455
2456 function cubehelixConvert(o) {
2457   if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity);
2458   if (!(o instanceof Rgb)) o = rgbConvert(o);
2459   var r = o.r / 255,
2460       g = o.g / 255,
2461       b = o.b / 255,
2462       l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB),
2463       bl = b - l,
2464       k = (E * (g - l) - C * bl) / D,
2465       s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1
2466       h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN;
2467   return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity);
2468 }
2469
2470 function cubehelix(h, s, l, opacity) {
2471   return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity);
2472 }
2473
2474 function Cubehelix(h, s, l, opacity) {
2475   this.h = +h;
2476   this.s = +s;
2477   this.l = +l;
2478   this.opacity = +opacity;
2479 }
2480
2481 define(Cubehelix, cubehelix, extend(Color, {
2482   brighter: function(k) {
2483     k = k == null ? brighter : Math.pow(brighter, k);
2484     return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
2485   },
2486   darker: function(k) {
2487     k = k == null ? darker : Math.pow(darker, k);
2488     return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
2489   },
2490   rgb: function() {
2491     var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad,
2492         l = +this.l,
2493         a = isNaN(this.s) ? 0 : this.s * l * (1 - l),
2494         cosh = Math.cos(h),
2495         sinh = Math.sin(h);
2496     return new Rgb(
2497       255 * (l + a * (A * cosh + B * sinh)),
2498       255 * (l + a * (C * cosh + D * sinh)),
2499       255 * (l + a * (E * cosh)),
2500       this.opacity
2501     );
2502   }
2503 }));
2504
2505 function basis(t1, v0, v1, v2, v3) {
2506   var t2 = t1 * t1, t3 = t2 * t1;
2507   return ((1 - 3 * t1 + 3 * t2 - t3) * v0
2508       + (4 - 6 * t2 + 3 * t3) * v1
2509       + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2
2510       + t3 * v3) / 6;
2511 }
2512
2513 function basis$1(values) {
2514   var n = values.length - 1;
2515   return function(t) {
2516     var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n),
2517         v1 = values[i],
2518         v2 = values[i + 1],
2519         v0 = i > 0 ? values[i - 1] : 2 * v1 - v2,
2520         v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1;
2521     return basis((t - i / n) * n, v0, v1, v2, v3);
2522   };
2523 }
2524
2525 function basisClosed(values) {
2526   var n = values.length;
2527   return function(t) {
2528     var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n),
2529         v0 = values[(i + n - 1) % n],
2530         v1 = values[i % n],
2531         v2 = values[(i + 1) % n],
2532         v3 = values[(i + 2) % n];
2533     return basis((t - i / n) * n, v0, v1, v2, v3);
2534   };
2535 }
2536
2537 function constant$3(x) {
2538   return function() {
2539     return x;
2540   };
2541 }
2542
2543 function linear(a, d) {
2544   return function(t) {
2545     return a + t * d;
2546   };
2547 }
2548
2549 function exponential(a, b, y) {
2550   return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {
2551     return Math.pow(a + t * b, y);
2552   };
2553 }
2554
2555 function hue(a, b) {
2556   var d = b - a;
2557   return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant$3(isNaN(a) ? b : a);
2558 }
2559
2560 function gamma(y) {
2561   return (y = +y) === 1 ? nogamma : function(a, b) {
2562     return b - a ? exponential(a, b, y) : constant$3(isNaN(a) ? b : a);
2563   };
2564 }
2565
2566 function nogamma(a, b) {
2567   var d = b - a;
2568   return d ? linear(a, d) : constant$3(isNaN(a) ? b : a);
2569 }
2570
2571 var d3_interpolateRgb = (function rgbGamma(y) {
2572   var color = gamma(y);
2573
2574   function rgb$$1(start, end) {
2575     var r = color((start = rgb(start)).r, (end = rgb(end)).r),
2576         g = color(start.g, end.g),
2577         b = color(start.b, end.b),
2578         opacity = nogamma(start.opacity, end.opacity);
2579     return function(t) {
2580       start.r = r(t);
2581       start.g = g(t);
2582       start.b = b(t);
2583       start.opacity = opacity(t);
2584       return start + "";
2585     };
2586   }
2587
2588   rgb$$1.gamma = rgbGamma;
2589
2590   return rgb$$1;
2591 })(1);
2592
2593 function rgbSpline(spline) {
2594   return function(colors) {
2595     var n = colors.length,
2596         r = new Array(n),
2597         g = new Array(n),
2598         b = new Array(n),
2599         i, color;
2600     for (i = 0; i < n; ++i) {
2601       color = rgb(colors[i]);
2602       r[i] = color.r || 0;
2603       g[i] = color.g || 0;
2604       b[i] = color.b || 0;
2605     }
2606     r = spline(r);
2607     g = spline(g);
2608     b = spline(b);
2609     color.opacity = 1;
2610     return function(t) {
2611       color.r = r(t);
2612       color.g = g(t);
2613       color.b = b(t);
2614       return color + "";
2615     };
2616   };
2617 }
2618
2619 var rgbBasis = rgbSpline(basis$1);
2620 var rgbBasisClosed = rgbSpline(basisClosed);
2621
2622 function array$1(a, b) {
2623   var nb = b ? b.length : 0,
2624       na = a ? Math.min(nb, a.length) : 0,
2625       x = new Array(na),
2626       c = new Array(nb),
2627       i;
2628
2629   for (i = 0; i < na; ++i) x[i] = d3_interpolate(a[i], b[i]);
2630   for (; i < nb; ++i) c[i] = b[i];
2631
2632   return function(t) {
2633     for (i = 0; i < na; ++i) c[i] = x[i](t);
2634     return c;
2635   };
2636 }
2637
2638 function date(a, b) {
2639   var d = new Date;
2640   return a = +a, b -= a, function(t) {
2641     return d.setTime(a + b * t), d;
2642   };
2643 }
2644
2645 function d3_interpolateNumber(a, b) {
2646   return a = +a, b -= a, function(t) {
2647     return a + b * t;
2648   };
2649 }
2650
2651 function object(a, b) {
2652   var i = {},
2653       c = {},
2654       k;
2655
2656   if (a === null || typeof a !== "object") a = {};
2657   if (b === null || typeof b !== "object") b = {};
2658
2659   for (k in b) {
2660     if (k in a) {
2661       i[k] = d3_interpolate(a[k], b[k]);
2662     } else {
2663       c[k] = b[k];
2664     }
2665   }
2666
2667   return function(t) {
2668     for (k in i) c[k] = i[k](t);
2669     return c;
2670   };
2671 }
2672
2673 var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;
2674 var reB = new RegExp(reA.source, "g");
2675
2676 function zero(b) {
2677   return function() {
2678     return b;
2679   };
2680 }
2681
2682 function one(b) {
2683   return function(t) {
2684     return b(t) + "";
2685   };
2686 }
2687
2688 function interpolateString(a, b) {
2689   var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b
2690       am, // current match in a
2691       bm, // current match in b
2692       bs, // string preceding current number in b, if any
2693       i = -1, // index in s
2694       s = [], // string constants and placeholders
2695       q = []; // number interpolators
2696
2697   // Coerce inputs to strings.
2698   a = a + "", b = b + "";
2699
2700   // Interpolate pairs of numbers in a & b.
2701   while ((am = reA.exec(a))
2702       && (bm = reB.exec(b))) {
2703     if ((bs = bm.index) > bi) { // a string precedes the next number in b
2704       bs = b.slice(bi, bs);
2705       if (s[i]) s[i] += bs; // coalesce with previous string
2706       else s[++i] = bs;
2707     }
2708     if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match
2709       if (s[i]) s[i] += bm; // coalesce with previous string
2710       else s[++i] = bm;
2711     } else { // interpolate non-matching numbers
2712       s[++i] = null;
2713       q.push({i: i, x: d3_interpolateNumber(am, bm)});
2714     }
2715     bi = reB.lastIndex;
2716   }
2717
2718   // Add remains of b.
2719   if (bi < b.length) {
2720     bs = b.slice(bi);
2721     if (s[i]) s[i] += bs; // coalesce with previous string
2722     else s[++i] = bs;
2723   }
2724
2725   // Special optimization for only a single match.
2726   // Otherwise, interpolate each of the numbers and rejoin the string.
2727   return s.length < 2 ? (q[0]
2728       ? one(q[0].x)
2729       : zero(b))
2730       : (b = q.length, function(t) {
2731           for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);
2732           return s.join("");
2733         });
2734 }
2735
2736 function d3_interpolate(a, b) {
2737   var t = typeof b, c;
2738   return b == null || t === "boolean" ? constant$3(b)
2739       : (t === "number" ? d3_interpolateNumber
2740       : t === "string" ? ((c = color(b)) ? (b = c, d3_interpolateRgb) : interpolateString)
2741       : b instanceof color ? d3_interpolateRgb
2742       : b instanceof Date ? date
2743       : Array.isArray(b) ? array$1
2744       : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object
2745       : d3_interpolateNumber)(a, b);
2746 }
2747
2748 function interpolateRound(a, b) {
2749   return a = +a, b -= a, function(t) {
2750     return Math.round(a + b * t);
2751   };
2752 }
2753
2754 var degrees = 180 / Math.PI;
2755
2756 var identity$2 = {
2757   translateX: 0,
2758   translateY: 0,
2759   rotate: 0,
2760   skewX: 0,
2761   scaleX: 1,
2762   scaleY: 1
2763 };
2764
2765 function decompose(a, b, c, d, e, f) {
2766   var scaleX, scaleY, skewX;
2767   if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;
2768   if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;
2769   if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;
2770   if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;
2771   return {
2772     translateX: e,
2773     translateY: f,
2774     rotate: Math.atan2(b, a) * degrees,
2775     skewX: Math.atan(skewX) * degrees,
2776     scaleX: scaleX,
2777     scaleY: scaleY
2778   };
2779 }
2780
2781 var cssNode;
2782 var cssRoot;
2783 var cssView;
2784 var svgNode;
2785
2786 function parseCss(value) {
2787   if (value === "none") return identity$2;
2788   if (!cssNode) cssNode = document.createElement("DIV"), cssRoot = document.documentElement, cssView = document.defaultView;
2789   cssNode.style.transform = value;
2790   value = cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).getPropertyValue("transform");
2791   cssRoot.removeChild(cssNode);
2792   value = value.slice(7, -1).split(",");
2793   return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]);
2794 }
2795
2796 function parseSvg(value) {
2797   if (value == null) return identity$2;
2798   if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g");
2799   svgNode.setAttribute("transform", value);
2800   if (!(value = svgNode.transform.baseVal.consolidate())) return identity$2;
2801   value = value.matrix;
2802   return decompose(value.a, value.b, value.c, value.d, value.e, value.f);
2803 }
2804
2805 function interpolateTransform(parse, pxComma, pxParen, degParen) {
2806
2807   function pop(s) {
2808     return s.length ? s.pop() + " " : "";
2809   }
2810
2811   function translate(xa, ya, xb, yb, s, q) {
2812     if (xa !== xb || ya !== yb) {
2813       var i = s.push("translate(", null, pxComma, null, pxParen);
2814       q.push({i: i - 4, x: d3_interpolateNumber(xa, xb)}, {i: i - 2, x: d3_interpolateNumber(ya, yb)});
2815     } else if (xb || yb) {
2816       s.push("translate(" + xb + pxComma + yb + pxParen);
2817     }
2818   }
2819
2820   function rotate(a, b, s, q) {
2821     if (a !== b) {
2822       if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path
2823       q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: d3_interpolateNumber(a, b)});
2824     } else if (b) {
2825       s.push(pop(s) + "rotate(" + b + degParen);
2826     }
2827   }
2828
2829   function skewX(a, b, s, q) {
2830     if (a !== b) {
2831       q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: d3_interpolateNumber(a, b)});
2832     } else if (b) {
2833       s.push(pop(s) + "skewX(" + b + degParen);
2834     }
2835   }
2836
2837   function scale(xa, ya, xb, yb, s, q) {
2838     if (xa !== xb || ya !== yb) {
2839       var i = s.push(pop(s) + "scale(", null, ",", null, ")");
2840       q.push({i: i - 4, x: d3_interpolateNumber(xa, xb)}, {i: i - 2, x: d3_interpolateNumber(ya, yb)});
2841     } else if (xb !== 1 || yb !== 1) {
2842       s.push(pop(s) + "scale(" + xb + "," + yb + ")");
2843     }
2844   }
2845
2846   return function(a, b) {
2847     var s = [], // string constants and placeholders
2848         q = []; // number interpolators
2849     a = parse(a), b = parse(b);
2850     translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);
2851     rotate(a.rotate, b.rotate, s, q);
2852     skewX(a.skewX, b.skewX, s, q);
2853     scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);
2854     a = b = null; // gc
2855     return function(t) {
2856       var i = -1, n = q.length, o;
2857       while (++i < n) s[(o = q[i]).i] = o.x(t);
2858       return s.join("");
2859     };
2860   };
2861 }
2862
2863 var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)");
2864 var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")");
2865
2866 var rho = Math.SQRT2;
2867 var rho2 = 2;
2868 var rho4 = 4;
2869 var epsilon2 = 1e-12;
2870
2871 function cosh(x) {
2872   return ((x = Math.exp(x)) + 1 / x) / 2;
2873 }
2874
2875 function sinh(x) {
2876   return ((x = Math.exp(x)) - 1 / x) / 2;
2877 }
2878
2879 function tanh(x) {
2880   return ((x = Math.exp(2 * x)) - 1) / (x + 1);
2881 }
2882
2883 // p0 = [ux0, uy0, w0]
2884 // p1 = [ux1, uy1, w1]
2885 function interpolateZoom(p0, p1) {
2886   var ux0 = p0[0], uy0 = p0[1], w0 = p0[2],
2887       ux1 = p1[0], uy1 = p1[1], w1 = p1[2],
2888       dx = ux1 - ux0,
2889       dy = uy1 - uy0,
2890       d2 = dx * dx + dy * dy,
2891       i,
2892       S;
2893
2894   // Special case for u0 ≅ u1.
2895   if (d2 < epsilon2) {
2896     S = Math.log(w1 / w0) / rho;
2897     i = function(t) {
2898       return [
2899         ux0 + t * dx,
2900         uy0 + t * dy,
2901         w0 * Math.exp(rho * t * S)
2902       ];
2903     };
2904   }
2905
2906   // General case.
2907   else {
2908     var d1 = Math.sqrt(d2),
2909         b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1),
2910         b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1),
2911         r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0),
2912         r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);
2913     S = (r1 - r0) / rho;
2914     i = function(t) {
2915       var s = t * S,
2916           coshr0 = cosh(r0),
2917           u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0));
2918       return [
2919         ux0 + u * dx,
2920         uy0 + u * dy,
2921         w0 * coshr0 / cosh(rho * s + r0)
2922       ];
2923     };
2924   }
2925
2926   i.duration = S * 1000;
2927
2928   return i;
2929 }
2930
2931 function hsl$1(hue$$1) {
2932   return function(start, end) {
2933     var h = hue$$1((start = hsl(start)).h, (end = hsl(end)).h),
2934         s = nogamma(start.s, end.s),
2935         l = nogamma(start.l, end.l),
2936         opacity = nogamma(start.opacity, end.opacity);
2937     return function(t) {
2938       start.h = h(t);
2939       start.s = s(t);
2940       start.l = l(t);
2941       start.opacity = opacity(t);
2942       return start + "";
2943     };
2944   }
2945 }
2946
2947 var hsl$2 = hsl$1(hue);
2948 var hslLong = hsl$1(nogamma);
2949
2950 function lab$1(start, end) {
2951   var l = nogamma((start = lab(start)).l, (end = lab(end)).l),
2952       a = nogamma(start.a, end.a),
2953       b = nogamma(start.b, end.b),
2954       opacity = nogamma(start.opacity, end.opacity);
2955   return function(t) {
2956     start.l = l(t);
2957     start.a = a(t);
2958     start.b = b(t);
2959     start.opacity = opacity(t);
2960     return start + "";
2961   };
2962 }
2963
2964 function hcl$1(hue$$1) {
2965   return function(start, end) {
2966     var h = hue$$1((start = hcl(start)).h, (end = hcl(end)).h),
2967         c = nogamma(start.c, end.c),
2968         l = nogamma(start.l, end.l),
2969         opacity = nogamma(start.opacity, end.opacity);
2970     return function(t) {
2971       start.h = h(t);
2972       start.c = c(t);
2973       start.l = l(t);
2974       start.opacity = opacity(t);
2975       return start + "";
2976     };
2977   }
2978 }
2979
2980 var hcl$2 = hcl$1(hue);
2981 var hclLong = hcl$1(nogamma);
2982
2983 function cubehelix$1(hue$$1) {
2984   return (function cubehelixGamma(y) {
2985     y = +y;
2986
2987     function cubehelix$$1(start, end) {
2988       var h = hue$$1((start = cubehelix(start)).h, (end = cubehelix(end)).h),
2989           s = nogamma(start.s, end.s),
2990           l = nogamma(start.l, end.l),
2991           opacity = nogamma(start.opacity, end.opacity);
2992       return function(t) {
2993         start.h = h(t);
2994         start.s = s(t);
2995         start.l = l(Math.pow(t, y));
2996         start.opacity = opacity(t);
2997         return start + "";
2998       };
2999     }
3000
3001     cubehelix$$1.gamma = cubehelixGamma;
3002
3003     return cubehelix$$1;
3004   })(1);
3005 }
3006
3007 var cubehelix$2 = cubehelix$1(hue);
3008 var cubehelixLong = cubehelix$1(nogamma);
3009
3010 function d3_quantize(interpolator, n) {
3011   var samples = new Array(n);
3012   for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1));
3013   return samples;
3014 }
3015
3016 var frame = 0;
3017 var timeout = 0;
3018 var interval = 0;
3019 var pokeDelay = 1000;
3020 var taskHead;
3021 var taskTail;
3022 var clockLast = 0;
3023 var clockNow = 0;
3024 var clockSkew = 0;
3025 var clock = typeof performance === "object" && performance.now ? performance : Date;
3026 var setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); };
3027
3028 function now() {
3029   return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);
3030 }
3031
3032 function clearNow() {
3033   clockNow = 0;
3034 }
3035
3036 function Timer() {
3037   this._call =
3038   this._time =
3039   this._next = null;
3040 }
3041
3042 Timer.prototype = timer.prototype = {
3043   constructor: Timer,
3044   restart: function(callback, delay, time) {
3045     if (typeof callback !== "function") throw new TypeError("callback is not a function");
3046     time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);
3047     if (!this._next && taskTail !== this) {
3048       if (taskTail) taskTail._next = this;
3049       else taskHead = this;
3050       taskTail = this;
3051     }
3052     this._call = callback;
3053     this._time = time;
3054     sleep();
3055   },
3056   stop: function() {
3057     if (this._call) {
3058       this._call = null;
3059       this._time = Infinity;
3060       sleep();
3061     }
3062   }
3063 };
3064
3065 function timer(callback, delay, time) {
3066   var t = new Timer;
3067   t.restart(callback, delay, time);
3068   return t;
3069 }
3070
3071 function timerFlush() {
3072   now(); // Get the current time, if not already set.
3073   ++frame; // Pretend we’ve set an alarm, if we haven’t already.
3074   var t = taskHead, e;
3075   while (t) {
3076     if ((e = clockNow - t._time) >= 0) t._call.call(null, e);
3077     t = t._next;
3078   }
3079   --frame;
3080 }
3081
3082 function wake() {
3083   clockNow = (clockLast = clock.now()) + clockSkew;
3084   frame = timeout = 0;
3085   try {
3086     timerFlush();
3087   } finally {
3088     frame = 0;
3089     nap();
3090     clockNow = 0;
3091   }
3092 }
3093
3094 function poke() {
3095   var now = clock.now(), delay = now - clockLast;
3096   if (delay > pokeDelay) clockSkew -= delay, clockLast = now;
3097 }
3098
3099 function nap() {
3100   var t0, t1 = taskHead, t2, time = Infinity;
3101   while (t1) {
3102     if (t1._call) {
3103       if (time > t1._time) time = t1._time;
3104       t0 = t1, t1 = t1._next;
3105     } else {
3106       t2 = t1._next, t1._next = null;
3107       t1 = t0 ? t0._next = t2 : taskHead = t2;
3108     }
3109   }
3110   taskTail = t0;
3111   sleep(time);
3112 }
3113
3114 function sleep(time) {
3115   if (frame) return; // Soonest alarm already set, or will be.
3116   if (timeout) timeout = clearTimeout(timeout);
3117   var delay = time - clockNow; // Strictly less than if we recomputed clockNow.
3118   if (delay > 24) {
3119     if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew);
3120     if (interval) interval = clearInterval(interval);
3121   } else {
3122     if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay);
3123     frame = 1, setFrame(wake);
3124   }
3125 }
3126
3127 function d3_timeout(callback, delay, time) {
3128   var t = new Timer;
3129   delay = delay == null ? 0 : +delay;
3130   t.restart(function(elapsed) {
3131     t.stop();
3132     callback(elapsed + delay);
3133   }, delay, time);
3134   return t;
3135 }
3136
3137 function interval$1(callback, delay, time) {
3138   var t = new Timer, total = delay;
3139   if (delay == null) return t.restart(callback, delay, time), t;
3140   delay = +delay, time = time == null ? now() : +time;
3141   t.restart(function tick(elapsed) {
3142     elapsed += total;
3143     t.restart(tick, total += delay, time);
3144     callback(elapsed);
3145   }, delay, time);
3146   return t;
3147 }
3148
3149 var emptyOn = dispatch("start", "end", "interrupt");
3150 var emptyTween = [];
3151
3152 var CREATED = 0;
3153 var SCHEDULED = 1;
3154 var STARTING = 2;
3155 var STARTED = 3;
3156 var RUNNING = 4;
3157 var ENDING = 5;
3158 var ENDED = 6;
3159
3160 function schedule(node, name, id, index, group, timing) {
3161   var schedules = node.__transition;
3162   if (!schedules) node.__transition = {};
3163   else if (id in schedules) return;
3164   create$1(node, id, {
3165     name: name,
3166     index: index, // For context during callback.
3167     group: group, // For context during callback.
3168     on: emptyOn,
3169     tween: emptyTween,
3170     time: timing.time,
3171     delay: timing.delay,
3172     duration: timing.duration,
3173     ease: timing.ease,
3174     timer: null,
3175     state: CREATED
3176   });
3177 }
3178
3179 function init(node, id) {
3180   var schedule = get$1(node, id);
3181   if (schedule.state > CREATED) throw new Error("too late; already scheduled");
3182   return schedule;
3183 }
3184
3185 function set$1(node, id) {
3186   var schedule = get$1(node, id);
3187   if (schedule.state > STARTING) throw new Error("too late; already started");
3188   return schedule;
3189 }
3190
3191 function get$1(node, id) {
3192   var schedule = node.__transition;
3193   if (!schedule || !(schedule = schedule[id])) throw new Error("transition not found");
3194   return schedule;
3195 }
3196
3197 function create$1(node, id, self) {
3198   var schedules = node.__transition,
3199       tween;
3200
3201   // Initialize the self timer when the transition is created.
3202   // Note the actual delay is not known until the first callback!
3203   schedules[id] = self;
3204   self.timer = timer(schedule, 0, self.time);
3205
3206   function schedule(elapsed) {
3207     self.state = SCHEDULED;
3208     self.timer.restart(start, self.delay, self.time);
3209
3210     // If the elapsed delay is less than our first sleep, start immediately.
3211     if (self.delay <= elapsed) start(elapsed - self.delay);
3212   }
3213
3214   function start(elapsed) {
3215     var i, j, n, o;
3216
3217     // If the state is not SCHEDULED, then we previously errored on start.
3218     if (self.state !== SCHEDULED) return stop();
3219
3220     for (i in schedules) {
3221       o = schedules[i];
3222       if (o.name !== self.name) continue;
3223
3224       // While this element already has a starting transition during this frame,
3225       // defer starting an interrupting transition until that transition has a
3226       // chance to tick (and possibly end); see d3/d3-transition#54!
3227       if (o.state === STARTED) return d3_timeout(start);
3228
3229       // Interrupt the active transition, if any.
3230       // Dispatch the interrupt event.
3231       if (o.state === RUNNING) {
3232         o.state = ENDED;
3233         o.timer.stop();
3234         o.on.call("interrupt", node, node.__data__, o.index, o.group);
3235         delete schedules[i];
3236       }
3237
3238       // Cancel any pre-empted transitions. No interrupt event is dispatched
3239       // because the cancelled transitions never started. Note that this also
3240       // removes this transition from the pending list!
3241       else if (+i < id) {
3242         o.state = ENDED;
3243         o.timer.stop();
3244         delete schedules[i];
3245       }
3246     }
3247
3248     // Defer the first tick to end of the current frame; see d3/d3#1576.
3249     // Note the transition may be canceled after start and before the first tick!
3250     // Note this must be scheduled before the start event; see d3/d3-transition#16!
3251     // Assuming this is successful, subsequent callbacks go straight to tick.
3252     d3_timeout(function() {
3253       if (self.state === STARTED) {
3254         self.state = RUNNING;
3255         self.timer.restart(tick, self.delay, self.time);
3256         tick(elapsed);
3257       }
3258     });
3259
3260     // Dispatch the start event.
3261     // Note this must be done before the tween are initialized.
3262     self.state = STARTING;
3263     self.on.call("start", node, node.__data__, self.index, self.group);
3264     if (self.state !== STARTING) return; // interrupted
3265     self.state = STARTED;
3266
3267     // Initialize the tween, deleting null tween.
3268     tween = new Array(n = self.tween.length);
3269     for (i = 0, j = -1; i < n; ++i) {
3270       if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) {
3271         tween[++j] = o;
3272       }
3273     }
3274     tween.length = j + 1;
3275   }
3276
3277   function tick(elapsed) {
3278     var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1),
3279         i = -1,
3280         n = tween.length;
3281
3282     while (++i < n) {
3283       tween[i].call(null, t);
3284     }
3285
3286     // Dispatch the end event.
3287     if (self.state === ENDING) {
3288       self.on.call("end", node, node.__data__, self.index, self.group);
3289       stop();
3290     }
3291   }
3292
3293   function stop() {
3294     self.state = ENDED;
3295     self.timer.stop();
3296     delete schedules[id];
3297     for (var i in schedules) return; // eslint-disable-line no-unused-vars
3298     delete node.__transition;
3299   }
3300 }
3301
3302 function interrupt(node, name) {
3303   var schedules = node.__transition,
3304       schedule$$1,
3305       active,
3306       empty = true,
3307       i;
3308
3309   if (!schedules) return;
3310
3311   name = name == null ? null : name + "";
3312
3313   for (i in schedules) {
3314     if ((schedule$$1 = schedules[i]).name !== name) { empty = false; continue; }
3315     active = schedule$$1.state > STARTING && schedule$$1.state < ENDING;
3316     schedule$$1.state = ENDED;
3317     schedule$$1.timer.stop();
3318     if (active) schedule$$1.on.call("interrupt", node, node.__data__, schedule$$1.index, schedule$$1.group);
3319     delete schedules[i];
3320   }
3321
3322   if (empty) delete node.__transition;
3323 }
3324
3325 function selection_interrupt(name) {
3326   return this.each(function() {
3327     interrupt(this, name);
3328   });
3329 }
3330
3331 function tweenRemove(id, name) {
3332   var tween0, tween1;
3333   return function() {
3334     var schedule$$1 = set$1(this, id),
3335         tween = schedule$$1.tween;
3336
3337     // If this node shared tween with the previous node,
3338     // just assign the updated shared tween and we’re done!
3339     // Otherwise, copy-on-write.
3340     if (tween !== tween0) {
3341       tween1 = tween0 = tween;
3342       for (var i = 0, n = tween1.length; i < n; ++i) {
3343         if (tween1[i].name === name) {
3344           tween1 = tween1.slice();
3345           tween1.splice(i, 1);
3346           break;
3347         }
3348       }
3349     }
3350
3351     schedule$$1.tween = tween1;
3352   };
3353 }
3354
3355 function tweenFunction(id, name, value) {
3356   var tween0, tween1;
3357   if (typeof value !== "function") throw new Error;
3358   return function() {
3359     var schedule$$1 = set$1(this, id),
3360         tween = schedule$$1.tween;
3361
3362     // If this node shared tween with the previous node,
3363     // just assign the updated shared tween and we’re done!
3364     // Otherwise, copy-on-write.
3365     if (tween !== tween0) {
3366       tween1 = (tween0 = tween).slice();
3367       for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) {
3368         if (tween1[i].name === name) {
3369           tween1[i] = t;
3370           break;
3371         }
3372       }
3373       if (i === n) tween1.push(t);
3374     }
3375
3376     schedule$$1.tween = tween1;
3377   };
3378 }
3379
3380 function transition_tween(name, value) {
3381   var id = this._id;
3382
3383   name += "";
3384
3385   if (arguments.length < 2) {
3386     var tween = get$1(this.node(), id).tween;
3387     for (var i = 0, n = tween.length, t; i < n; ++i) {
3388       if ((t = tween[i]).name === name) {
3389         return t.value;
3390       }
3391     }
3392     return null;
3393   }
3394
3395   return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value));
3396 }
3397
3398 function tweenValue(transition, name, value) {
3399   var id = transition._id;
3400
3401   transition.each(function() {
3402     var schedule$$1 = set$1(this, id);
3403     (schedule$$1.value || (schedule$$1.value = {}))[name] = value.apply(this, arguments);
3404   });
3405
3406   return function(node) {
3407     return get$1(node, id).value[name];
3408   };
3409 }
3410
3411 function interpolate(a, b) {
3412   var c;
3413   return (typeof b === "number" ? d3_interpolateNumber
3414       : b instanceof color ? d3_interpolateRgb
3415       : (c = color(b)) ? (b = c, d3_interpolateRgb)
3416       : interpolateString)(a, b);
3417 }
3418
3419 function attrRemove$1(name) {
3420   return function() {
3421     this.removeAttribute(name);
3422   };
3423 }
3424
3425 function attrRemoveNS$1(fullname) {
3426   return function() {
3427     this.removeAttributeNS(fullname.space, fullname.local);
3428   };
3429 }
3430
3431 function attrConstant$1(name, interpolate$$1, value1) {
3432   var value00,
3433       interpolate0;
3434   return function() {
3435     var value0 = this.getAttribute(name);
3436     return value0 === value1 ? null
3437         : value0 === value00 ? interpolate0
3438         : interpolate0 = interpolate$$1(value00 = value0, value1);
3439   };
3440 }
3441
3442 function attrConstantNS$1(fullname, interpolate$$1, value1) {
3443   var value00,
3444       interpolate0;
3445   return function() {
3446     var value0 = this.getAttributeNS(fullname.space, fullname.local);
3447     return value0 === value1 ? null
3448         : value0 === value00 ? interpolate0
3449         : interpolate0 = interpolate$$1(value00 = value0, value1);
3450   };
3451 }
3452
3453 function attrFunction$1(name, interpolate$$1, value) {
3454   var value00,
3455       value10,
3456       interpolate0;
3457   return function() {
3458     var value0, value1 = value(this);
3459     if (value1 == null) return void this.removeAttribute(name);
3460     value0 = this.getAttribute(name);
3461     return value0 === value1 ? null
3462         : value0 === value00 && value1 === value10 ? interpolate0
3463         : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
3464   };
3465 }
3466
3467 function attrFunctionNS$1(fullname, interpolate$$1, value) {
3468   var value00,
3469       value10,
3470       interpolate0;
3471   return function() {
3472     var value0, value1 = value(this);
3473     if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local);
3474     value0 = this.getAttributeNS(fullname.space, fullname.local);
3475     return value0 === value1 ? null
3476         : value0 === value00 && value1 === value10 ? interpolate0
3477         : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
3478   };
3479 }
3480
3481 function transition_attr(name, value) {
3482   var fullname = namespace(name), i = fullname === "transform" ? interpolateTransformSvg : interpolate;
3483   return this.attrTween(name, typeof value === "function"
3484       ? (fullname.local ? attrFunctionNS$1 : attrFunction$1)(fullname, i, tweenValue(this, "attr." + name, value))
3485       : value == null ? (fullname.local ? attrRemoveNS$1 : attrRemove$1)(fullname)
3486       : (fullname.local ? attrConstantNS$1 : attrConstant$1)(fullname, i, value + ""));
3487 }
3488
3489 function attrTweenNS(fullname, value) {
3490   function tween() {
3491     var node = this, i = value.apply(node, arguments);
3492     return i && function(t) {
3493       node.setAttributeNS(fullname.space, fullname.local, i(t));
3494     };
3495   }
3496   tween._value = value;
3497   return tween;
3498 }
3499
3500 function attrTween(name, value) {
3501   function tween() {
3502     var node = this, i = value.apply(node, arguments);
3503     return i && function(t) {
3504       node.setAttribute(name, i(t));
3505     };
3506   }
3507   tween._value = value;
3508   return tween;
3509 }
3510
3511 function transition_attrTween(name, value) {
3512   var key = "attr." + name;
3513   if (arguments.length < 2) return (key = this.tween(key)) && key._value;
3514   if (value == null) return this.tween(key, null);
3515   if (typeof value !== "function") throw new Error;
3516   var fullname = namespace(name);
3517   return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value));
3518 }
3519
3520 function delayFunction(id, value) {
3521   return function() {
3522     init(this, id).delay = +value.apply(this, arguments);
3523   };
3524 }
3525
3526 function delayConstant(id, value) {
3527   return value = +value, function() {
3528     init(this, id).delay = value;
3529   };
3530 }
3531
3532 function transition_delay(value) {
3533   var id = this._id;
3534
3535   return arguments.length
3536       ? this.each((typeof value === "function"
3537           ? delayFunction
3538           : delayConstant)(id, value))
3539       : get$1(this.node(), id).delay;
3540 }
3541
3542 function durationFunction(id, value) {
3543   return function() {
3544     set$1(this, id).duration = +value.apply(this, arguments);
3545   };
3546 }
3547
3548 function durationConstant(id, value) {
3549   return value = +value, function() {
3550     set$1(this, id).duration = value;
3551   };
3552 }
3553
3554 function transition_duration(value) {
3555   var id = this._id;
3556
3557   return arguments.length
3558       ? this.each((typeof value === "function"
3559           ? durationFunction
3560           : durationConstant)(id, value))
3561       : get$1(this.node(), id).duration;
3562 }
3563
3564 function easeConstant(id, value) {
3565   if (typeof value !== "function") throw new Error;
3566   return function() {
3567     set$1(this, id).ease = value;
3568   };
3569 }
3570
3571 function transition_ease(value) {
3572   var id = this._id;
3573
3574   return arguments.length
3575       ? this.each(easeConstant(id, value))
3576       : get$1(this.node(), id).ease;
3577 }
3578
3579 function transition_filter(match) {
3580   if (typeof match !== "function") match = matcher$1(match);
3581
3582   for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
3583     for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
3584       if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
3585         subgroup.push(node);
3586       }
3587     }
3588   }
3589
3590   return new Transition(subgroups, this._parents, this._name, this._id);
3591 }
3592
3593 function transition_merge(transition$$1) {
3594   if (transition$$1._id !== this._id) throw new Error;
3595
3596   for (var groups0 = this._groups, groups1 = transition$$1._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {
3597     for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
3598       if (node = group0[i] || group1[i]) {
3599         merge[i] = node;
3600       }
3601     }
3602   }
3603
3604   for (; j < m0; ++j) {
3605     merges[j] = groups0[j];
3606   }
3607
3608   return new Transition(merges, this._parents, this._name, this._id);
3609 }
3610
3611 function start(name) {
3612   return (name + "").trim().split(/^|\s+/).every(function(t) {
3613     var i = t.indexOf(".");
3614     if (i >= 0) t = t.slice(0, i);
3615     return !t || t === "start";
3616   });
3617 }
3618
3619 function onFunction(id, name, listener) {
3620   var on0, on1, sit = start(name) ? init : set$1;
3621   return function() {
3622     var schedule$$1 = sit(this, id),
3623         on = schedule$$1.on;
3624
3625     // If this node shared a dispatch with the previous node,
3626     // just assign the updated shared dispatch and we’re done!
3627     // Otherwise, copy-on-write.
3628     if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener);
3629
3630     schedule$$1.on = on1;
3631   };
3632 }
3633
3634 function transition_on(name, listener) {
3635   var id = this._id;
3636
3637   return arguments.length < 2
3638       ? get$1(this.node(), id).on.on(name)
3639       : this.each(onFunction(id, name, listener));
3640 }
3641
3642 function removeFunction(id) {
3643   return function() {
3644     var parent = this.parentNode;
3645     for (var i in this.__transition) if (+i !== id) return;
3646     if (parent) parent.removeChild(this);
3647   };
3648 }
3649
3650 function transition_remove() {
3651   return this.on("end.remove", removeFunction(this._id));
3652 }
3653
3654 function transition_select(select) {
3655   var name = this._name,
3656       id = this._id;
3657
3658   if (typeof select !== "function") select = selector(select);
3659
3660   for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
3661     for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
3662       if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {
3663         if ("__data__" in node) subnode.__data__ = node.__data__;
3664         subgroup[i] = subnode;
3665         schedule(subgroup[i], name, id, i, subgroup, get$1(node, id));
3666       }
3667     }
3668   }
3669
3670   return new Transition(subgroups, this._parents, name, id);
3671 }
3672
3673 function transition_selectAll(select) {
3674   var name = this._name,
3675       id = this._id;
3676
3677   if (typeof select !== "function") select = selectorAll(select);
3678
3679   for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
3680     for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
3681       if (node = group[i]) {
3682         for (var children = select.call(node, node.__data__, i, group), child, inherit = get$1(node, id), k = 0, l = children.length; k < l; ++k) {
3683           if (child = children[k]) {
3684             schedule(child, name, id, k, children, inherit);
3685           }
3686         }
3687         subgroups.push(children);
3688         parents.push(node);
3689       }
3690     }
3691   }
3692
3693   return new Transition(subgroups, parents, name, id);
3694 }
3695
3696 var Selection$1 = selection.prototype.constructor;
3697
3698 function transition_selection() {
3699   return new Selection$1(this._groups, this._parents);
3700 }
3701
3702 function styleRemove$1(name, interpolate$$1) {
3703   var value00,
3704       value10,
3705       interpolate0;
3706   return function() {
3707     var value0 = styleValue(this, name),
3708         value1 = (this.style.removeProperty(name), styleValue(this, name));
3709     return value0 === value1 ? null
3710         : value0 === value00 && value1 === value10 ? interpolate0
3711         : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
3712   };
3713 }
3714
3715 function styleRemoveEnd(name) {
3716   return function() {
3717     this.style.removeProperty(name);
3718   };
3719 }
3720
3721 function styleConstant$1(name, interpolate$$1, value1) {
3722   var value00,
3723       interpolate0;
3724   return function() {
3725     var value0 = styleValue(this, name);
3726     return value0 === value1 ? null
3727         : value0 === value00 ? interpolate0
3728         : interpolate0 = interpolate$$1(value00 = value0, value1);
3729   };
3730 }
3731
3732 function styleFunction$1(name, interpolate$$1, value) {
3733   var value00,
3734       value10,
3735       interpolate0;
3736   return function() {
3737     var value0 = styleValue(this, name),
3738         value1 = value(this);
3739     if (value1 == null) value1 = (this.style.removeProperty(name), styleValue(this, name));
3740     return value0 === value1 ? null
3741         : value0 === value00 && value1 === value10 ? interpolate0
3742         : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
3743   };
3744 }
3745
3746 function transition_style(name, value, priority) {
3747   var i = (name += "") === "transform" ? interpolateTransformCss : interpolate;
3748   return value == null ? this
3749           .styleTween(name, styleRemove$1(name, i))
3750           .on("end.style." + name, styleRemoveEnd(name))
3751       : this.styleTween(name, typeof value === "function"
3752           ? styleFunction$1(name, i, tweenValue(this, "style." + name, value))
3753           : styleConstant$1(name, i, value + ""), priority);
3754 }
3755
3756 function styleTween(name, value, priority) {
3757   function tween() {
3758     var node = this, i = value.apply(node, arguments);
3759     return i && function(t) {
3760       node.style.setProperty(name, i(t), priority);
3761     };
3762   }
3763   tween._value = value;
3764   return tween;
3765 }
3766
3767 function transition_styleTween(name, value, priority) {
3768   var key = "style." + (name += "");
3769   if (arguments.length < 2) return (key = this.tween(key)) && key._value;
3770   if (value == null) return this.tween(key, null);
3771   if (typeof value !== "function") throw new Error;
3772   return this.tween(key, styleTween(name, value, priority == null ? "" : priority));
3773 }
3774
3775 function textConstant$1(value) {
3776   return function() {
3777     this.textContent = value;
3778   };
3779 }
3780
3781 function textFunction$1(value) {
3782   return function() {
3783     var value1 = value(this);
3784     this.textContent = value1 == null ? "" : value1;
3785   };
3786 }
3787
3788 function transition_text(value) {
3789   return this.tween("text", typeof value === "function"
3790       ? textFunction$1(tweenValue(this, "text", value))
3791       : textConstant$1(value == null ? "" : value + ""));
3792 }
3793
3794 function transition_transition() {
3795   var name = this._name,
3796       id0 = this._id,
3797       id1 = newId();
3798
3799   for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {
3800     for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
3801       if (node = group[i]) {
3802         var inherit = get$1(node, id0);
3803         schedule(node, name, id1, i, group, {
3804           time: inherit.time + inherit.delay + inherit.duration,
3805           delay: 0,
3806           duration: inherit.duration,
3807           ease: inherit.ease
3808         });
3809       }
3810     }
3811   }
3812
3813   return new Transition(groups, this._parents, name, id1);
3814 }
3815
3816 var id = 0;
3817
3818 function Transition(groups, parents, name, id) {
3819   this._groups = groups;
3820   this._parents = parents;
3821   this._name = name;
3822   this._id = id;
3823 }
3824
3825 function transition(name) {
3826   return selection().transition(name);
3827 }
3828
3829 function newId() {
3830   return ++id;
3831 }
3832
3833 var selection_prototype = selection.prototype;
3834
3835 Transition.prototype = transition.prototype = {
3836   constructor: Transition,
3837   select: transition_select,
3838   selectAll: transition_selectAll,
3839   filter: transition_filter,
3840   merge: transition_merge,
3841   selection: transition_selection,
3842   transition: transition_transition,
3843   call: selection_prototype.call,
3844   nodes: selection_prototype.nodes,
3845   node: selection_prototype.node,
3846   size: selection_prototype.size,
3847   empty: selection_prototype.empty,
3848   each: selection_prototype.each,
3849   on: transition_on,
3850   attr: transition_attr,
3851   attrTween: transition_attrTween,
3852   style: transition_style,
3853   styleTween: transition_styleTween,
3854   text: transition_text,
3855   remove: transition_remove,
3856   tween: transition_tween,
3857   delay: transition_delay,
3858   duration: transition_duration,
3859   ease: transition_ease
3860 };
3861
3862 function linear$1(t) {
3863   return +t;
3864 }
3865
3866 function quadIn(t) {
3867   return t * t;
3868 }
3869
3870 function quadOut(t) {
3871   return t * (2 - t);
3872 }
3873
3874 function quadInOut(t) {
3875   return ((t *= 2) <= 1 ? t * t : --t * (2 - t) + 1) / 2;
3876 }
3877
3878 function cubicIn(t) {
3879   return t * t * t;
3880 }
3881
3882 function cubicOut(t) {
3883   return --t * t * t + 1;
3884 }
3885
3886 function cubicInOut(t) {
3887   return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
3888 }
3889
3890 var exponent = 3;
3891
3892 var polyIn = (function custom(e) {
3893   e = +e;
3894
3895   function polyIn(t) {
3896     return Math.pow(t, e);
3897   }
3898
3899   polyIn.exponent = custom;
3900
3901   return polyIn;
3902 })(exponent);
3903
3904 var polyOut = (function custom(e) {
3905   e = +e;
3906
3907   function polyOut(t) {
3908     return 1 - Math.pow(1 - t, e);
3909   }
3910
3911   polyOut.exponent = custom;
3912
3913   return polyOut;
3914 })(exponent);
3915
3916 var polyInOut = (function custom(e) {
3917   e = +e;
3918
3919   function polyInOut(t) {
3920     return ((t *= 2) <= 1 ? Math.pow(t, e) : 2 - Math.pow(2 - t, e)) / 2;
3921   }
3922
3923   polyInOut.exponent = custom;
3924
3925   return polyInOut;
3926 })(exponent);
3927
3928 var pi = Math.PI;
3929 var halfPi = pi / 2;
3930
3931 function sinIn(t) {
3932   return 1 - Math.cos(t * halfPi);
3933 }
3934
3935 function sinOut(t) {
3936   return Math.sin(t * halfPi);
3937 }
3938
3939 function sinInOut(t) {
3940   return (1 - Math.cos(pi * t)) / 2;
3941 }
3942
3943 function expIn(t) {
3944   return Math.pow(2, 10 * t - 10);
3945 }
3946
3947 function expOut(t) {
3948   return 1 - Math.pow(2, -10 * t);
3949 }
3950
3951 function expInOut(t) {
3952   return ((t *= 2) <= 1 ? Math.pow(2, 10 * t - 10) : 2 - Math.pow(2, 10 - 10 * t)) / 2;
3953 }
3954
3955 function circleIn(t) {
3956   return 1 - Math.sqrt(1 - t * t);
3957 }
3958
3959 function circleOut(t) {
3960   return Math.sqrt(1 - --t * t);
3961 }
3962
3963 function circleInOut(t) {
3964   return ((t *= 2) <= 1 ? 1 - Math.sqrt(1 - t * t) : Math.sqrt(1 - (t -= 2) * t) + 1) / 2;
3965 }
3966
3967 var b1 = 4 / 11;
3968 var b2 = 6 / 11;
3969 var b3 = 8 / 11;
3970 var b4 = 3 / 4;
3971 var b5 = 9 / 11;
3972 var b6 = 10 / 11;
3973 var b7 = 15 / 16;
3974 var b8 = 21 / 22;
3975 var b9 = 63 / 64;
3976 var b0 = 1 / b1 / b1;
3977
3978 function bounceIn(t) {
3979   return 1 - bounceOut(1 - t);
3980 }
3981
3982 function bounceOut(t) {
3983   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;
3984 }
3985
3986 function bounceInOut(t) {
3987   return ((t *= 2) <= 1 ? 1 - bounceOut(1 - t) : bounceOut(t - 1) + 1) / 2;
3988 }
3989
3990 var overshoot = 1.70158;
3991
3992 var backIn = (function custom(s) {
3993   s = +s;
3994
3995   function backIn(t) {
3996     return t * t * ((s + 1) * t - s);
3997   }
3998
3999   backIn.overshoot = custom;
4000
4001   return backIn;
4002 })(overshoot);
4003
4004 var backOut = (function custom(s) {
4005   s = +s;
4006
4007   function backOut(t) {
4008     return --t * t * ((s + 1) * t + s) + 1;
4009   }
4010
4011   backOut.overshoot = custom;
4012
4013   return backOut;
4014 })(overshoot);
4015
4016 var backInOut = (function custom(s) {
4017   s = +s;
4018
4019   function backInOut(t) {
4020     return ((t *= 2) < 1 ? t * t * ((s + 1) * t - s) : (t -= 2) * t * ((s + 1) * t + s) + 2) / 2;
4021   }
4022
4023   backInOut.overshoot = custom;
4024
4025   return backInOut;
4026 })(overshoot);
4027
4028 var tau = 2 * Math.PI;
4029 var amplitude = 1;
4030 var period = 0.3;
4031
4032 var elasticIn = (function custom(a, p) {
4033   var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
4034
4035   function elasticIn(t) {
4036     return a * Math.pow(2, 10 * --t) * Math.sin((s - t) / p);
4037   }
4038
4039   elasticIn.amplitude = function(a) { return custom(a, p * tau); };
4040   elasticIn.period = function(p) { return custom(a, p); };
4041
4042   return elasticIn;
4043 })(amplitude, period);
4044
4045 var elasticOut = (function custom(a, p) {
4046   var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
4047
4048   function elasticOut(t) {
4049     return 1 - a * Math.pow(2, -10 * (t = +t)) * Math.sin((t + s) / p);
4050   }
4051
4052   elasticOut.amplitude = function(a) { return custom(a, p * tau); };
4053   elasticOut.period = function(p) { return custom(a, p); };
4054
4055   return elasticOut;
4056 })(amplitude, period);
4057
4058 var elasticInOut = (function custom(a, p) {
4059   var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
4060
4061   function elasticInOut(t) {
4062     return ((t = t * 2 - 1) < 0
4063         ? a * Math.pow(2, 10 * t) * Math.sin((s - t) / p)
4064         : 2 - a * Math.pow(2, -10 * t) * Math.sin((s + t) / p)) / 2;
4065   }
4066
4067   elasticInOut.amplitude = function(a) { return custom(a, p * tau); };
4068   elasticInOut.period = function(p) { return custom(a, p); };
4069
4070   return elasticInOut;
4071 })(amplitude, period);
4072
4073 var defaultTiming = {
4074   time: null, // Set on use.
4075   delay: 0,
4076   duration: 250,
4077   ease: cubicInOut
4078 };
4079
4080 function inherit(node, id) {
4081   var timing;
4082   while (!(timing = node.__transition) || !(timing = timing[id])) {
4083     if (!(node = node.parentNode)) {
4084       return defaultTiming.time = now(), defaultTiming;
4085     }
4086   }
4087   return timing;
4088 }
4089
4090 function selection_transition(name) {
4091   var id,
4092       timing;
4093
4094   if (name instanceof Transition) {
4095     id = name._id, name = name._name;
4096   } else {
4097     id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + "";
4098   }
4099
4100   for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {
4101     for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
4102       if (node = group[i]) {
4103         schedule(node, name, id, i, group, timing || inherit(node, id));
4104       }
4105     }
4106   }
4107
4108   return new Transition(groups, this._parents, name, id);
4109 }
4110
4111 selection.prototype.interrupt = selection_interrupt;
4112 selection.prototype.transition = selection_transition;
4113
4114 var root$1 = [null];
4115
4116 function active(node, name) {
4117   var schedules = node.__transition,
4118       schedule$$1,
4119       i;
4120
4121   if (schedules) {
4122     name = name == null ? null : name + "";
4123     for (i in schedules) {
4124       if ((schedule$$1 = schedules[i]).state > SCHEDULED && schedule$$1.name === name) {
4125         return new Transition([[node]], root$1, name, +i);
4126       }
4127     }
4128   }
4129
4130   return null;
4131 }
4132
4133 function constant$4(x) {
4134   return function() {
4135     return x;
4136   };
4137 }
4138
4139 function BrushEvent(target, type, selection) {
4140   this.target = target;
4141   this.type = type;
4142   this.selection = selection;
4143 }
4144
4145 function nopropagation$1() {
4146   event.stopImmediatePropagation();
4147 }
4148
4149 function noevent$1() {
4150   event.preventDefault();
4151   event.stopImmediatePropagation();
4152 }
4153
4154 var MODE_DRAG = {name: "drag"};
4155 var MODE_SPACE = {name: "space"};
4156 var MODE_HANDLE = {name: "handle"};
4157 var MODE_CENTER = {name: "center"};
4158
4159 var X = {
4160   name: "x",
4161   handles: ["e", "w"].map(type),
4162   input: function(x, e) { return x && [[x[0], e[0][1]], [x[1], e[1][1]]]; },
4163   output: function(xy) { return xy && [xy[0][0], xy[1][0]]; }
4164 };
4165
4166 var Y = {
4167   name: "y",
4168   handles: ["n", "s"].map(type),
4169   input: function(y, e) { return y && [[e[0][0], y[0]], [e[1][0], y[1]]]; },
4170   output: function(xy) { return xy && [xy[0][1], xy[1][1]]; }
4171 };
4172
4173 var XY = {
4174   name: "xy",
4175   handles: ["n", "e", "s", "w", "nw", "ne", "se", "sw"].map(type),
4176   input: function(xy) { return xy; },
4177   output: function(xy) { return xy; }
4178 };
4179
4180 var cursors = {
4181   overlay: "crosshair",
4182   selection: "move",
4183   n: "ns-resize",
4184   e: "ew-resize",
4185   s: "ns-resize",
4186   w: "ew-resize",
4187   nw: "nwse-resize",
4188   ne: "nesw-resize",
4189   se: "nwse-resize",
4190   sw: "nesw-resize"
4191 };
4192
4193 var flipX = {
4194   e: "w",
4195   w: "e",
4196   nw: "ne",
4197   ne: "nw",
4198   se: "sw",
4199   sw: "se"
4200 };
4201
4202 var flipY = {
4203   n: "s",
4204   s: "n",
4205   nw: "sw",
4206   ne: "se",
4207   se: "ne",
4208   sw: "nw"
4209 };
4210
4211 var signsX = {
4212   overlay: +1,
4213   selection: +1,
4214   n: null,
4215   e: +1,
4216   s: null,
4217   w: -1,
4218   nw: -1,
4219   ne: +1,
4220   se: +1,
4221   sw: -1
4222 };
4223
4224 var signsY = {
4225   overlay: +1,
4226   selection: +1,
4227   n: -1,
4228   e: null,
4229   s: +1,
4230   w: null,
4231   nw: -1,
4232   ne: -1,
4233   se: +1,
4234   sw: +1
4235 };
4236
4237 function type(t) {
4238   return {type: t};
4239 }
4240
4241 // Ignore right-click, since that should open the context menu.
4242 function defaultFilter$1() {
4243   return !event.button;
4244 }
4245
4246 function defaultExtent() {
4247   var svg = this.ownerSVGElement || this;
4248   return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];
4249 }
4250
4251 // Like d3.local, but with the name “__brush” rather than auto-generated.
4252 function local$1(node) {
4253   while (!node.__brush) if (!(node = node.parentNode)) return;
4254   return node.__brush;
4255 }
4256
4257 function empty$1(extent) {
4258   return extent[0][0] === extent[1][0]
4259       || extent[0][1] === extent[1][1];
4260 }
4261
4262 function brushSelection(node) {
4263   var state = node.__brush;
4264   return state ? state.dim.output(state.selection) : null;
4265 }
4266
4267 function brushX() {
4268   return brush$1(X);
4269 }
4270
4271 function brushY() {
4272   return brush$1(Y);
4273 }
4274
4275 function brush() {
4276   return brush$1(XY);
4277 }
4278
4279 function brush$1(dim) {
4280   var extent = defaultExtent,
4281       filter = defaultFilter$1,
4282       listeners = dispatch(brush, "start", "brush", "end"),
4283       handleSize = 6,
4284       touchending;
4285
4286   function brush(group) {
4287     var overlay = group
4288         .property("__brush", initialize)
4289       .selectAll(".overlay")
4290       .data([type("overlay")]);
4291
4292     overlay.enter().append("rect")
4293         .attr("class", "overlay")
4294         .attr("pointer-events", "all")
4295         .attr("cursor", cursors.overlay)
4296       .merge(overlay)
4297         .each(function() {
4298           var extent = local$1(this).extent;
4299           d3_select(this)
4300               .attr("x", extent[0][0])
4301               .attr("y", extent[0][1])
4302               .attr("width", extent[1][0] - extent[0][0])
4303               .attr("height", extent[1][1] - extent[0][1]);
4304         });
4305
4306     group.selectAll(".selection")
4307       .data([type("selection")])
4308       .enter().append("rect")
4309         .attr("class", "selection")
4310         .attr("cursor", cursors.selection)
4311         .attr("fill", "#777")
4312         .attr("fill-opacity", 0.3)
4313         .attr("stroke", "#fff")
4314         .attr("shape-rendering", "crispEdges");
4315
4316     var handle = group.selectAll(".handle")
4317       .data(dim.handles, function(d) { return d.type; });
4318
4319     handle.exit().remove();
4320
4321     handle.enter().append("rect")
4322         .attr("class", function(d) { return "handle handle--" + d.type; })
4323         .attr("cursor", function(d) { return cursors[d.type]; });
4324
4325     group
4326         .each(redraw)
4327         .attr("fill", "none")
4328         .attr("pointer-events", "all")
4329         .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)")
4330         .on("mousedown.brush touchstart.brush", started);
4331   }
4332
4333   brush.move = function(group, selection) {
4334     if (group.selection) {
4335       group
4336           .on("start.brush", function() { emitter(this, arguments).beforestart().start(); })
4337           .on("interrupt.brush end.brush", function() { emitter(this, arguments).end(); })
4338           .tween("brush", function() {
4339             var that = this,
4340                 state = that.__brush,
4341                 emit = emitter(that, arguments),
4342                 selection0 = state.selection,
4343                 selection1 = dim.input(typeof selection === "function" ? selection.apply(this, arguments) : selection, state.extent),
4344                 i = d3_interpolate(selection0, selection1);
4345
4346             function tween(t) {
4347               state.selection = t === 1 && empty$1(selection1) ? null : i(t);
4348               redraw.call(that);
4349               emit.brush();
4350             }
4351
4352             return selection0 && selection1 ? tween : tween(1);
4353           });
4354     } else {
4355       group
4356           .each(function() {
4357             var that = this,
4358                 args = arguments,
4359                 state = that.__brush,
4360                 selection1 = dim.input(typeof selection === "function" ? selection.apply(that, args) : selection, state.extent),
4361                 emit = emitter(that, args).beforestart();
4362
4363             interrupt(that);
4364             state.selection = selection1 == null || empty$1(selection1) ? null : selection1;
4365             redraw.call(that);
4366             emit.start().brush().end();
4367           });
4368     }
4369   };
4370
4371   function redraw() {
4372     var group = d3_select(this),
4373         selection = local$1(this).selection;
4374
4375     if (selection) {
4376       group.selectAll(".selection")
4377           .style("display", null)
4378           .attr("x", selection[0][0])
4379           .attr("y", selection[0][1])
4380           .attr("width", selection[1][0] - selection[0][0])
4381           .attr("height", selection[1][1] - selection[0][1]);
4382
4383       group.selectAll(".handle")
4384           .style("display", null)
4385           .attr("x", function(d) { return d.type[d.type.length - 1] === "e" ? selection[1][0] - handleSize / 2 : selection[0][0] - handleSize / 2; })
4386           .attr("y", function(d) { return d.type[0] === "s" ? selection[1][1] - handleSize / 2 : selection[0][1] - handleSize / 2; })
4387           .attr("width", function(d) { return d.type === "n" || d.type === "s" ? selection[1][0] - selection[0][0] + handleSize : handleSize; })
4388           .attr("height", function(d) { return d.type === "e" || d.type === "w" ? selection[1][1] - selection[0][1] + handleSize : handleSize; });
4389     }
4390
4391     else {
4392       group.selectAll(".selection,.handle")
4393           .style("display", "none")
4394           .attr("x", null)
4395           .attr("y", null)
4396           .attr("width", null)
4397           .attr("height", null);
4398     }
4399   }
4400
4401   function emitter(that, args) {
4402     return that.__brush.emitter || new Emitter(that, args);
4403   }
4404
4405   function Emitter(that, args) {
4406     this.that = that;
4407     this.args = args;
4408     this.state = that.__brush;
4409     this.active = 0;
4410   }
4411
4412   Emitter.prototype = {
4413     beforestart: function() {
4414       if (++this.active === 1) this.state.emitter = this, this.starting = true;
4415       return this;
4416     },
4417     start: function() {
4418       if (this.starting) this.starting = false, this.emit("start");
4419       return this;
4420     },
4421     brush: function() {
4422       this.emit("brush");
4423       return this;
4424     },
4425     end: function() {
4426       if (--this.active === 0) delete this.state.emitter, this.emit("end");
4427       return this;
4428     },
4429     emit: function(type) {
4430       customEvent(new BrushEvent(brush, type, dim.output(this.state.selection)), listeners.apply, listeners, [type, this.that, this.args]);
4431     }
4432   };
4433
4434   function started() {
4435     if (event.touches) { if (event.changedTouches.length < event.touches.length) return noevent$1(); }
4436     else if (touchending) return;
4437     if (!filter.apply(this, arguments)) return;
4438
4439     var that = this,
4440         type = event.target.__data__.type,
4441         mode = (event.metaKey ? type = "overlay" : type) === "selection" ? MODE_DRAG : (event.altKey ? MODE_CENTER : MODE_HANDLE),
4442         signX = dim === Y ? null : signsX[type],
4443         signY = dim === X ? null : signsY[type],
4444         state = local$1(that),
4445         extent = state.extent,
4446         selection = state.selection,
4447         W = extent[0][0], w0, w1,
4448         N = extent[0][1], n0, n1,
4449         E = extent[1][0], e0, e1,
4450         S = extent[1][1], s0, s1,
4451         dx,
4452         dy,
4453         moving,
4454         shifting = signX && signY && event.shiftKey,
4455         lockX,
4456         lockY,
4457         point0 = d3_mouse(that),
4458         point = point0,
4459         emit = emitter(that, arguments).beforestart();
4460
4461     if (type === "overlay") {
4462       state.selection = selection = [
4463         [w0 = dim === Y ? W : point0[0], n0 = dim === X ? N : point0[1]],
4464         [e0 = dim === Y ? E : w0, s0 = dim === X ? S : n0]
4465       ];
4466     } else {
4467       w0 = selection[0][0];
4468       n0 = selection[0][1];
4469       e0 = selection[1][0];
4470       s0 = selection[1][1];
4471     }
4472
4473     w1 = w0;
4474     n1 = n0;
4475     e1 = e0;
4476     s1 = s0;
4477
4478     var group = d3_select(that)
4479         .attr("pointer-events", "none");
4480
4481     var overlay = group.selectAll(".overlay")
4482         .attr("cursor", cursors[type]);
4483
4484     if (event.touches) {
4485       group
4486           .on("touchmove.brush", moved, true)
4487           .on("touchend.brush touchcancel.brush", ended, true);
4488     } else {
4489       var view = d3_select(event.view)
4490           .on("keydown.brush", keydowned, true)
4491           .on("keyup.brush", keyupped, true)
4492           .on("mousemove.brush", moved, true)
4493           .on("mouseup.brush", ended, true);
4494
4495       dragDisable(event.view);
4496     }
4497
4498     nopropagation$1();
4499     interrupt(that);
4500     redraw.call(that);
4501     emit.start();
4502
4503     function moved() {
4504       var point1 = d3_mouse(that);
4505       if (shifting && !lockX && !lockY) {
4506         if (Math.abs(point1[0] - point[0]) > Math.abs(point1[1] - point[1])) lockY = true;
4507         else lockX = true;
4508       }
4509       point = point1;
4510       moving = true;
4511       noevent$1();
4512       move();
4513     }
4514
4515     function move() {
4516       var t;
4517
4518       dx = point[0] - point0[0];
4519       dy = point[1] - point0[1];
4520
4521       switch (mode) {
4522         case MODE_SPACE:
4523         case MODE_DRAG: {
4524           if (signX) dx = Math.max(W - w0, Math.min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx;
4525           if (signY) dy = Math.max(N - n0, Math.min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy;
4526           break;
4527         }
4528         case MODE_HANDLE: {
4529           if (signX < 0) dx = Math.max(W - w0, Math.min(E - w0, dx)), w1 = w0 + dx, e1 = e0;
4530           else if (signX > 0) dx = Math.max(W - e0, Math.min(E - e0, dx)), w1 = w0, e1 = e0 + dx;
4531           if (signY < 0) dy = Math.max(N - n0, Math.min(S - n0, dy)), n1 = n0 + dy, s1 = s0;
4532           else if (signY > 0) dy = Math.max(N - s0, Math.min(S - s0, dy)), n1 = n0, s1 = s0 + dy;
4533           break;
4534         }
4535         case MODE_CENTER: {
4536           if (signX) w1 = Math.max(W, Math.min(E, w0 - dx * signX)), e1 = Math.max(W, Math.min(E, e0 + dx * signX));
4537           if (signY) n1 = Math.max(N, Math.min(S, n0 - dy * signY)), s1 = Math.max(N, Math.min(S, s0 + dy * signY));
4538           break;
4539         }
4540       }
4541
4542       if (e1 < w1) {
4543         signX *= -1;
4544         t = w0, w0 = e0, e0 = t;
4545         t = w1, w1 = e1, e1 = t;
4546         if (type in flipX) overlay.attr("cursor", cursors[type = flipX[type]]);
4547       }
4548
4549       if (s1 < n1) {
4550         signY *= -1;
4551         t = n0, n0 = s0, s0 = t;
4552         t = n1, n1 = s1, s1 = t;
4553         if (type in flipY) overlay.attr("cursor", cursors[type = flipY[type]]);
4554       }
4555
4556       if (state.selection) selection = state.selection; // May be set by brush.move!
4557       if (lockX) w1 = selection[0][0], e1 = selection[1][0];
4558       if (lockY) n1 = selection[0][1], s1 = selection[1][1];
4559
4560       if (selection[0][0] !== w1
4561           || selection[0][1] !== n1
4562           || selection[1][0] !== e1
4563           || selection[1][1] !== s1) {
4564         state.selection = [[w1, n1], [e1, s1]];
4565         redraw.call(that);
4566         emit.brush();
4567       }
4568     }
4569
4570     function ended() {
4571       nopropagation$1();
4572       if (event.touches) {
4573         if (event.touches.length) return;
4574         if (touchending) clearTimeout(touchending);
4575         touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
4576         group.on("touchmove.brush touchend.brush touchcancel.brush", null);
4577       } else {
4578         yesdrag(event.view, moving);
4579         view.on("keydown.brush keyup.brush mousemove.brush mouseup.brush", null);
4580       }
4581       group.attr("pointer-events", "all");
4582       overlay.attr("cursor", cursors.overlay);
4583       if (state.selection) selection = state.selection; // May be set by brush.move (on start)!
4584       if (empty$1(selection)) state.selection = null, redraw.call(that);
4585       emit.end();
4586     }
4587
4588     function keydowned() {
4589       switch (event.keyCode) {
4590         case 16: { // SHIFT
4591           shifting = signX && signY;
4592           break;
4593         }
4594         case 18: { // ALT
4595           if (mode === MODE_HANDLE) {
4596             if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
4597             if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
4598             mode = MODE_CENTER;
4599             move();
4600           }
4601           break;
4602         }
4603         case 32: { // SPACE; takes priority over ALT
4604           if (mode === MODE_HANDLE || mode === MODE_CENTER) {
4605             if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx;
4606             if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy;
4607             mode = MODE_SPACE;
4608             overlay.attr("cursor", cursors.selection);
4609             move();
4610           }
4611           break;
4612         }
4613         default: return;
4614       }
4615       noevent$1();
4616     }
4617
4618     function keyupped() {
4619       switch (event.keyCode) {
4620         case 16: { // SHIFT
4621           if (shifting) {
4622             lockX = lockY = shifting = false;
4623             move();
4624           }
4625           break;
4626         }
4627         case 18: { // ALT
4628           if (mode === MODE_CENTER) {
4629             if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
4630             if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
4631             mode = MODE_HANDLE;
4632             move();
4633           }
4634           break;
4635         }
4636         case 32: { // SPACE
4637           if (mode === MODE_SPACE) {
4638             if (event.altKey) {
4639               if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
4640               if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
4641               mode = MODE_CENTER;
4642             } else {
4643               if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
4644               if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
4645               mode = MODE_HANDLE;
4646             }
4647             overlay.attr("cursor", cursors[type]);
4648             move();
4649           }
4650           break;
4651         }
4652         default: return;
4653       }
4654       noevent$1();
4655     }
4656   }
4657
4658   function initialize() {
4659     var state = this.__brush || {selection: null};
4660     state.extent = extent.apply(this, arguments);
4661     state.dim = dim;
4662     return state;
4663   }
4664
4665   brush.extent = function(_) {
4666     return arguments.length ? (extent = typeof _ === "function" ? _ : constant$4([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), brush) : extent;
4667   };
4668
4669   brush.filter = function(_) {
4670     return arguments.length ? (filter = typeof _ === "function" ? _ : constant$4(!!_), brush) : filter;
4671   };
4672
4673   brush.handleSize = function(_) {
4674     return arguments.length ? (handleSize = +_, brush) : handleSize;
4675   };
4676
4677   brush.on = function() {
4678     var value = listeners.on.apply(listeners, arguments);
4679     return value === listeners ? brush : value;
4680   };
4681
4682   return brush;
4683 }
4684
4685 var cos = Math.cos;
4686 var sin = Math.sin;
4687 var pi$1 = Math.PI;
4688 var halfPi$1 = pi$1 / 2;
4689 var tau$1 = pi$1 * 2;
4690 var max$1 = Math.max;
4691
4692 function compareValue(compare) {
4693   return function(a, b) {
4694     return compare(
4695       a.source.value + a.target.value,
4696       b.source.value + b.target.value
4697     );
4698   };
4699 }
4700
4701 function chord() {
4702   var padAngle = 0,
4703       sortGroups = null,
4704       sortSubgroups = null,
4705       sortChords = null;
4706
4707   function chord(matrix) {
4708     var n = matrix.length,
4709         groupSums = [],
4710         groupIndex = d3_range(n),
4711         subgroupIndex = [],
4712         chords = [],
4713         groups = chords.groups = new Array(n),
4714         subgroups = new Array(n * n),
4715         k,
4716         x,
4717         x0,
4718         dx,
4719         i,
4720         j;
4721
4722     // Compute the sum.
4723     k = 0, i = -1; while (++i < n) {
4724       x = 0, j = -1; while (++j < n) {
4725         x += matrix[i][j];
4726       }
4727       groupSums.push(x);
4728       subgroupIndex.push(d3_range(n));
4729       k += x;
4730     }
4731
4732     // Sort groups…
4733     if (sortGroups) groupIndex.sort(function(a, b) {
4734       return sortGroups(groupSums[a], groupSums[b]);
4735     });
4736
4737     // Sort subgroups…
4738     if (sortSubgroups) subgroupIndex.forEach(function(d, i) {
4739       d.sort(function(a, b) {
4740         return sortSubgroups(matrix[i][a], matrix[i][b]);
4741       });
4742     });
4743
4744     // Convert the sum to scaling factor for [0, 2pi].
4745     // TODO Allow start and end angle to be specified?
4746     // TODO Allow padding to be specified as percentage?
4747     k = max$1(0, tau$1 - padAngle * n) / k;
4748     dx = k ? padAngle : tau$1 / n;
4749
4750     // Compute the start and end angle for each group and subgroup.
4751     // Note: Opera has a bug reordering object literal properties!
4752     x = 0, i = -1; while (++i < n) {
4753       x0 = x, j = -1; while (++j < n) {
4754         var di = groupIndex[i],
4755             dj = subgroupIndex[di][j],
4756             v = matrix[di][dj],
4757             a0 = x,
4758             a1 = x += v * k;
4759         subgroups[dj * n + di] = {
4760           index: di,
4761           subindex: dj,
4762           startAngle: a0,
4763           endAngle: a1,
4764           value: v
4765         };
4766       }
4767       groups[di] = {
4768         index: di,
4769         startAngle: x0,
4770         endAngle: x,
4771         value: groupSums[di]
4772       };
4773       x += dx;
4774     }
4775
4776     // Generate chords for each (non-empty) subgroup-subgroup link.
4777     i = -1; while (++i < n) {
4778       j = i - 1; while (++j < n) {
4779         var source = subgroups[j * n + i],
4780             target = subgroups[i * n + j];
4781         if (source.value || target.value) {
4782           chords.push(source.value < target.value
4783               ? {source: target, target: source}
4784               : {source: source, target: target});
4785         }
4786       }
4787     }
4788
4789     return sortChords ? chords.sort(sortChords) : chords;
4790   }
4791
4792   chord.padAngle = function(_) {
4793     return arguments.length ? (padAngle = max$1(0, _), chord) : padAngle;
4794   };
4795
4796   chord.sortGroups = function(_) {
4797     return arguments.length ? (sortGroups = _, chord) : sortGroups;
4798   };
4799
4800   chord.sortSubgroups = function(_) {
4801     return arguments.length ? (sortSubgroups = _, chord) : sortSubgroups;
4802   };
4803
4804   chord.sortChords = function(_) {
4805     return arguments.length ? (_ == null ? sortChords = null : (sortChords = compareValue(_))._ = _, chord) : sortChords && sortChords._;
4806   };
4807
4808   return chord;
4809 }
4810
4811 var slice$2 = Array.prototype.slice;
4812
4813 function constant$5(x) {
4814   return function() {
4815     return x;
4816   };
4817 }
4818
4819 var pi$2 = Math.PI;
4820 var tau$2 = 2 * pi$2;
4821 var epsilon$1 = 1e-6;
4822 var tauEpsilon = tau$2 - epsilon$1;
4823
4824 function Path() {
4825   this._x0 = this._y0 = // start of current subpath
4826   this._x1 = this._y1 = null; // end of current subpath
4827   this._ = "";
4828 }
4829
4830 function path() {
4831   return new Path;
4832 }
4833
4834 Path.prototype = path.prototype = {
4835   constructor: Path,
4836   moveTo: function(x, y) {
4837     this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y);
4838   },
4839   closePath: function() {
4840     if (this._x1 !== null) {
4841       this._x1 = this._x0, this._y1 = this._y0;
4842       this._ += "Z";
4843     }
4844   },
4845   lineTo: function(x, y) {
4846     this._ += "L" + (this._x1 = +x) + "," + (this._y1 = +y);
4847   },
4848   quadraticCurveTo: function(x1, y1, x, y) {
4849     this._ += "Q" + (+x1) + "," + (+y1) + "," + (this._x1 = +x) + "," + (this._y1 = +y);
4850   },
4851   bezierCurveTo: function(x1, y1, x2, y2, x, y) {
4852     this._ += "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + "," + (this._x1 = +x) + "," + (this._y1 = +y);
4853   },
4854   arcTo: function(x1, y1, x2, y2, r) {
4855     x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;
4856     var x0 = this._x1,
4857         y0 = this._y1,
4858         x21 = x2 - x1,
4859         y21 = y2 - y1,
4860         x01 = x0 - x1,
4861         y01 = y0 - y1,
4862         l01_2 = x01 * x01 + y01 * y01;
4863
4864     // Is the radius negative? Error.
4865     if (r < 0) throw new Error("negative radius: " + r);
4866
4867     // Is this path empty? Move to (x1,y1).
4868     if (this._x1 === null) {
4869       this._ += "M" + (this._x1 = x1) + "," + (this._y1 = y1);
4870     }
4871
4872     // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.
4873     else if (!(l01_2 > epsilon$1)) {}
4874
4875     // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?
4876     // Equivalently, is (x1,y1) coincident with (x2,y2)?
4877     // Or, is the radius zero? Line to (x1,y1).
4878     else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon$1) || !r) {
4879       this._ += "L" + (this._x1 = x1) + "," + (this._y1 = y1);
4880     }
4881
4882     // Otherwise, draw an arc!
4883     else {
4884       var x20 = x2 - x0,
4885           y20 = y2 - y0,
4886           l21_2 = x21 * x21 + y21 * y21,
4887           l20_2 = x20 * x20 + y20 * y20,
4888           l21 = Math.sqrt(l21_2),
4889           l01 = Math.sqrt(l01_2),
4890           l = r * Math.tan((pi$2 - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),
4891           t01 = l / l01,
4892           t21 = l / l21;
4893
4894       // If the start tangent is not coincident with (x0,y0), line to.
4895       if (Math.abs(t01 - 1) > epsilon$1) {
4896         this._ += "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01);
4897       }
4898
4899       this._ += "A" + r + "," + r + ",0,0," + (+(y01 * x20 > x01 * y20)) + "," + (this._x1 = x1 + t21 * x21) + "," + (this._y1 = y1 + t21 * y21);
4900     }
4901   },
4902   arc: function(x, y, r, a0, a1, ccw) {
4903     x = +x, y = +y, r = +r;
4904     var dx = r * Math.cos(a0),
4905         dy = r * Math.sin(a0),
4906         x0 = x + dx,
4907         y0 = y + dy,
4908         cw = 1 ^ ccw,
4909         da = ccw ? a0 - a1 : a1 - a0;
4910
4911     // Is the radius negative? Error.
4912     if (r < 0) throw new Error("negative radius: " + r);
4913
4914     // Is this path empty? Move to (x0,y0).
4915     if (this._x1 === null) {
4916       this._ += "M" + x0 + "," + y0;
4917     }
4918
4919     // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).
4920     else if (Math.abs(this._x1 - x0) > epsilon$1 || Math.abs(this._y1 - y0) > epsilon$1) {
4921       this._ += "L" + x0 + "," + y0;
4922     }
4923
4924     // Is this arc empty? We’re done.
4925     if (!r) return;
4926
4927     // Does the angle go the wrong way? Flip the direction.
4928     if (da < 0) da = da % tau$2 + tau$2;
4929
4930     // Is this a complete circle? Draw two arcs to complete the circle.
4931     if (da > tauEpsilon) {
4932       this._ += "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," + (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 = x0) + "," + (this._y1 = y0);
4933     }
4934
4935     // Is this arc non-empty? Draw an arc!
4936     else if (da > epsilon$1) {
4937       this._ += "A" + r + "," + r + ",0," + (+(da >= pi$2)) + "," + cw + "," + (this._x1 = x + r * Math.cos(a1)) + "," + (this._y1 = y + r * Math.sin(a1));
4938     }
4939   },
4940   rect: function(x, y, w, h) {
4941     this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y) + "h" + (+w) + "v" + (+h) + "h" + (-w) + "Z";
4942   },
4943   toString: function() {
4944     return this._;
4945   }
4946 };
4947
4948 function defaultSource(d) {
4949   return d.source;
4950 }
4951
4952 function defaultTarget(d) {
4953   return d.target;
4954 }
4955
4956 function defaultRadius(d) {
4957   return d.radius;
4958 }
4959
4960 function defaultStartAngle(d) {
4961   return d.startAngle;
4962 }
4963
4964 function defaultEndAngle(d) {
4965   return d.endAngle;
4966 }
4967
4968 function ribbon() {
4969   var source = defaultSource,
4970       target = defaultTarget,
4971       radius = defaultRadius,
4972       startAngle = defaultStartAngle,
4973       endAngle = defaultEndAngle,
4974       context = null;
4975
4976   function ribbon() {
4977     var buffer,
4978         argv = slice$2.call(arguments),
4979         s = source.apply(this, argv),
4980         t = target.apply(this, argv),
4981         sr = +radius.apply(this, (argv[0] = s, argv)),
4982         sa0 = startAngle.apply(this, argv) - halfPi$1,
4983         sa1 = endAngle.apply(this, argv) - halfPi$1,
4984         sx0 = sr * cos(sa0),
4985         sy0 = sr * sin(sa0),
4986         tr = +radius.apply(this, (argv[0] = t, argv)),
4987         ta0 = startAngle.apply(this, argv) - halfPi$1,
4988         ta1 = endAngle.apply(this, argv) - halfPi$1;
4989
4990     if (!context) context = buffer = path();
4991
4992     context.moveTo(sx0, sy0);
4993     context.arc(0, 0, sr, sa0, sa1);
4994     if (sa0 !== ta0 || sa1 !== ta1) { // TODO sr !== tr?
4995       context.quadraticCurveTo(0, 0, tr * cos(ta0), tr * sin(ta0));
4996       context.arc(0, 0, tr, ta0, ta1);
4997     }
4998     context.quadraticCurveTo(0, 0, sx0, sy0);
4999     context.closePath();
5000
5001     if (buffer) return context = null, buffer + "" || null;
5002   }
5003
5004   ribbon.radius = function(_) {
5005     return arguments.length ? (radius = typeof _ === "function" ? _ : constant$5(+_), ribbon) : radius;
5006   };
5007
5008   ribbon.startAngle = function(_) {
5009     return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$5(+_), ribbon) : startAngle;
5010   };
5011
5012   ribbon.endAngle = function(_) {
5013     return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$5(+_), ribbon) : endAngle;
5014   };
5015
5016   ribbon.source = function(_) {
5017     return arguments.length ? (source = _, ribbon) : source;
5018   };
5019
5020   ribbon.target = function(_) {
5021     return arguments.length ? (target = _, ribbon) : target;
5022   };
5023
5024   ribbon.context = function(_) {
5025     return arguments.length ? (context = _ == null ? null : _, ribbon) : context;
5026   };
5027
5028   return ribbon;
5029 }
5030
5031 var prefix = "$";
5032
5033 function Map() {}
5034
5035 Map.prototype = map$1.prototype = {
5036   constructor: Map,
5037   has: function(key) {
5038     return (prefix + key) in this;
5039   },
5040   get: function(key) {
5041     return this[prefix + key];
5042   },
5043   set: function(key, value) {
5044     this[prefix + key] = value;
5045     return this;
5046   },
5047   remove: function(key) {
5048     var property = prefix + key;
5049     return property in this && delete this[property];
5050   },
5051   clear: function() {
5052     for (var property in this) if (property[0] === prefix) delete this[property];
5053   },
5054   keys: function() {
5055     var keys = [];
5056     for (var property in this) if (property[0] === prefix) keys.push(property.slice(1));
5057     return keys;
5058   },
5059   values: function() {
5060     var values = [];
5061     for (var property in this) if (property[0] === prefix) values.push(this[property]);
5062     return values;
5063   },
5064   entries: function() {
5065     var entries = [];
5066     for (var property in this) if (property[0] === prefix) entries.push({key: property.slice(1), value: this[property]});
5067     return entries;
5068   },
5069   size: function() {
5070     var size = 0;
5071     for (var property in this) if (property[0] === prefix) ++size;
5072     return size;
5073   },
5074   empty: function() {
5075     for (var property in this) if (property[0] === prefix) return false;
5076     return true;
5077   },
5078   each: function(f) {
5079     for (var property in this) if (property[0] === prefix) f(this[property], property.slice(1), this);
5080   }
5081 };
5082
5083 function map$1(object, f) {
5084   var map = new Map;
5085
5086   // Copy constructor.
5087   if (object instanceof Map) object.each(function(value, key) { map.set(key, value); });
5088
5089   // Index array by numeric index or specified key function.
5090   else if (Array.isArray(object)) {
5091     var i = -1,
5092         n = object.length,
5093         o;
5094
5095     if (f == null) while (++i < n) map.set(i, object[i]);
5096     else while (++i < n) map.set(f(o = object[i], i, object), o);
5097   }
5098
5099   // Convert object to map.
5100   else if (object) for (var key in object) map.set(key, object[key]);
5101
5102   return map;
5103 }
5104
5105 function nest() {
5106   var keys = [],
5107       sortKeys = [],
5108       sortValues,
5109       rollup,
5110       nest;
5111
5112   function apply(array, depth, createResult, setResult) {
5113     if (depth >= keys.length) {
5114       if (sortValues != null) array.sort(sortValues);
5115       return rollup != null ? rollup(array) : array;
5116     }
5117
5118     var i = -1,
5119         n = array.length,
5120         key = keys[depth++],
5121         keyValue,
5122         value,
5123         valuesByKey = map$1(),
5124         values,
5125         result = createResult();
5126
5127     while (++i < n) {
5128       if (values = valuesByKey.get(keyValue = key(value = array[i]) + "")) {
5129         values.push(value);
5130       } else {
5131         valuesByKey.set(keyValue, [value]);
5132       }
5133     }
5134
5135     valuesByKey.each(function(values, key) {
5136       setResult(result, key, apply(values, depth, createResult, setResult));
5137     });
5138
5139     return result;
5140   }
5141
5142   function entries(map, depth) {
5143     if (++depth > keys.length) return map;
5144     var array, sortKey = sortKeys[depth - 1];
5145     if (rollup != null && depth >= keys.length) array = map.entries();
5146     else array = [], map.each(function(v, k) { array.push({key: k, values: entries(v, depth)}); });
5147     return sortKey != null ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) : array;
5148   }
5149
5150   return nest = {
5151     object: function(array) { return apply(array, 0, createObject, setObject); },
5152     map: function(array) { return apply(array, 0, createMap, setMap); },
5153     entries: function(array) { return entries(apply(array, 0, createMap, setMap), 0); },
5154     key: function(d) { keys.push(d); return nest; },
5155     sortKeys: function(order) { sortKeys[keys.length - 1] = order; return nest; },
5156     sortValues: function(order) { sortValues = order; return nest; },
5157     rollup: function(f) { rollup = f; return nest; }
5158   };
5159 }
5160
5161 function createObject() {
5162   return {};
5163 }
5164
5165 function setObject(object, key, value) {
5166   object[key] = value;
5167 }
5168
5169 function createMap() {
5170   return map$1();
5171 }
5172
5173 function setMap(map, key, value) {
5174   map.set(key, value);
5175 }
5176
5177 function Set() {}
5178
5179 var proto = map$1.prototype;
5180
5181 Set.prototype = set$2.prototype = {
5182   constructor: Set,
5183   has: proto.has,
5184   add: function(value) {
5185     value += "";
5186     this[prefix + value] = value;
5187     return this;
5188   },
5189   remove: proto.remove,
5190   clear: proto.clear,
5191   values: proto.keys,
5192   size: proto.size,
5193   empty: proto.empty,
5194   each: proto.each
5195 };
5196
5197 function set$2(object, f) {
5198   var set = new Set;
5199
5200   // Copy constructor.
5201   if (object instanceof Set) object.each(function(value) { set.add(value); });
5202
5203   // Otherwise, assume it’s an array.
5204   else if (object) {
5205     var i = -1, n = object.length;
5206     if (f == null) while (++i < n) set.add(object[i]);
5207     else while (++i < n) set.add(f(object[i], i, object));
5208   }
5209
5210   return set;
5211 }
5212
5213 function keys(map) {
5214   var keys = [];
5215   for (var key in map) keys.push(key);
5216   return keys;
5217 }
5218
5219 function values(map) {
5220   var values = [];
5221   for (var key in map) values.push(map[key]);
5222   return values;
5223 }
5224
5225 function entries(map) {
5226   var entries = [];
5227   for (var key in map) entries.push({key: key, value: map[key]});
5228   return entries;
5229 }
5230
5231 var EOL = {};
5232 var EOF = {};
5233 var QUOTE = 34;
5234 var NEWLINE = 10;
5235 var RETURN = 13;
5236
5237 function objectConverter(columns) {
5238   return new Function("d", "return {" + columns.map(function(name, i) {
5239     return JSON.stringify(name) + ": d[" + i + "]";
5240   }).join(",") + "}");
5241 }
5242
5243 function customConverter(columns, f) {
5244   var object = objectConverter(columns);
5245   return function(row, i) {
5246     return f(object(row), i, columns);
5247   };
5248 }
5249
5250 // Compute unique columns in order of discovery.
5251 function inferColumns(rows) {
5252   var columnSet = Object.create(null),
5253       columns = [];
5254
5255   rows.forEach(function(row) {
5256     for (var column in row) {
5257       if (!(column in columnSet)) {
5258         columns.push(columnSet[column] = column);
5259       }
5260     }
5261   });
5262
5263   return columns;
5264 }
5265
5266 function dsv(delimiter) {
5267   var reFormat = new RegExp("[\"" + delimiter + "\n\r]"),
5268       DELIMITER = delimiter.charCodeAt(0);
5269
5270   function parse(text, f) {
5271     var convert, columns, rows = parseRows(text, function(row, i) {
5272       if (convert) return convert(row, i - 1);
5273       columns = row, convert = f ? customConverter(row, f) : objectConverter(row);
5274     });
5275     rows.columns = columns || [];
5276     return rows;
5277   }
5278
5279   function parseRows(text, f) {
5280     var rows = [], // output rows
5281         N = text.length,
5282         I = 0, // current character index
5283         n = 0, // current line number
5284         t, // current token
5285         eof = N <= 0, // current token followed by EOF?
5286         eol = false; // current token followed by EOL?
5287
5288     // Strip the trailing newline.
5289     if (text.charCodeAt(N - 1) === NEWLINE) --N;
5290     if (text.charCodeAt(N - 1) === RETURN) --N;
5291
5292     function token() {
5293       if (eof) return EOF;
5294       if (eol) return eol = false, EOL;
5295
5296       // Unescape quotes.
5297       var i, j = I, c;
5298       if (text.charCodeAt(j) === QUOTE) {
5299         while (I++ < N && text.charCodeAt(I) !== QUOTE || text.charCodeAt(++I) === QUOTE);
5300         if ((i = I) >= N) eof = true;
5301         else if ((c = text.charCodeAt(I++)) === NEWLINE) eol = true;
5302         else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; }
5303         return text.slice(j + 1, i - 1).replace(/""/g, "\"");
5304       }
5305
5306       // Find next delimiter or newline.
5307       while (I < N) {
5308         if ((c = text.charCodeAt(i = I++)) === NEWLINE) eol = true;
5309         else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; }
5310         else if (c !== DELIMITER) continue;
5311         return text.slice(j, i);
5312       }
5313
5314       // Return last token before EOF.
5315       return eof = true, text.slice(j, N);
5316     }
5317
5318     while ((t = token()) !== EOF) {
5319       var row = [];
5320       while (t !== EOL && t !== EOF) row.push(t), t = token();
5321       if (f && (row = f(row, n++)) == null) continue;
5322       rows.push(row);
5323     }
5324
5325     return rows;
5326   }
5327
5328   function format(rows, columns) {
5329     if (columns == null) columns = inferColumns(rows);
5330     return [columns.map(formatValue).join(delimiter)].concat(rows.map(function(row) {
5331       return columns.map(function(column) {
5332         return formatValue(row[column]);
5333       }).join(delimiter);
5334     })).join("\n");
5335   }
5336
5337   function formatRows(rows) {
5338     return rows.map(formatRow).join("\n");
5339   }
5340
5341   function formatRow(row) {
5342     return row.map(formatValue).join(delimiter);
5343   }
5344
5345   function formatValue(text) {
5346     return text == null ? ""
5347         : reFormat.test(text += "") ? "\"" + text.replace(/"/g, "\"\"") + "\""
5348         : text;
5349   }
5350
5351   return {
5352     parse: parse,
5353     parseRows: parseRows,
5354     format: format,
5355     formatRows: formatRows
5356   };
5357 }
5358
5359 var csv = dsv(",");
5360
5361 var csvParse = csv.parse;
5362 var csvParseRows = csv.parseRows;
5363 var csvFormat = csv.format;
5364 var csvFormatRows = csv.formatRows;
5365
5366 var tsv = dsv("\t");
5367
5368 var tsvParse = tsv.parse;
5369 var tsvParseRows = tsv.parseRows;
5370 var tsvFormat = tsv.format;
5371 var tsvFormatRows = tsv.formatRows;
5372
5373 function center$1(x, y) {
5374   var nodes;
5375
5376   if (x == null) x = 0;
5377   if (y == null) y = 0;
5378
5379   function force() {
5380     var i,
5381         n = nodes.length,
5382         node,
5383         sx = 0,
5384         sy = 0;
5385
5386     for (i = 0; i < n; ++i) {
5387       node = nodes[i], sx += node.x, sy += node.y;
5388     }
5389
5390     for (sx = sx / n - x, sy = sy / n - y, i = 0; i < n; ++i) {
5391       node = nodes[i], node.x -= sx, node.y -= sy;
5392     }
5393   }
5394
5395   force.initialize = function(_) {
5396     nodes = _;
5397   };
5398
5399   force.x = function(_) {
5400     return arguments.length ? (x = +_, force) : x;
5401   };
5402
5403   force.y = function(_) {
5404     return arguments.length ? (y = +_, force) : y;
5405   };
5406
5407   return force;
5408 }
5409
5410 function constant$6(x) {
5411   return function() {
5412     return x;
5413   };
5414 }
5415
5416 function jiggle() {
5417   return (Math.random() - 0.5) * 1e-6;
5418 }
5419
5420 function tree_add(d) {
5421   var x = +this._x.call(null, d),
5422       y = +this._y.call(null, d);
5423   return add(this.cover(x, y), x, y, d);
5424 }
5425
5426 function add(tree, x, y, d) {
5427   if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points
5428
5429   var parent,
5430       node = tree._root,
5431       leaf = {data: d},
5432       x0 = tree._x0,
5433       y0 = tree._y0,
5434       x1 = tree._x1,
5435       y1 = tree._y1,
5436       xm,
5437       ym,
5438       xp,
5439       yp,
5440       right,
5441       bottom,
5442       i,
5443       j;
5444
5445   // If the tree is empty, initialize the root as a leaf.
5446   if (!node) return tree._root = leaf, tree;
5447
5448   // Find the existing leaf for the new point, or add it.
5449   while (node.length) {
5450     if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
5451     if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
5452     if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree;
5453   }
5454
5455   // Is the new point is exactly coincident with the existing point?
5456   xp = +tree._x.call(null, node.data);
5457   yp = +tree._y.call(null, node.data);
5458   if (x === xp && y === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree;
5459
5460   // Otherwise, split the leaf node until the old and new point are separated.
5461   do {
5462     parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4);
5463     if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
5464     if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
5465   } while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | (xp >= xm)));
5466   return parent[j] = node, parent[i] = leaf, tree;
5467 }
5468
5469 function addAll(data) {
5470   var d, i, n = data.length,
5471       x,
5472       y,
5473       xz = new Array(n),
5474       yz = new Array(n),
5475       x0 = Infinity,
5476       y0 = Infinity,
5477       x1 = -Infinity,
5478       y1 = -Infinity;
5479
5480   // Compute the points and their extent.
5481   for (i = 0; i < n; ++i) {
5482     if (isNaN(x = +this._x.call(null, d = data[i])) || isNaN(y = +this._y.call(null, d))) continue;
5483     xz[i] = x;
5484     yz[i] = y;
5485     if (x < x0) x0 = x;
5486     if (x > x1) x1 = x;
5487     if (y < y0) y0 = y;
5488     if (y > y1) y1 = y;
5489   }
5490
5491   // If there were no (valid) points, inherit the existing extent.
5492   if (x1 < x0) x0 = this._x0, x1 = this._x1;
5493   if (y1 < y0) y0 = this._y0, y1 = this._y1;
5494
5495   // Expand the tree to cover the new points.
5496   this.cover(x0, y0).cover(x1, y1);
5497
5498   // Add the new points.
5499   for (i = 0; i < n; ++i) {
5500     add(this, xz[i], yz[i], data[i]);
5501   }
5502
5503   return this;
5504 }
5505
5506 function tree_cover(x, y) {
5507   if (isNaN(x = +x) || isNaN(y = +y)) return this; // ignore invalid points
5508
5509   var x0 = this._x0,
5510       y0 = this._y0,
5511       x1 = this._x1,
5512       y1 = this._y1;
5513
5514   // If the quadtree has no extent, initialize them.
5515   // Integer extent are necessary so that if we later double the extent,
5516   // the existing quadrant boundaries don’t change due to floating point error!
5517   if (isNaN(x0)) {
5518     x1 = (x0 = Math.floor(x)) + 1;
5519     y1 = (y0 = Math.floor(y)) + 1;
5520   }
5521
5522   // Otherwise, double repeatedly to cover.
5523   else if (x0 > x || x > x1 || y0 > y || y > y1) {
5524     var z = x1 - x0,
5525         node = this._root,
5526         parent,
5527         i;
5528
5529     switch (i = (y < (y0 + y1) / 2) << 1 | (x < (x0 + x1) / 2)) {
5530       case 0: {
5531         do parent = new Array(4), parent[i] = node, node = parent;
5532         while (z *= 2, x1 = x0 + z, y1 = y0 + z, x > x1 || y > y1);
5533         break;
5534       }
5535       case 1: {
5536         do parent = new Array(4), parent[i] = node, node = parent;
5537         while (z *= 2, x0 = x1 - z, y1 = y0 + z, x0 > x || y > y1);
5538         break;
5539       }
5540       case 2: {
5541         do parent = new Array(4), parent[i] = node, node = parent;
5542         while (z *= 2, x1 = x0 + z, y0 = y1 - z, x > x1 || y0 > y);
5543         break;
5544       }
5545       case 3: {
5546         do parent = new Array(4), parent[i] = node, node = parent;
5547         while (z *= 2, x0 = x1 - z, y0 = y1 - z, x0 > x || y0 > y);
5548         break;
5549       }
5550     }
5551
5552     if (this._root && this._root.length) this._root = node;
5553   }
5554
5555   // If the quadtree covers the point already, just return.
5556   else return this;
5557
5558   this._x0 = x0;
5559   this._y0 = y0;
5560   this._x1 = x1;
5561   this._y1 = y1;
5562   return this;
5563 }
5564
5565 function tree_data() {
5566   var data = [];
5567   this.visit(function(node) {
5568     if (!node.length) do data.push(node.data); while (node = node.next)
5569   });
5570   return data;
5571 }
5572
5573 function tree_extent(_) {
5574   return arguments.length
5575       ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1])
5576       : isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, this._y1]];
5577 }
5578
5579 function Quad(node, x0, y0, x1, y1) {
5580   this.node = node;
5581   this.x0 = x0;
5582   this.y0 = y0;
5583   this.x1 = x1;
5584   this.y1 = y1;
5585 }
5586
5587 function tree_find(x, y, radius) {
5588   var data,
5589       x0 = this._x0,
5590       y0 = this._y0,
5591       x1,
5592       y1,
5593       x2,
5594       y2,
5595       x3 = this._x1,
5596       y3 = this._y1,
5597       quads = [],
5598       node = this._root,
5599       q,
5600       i;
5601
5602   if (node) quads.push(new Quad(node, x0, y0, x3, y3));
5603   if (radius == null) radius = Infinity;
5604   else {
5605     x0 = x - radius, y0 = y - radius;
5606     x3 = x + radius, y3 = y + radius;
5607     radius *= radius;
5608   }
5609
5610   while (q = quads.pop()) {
5611
5612     // Stop searching if this quadrant can’t contain a closer node.
5613     if (!(node = q.node)
5614         || (x1 = q.x0) > x3
5615         || (y1 = q.y0) > y3
5616         || (x2 = q.x1) < x0
5617         || (y2 = q.y1) < y0) continue;
5618
5619     // Bisect the current quadrant.
5620     if (node.length) {
5621       var xm = (x1 + x2) / 2,
5622           ym = (y1 + y2) / 2;
5623
5624       quads.push(
5625         new Quad(node[3], xm, ym, x2, y2),
5626         new Quad(node[2], x1, ym, xm, y2),
5627         new Quad(node[1], xm, y1, x2, ym),
5628         new Quad(node[0], x1, y1, xm, ym)
5629       );
5630
5631       // Visit the closest quadrant first.
5632       if (i = (y >= ym) << 1 | (x >= xm)) {
5633         q = quads[quads.length - 1];
5634         quads[quads.length - 1] = quads[quads.length - 1 - i];
5635         quads[quads.length - 1 - i] = q;
5636       }
5637     }
5638
5639     // Visit this point. (Visiting coincident points isn’t necessary!)
5640     else {
5641       var dx = x - +this._x.call(null, node.data),
5642           dy = y - +this._y.call(null, node.data),
5643           d2 = dx * dx + dy * dy;
5644       if (d2 < radius) {
5645         var d = Math.sqrt(radius = d2);
5646         x0 = x - d, y0 = y - d;
5647         x3 = x + d, y3 = y + d;
5648         data = node.data;
5649       }
5650     }
5651   }
5652
5653   return data;
5654 }
5655
5656 function tree_remove(d) {
5657   if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points
5658
5659   var parent,
5660       node = this._root,
5661       retainer,
5662       previous,
5663       next,
5664       x0 = this._x0,
5665       y0 = this._y0,
5666       x1 = this._x1,
5667       y1 = this._y1,
5668       x,
5669       y,
5670       xm,
5671       ym,
5672       right,
5673       bottom,
5674       i,
5675       j;
5676
5677   // If the tree is empty, initialize the root as a leaf.
5678   if (!node) return this;
5679
5680   // Find the leaf node for the point.
5681   // While descending, also retain the deepest parent with a non-removed sibling.
5682   if (node.length) while (true) {
5683     if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
5684     if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
5685     if (!(parent = node, node = node[i = bottom << 1 | right])) return this;
5686     if (!node.length) break;
5687     if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i;
5688   }
5689
5690   // Find the point to remove.
5691   while (node.data !== d) if (!(previous = node, node = node.next)) return this;
5692   if (next = node.next) delete node.next;
5693
5694   // If there are multiple coincident points, remove just the point.
5695   if (previous) return next ? previous.next = next : delete previous.next, this;
5696
5697   // If this is the root point, remove it.
5698   if (!parent) return this._root = next, this;
5699
5700   // Remove this leaf.
5701   next ? parent[i] = next : delete parent[i];
5702
5703   // If the parent now contains exactly one leaf, collapse superfluous parents.
5704   if ((node = parent[0] || parent[1] || parent[2] || parent[3])
5705       && node === (parent[3] || parent[2] || parent[1] || parent[0])
5706       && !node.length) {
5707     if (retainer) retainer[j] = node;
5708     else this._root = node;
5709   }
5710
5711   return this;
5712 }
5713
5714 function removeAll(data) {
5715   for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]);
5716   return this;
5717 }
5718
5719 function tree_root() {
5720   return this._root;
5721 }
5722
5723 function tree_size() {
5724   var size = 0;
5725   this.visit(function(node) {
5726     if (!node.length) do ++size; while (node = node.next)
5727   });
5728   return size;
5729 }
5730
5731 function tree_visit(callback) {
5732   var quads = [], q, node = this._root, child, x0, y0, x1, y1;
5733   if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y1));
5734   while (q = quads.pop()) {
5735     if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) {
5736       var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
5737       if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
5738       if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
5739       if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
5740       if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
5741     }
5742   }
5743   return this;
5744 }
5745
5746 function tree_visitAfter(callback) {
5747   var quads = [], next = [], q;
5748   if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this._x1, this._y1));
5749   while (q = quads.pop()) {
5750     var node = q.node;
5751     if (node.length) {
5752       var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
5753       if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
5754       if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
5755       if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
5756       if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
5757     }
5758     next.push(q);
5759   }
5760   while (q = next.pop()) {
5761     callback(q.node, q.x0, q.y0, q.x1, q.y1);
5762   }
5763   return this;
5764 }
5765
5766 function defaultX(d) {
5767   return d[0];
5768 }
5769
5770 function tree_x(_) {
5771   return arguments.length ? (this._x = _, this) : this._x;
5772 }
5773
5774 function defaultY(d) {
5775   return d[1];
5776 }
5777
5778 function tree_y(_) {
5779   return arguments.length ? (this._y = _, this) : this._y;
5780 }
5781
5782 function quadtree(nodes, x, y) {
5783   var tree = new Quadtree(x == null ? defaultX : x, y == null ? defaultY : y, NaN, NaN, NaN, NaN);
5784   return nodes == null ? tree : tree.addAll(nodes);
5785 }
5786
5787 function Quadtree(x, y, x0, y0, x1, y1) {
5788   this._x = x;
5789   this._y = y;
5790   this._x0 = x0;
5791   this._y0 = y0;
5792   this._x1 = x1;
5793   this._y1 = y1;
5794   this._root = undefined;
5795 }
5796
5797 function leaf_copy(leaf) {
5798   var copy = {data: leaf.data}, next = copy;
5799   while (leaf = leaf.next) next = next.next = {data: leaf.data};
5800   return copy;
5801 }
5802
5803 var treeProto = quadtree.prototype = Quadtree.prototype;
5804
5805 treeProto.copy = function() {
5806   var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1),
5807       node = this._root,
5808       nodes,
5809       child;
5810
5811   if (!node) return copy;
5812
5813   if (!node.length) return copy._root = leaf_copy(node), copy;
5814
5815   nodes = [{source: node, target: copy._root = new Array(4)}];
5816   while (node = nodes.pop()) {
5817     for (var i = 0; i < 4; ++i) {
5818       if (child = node.source[i]) {
5819         if (child.length) nodes.push({source: child, target: node.target[i] = new Array(4)});
5820         else node.target[i] = leaf_copy(child);
5821       }
5822     }
5823   }
5824
5825   return copy;
5826 };
5827
5828 treeProto.add = tree_add;
5829 treeProto.addAll = addAll;
5830 treeProto.cover = tree_cover;
5831 treeProto.data = tree_data;
5832 treeProto.extent = tree_extent;
5833 treeProto.find = tree_find;
5834 treeProto.remove = tree_remove;
5835 treeProto.removeAll = removeAll;
5836 treeProto.root = tree_root;
5837 treeProto.size = tree_size;
5838 treeProto.visit = tree_visit;
5839 treeProto.visitAfter = tree_visitAfter;
5840 treeProto.x = tree_x;
5841 treeProto.y = tree_y;
5842
5843 function x(d) {
5844   return d.x + d.vx;
5845 }
5846
5847 function y(d) {
5848   return d.y + d.vy;
5849 }
5850
5851 function collide(radius) {
5852   var nodes,
5853       radii,
5854       strength = 1,
5855       iterations = 1;
5856
5857   if (typeof radius !== "function") radius = constant$6(radius == null ? 1 : +radius);
5858
5859   function force() {
5860     var i, n = nodes.length,
5861         tree,
5862         node,
5863         xi,
5864         yi,
5865         ri,
5866         ri2;
5867
5868     for (var k = 0; k < iterations; ++k) {
5869       tree = quadtree(nodes, x, y).visitAfter(prepare);
5870       for (i = 0; i < n; ++i) {
5871         node = nodes[i];
5872         ri = radii[node.index], ri2 = ri * ri;
5873         xi = node.x + node.vx;
5874         yi = node.y + node.vy;
5875         tree.visit(apply);
5876       }
5877     }
5878
5879     function apply(quad, x0, y0, x1, y1) {
5880       var data = quad.data, rj = quad.r, r = ri + rj;
5881       if (data) {
5882         if (data.index > node.index) {
5883           var x = xi - data.x - data.vx,
5884               y = yi - data.y - data.vy,
5885               l = x * x + y * y;
5886           if (l < r * r) {
5887             if (x === 0) x = jiggle(), l += x * x;
5888             if (y === 0) y = jiggle(), l += y * y;
5889             l = (r - (l = Math.sqrt(l))) / l * strength;
5890             node.vx += (x *= l) * (r = (rj *= rj) / (ri2 + rj));
5891             node.vy += (y *= l) * r;
5892             data.vx -= x * (r = 1 - r);
5893             data.vy -= y * r;
5894           }
5895         }
5896         return;
5897       }
5898       return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r;
5899     }
5900   }
5901
5902   function prepare(quad) {
5903     if (quad.data) return quad.r = radii[quad.data.index];
5904     for (var i = quad.r = 0; i < 4; ++i) {
5905       if (quad[i] && quad[i].r > quad.r) {
5906         quad.r = quad[i].r;
5907       }
5908     }
5909   }
5910
5911   function initialize() {
5912     if (!nodes) return;
5913     var i, n = nodes.length, node;
5914     radii = new Array(n);
5915     for (i = 0; i < n; ++i) node = nodes[i], radii[node.index] = +radius(node, i, nodes);
5916   }
5917
5918   force.initialize = function(_) {
5919     nodes = _;
5920     initialize();
5921   };
5922
5923   force.iterations = function(_) {
5924     return arguments.length ? (iterations = +_, force) : iterations;
5925   };
5926
5927   force.strength = function(_) {
5928     return arguments.length ? (strength = +_, force) : strength;
5929   };
5930
5931   force.radius = function(_) {
5932     return arguments.length ? (radius = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : radius;
5933   };
5934
5935   return force;
5936 }
5937
5938 function index(d) {
5939   return d.index;
5940 }
5941
5942 function find(nodeById, nodeId) {
5943   var node = nodeById.get(nodeId);
5944   if (!node) throw new Error("missing: " + nodeId);
5945   return node;
5946 }
5947
5948 function link(links) {
5949   var id = index,
5950       strength = defaultStrength,
5951       strengths,
5952       distance = constant$6(30),
5953       distances,
5954       nodes,
5955       count,
5956       bias,
5957       iterations = 1;
5958
5959   if (links == null) links = [];
5960
5961   function defaultStrength(link) {
5962     return 1 / Math.min(count[link.source.index], count[link.target.index]);
5963   }
5964
5965   function force(alpha) {
5966     for (var k = 0, n = links.length; k < iterations; ++k) {
5967       for (var i = 0, link, source, target, x, y, l, b; i < n; ++i) {
5968         link = links[i], source = link.source, target = link.target;
5969         x = target.x + target.vx - source.x - source.vx || jiggle();
5970         y = target.y + target.vy - source.y - source.vy || jiggle();
5971         l = Math.sqrt(x * x + y * y);
5972         l = (l - distances[i]) / l * alpha * strengths[i];
5973         x *= l, y *= l;
5974         target.vx -= x * (b = bias[i]);
5975         target.vy -= y * b;
5976         source.vx += x * (b = 1 - b);
5977         source.vy += y * b;
5978       }
5979     }
5980   }
5981
5982   function initialize() {
5983     if (!nodes) return;
5984
5985     var i,
5986         n = nodes.length,
5987         m = links.length,
5988         nodeById = map$1(nodes, id),
5989         link;
5990
5991     for (i = 0, count = new Array(n); i < m; ++i) {
5992       link = links[i], link.index = i;
5993       if (typeof link.source !== "object") link.source = find(nodeById, link.source);
5994       if (typeof link.target !== "object") link.target = find(nodeById, link.target);
5995       count[link.source.index] = (count[link.source.index] || 0) + 1;
5996       count[link.target.index] = (count[link.target.index] || 0) + 1;
5997     }
5998
5999     for (i = 0, bias = new Array(m); i < m; ++i) {
6000       link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]);
6001     }
6002
6003     strengths = new Array(m), initializeStrength();
6004     distances = new Array(m), initializeDistance();
6005   }
6006
6007   function initializeStrength() {
6008     if (!nodes) return;
6009
6010     for (var i = 0, n = links.length; i < n; ++i) {
6011       strengths[i] = +strength(links[i], i, links);
6012     }
6013   }
6014
6015   function initializeDistance() {
6016     if (!nodes) return;
6017
6018     for (var i = 0, n = links.length; i < n; ++i) {
6019       distances[i] = +distance(links[i], i, links);
6020     }
6021   }
6022
6023   force.initialize = function(_) {
6024     nodes = _;
6025     initialize();
6026   };
6027
6028   force.links = function(_) {
6029     return arguments.length ? (links = _, initialize(), force) : links;
6030   };
6031
6032   force.id = function(_) {
6033     return arguments.length ? (id = _, force) : id;
6034   };
6035
6036   force.iterations = function(_) {
6037     return arguments.length ? (iterations = +_, force) : iterations;
6038   };
6039
6040   force.strength = function(_) {
6041     return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initializeStrength(), force) : strength;
6042   };
6043
6044   force.distance = function(_) {
6045     return arguments.length ? (distance = typeof _ === "function" ? _ : constant$6(+_), initializeDistance(), force) : distance;
6046   };
6047
6048   return force;
6049 }
6050
6051 function x$1(d) {
6052   return d.x;
6053 }
6054
6055 function y$1(d) {
6056   return d.y;
6057 }
6058
6059 var initialRadius = 10;
6060 var initialAngle = Math.PI * (3 - Math.sqrt(5));
6061
6062 function simulation(nodes) {
6063   var simulation,
6064       alpha = 1,
6065       alphaMin = 0.001,
6066       alphaDecay = 1 - Math.pow(alphaMin, 1 / 300),
6067       alphaTarget = 0,
6068       velocityDecay = 0.6,
6069       forces = map$1(),
6070       stepper = timer(step),
6071       event = dispatch("tick", "end");
6072
6073   if (nodes == null) nodes = [];
6074
6075   function step() {
6076     tick();
6077     event.call("tick", simulation);
6078     if (alpha < alphaMin) {
6079       stepper.stop();
6080       event.call("end", simulation);
6081     }
6082   }
6083
6084   function tick() {
6085     var i, n = nodes.length, node;
6086
6087     alpha += (alphaTarget - alpha) * alphaDecay;
6088
6089     forces.each(function(force) {
6090       force(alpha);
6091     });
6092
6093     for (i = 0; i < n; ++i) {
6094       node = nodes[i];
6095       if (node.fx == null) node.x += node.vx *= velocityDecay;
6096       else node.x = node.fx, node.vx = 0;
6097       if (node.fy == null) node.y += node.vy *= velocityDecay;
6098       else node.y = node.fy, node.vy = 0;
6099     }
6100   }
6101
6102   function initializeNodes() {
6103     for (var i = 0, n = nodes.length, node; i < n; ++i) {
6104       node = nodes[i], node.index = i;
6105       if (isNaN(node.x) || isNaN(node.y)) {
6106         var radius = initialRadius * Math.sqrt(i), angle = i * initialAngle;
6107         node.x = radius * Math.cos(angle);
6108         node.y = radius * Math.sin(angle);
6109       }
6110       if (isNaN(node.vx) || isNaN(node.vy)) {
6111         node.vx = node.vy = 0;
6112       }
6113     }
6114   }
6115
6116   function initializeForce(force) {
6117     if (force.initialize) force.initialize(nodes);
6118     return force;
6119   }
6120
6121   initializeNodes();
6122
6123   return simulation = {
6124     tick: tick,
6125
6126     restart: function() {
6127       return stepper.restart(step), simulation;
6128     },
6129
6130     stop: function() {
6131       return stepper.stop(), simulation;
6132     },
6133
6134     nodes: function(_) {
6135       return arguments.length ? (nodes = _, initializeNodes(), forces.each(initializeForce), simulation) : nodes;
6136     },
6137
6138     alpha: function(_) {
6139       return arguments.length ? (alpha = +_, simulation) : alpha;
6140     },
6141
6142     alphaMin: function(_) {
6143       return arguments.length ? (alphaMin = +_, simulation) : alphaMin;
6144     },
6145
6146     alphaDecay: function(_) {
6147       return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay;
6148     },
6149
6150     alphaTarget: function(_) {
6151       return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget;
6152     },
6153
6154     velocityDecay: function(_) {
6155       return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay;
6156     },
6157
6158     force: function(name, _) {
6159       return arguments.length > 1 ? (_ == null ? forces.remove(name) : forces.set(name, initializeForce(_)), simulation) : forces.get(name);
6160     },
6161
6162     find: function(x, y, radius) {
6163       var i = 0,
6164           n = nodes.length,
6165           dx,
6166           dy,
6167           d2,
6168           node,
6169           closest;
6170
6171       if (radius == null) radius = Infinity;
6172       else radius *= radius;
6173
6174       for (i = 0; i < n; ++i) {
6175         node = nodes[i];
6176         dx = x - node.x;
6177         dy = y - node.y;
6178         d2 = dx * dx + dy * dy;
6179         if (d2 < radius) closest = node, radius = d2;
6180       }
6181
6182       return closest;
6183     },
6184
6185     on: function(name, _) {
6186       return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name);
6187     }
6188   };
6189 }
6190
6191 function manyBody() {
6192   var nodes,
6193       node,
6194       alpha,
6195       strength = constant$6(-30),
6196       strengths,
6197       distanceMin2 = 1,
6198       distanceMax2 = Infinity,
6199       theta2 = 0.81;
6200
6201   function force(_) {
6202     var i, n = nodes.length, tree = quadtree(nodes, x$1, y$1).visitAfter(accumulate);
6203     for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply);
6204   }
6205
6206   function initialize() {
6207     if (!nodes) return;
6208     var i, n = nodes.length, node;
6209     strengths = new Array(n);
6210     for (i = 0; i < n; ++i) node = nodes[i], strengths[node.index] = +strength(node, i, nodes);
6211   }
6212
6213   function accumulate(quad) {
6214     var strength = 0, q, c, weight = 0, x, y, i;
6215
6216     // For internal nodes, accumulate forces from child quadrants.
6217     if (quad.length) {
6218       for (x = y = i = 0; i < 4; ++i) {
6219         if ((q = quad[i]) && (c = Math.abs(q.value))) {
6220           strength += q.value, weight += c, x += c * q.x, y += c * q.y;
6221         }
6222       }
6223       quad.x = x / weight;
6224       quad.y = y / weight;
6225     }
6226
6227     // For leaf nodes, accumulate forces from coincident quadrants.
6228     else {
6229       q = quad;
6230       q.x = q.data.x;
6231       q.y = q.data.y;
6232       do strength += strengths[q.data.index];
6233       while (q = q.next);
6234     }
6235
6236     quad.value = strength;
6237   }
6238
6239   function apply(quad, x1, _, x2) {
6240     if (!quad.value) return true;
6241
6242     var x = quad.x - node.x,
6243         y = quad.y - node.y,
6244         w = x2 - x1,
6245         l = x * x + y * y;
6246
6247     // Apply the Barnes-Hut approximation if possible.
6248     // Limit forces for very close nodes; randomize direction if coincident.
6249     if (w * w / theta2 < l) {
6250       if (l < distanceMax2) {
6251         if (x === 0) x = jiggle(), l += x * x;
6252         if (y === 0) y = jiggle(), l += y * y;
6253         if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
6254         node.vx += x * quad.value * alpha / l;
6255         node.vy += y * quad.value * alpha / l;
6256       }
6257       return true;
6258     }
6259
6260     // Otherwise, process points directly.
6261     else if (quad.length || l >= distanceMax2) return;
6262
6263     // Limit forces for very close nodes; randomize direction if coincident.
6264     if (quad.data !== node || quad.next) {
6265       if (x === 0) x = jiggle(), l += x * x;
6266       if (y === 0) y = jiggle(), l += y * y;
6267       if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
6268     }
6269
6270     do if (quad.data !== node) {
6271       w = strengths[quad.data.index] * alpha / l;
6272       node.vx += x * w;
6273       node.vy += y * w;
6274     } while (quad = quad.next);
6275   }
6276
6277   force.initialize = function(_) {
6278     nodes = _;
6279     initialize();
6280   };
6281
6282   force.strength = function(_) {
6283     return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength;
6284   };
6285
6286   force.distanceMin = function(_) {
6287     return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2);
6288   };
6289
6290   force.distanceMax = function(_) {
6291     return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2);
6292   };
6293
6294   force.theta = function(_) {
6295     return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2);
6296   };
6297
6298   return force;
6299 }
6300
6301 function radial(radius, x, y) {
6302   var nodes,
6303       strength = constant$6(0.1),
6304       strengths,
6305       radiuses;
6306
6307   if (typeof radius !== "function") radius = constant$6(+radius);
6308   if (x == null) x = 0;
6309   if (y == null) y = 0;
6310
6311   function force(alpha) {
6312     for (var i = 0, n = nodes.length; i < n; ++i) {
6313       var node = nodes[i],
6314           dx = node.x - x || 1e-6,
6315           dy = node.y - y || 1e-6,
6316           r = Math.sqrt(dx * dx + dy * dy),
6317           k = (radiuses[i] - r) * strengths[i] * alpha / r;
6318       node.vx += dx * k;
6319       node.vy += dy * k;
6320     }
6321   }
6322
6323   function initialize() {
6324     if (!nodes) return;
6325     var i, n = nodes.length;
6326     strengths = new Array(n);
6327     radiuses = new Array(n);
6328     for (i = 0; i < n; ++i) {
6329       radiuses[i] = +radius(nodes[i], i, nodes);
6330       strengths[i] = isNaN(radiuses[i]) ? 0 : +strength(nodes[i], i, nodes);
6331     }
6332   }
6333
6334   force.initialize = function(_) {
6335     nodes = _, initialize();
6336   };
6337
6338   force.strength = function(_) {
6339     return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength;
6340   };
6341
6342   force.radius = function(_) {
6343     return arguments.length ? (radius = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : radius;
6344   };
6345
6346   force.x = function(_) {
6347     return arguments.length ? (x = +_, force) : x;
6348   };
6349
6350   force.y = function(_) {
6351     return arguments.length ? (y = +_, force) : y;
6352   };
6353
6354   return force;
6355 }
6356
6357 function x$2(x) {
6358   var strength = constant$6(0.1),
6359       nodes,
6360       strengths,
6361       xz;
6362
6363   if (typeof x !== "function") x = constant$6(x == null ? 0 : +x);
6364
6365   function force(alpha) {
6366     for (var i = 0, n = nodes.length, node; i < n; ++i) {
6367       node = nodes[i], node.vx += (xz[i] - node.x) * strengths[i] * alpha;
6368     }
6369   }
6370
6371   function initialize() {
6372     if (!nodes) return;
6373     var i, n = nodes.length;
6374     strengths = new Array(n);
6375     xz = new Array(n);
6376     for (i = 0; i < n; ++i) {
6377       strengths[i] = isNaN(xz[i] = +x(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
6378     }
6379   }
6380
6381   force.initialize = function(_) {
6382     nodes = _;
6383     initialize();
6384   };
6385
6386   force.strength = function(_) {
6387     return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength;
6388   };
6389
6390   force.x = function(_) {
6391     return arguments.length ? (x = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : x;
6392   };
6393
6394   return force;
6395 }
6396
6397 function y$2(y) {
6398   var strength = constant$6(0.1),
6399       nodes,
6400       strengths,
6401       yz;
6402
6403   if (typeof y !== "function") y = constant$6(y == null ? 0 : +y);
6404
6405   function force(alpha) {
6406     for (var i = 0, n = nodes.length, node; i < n; ++i) {
6407       node = nodes[i], node.vy += (yz[i] - node.y) * strengths[i] * alpha;
6408     }
6409   }
6410
6411   function initialize() {
6412     if (!nodes) return;
6413     var i, n = nodes.length;
6414     strengths = new Array(n);
6415     yz = new Array(n);
6416     for (i = 0; i < n; ++i) {
6417       strengths[i] = isNaN(yz[i] = +y(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
6418     }
6419   }
6420
6421   force.initialize = function(_) {
6422     nodes = _;
6423     initialize();
6424   };
6425
6426   force.strength = function(_) {
6427     return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength;
6428   };
6429
6430   force.y = function(_) {
6431     return arguments.length ? (y = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : y;
6432   };
6433
6434   return force;
6435 }
6436
6437 // Computes the decimal coefficient and exponent of the specified number x with
6438 // significant digits p, where x is positive and p is in [1, 21] or undefined.
6439 // For example, formatDecimal(1.23) returns ["123", 0].
6440 function formatDecimal(x, p) {
6441   if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity
6442   var i, coefficient = x.slice(0, i);
6443
6444   // The string returned by toExponential either has the form \d\.\d+e[-+]\d+
6445   // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3).
6446   return [
6447     coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,
6448     +x.slice(i + 1)
6449   ];
6450 }
6451
6452 function exponent$1(x) {
6453   return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN;
6454 }
6455
6456 function formatGroup(grouping, thousands) {
6457   return function(value, width) {
6458     var i = value.length,
6459         t = [],
6460         j = 0,
6461         g = grouping[0],
6462         length = 0;
6463
6464     while (i > 0 && g > 0) {
6465       if (length + g + 1 > width) g = Math.max(1, width - length);
6466       t.push(value.substring(i -= g, i + g));
6467       if ((length += g + 1) > width) break;
6468       g = grouping[j = (j + 1) % grouping.length];
6469     }
6470
6471     return t.reverse().join(thousands);
6472   };
6473 }
6474
6475 function formatNumerals(numerals) {
6476   return function(value) {
6477     return value.replace(/[0-9]/g, function(i) {
6478       return numerals[+i];
6479     });
6480   };
6481 }
6482
6483 function formatDefault(x, p) {
6484   x = x.toPrecision(p);
6485
6486   out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) {
6487     switch (x[i]) {
6488       case ".": i0 = i1 = i; break;
6489       case "0": if (i0 === 0) i0 = i; i1 = i; break;
6490       case "e": break out;
6491       default: if (i0 > 0) i0 = 0; break;
6492     }
6493   }
6494
6495   return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x;
6496 }
6497
6498 var prefixExponent;
6499
6500 function formatPrefixAuto(x, p) {
6501   var d = formatDecimal(x, p);
6502   if (!d) return x + "";
6503   var coefficient = d[0],
6504       exponent = d[1],
6505       i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,
6506       n = coefficient.length;
6507   return i === n ? coefficient
6508       : i > n ? coefficient + new Array(i - n + 1).join("0")
6509       : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i)
6510       : "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y!
6511 }
6512
6513 function formatRounded(x, p) {
6514   var d = formatDecimal(x, p);
6515   if (!d) return x + "";
6516   var coefficient = d[0],
6517       exponent = d[1];
6518   return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient
6519       : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1)
6520       : coefficient + new Array(exponent - coefficient.length + 2).join("0");
6521 }
6522
6523 var formatTypes = {
6524   "": formatDefault,
6525   "%": function(x, p) { return (x * 100).toFixed(p); },
6526   "b": function(x) { return Math.round(x).toString(2); },
6527   "c": function(x) { return x + ""; },
6528   "d": function(x) { return Math.round(x).toString(10); },
6529   "e": function(x, p) { return x.toExponential(p); },
6530   "f": function(x, p) { return x.toFixed(p); },
6531   "g": function(x, p) { return x.toPrecision(p); },
6532   "o": function(x) { return Math.round(x).toString(8); },
6533   "p": function(x, p) { return formatRounded(x * 100, p); },
6534   "r": formatRounded,
6535   "s": formatPrefixAuto,
6536   "X": function(x) { return Math.round(x).toString(16).toUpperCase(); },
6537   "x": function(x) { return Math.round(x).toString(16); }
6538 };
6539
6540 // [[fill]align][sign][symbol][0][width][,][.precision][type]
6541 var re = /^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i;
6542
6543 function formatSpecifier(specifier) {
6544   return new FormatSpecifier(specifier);
6545 }
6546
6547 formatSpecifier.prototype = FormatSpecifier.prototype; // instanceof
6548
6549 function FormatSpecifier(specifier) {
6550   if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier);
6551
6552   var match,
6553       fill = match[1] || " ",
6554       align = match[2] || ">",
6555       sign = match[3] || "-",
6556       symbol = match[4] || "",
6557       zero = !!match[5],
6558       width = match[6] && +match[6],
6559       comma = !!match[7],
6560       precision = match[8] && +match[8].slice(1),
6561       type = match[9] || "";
6562
6563   // The "n" type is an alias for ",g".
6564   if (type === "n") comma = true, type = "g";
6565
6566   // Map invalid types to the default format.
6567   else if (!formatTypes[type]) type = "";
6568
6569   // If zero fill is specified, padding goes after sign and before digits.
6570   if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "=";
6571
6572   this.fill = fill;
6573   this.align = align;
6574   this.sign = sign;
6575   this.symbol = symbol;
6576   this.zero = zero;
6577   this.width = width;
6578   this.comma = comma;
6579   this.precision = precision;
6580   this.type = type;
6581 }
6582
6583 FormatSpecifier.prototype.toString = function() {
6584   return this.fill
6585       + this.align
6586       + this.sign
6587       + this.symbol
6588       + (this.zero ? "0" : "")
6589       + (this.width == null ? "" : Math.max(1, this.width | 0))
6590       + (this.comma ? "," : "")
6591       + (this.precision == null ? "" : "." + Math.max(0, this.precision | 0))
6592       + this.type;
6593 };
6594
6595 function identity$3(x) {
6596   return x;
6597 }
6598
6599 var prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];
6600
6601 function formatLocale(locale) {
6602   var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity$3,
6603       currency = locale.currency,
6604       decimal = locale.decimal,
6605       numerals = locale.numerals ? formatNumerals(locale.numerals) : identity$3,
6606       percent = locale.percent || "%";
6607
6608   function newFormat(specifier) {
6609     specifier = formatSpecifier(specifier);
6610
6611     var fill = specifier.fill,
6612         align = specifier.align,
6613         sign = specifier.sign,
6614         symbol = specifier.symbol,
6615         zero = specifier.zero,
6616         width = specifier.width,
6617         comma = specifier.comma,
6618         precision = specifier.precision,
6619         type = specifier.type;
6620
6621     // Compute the prefix and suffix.
6622     // For SI-prefix, the suffix is lazily computed.
6623     var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "",
6624         suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? percent : "";
6625
6626     // What format function should we use?
6627     // Is this an integer type?
6628     // Can this type generate exponential notation?
6629     var formatType = formatTypes[type],
6630         maybeSuffix = !type || /[defgprs%]/.test(type);
6631
6632     // Set the default precision if not specified,
6633     // or clamp the specified precision to the supported range.
6634     // For significant precision, it must be in [1, 21].
6635     // For fixed precision, it must be in [0, 20].
6636     precision = precision == null ? (type ? 6 : 12)
6637         : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))
6638         : Math.max(0, Math.min(20, precision));
6639
6640     function format(value) {
6641       var valuePrefix = prefix,
6642           valueSuffix = suffix,
6643           i, n, c;
6644
6645       if (type === "c") {
6646         valueSuffix = formatType(value) + valueSuffix;
6647         value = "";
6648       } else {
6649         value = +value;
6650
6651         // Perform the initial formatting.
6652         var valueNegative = value < 0;
6653         value = formatType(Math.abs(value), precision);
6654
6655         // If a negative value rounds to zero during formatting, treat as positive.
6656         if (valueNegative && +value === 0) valueNegative = false;
6657
6658         // Compute the prefix and suffix.
6659         valuePrefix = (valueNegative ? (sign === "(" ? sign : "-") : sign === "-" || sign === "(" ? "" : sign) + valuePrefix;
6660         valueSuffix = (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + valueSuffix + (valueNegative && sign === "(" ? ")" : "");
6661
6662         // Break the formatted value into the integer “value” part that can be
6663         // grouped, and fractional or exponential “suffix” part that is not.
6664         if (maybeSuffix) {
6665           i = -1, n = value.length;
6666           while (++i < n) {
6667             if (c = value.charCodeAt(i), 48 > c || c > 57) {
6668               valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;
6669               value = value.slice(0, i);
6670               break;
6671             }
6672           }
6673         }
6674       }
6675
6676       // If the fill character is not "0", grouping is applied before padding.
6677       if (comma && !zero) value = group(value, Infinity);
6678
6679       // Compute the padding.
6680       var length = valuePrefix.length + value.length + valueSuffix.length,
6681           padding = length < width ? new Array(width - length + 1).join(fill) : "";
6682
6683       // If the fill character is "0", grouping is applied after padding.
6684       if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = "";
6685
6686       // Reconstruct the final output based on the desired alignment.
6687       switch (align) {
6688         case "<": value = valuePrefix + value + valueSuffix + padding; break;
6689         case "=": value = valuePrefix + padding + value + valueSuffix; break;
6690         case "^": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break;
6691         default: value = padding + valuePrefix + value + valueSuffix; break;
6692       }
6693
6694       return numerals(value);
6695     }
6696
6697     format.toString = function() {
6698       return specifier + "";
6699     };
6700
6701     return format;
6702   }
6703
6704   function formatPrefix(specifier, value) {
6705     var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)),
6706         e = Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3,
6707         k = Math.pow(10, -e),
6708         prefix = prefixes[8 + e / 3];
6709     return function(value) {
6710       return f(k * value) + prefix;
6711     };
6712   }
6713
6714   return {
6715     format: newFormat,
6716     formatPrefix: formatPrefix
6717   };
6718 }
6719
6720 var locale;
6721 var format;
6722 var formatPrefix;
6723
6724 defaultLocale({
6725   decimal: ".",
6726   thousands: ",",
6727   grouping: [3],
6728   currency: ["$", ""]
6729 });
6730
6731 function defaultLocale(definition) {
6732   locale = formatLocale(definition);
6733   format = locale.format;
6734   formatPrefix = locale.formatPrefix;
6735   return locale;
6736 }
6737
6738 function precisionFixed(step) {
6739   return Math.max(0, -exponent$1(Math.abs(step)));
6740 }
6741
6742 function precisionPrefix(step, value) {
6743   return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3 - exponent$1(Math.abs(step)));
6744 }
6745
6746 function precisionRound(step, max) {
6747   step = Math.abs(step), max = Math.abs(max) - step;
6748   return Math.max(0, exponent$1(max) - exponent$1(step)) + 1;
6749 }
6750
6751 // Adds floating point numbers with twice the normal precision.
6752 // Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic and
6753 // Fast Robust Geometric Predicates, Discrete & Computational Geometry 18(3)
6754 // 305–363 (1997).
6755 // Code adapted from GeographicLib by Charles F. F. Karney,
6756 // http://geographiclib.sourceforge.net/
6757
6758 function adder() {
6759   return new Adder;
6760 }
6761
6762 function Adder() {
6763   this.reset();
6764 }
6765
6766 Adder.prototype = {
6767   constructor: Adder,
6768   reset: function() {
6769     this.s = // rounded value
6770     this.t = 0; // exact error
6771   },
6772   add: function(y) {
6773     add$1(temp, y, this.t);
6774     add$1(this, temp.s, this.s);
6775     if (this.s) this.t += temp.t;
6776     else this.s = temp.t;
6777   },
6778   valueOf: function() {
6779     return this.s;
6780   }
6781 };
6782
6783 var temp = new Adder;
6784
6785 function add$1(adder, a, b) {
6786   var x = adder.s = a + b,
6787       bv = x - a,
6788       av = x - bv;
6789   adder.t = (a - av) + (b - bv);
6790 }
6791
6792 var epsilon$2 = 1e-6;
6793 var epsilon2$1 = 1e-12;
6794 var pi$3 = Math.PI;
6795 var halfPi$2 = pi$3 / 2;
6796 var quarterPi = pi$3 / 4;
6797 var tau$3 = pi$3 * 2;
6798
6799 var degrees$1 = 180 / pi$3;
6800 var radians = pi$3 / 180;
6801
6802 var abs = Math.abs;
6803 var atan = Math.atan;
6804 var atan2 = Math.atan2;
6805 var cos$1 = Math.cos;
6806 var ceil = Math.ceil;
6807 var exp = Math.exp;
6808
6809 var log = Math.log;
6810 var pow = Math.pow;
6811 var sin$1 = Math.sin;
6812 var sign = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; };
6813 var sqrt = Math.sqrt;
6814 var tan = Math.tan;
6815
6816 function acos(x) {
6817   return x > 1 ? 0 : x < -1 ? pi$3 : Math.acos(x);
6818 }
6819
6820 function asin(x) {
6821   return x > 1 ? halfPi$2 : x < -1 ? -halfPi$2 : Math.asin(x);
6822 }
6823
6824 function haversin(x) {
6825   return (x = sin$1(x / 2)) * x;
6826 }
6827
6828 function noop$1() {}
6829
6830 function streamGeometry(geometry, stream) {
6831   if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) {
6832     streamGeometryType[geometry.type](geometry, stream);
6833   }
6834 }
6835
6836 var streamObjectType = {
6837   Feature: function(object, stream) {
6838     streamGeometry(object.geometry, stream);
6839   },
6840   FeatureCollection: function(object, stream) {
6841     var features = object.features, i = -1, n = features.length;
6842     while (++i < n) streamGeometry(features[i].geometry, stream);
6843   }
6844 };
6845
6846 var streamGeometryType = {
6847   Sphere: function(object, stream) {
6848     stream.sphere();
6849   },
6850   Point: function(object, stream) {
6851     object = object.coordinates;
6852     stream.point(object[0], object[1], object[2]);
6853   },
6854   MultiPoint: function(object, stream) {
6855     var coordinates = object.coordinates, i = -1, n = coordinates.length;
6856     while (++i < n) object = coordinates[i], stream.point(object[0], object[1], object[2]);
6857   },
6858   LineString: function(object, stream) {
6859     streamLine(object.coordinates, stream, 0);
6860   },
6861   MultiLineString: function(object, stream) {
6862     var coordinates = object.coordinates, i = -1, n = coordinates.length;
6863     while (++i < n) streamLine(coordinates[i], stream, 0);
6864   },
6865   Polygon: function(object, stream) {
6866     streamPolygon(object.coordinates, stream);
6867   },
6868   MultiPolygon: function(object, stream) {
6869     var coordinates = object.coordinates, i = -1, n = coordinates.length;
6870     while (++i < n) streamPolygon(coordinates[i], stream);
6871   },
6872   GeometryCollection: function(object, stream) {
6873     var geometries = object.geometries, i = -1, n = geometries.length;
6874     while (++i < n) streamGeometry(geometries[i], stream);
6875   }
6876 };
6877
6878 function streamLine(coordinates, stream, closed) {
6879   var i = -1, n = coordinates.length - closed, coordinate;
6880   stream.lineStart();
6881   while (++i < n) coordinate = coordinates[i], stream.point(coordinate[0], coordinate[1], coordinate[2]);
6882   stream.lineEnd();
6883 }
6884
6885 function streamPolygon(coordinates, stream) {
6886   var i = -1, n = coordinates.length;
6887   stream.polygonStart();
6888   while (++i < n) streamLine(coordinates[i], stream, 1);
6889   stream.polygonEnd();
6890 }
6891
6892 function d3_geoStream(object, stream) {
6893   if (object && streamObjectType.hasOwnProperty(object.type)) {
6894     streamObjectType[object.type](object, stream);
6895   } else {
6896     streamGeometry(object, stream);
6897   }
6898 }
6899
6900 var areaRingSum = adder();
6901
6902 var areaSum = adder();
6903 var lambda00;
6904 var phi00;
6905 var lambda0;
6906 var cosPhi0;
6907 var sinPhi0;
6908
6909 var areaStream = {
6910   point: noop$1,
6911   lineStart: noop$1,
6912   lineEnd: noop$1,
6913   polygonStart: function() {
6914     areaRingSum.reset();
6915     areaStream.lineStart = areaRingStart;
6916     areaStream.lineEnd = areaRingEnd;
6917   },
6918   polygonEnd: function() {
6919     var areaRing = +areaRingSum;
6920     areaSum.add(areaRing < 0 ? tau$3 + areaRing : areaRing);
6921     this.lineStart = this.lineEnd = this.point = noop$1;
6922   },
6923   sphere: function() {
6924     areaSum.add(tau$3);
6925   }
6926 };
6927
6928 function areaRingStart() {
6929   areaStream.point = areaPointFirst;
6930 }
6931
6932 function areaRingEnd() {
6933   areaPoint(lambda00, phi00);
6934 }
6935
6936 function areaPointFirst(lambda, phi) {
6937   areaStream.point = areaPoint;
6938   lambda00 = lambda, phi00 = phi;
6939   lambda *= radians, phi *= radians;
6940   lambda0 = lambda, cosPhi0 = cos$1(phi = phi / 2 + quarterPi), sinPhi0 = sin$1(phi);
6941 }
6942
6943 function areaPoint(lambda, phi) {
6944   lambda *= radians, phi *= radians;
6945   phi = phi / 2 + quarterPi; // half the angular distance from south pole
6946
6947   // Spherical excess E for a spherical triangle with vertices: south pole,
6948   // previous point, current point.  Uses a formula derived from Cagnoli’s
6949   // theorem.  See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2).
6950   var dLambda = lambda - lambda0,
6951       sdLambda = dLambda >= 0 ? 1 : -1,
6952       adLambda = sdLambda * dLambda,
6953       cosPhi = cos$1(phi),
6954       sinPhi = sin$1(phi),
6955       k = sinPhi0 * sinPhi,
6956       u = cosPhi0 * cosPhi + k * cos$1(adLambda),
6957       v = k * sdLambda * sin$1(adLambda);
6958   areaRingSum.add(atan2(v, u));
6959
6960   // Advance the previous points.
6961   lambda0 = lambda, cosPhi0 = cosPhi, sinPhi0 = sinPhi;
6962 }
6963
6964 function d3_geoArea(object) {
6965   areaSum.reset();
6966   d3_geoStream(object, areaStream);
6967   return areaSum * 2;
6968 }
6969
6970 function spherical(cartesian) {
6971   return [atan2(cartesian[1], cartesian[0]), asin(cartesian[2])];
6972 }
6973
6974 function cartesian(spherical) {
6975   var lambda = spherical[0], phi = spherical[1], cosPhi = cos$1(phi);
6976   return [cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi)];
6977 }
6978
6979 function cartesianDot(a, b) {
6980   return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
6981 }
6982
6983 function cartesianCross(a, b) {
6984   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]];
6985 }
6986
6987 // TODO return a
6988 function cartesianAddInPlace(a, b) {
6989   a[0] += b[0], a[1] += b[1], a[2] += b[2];
6990 }
6991
6992 function cartesianScale(vector, k) {
6993   return [vector[0] * k, vector[1] * k, vector[2] * k];
6994 }
6995
6996 // TODO return d
6997 function cartesianNormalizeInPlace(d) {
6998   var l = sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
6999   d[0] /= l, d[1] /= l, d[2] /= l;
7000 }
7001
7002 var lambda0$1;
7003 var phi0;
7004 var lambda1;
7005 var phi1;
7006 var lambda2;
7007 var lambda00$1;
7008 var phi00$1;
7009 var p0;
7010 var deltaSum = adder();
7011 var ranges;
7012 var range;
7013
7014 var boundsStream = {
7015   point: boundsPoint,
7016   lineStart: boundsLineStart,
7017   lineEnd: boundsLineEnd,
7018   polygonStart: function() {
7019     boundsStream.point = boundsRingPoint;
7020     boundsStream.lineStart = boundsRingStart;
7021     boundsStream.lineEnd = boundsRingEnd;
7022     deltaSum.reset();
7023     areaStream.polygonStart();
7024   },
7025   polygonEnd: function() {
7026     areaStream.polygonEnd();
7027     boundsStream.point = boundsPoint;
7028     boundsStream.lineStart = boundsLineStart;
7029     boundsStream.lineEnd = boundsLineEnd;
7030     if (areaRingSum < 0) lambda0$1 = -(lambda1 = 180), phi0 = -(phi1 = 90);
7031     else if (deltaSum > epsilon$2) phi1 = 90;
7032     else if (deltaSum < -epsilon$2) phi0 = -90;
7033     range[0] = lambda0$1, range[1] = lambda1;
7034   }
7035 };
7036
7037 function boundsPoint(lambda, phi) {
7038   ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]);
7039   if (phi < phi0) phi0 = phi;
7040   if (phi > phi1) phi1 = phi;
7041 }
7042
7043 function linePoint(lambda, phi) {
7044   var p = cartesian([lambda * radians, phi * radians]);
7045   if (p0) {
7046     var normal = cartesianCross(p0, p),
7047         equatorial = [normal[1], -normal[0], 0],
7048         inflection = cartesianCross(equatorial, normal);
7049     cartesianNormalizeInPlace(inflection);
7050     inflection = spherical(inflection);
7051     var delta = lambda - lambda2,
7052         sign$$1 = delta > 0 ? 1 : -1,
7053         lambdai = inflection[0] * degrees$1 * sign$$1,
7054         phii,
7055         antimeridian = abs(delta) > 180;
7056     if (antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {
7057       phii = inflection[1] * degrees$1;
7058       if (phii > phi1) phi1 = phii;
7059     } else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {
7060       phii = -inflection[1] * degrees$1;
7061       if (phii < phi0) phi0 = phii;
7062     } else {
7063       if (phi < phi0) phi0 = phi;
7064       if (phi > phi1) phi1 = phi;
7065     }
7066     if (antimeridian) {
7067       if (lambda < lambda2) {
7068         if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;
7069       } else {
7070         if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;
7071       }
7072     } else {
7073       if (lambda1 >= lambda0$1) {
7074         if (lambda < lambda0$1) lambda0$1 = lambda;
7075         if (lambda > lambda1) lambda1 = lambda;
7076       } else {
7077         if (lambda > lambda2) {
7078           if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;
7079         } else {
7080           if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;
7081         }
7082       }
7083     }
7084   } else {
7085     ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]);
7086   }
7087   if (phi < phi0) phi0 = phi;
7088   if (phi > phi1) phi1 = phi;
7089   p0 = p, lambda2 = lambda;
7090 }
7091
7092 function boundsLineStart() {
7093   boundsStream.point = linePoint;
7094 }
7095
7096 function boundsLineEnd() {
7097   range[0] = lambda0$1, range[1] = lambda1;
7098   boundsStream.point = boundsPoint;
7099   p0 = null;
7100 }
7101
7102 function boundsRingPoint(lambda, phi) {
7103   if (p0) {
7104     var delta = lambda - lambda2;
7105     deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta);
7106   } else {
7107     lambda00$1 = lambda, phi00$1 = phi;
7108   }
7109   areaStream.point(lambda, phi);
7110   linePoint(lambda, phi);
7111 }
7112
7113 function boundsRingStart() {
7114   areaStream.lineStart();
7115 }
7116
7117 function boundsRingEnd() {
7118   boundsRingPoint(lambda00$1, phi00$1);
7119   areaStream.lineEnd();
7120   if (abs(deltaSum) > epsilon$2) lambda0$1 = -(lambda1 = 180);
7121   range[0] = lambda0$1, range[1] = lambda1;
7122   p0 = null;
7123 }
7124
7125 // Finds the left-right distance between two longitudes.
7126 // This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want
7127 // the distance between ±180° to be 360°.
7128 function angle(lambda0, lambda1) {
7129   return (lambda1 -= lambda0) < 0 ? lambda1 + 360 : lambda1;
7130 }
7131
7132 function rangeCompare(a, b) {
7133   return a[0] - b[0];
7134 }
7135
7136 function rangeContains(range, x) {
7137   return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x;
7138 }
7139
7140 function d3_geoBounds(feature) {
7141   var i, n, a, b, merged, deltaMax, delta;
7142
7143   phi1 = lambda1 = -(lambda0$1 = phi0 = Infinity);
7144   ranges = [];
7145   d3_geoStream(feature, boundsStream);
7146
7147   // First, sort ranges by their minimum longitudes.
7148   if (n = ranges.length) {
7149     ranges.sort(rangeCompare);
7150
7151     // Then, merge any ranges that overlap.
7152     for (i = 1, a = ranges[0], merged = [a]; i < n; ++i) {
7153       b = ranges[i];
7154       if (rangeContains(a, b[0]) || rangeContains(a, b[1])) {
7155         if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1];
7156         if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0];
7157       } else {
7158         merged.push(a = b);
7159       }
7160     }
7161
7162     // Finally, find the largest gap between the merged ranges.
7163     // The final bounding box will be the inverse of this gap.
7164     for (deltaMax = -Infinity, n = merged.length - 1, i = 0, a = merged[n]; i <= n; a = b, ++i) {
7165       b = merged[i];
7166       if ((delta = angle(a[1], b[0])) > deltaMax) deltaMax = delta, lambda0$1 = b[0], lambda1 = a[1];
7167     }
7168   }
7169
7170   ranges = range = null;
7171
7172   return lambda0$1 === Infinity || phi0 === Infinity
7173       ? [[NaN, NaN], [NaN, NaN]]
7174       : [[lambda0$1, phi0], [lambda1, phi1]];
7175 }
7176
7177 var W0;
7178 var W1;
7179 var X0;
7180 var Y0;
7181 var Z0;
7182 var X1;
7183 var Y1;
7184 var Z1;
7185 var X2;
7186 var Y2;
7187 var Z2;
7188 var lambda00$2;
7189 var phi00$2;
7190 var x0;
7191 var y0;
7192 var z0; // previous point
7193
7194 var centroidStream = {
7195   sphere: noop$1,
7196   point: centroidPoint,
7197   lineStart: centroidLineStart,
7198   lineEnd: centroidLineEnd,
7199   polygonStart: function() {
7200     centroidStream.lineStart = centroidRingStart;
7201     centroidStream.lineEnd = centroidRingEnd;
7202   },
7203   polygonEnd: function() {
7204     centroidStream.lineStart = centroidLineStart;
7205     centroidStream.lineEnd = centroidLineEnd;
7206   }
7207 };
7208
7209 // Arithmetic mean of Cartesian vectors.
7210 function centroidPoint(lambda, phi) {
7211   lambda *= radians, phi *= radians;
7212   var cosPhi = cos$1(phi);
7213   centroidPointCartesian(cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi));
7214 }
7215
7216 function centroidPointCartesian(x, y, z) {
7217   ++W0;
7218   X0 += (x - X0) / W0;
7219   Y0 += (y - Y0) / W0;
7220   Z0 += (z - Z0) / W0;
7221 }
7222
7223 function centroidLineStart() {
7224   centroidStream.point = centroidLinePointFirst;
7225 }
7226
7227 function centroidLinePointFirst(lambda, phi) {
7228   lambda *= radians, phi *= radians;
7229   var cosPhi = cos$1(phi);
7230   x0 = cosPhi * cos$1(lambda);
7231   y0 = cosPhi * sin$1(lambda);
7232   z0 = sin$1(phi);
7233   centroidStream.point = centroidLinePoint;
7234   centroidPointCartesian(x0, y0, z0);
7235 }
7236
7237 function centroidLinePoint(lambda, phi) {
7238   lambda *= radians, phi *= radians;
7239   var cosPhi = cos$1(phi),
7240       x = cosPhi * cos$1(lambda),
7241       y = cosPhi * sin$1(lambda),
7242       z = sin$1(phi),
7243       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);
7244   W1 += w;
7245   X1 += w * (x0 + (x0 = x));
7246   Y1 += w * (y0 + (y0 = y));
7247   Z1 += w * (z0 + (z0 = z));
7248   centroidPointCartesian(x0, y0, z0);
7249 }
7250
7251 function centroidLineEnd() {
7252   centroidStream.point = centroidPoint;
7253 }
7254
7255 // See J. E. Brock, The Inertia Tensor for a Spherical Triangle,
7256 // J. Applied Mechanics 42, 239 (1975).
7257 function centroidRingStart() {
7258   centroidStream.point = centroidRingPointFirst;
7259 }
7260
7261 function centroidRingEnd() {
7262   centroidRingPoint(lambda00$2, phi00$2);
7263   centroidStream.point = centroidPoint;
7264 }
7265
7266 function centroidRingPointFirst(lambda, phi) {
7267   lambda00$2 = lambda, phi00$2 = phi;
7268   lambda *= radians, phi *= radians;
7269   centroidStream.point = centroidRingPoint;
7270   var cosPhi = cos$1(phi);
7271   x0 = cosPhi * cos$1(lambda);
7272   y0 = cosPhi * sin$1(lambda);
7273   z0 = sin$1(phi);
7274   centroidPointCartesian(x0, y0, z0);
7275 }
7276
7277 function centroidRingPoint(lambda, phi) {
7278   lambda *= radians, phi *= radians;
7279   var cosPhi = cos$1(phi),
7280       x = cosPhi * cos$1(lambda),
7281       y = cosPhi * sin$1(lambda),
7282       z = sin$1(phi),
7283       cx = y0 * z - z0 * y,
7284       cy = z0 * x - x0 * z,
7285       cz = x0 * y - y0 * x,
7286       m = sqrt(cx * cx + cy * cy + cz * cz),
7287       w = asin(m), // line weight = angle
7288       v = m && -w / m; // area weight multiplier
7289   X2 += v * cx;
7290   Y2 += v * cy;
7291   Z2 += v * cz;
7292   W1 += w;
7293   X1 += w * (x0 + (x0 = x));
7294   Y1 += w * (y0 + (y0 = y));
7295   Z1 += w * (z0 + (z0 = z));
7296   centroidPointCartesian(x0, y0, z0);
7297 }
7298
7299 function d3_geoCentroid(object) {
7300   W0 = W1 =
7301   X0 = Y0 = Z0 =
7302   X1 = Y1 = Z1 =
7303   X2 = Y2 = Z2 = 0;
7304   d3_geoStream(object, centroidStream);
7305
7306   var x = X2,
7307       y = Y2,
7308       z = Z2,
7309       m = x * x + y * y + z * z;
7310
7311   // If the area-weighted ccentroid is undefined, fall back to length-weighted ccentroid.
7312   if (m < epsilon2$1) {
7313     x = X1, y = Y1, z = Z1;
7314     // If the feature has zero length, fall back to arithmetic mean of point vectors.
7315     if (W1 < epsilon$2) x = X0, y = Y0, z = Z0;
7316     m = x * x + y * y + z * z;
7317     // If the feature still has an undefined ccentroid, then return.
7318     if (m < epsilon2$1) return [NaN, NaN];
7319   }
7320
7321   return [atan2(y, x) * degrees$1, asin(z / sqrt(m)) * degrees$1];
7322 }
7323
7324 function constant$7(x) {
7325   return function() {
7326     return x;
7327   };
7328 }
7329
7330 function compose(a, b) {
7331
7332   function compose(x, y) {
7333     return x = a(x, y), b(x[0], x[1]);
7334   }
7335
7336   if (a.invert && b.invert) compose.invert = function(x, y) {
7337     return x = b.invert(x, y), x && a.invert(x[0], x[1]);
7338   };
7339
7340   return compose;
7341 }
7342
7343 function rotationIdentity(lambda, phi) {
7344   return [lambda > pi$3 ? lambda - tau$3 : lambda < -pi$3 ? lambda + tau$3 : lambda, phi];
7345 }
7346
7347 rotationIdentity.invert = rotationIdentity;
7348
7349 function rotateRadians(deltaLambda, deltaPhi, deltaGamma) {
7350   return (deltaLambda %= tau$3) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma))
7351     : rotationLambda(deltaLambda))
7352     : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma)
7353     : rotationIdentity);
7354 }
7355
7356 function forwardRotationLambda(deltaLambda) {
7357   return function(lambda, phi) {
7358     return lambda += deltaLambda, [lambda > pi$3 ? lambda - tau$3 : lambda < -pi$3 ? lambda + tau$3 : lambda, phi];
7359   };
7360 }
7361
7362 function rotationLambda(deltaLambda) {
7363   var rotation = forwardRotationLambda(deltaLambda);
7364   rotation.invert = forwardRotationLambda(-deltaLambda);
7365   return rotation;
7366 }
7367
7368 function rotationPhiGamma(deltaPhi, deltaGamma) {
7369   var cosDeltaPhi = cos$1(deltaPhi),
7370       sinDeltaPhi = sin$1(deltaPhi),
7371       cosDeltaGamma = cos$1(deltaGamma),
7372       sinDeltaGamma = sin$1(deltaGamma);
7373
7374   function rotation(lambda, phi) {
7375     var cosPhi = cos$1(phi),
7376         x = cos$1(lambda) * cosPhi,
7377         y = sin$1(lambda) * cosPhi,
7378         z = sin$1(phi),
7379         k = z * cosDeltaPhi + x * sinDeltaPhi;
7380     return [
7381       atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi),
7382       asin(k * cosDeltaGamma + y * sinDeltaGamma)
7383     ];
7384   }
7385
7386   rotation.invert = function(lambda, phi) {
7387     var cosPhi = cos$1(phi),
7388         x = cos$1(lambda) * cosPhi,
7389         y = sin$1(lambda) * cosPhi,
7390         z = sin$1(phi),
7391         k = z * cosDeltaGamma - y * sinDeltaGamma;
7392     return [
7393       atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi),
7394       asin(k * cosDeltaPhi - x * sinDeltaPhi)
7395     ];
7396   };
7397
7398   return rotation;
7399 }
7400
7401 function rotation(rotate) {
7402   rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0);
7403
7404   function forward(coordinates) {
7405     coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians);
7406     return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates;
7407   }
7408
7409   forward.invert = function(coordinates) {
7410     coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians);
7411     return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates;
7412   };
7413
7414   return forward;
7415 }
7416
7417 // Generates a circle centered at [0°, 0°], with a given radius and precision.
7418 function circleStream(stream, radius, delta, direction, t0, t1) {
7419   if (!delta) return;
7420   var cosRadius = cos$1(radius),
7421       sinRadius = sin$1(radius),
7422       step = direction * delta;
7423   if (t0 == null) {
7424     t0 = radius + direction * tau$3;
7425     t1 = radius - step / 2;
7426   } else {
7427     t0 = circleRadius(cosRadius, t0);
7428     t1 = circleRadius(cosRadius, t1);
7429     if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau$3;
7430   }
7431   for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) {
7432     point = spherical([cosRadius, -sinRadius * cos$1(t), -sinRadius * sin$1(t)]);
7433     stream.point(point[0], point[1]);
7434   }
7435 }
7436
7437 // Returns the signed angle of a cartesian point relative to [cosRadius, 0, 0].
7438 function circleRadius(cosRadius, point) {
7439   point = cartesian(point), point[0] -= cosRadius;
7440   cartesianNormalizeInPlace(point);
7441   var radius = acos(-point[1]);
7442   return ((-point[2] < 0 ? -radius : radius) + tau$3 - epsilon$2) % tau$3;
7443 }
7444
7445 function circle() {
7446   var center = constant$7([0, 0]),
7447       radius = constant$7(90),
7448       precision = constant$7(6),
7449       ring,
7450       rotate,
7451       stream = {point: point};
7452
7453   function point(x, y) {
7454     ring.push(x = rotate(x, y));
7455     x[0] *= degrees$1, x[1] *= degrees$1;
7456   }
7457
7458   function circle() {
7459     var c = center.apply(this, arguments),
7460         r = radius.apply(this, arguments) * radians,
7461         p = precision.apply(this, arguments) * radians;
7462     ring = [];
7463     rotate = rotateRadians(-c[0] * radians, -c[1] * radians, 0).invert;
7464     circleStream(stream, r, p, 1);
7465     c = {type: "Polygon", coordinates: [ring]};
7466     ring = rotate = null;
7467     return c;
7468   }
7469
7470   circle.center = function(_) {
7471     return arguments.length ? (center = typeof _ === "function" ? _ : constant$7([+_[0], +_[1]]), circle) : center;
7472   };
7473
7474   circle.radius = function(_) {
7475     return arguments.length ? (radius = typeof _ === "function" ? _ : constant$7(+_), circle) : radius;
7476   };
7477
7478   circle.precision = function(_) {
7479     return arguments.length ? (precision = typeof _ === "function" ? _ : constant$7(+_), circle) : precision;
7480   };
7481
7482   return circle;
7483 }
7484
7485 function clipBuffer() {
7486   var lines = [],
7487       line;
7488   return {
7489     point: function(x, y) {
7490       line.push([x, y]);
7491     },
7492     lineStart: function() {
7493       lines.push(line = []);
7494     },
7495     lineEnd: noop$1,
7496     rejoin: function() {
7497       if (lines.length > 1) lines.push(lines.pop().concat(lines.shift()));
7498     },
7499     result: function() {
7500       var result = lines;
7501       lines = [];
7502       line = null;
7503       return result;
7504     }
7505   };
7506 }
7507
7508 function pointEqual(a, b) {
7509   return abs(a[0] - b[0]) < epsilon$2 && abs(a[1] - b[1]) < epsilon$2;
7510 }
7511
7512 function Intersection(point, points, other, entry) {
7513   this.x = point;
7514   this.z = points;
7515   this.o = other; // another intersection
7516   this.e = entry; // is an entry?
7517   this.v = false; // visited
7518   this.n = this.p = null; // next & previous
7519 }
7520
7521 // A generalized polygon clipping algorithm: given a polygon that has been cut
7522 // into its visible line segments, and rejoins the segments by interpolating
7523 // along the clip edge.
7524 function clipRejoin(segments, compareIntersection, startInside, interpolate, stream) {
7525   var subject = [],
7526       clip = [],
7527       i,
7528       n;
7529
7530   segments.forEach(function(segment) {
7531     if ((n = segment.length - 1) <= 0) return;
7532     var n, p0 = segment[0], p1 = segment[n], x;
7533
7534     // If the first and last points of a segment are coincident, then treat as a
7535     // closed ring. TODO if all rings are closed, then the winding order of the
7536     // exterior ring should be checked.
7537     if (pointEqual(p0, p1)) {
7538       stream.lineStart();
7539       for (i = 0; i < n; ++i) stream.point((p0 = segment[i])[0], p0[1]);
7540       stream.lineEnd();
7541       return;
7542     }
7543
7544     subject.push(x = new Intersection(p0, segment, null, true));
7545     clip.push(x.o = new Intersection(p0, null, x, false));
7546     subject.push(x = new Intersection(p1, segment, null, false));
7547     clip.push(x.o = new Intersection(p1, null, x, true));
7548   });
7549
7550   if (!subject.length) return;
7551
7552   clip.sort(compareIntersection);
7553   link$1(subject);
7554   link$1(clip);
7555
7556   for (i = 0, n = clip.length; i < n; ++i) {
7557     clip[i].e = startInside = !startInside;
7558   }
7559
7560   var start = subject[0],
7561       points,
7562       point;
7563
7564   while (1) {
7565     // Find first unvisited intersection.
7566     var current = start,
7567         isSubject = true;
7568     while (current.v) if ((current = current.n) === start) return;
7569     points = current.z;
7570     stream.lineStart();
7571     do {
7572       current.v = current.o.v = true;
7573       if (current.e) {
7574         if (isSubject) {
7575           for (i = 0, n = points.length; i < n; ++i) stream.point((point = points[i])[0], point[1]);
7576         } else {
7577           interpolate(current.x, current.n.x, 1, stream);
7578         }
7579         current = current.n;
7580       } else {
7581         if (isSubject) {
7582           points = current.p.z;
7583           for (i = points.length - 1; i >= 0; --i) stream.point((point = points[i])[0], point[1]);
7584         } else {
7585           interpolate(current.x, current.p.x, -1, stream);
7586         }
7587         current = current.p;
7588       }
7589       current = current.o;
7590       points = current.z;
7591       isSubject = !isSubject;
7592     } while (!current.v);
7593     stream.lineEnd();
7594   }
7595 }
7596
7597 function link$1(array) {
7598   if (!(n = array.length)) return;
7599   var n,
7600       i = 0,
7601       a = array[0],
7602       b;
7603   while (++i < n) {
7604     a.n = b = array[i];
7605     b.p = a;
7606     a = b;
7607   }
7608   a.n = b = array[0];
7609   b.p = a;
7610 }
7611
7612 var sum$1 = adder();
7613
7614 function polygonContains(polygon, point) {
7615   var lambda = point[0],
7616       phi = point[1],
7617       normal = [sin$1(lambda), -cos$1(lambda), 0],
7618       angle = 0,
7619       winding = 0;
7620
7621   sum$1.reset();
7622
7623   for (var i = 0, n = polygon.length; i < n; ++i) {
7624     if (!(m = (ring = polygon[i]).length)) continue;
7625     var ring,
7626         m,
7627         point0 = ring[m - 1],
7628         lambda0 = point0[0],
7629         phi0 = point0[1] / 2 + quarterPi,
7630         sinPhi0 = sin$1(phi0),
7631         cosPhi0 = cos$1(phi0);
7632
7633     for (var j = 0; j < m; ++j, lambda0 = lambda1, sinPhi0 = sinPhi1, cosPhi0 = cosPhi1, point0 = point1) {
7634       var point1 = ring[j],
7635           lambda1 = point1[0],
7636           phi1 = point1[1] / 2 + quarterPi,
7637           sinPhi1 = sin$1(phi1),
7638           cosPhi1 = cos$1(phi1),
7639           delta = lambda1 - lambda0,
7640           sign$$1 = delta >= 0 ? 1 : -1,
7641           absDelta = sign$$1 * delta,
7642           antimeridian = absDelta > pi$3,
7643           k = sinPhi0 * sinPhi1;
7644
7645       sum$1.add(atan2(k * sign$$1 * sin$1(absDelta), cosPhi0 * cosPhi1 + k * cos$1(absDelta)));
7646       angle += antimeridian ? delta + sign$$1 * tau$3 : delta;
7647
7648       // Are the longitudes either side of the point’s meridian (lambda),
7649       // and are the latitudes smaller than the parallel (phi)?
7650       if (antimeridian ^ lambda0 >= lambda ^ lambda1 >= lambda) {
7651         var arc = cartesianCross(cartesian(point0), cartesian(point1));
7652         cartesianNormalizeInPlace(arc);
7653         var intersection = cartesianCross(normal, arc);
7654         cartesianNormalizeInPlace(intersection);
7655         var phiArc = (antimeridian ^ delta >= 0 ? -1 : 1) * asin(intersection[2]);
7656         if (phi > phiArc || phi === phiArc && (arc[0] || arc[1])) {
7657           winding += antimeridian ^ delta >= 0 ? 1 : -1;
7658         }
7659       }
7660     }
7661   }
7662
7663   // First, determine whether the South pole is inside or outside:
7664   //
7665   // It is inside if:
7666   // * the polygon winds around it in a clockwise direction.
7667   // * the polygon does not (cumulatively) wind around it, but has a negative
7668   //   (counter-clockwise) area.
7669   //
7670   // Second, count the (signed) number of times a segment crosses a lambda
7671   // from the point to the South pole.  If it is zero, then the point is the
7672   // same side as the South pole.
7673
7674   return (angle < -epsilon$2 || angle < epsilon$2 && sum$1 < -epsilon$2) ^ (winding & 1);
7675 }
7676
7677 function clip(pointVisible, clipLine, interpolate, start) {
7678   return function(sink) {
7679     var line = clipLine(sink),
7680         ringBuffer = clipBuffer(),
7681         ringSink = clipLine(ringBuffer),
7682         polygonStarted = false,
7683         polygon,
7684         segments,
7685         ring;
7686
7687     var clip = {
7688       point: point,
7689       lineStart: lineStart,
7690       lineEnd: lineEnd,
7691       polygonStart: function() {
7692         clip.point = pointRing;
7693         clip.lineStart = ringStart;
7694         clip.lineEnd = ringEnd;
7695         segments = [];
7696         polygon = [];
7697       },
7698       polygonEnd: function() {
7699         clip.point = point;
7700         clip.lineStart = lineStart;
7701         clip.lineEnd = lineEnd;
7702         segments = merge(segments);
7703         var startInside = polygonContains(polygon, start);
7704         if (segments.length) {
7705           if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
7706           clipRejoin(segments, compareIntersection, startInside, interpolate, sink);
7707         } else if (startInside) {
7708           if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
7709           sink.lineStart();
7710           interpolate(null, null, 1, sink);
7711           sink.lineEnd();
7712         }
7713         if (polygonStarted) sink.polygonEnd(), polygonStarted = false;
7714         segments = polygon = null;
7715       },
7716       sphere: function() {
7717         sink.polygonStart();
7718         sink.lineStart();
7719         interpolate(null, null, 1, sink);
7720         sink.lineEnd();
7721         sink.polygonEnd();
7722       }
7723     };
7724
7725     function point(lambda, phi) {
7726       if (pointVisible(lambda, phi)) sink.point(lambda, phi);
7727     }
7728
7729     function pointLine(lambda, phi) {
7730       line.point(lambda, phi);
7731     }
7732
7733     function lineStart() {
7734       clip.point = pointLine;
7735       line.lineStart();
7736     }
7737
7738     function lineEnd() {
7739       clip.point = point;
7740       line.lineEnd();
7741     }
7742
7743     function pointRing(lambda, phi) {
7744       ring.push([lambda, phi]);
7745       ringSink.point(lambda, phi);
7746     }
7747
7748     function ringStart() {
7749       ringSink.lineStart();
7750       ring = [];
7751     }
7752
7753     function ringEnd() {
7754       pointRing(ring[0][0], ring[0][1]);
7755       ringSink.lineEnd();
7756
7757       var clean = ringSink.clean(),
7758           ringSegments = ringBuffer.result(),
7759           i, n = ringSegments.length, m,
7760           segment,
7761           point;
7762
7763       ring.pop();
7764       polygon.push(ring);
7765       ring = null;
7766
7767       if (!n) return;
7768
7769       // No intersections.
7770       if (clean & 1) {
7771         segment = ringSegments[0];
7772         if ((m = segment.length - 1) > 0) {
7773           if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
7774           sink.lineStart();
7775           for (i = 0; i < m; ++i) sink.point((point = segment[i])[0], point[1]);
7776           sink.lineEnd();
7777         }
7778         return;
7779       }
7780
7781       // Rejoin connected segments.
7782       // TODO reuse ringBuffer.rejoin()?
7783       if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));
7784
7785       segments.push(ringSegments.filter(validSegment));
7786     }
7787
7788     return clip;
7789   };
7790 }
7791
7792 function validSegment(segment) {
7793   return segment.length > 1;
7794 }
7795
7796 // Intersections are sorted along the clip edge. For both antimeridian cutting
7797 // and circle clipping, the same comparison is used.
7798 function compareIntersection(a, b) {
7799   return ((a = a.x)[0] < 0 ? a[1] - halfPi$2 - epsilon$2 : halfPi$2 - a[1])
7800        - ((b = b.x)[0] < 0 ? b[1] - halfPi$2 - epsilon$2 : halfPi$2 - b[1]);
7801 }
7802
7803 var clipAntimeridian = clip(
7804   function() { return true; },
7805   clipAntimeridianLine,
7806   clipAntimeridianInterpolate,
7807   [-pi$3, -halfPi$2]
7808 );
7809
7810 // Takes a line and cuts into visible segments. Return values: 0 - there were
7811 // intersections or the line was empty; 1 - no intersections; 2 - there were
7812 // intersections, and the first and last segments should be rejoined.
7813 function clipAntimeridianLine(stream) {
7814   var lambda0 = NaN,
7815       phi0 = NaN,
7816       sign0 = NaN,
7817       clean; // no intersections
7818
7819   return {
7820     lineStart: function() {
7821       stream.lineStart();
7822       clean = 1;
7823     },
7824     point: function(lambda1, phi1) {
7825       var sign1 = lambda1 > 0 ? pi$3 : -pi$3,
7826           delta = abs(lambda1 - lambda0);
7827       if (abs(delta - pi$3) < epsilon$2) { // line crosses a pole
7828         stream.point(lambda0, phi0 = (phi0 + phi1) / 2 > 0 ? halfPi$2 : -halfPi$2);
7829         stream.point(sign0, phi0);
7830         stream.lineEnd();
7831         stream.lineStart();
7832         stream.point(sign1, phi0);
7833         stream.point(lambda1, phi0);
7834         clean = 0;
7835       } else if (sign0 !== sign1 && delta >= pi$3) { // line crosses antimeridian
7836         if (abs(lambda0 - sign0) < epsilon$2) lambda0 -= sign0 * epsilon$2; // handle degeneracies
7837         if (abs(lambda1 - sign1) < epsilon$2) lambda1 -= sign1 * epsilon$2;
7838         phi0 = clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1);
7839         stream.point(sign0, phi0);
7840         stream.lineEnd();
7841         stream.lineStart();
7842         stream.point(sign1, phi0);
7843         clean = 0;
7844       }
7845       stream.point(lambda0 = lambda1, phi0 = phi1);
7846       sign0 = sign1;
7847     },
7848     lineEnd: function() {
7849       stream.lineEnd();
7850       lambda0 = phi0 = NaN;
7851     },
7852     clean: function() {
7853       return 2 - clean; // if intersections, rejoin first and last segments
7854     }
7855   };
7856 }
7857
7858 function clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) {
7859   var cosPhi0,
7860       cosPhi1,
7861       sinLambda0Lambda1 = sin$1(lambda0 - lambda1);
7862   return abs(sinLambda0Lambda1) > epsilon$2
7863       ? atan((sin$1(phi0) * (cosPhi1 = cos$1(phi1)) * sin$1(lambda1)
7864           - sin$1(phi1) * (cosPhi0 = cos$1(phi0)) * sin$1(lambda0))
7865           / (cosPhi0 * cosPhi1 * sinLambda0Lambda1))
7866       : (phi0 + phi1) / 2;
7867 }
7868
7869 function clipAntimeridianInterpolate(from, to, direction, stream) {
7870   var phi;
7871   if (from == null) {
7872     phi = direction * halfPi$2;
7873     stream.point(-pi$3, phi);
7874     stream.point(0, phi);
7875     stream.point(pi$3, phi);
7876     stream.point(pi$3, 0);
7877     stream.point(pi$3, -phi);
7878     stream.point(0, -phi);
7879     stream.point(-pi$3, -phi);
7880     stream.point(-pi$3, 0);
7881     stream.point(-pi$3, phi);
7882   } else if (abs(from[0] - to[0]) > epsilon$2) {
7883     var lambda = from[0] < to[0] ? pi$3 : -pi$3;
7884     phi = direction * lambda / 2;
7885     stream.point(-lambda, phi);
7886     stream.point(0, phi);
7887     stream.point(lambda, phi);
7888   } else {
7889     stream.point(to[0], to[1]);
7890   }
7891 }
7892
7893 function clipCircle(radius) {
7894   var cr = cos$1(radius),
7895       delta = 6 * radians,
7896       smallRadius = cr > 0,
7897       notHemisphere = abs(cr) > epsilon$2; // TODO optimise for this common case
7898
7899   function interpolate(from, to, direction, stream) {
7900     circleStream(stream, radius, delta, direction, from, to);
7901   }
7902
7903   function visible(lambda, phi) {
7904     return cos$1(lambda) * cos$1(phi) > cr;
7905   }
7906
7907   // Takes a line and cuts into visible segments. Return values used for polygon
7908   // clipping: 0 - there were intersections or the line was empty; 1 - no
7909   // intersections 2 - there were intersections, and the first and last segments
7910   // should be rejoined.
7911   function clipLine(stream) {
7912     var point0, // previous point
7913         c0, // code for previous point
7914         v0, // visibility of previous point
7915         v00, // visibility of first point
7916         clean; // no intersections
7917     return {
7918       lineStart: function() {
7919         v00 = v0 = false;
7920         clean = 1;
7921       },
7922       point: function(lambda, phi) {
7923         var point1 = [lambda, phi],
7924             point2,
7925             v = visible(lambda, phi),
7926             c = smallRadius
7927               ? v ? 0 : code(lambda, phi)
7928               : v ? code(lambda + (lambda < 0 ? pi$3 : -pi$3), phi) : 0;
7929         if (!point0 && (v00 = v0 = v)) stream.lineStart();
7930         // Handle degeneracies.
7931         // TODO ignore if not clipping polygons.
7932         if (v !== v0) {
7933           point2 = intersect(point0, point1);
7934           if (!point2 || pointEqual(point0, point2) || pointEqual(point1, point2)) {
7935             point1[0] += epsilon$2;
7936             point1[1] += epsilon$2;
7937             v = visible(point1[0], point1[1]);
7938           }
7939         }
7940         if (v !== v0) {
7941           clean = 0;
7942           if (v) {
7943             // outside going in
7944             stream.lineStart();
7945             point2 = intersect(point1, point0);
7946             stream.point(point2[0], point2[1]);
7947           } else {
7948             // inside going out
7949             point2 = intersect(point0, point1);
7950             stream.point(point2[0], point2[1]);
7951             stream.lineEnd();
7952           }
7953           point0 = point2;
7954         } else if (notHemisphere && point0 && smallRadius ^ v) {
7955           var t;
7956           // If the codes for two points are different, or are both zero,
7957           // and there this segment intersects with the small circle.
7958           if (!(c & c0) && (t = intersect(point1, point0, true))) {
7959             clean = 0;
7960             if (smallRadius) {
7961               stream.lineStart();
7962               stream.point(t[0][0], t[0][1]);
7963               stream.point(t[1][0], t[1][1]);
7964               stream.lineEnd();
7965             } else {
7966               stream.point(t[1][0], t[1][1]);
7967               stream.lineEnd();
7968               stream.lineStart();
7969               stream.point(t[0][0], t[0][1]);
7970             }
7971           }
7972         }
7973         if (v && (!point0 || !pointEqual(point0, point1))) {
7974           stream.point(point1[0], point1[1]);
7975         }
7976         point0 = point1, v0 = v, c0 = c;
7977       },
7978       lineEnd: function() {
7979         if (v0) stream.lineEnd();
7980         point0 = null;
7981       },
7982       // Rejoin first and last segments if there were intersections and the first
7983       // and last points were visible.
7984       clean: function() {
7985         return clean | ((v00 && v0) << 1);
7986       }
7987     };
7988   }
7989
7990   // Intersects the great circle between a and b with the clip circle.
7991   function intersect(a, b, two) {
7992     var pa = cartesian(a),
7993         pb = cartesian(b);
7994
7995     // We have two planes, n1.p = d1 and n2.p = d2.
7996     // Find intersection line p(t) = c1 n1 + c2 n2 + t (n1 ⨯ n2).
7997     var n1 = [1, 0, 0], // normal
7998         n2 = cartesianCross(pa, pb),
7999         n2n2 = cartesianDot(n2, n2),
8000         n1n2 = n2[0], // cartesianDot(n1, n2),
8001         determinant = n2n2 - n1n2 * n1n2;
8002
8003     // Two polar points.
8004     if (!determinant) return !two && a;
8005
8006     var c1 =  cr * n2n2 / determinant,
8007         c2 = -cr * n1n2 / determinant,
8008         n1xn2 = cartesianCross(n1, n2),
8009         A = cartesianScale(n1, c1),
8010         B = cartesianScale(n2, c2);
8011     cartesianAddInPlace(A, B);
8012
8013     // Solve |p(t)|^2 = 1.
8014     var u = n1xn2,
8015         w = cartesianDot(A, u),
8016         uu = cartesianDot(u, u),
8017         t2 = w * w - uu * (cartesianDot(A, A) - 1);
8018
8019     if (t2 < 0) return;
8020
8021     var t = sqrt(t2),
8022         q = cartesianScale(u, (-w - t) / uu);
8023     cartesianAddInPlace(q, A);
8024     q = spherical(q);
8025
8026     if (!two) return q;
8027
8028     // Two intersection points.
8029     var lambda0 = a[0],
8030         lambda1 = b[0],
8031         phi0 = a[1],
8032         phi1 = b[1],
8033         z;
8034
8035     if (lambda1 < lambda0) z = lambda0, lambda0 = lambda1, lambda1 = z;
8036
8037     var delta = lambda1 - lambda0,
8038         polar = abs(delta - pi$3) < epsilon$2,
8039         meridian = polar || delta < epsilon$2;
8040
8041     if (!polar && phi1 < phi0) z = phi0, phi0 = phi1, phi1 = z;
8042
8043     // Check that the first point is between a and b.
8044     if (meridian
8045         ? polar
8046           ? phi0 + phi1 > 0 ^ q[1] < (abs(q[0] - lambda0) < epsilon$2 ? phi0 : phi1)
8047           : phi0 <= q[1] && q[1] <= phi1
8048         : delta > pi$3 ^ (lambda0 <= q[0] && q[0] <= lambda1)) {
8049       var q1 = cartesianScale(u, (-w + t) / uu);
8050       cartesianAddInPlace(q1, A);
8051       return [q, spherical(q1)];
8052     }
8053   }
8054
8055   // Generates a 4-bit vector representing the location of a point relative to
8056   // the small circle's bounding box.
8057   function code(lambda, phi) {
8058     var r = smallRadius ? radius : pi$3 - radius,
8059         code = 0;
8060     if (lambda < -r) code |= 1; // left
8061     else if (lambda > r) code |= 2; // right
8062     if (phi < -r) code |= 4; // below
8063     else if (phi > r) code |= 8; // above
8064     return code;
8065   }
8066
8067   return clip(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-pi$3, radius - pi$3]);
8068 }
8069
8070 function clipLine(a, b, x0, y0, x1, y1) {
8071   var ax = a[0],
8072       ay = a[1],
8073       bx = b[0],
8074       by = b[1],
8075       t0 = 0,
8076       t1 = 1,
8077       dx = bx - ax,
8078       dy = by - ay,
8079       r;
8080
8081   r = x0 - ax;
8082   if (!dx && r > 0) return;
8083   r /= dx;
8084   if (dx < 0) {
8085     if (r < t0) return;
8086     if (r < t1) t1 = r;
8087   } else if (dx > 0) {
8088     if (r > t1) return;
8089     if (r > t0) t0 = r;
8090   }
8091
8092   r = x1 - ax;
8093   if (!dx && r < 0) return;
8094   r /= dx;
8095   if (dx < 0) {
8096     if (r > t1) return;
8097     if (r > t0) t0 = r;
8098   } else if (dx > 0) {
8099     if (r < t0) return;
8100     if (r < t1) t1 = r;
8101   }
8102
8103   r = y0 - ay;
8104   if (!dy && r > 0) return;
8105   r /= dy;
8106   if (dy < 0) {
8107     if (r < t0) return;
8108     if (r < t1) t1 = r;
8109   } else if (dy > 0) {
8110     if (r > t1) return;
8111     if (r > t0) t0 = r;
8112   }
8113
8114   r = y1 - ay;
8115   if (!dy && r < 0) return;
8116   r /= dy;
8117   if (dy < 0) {
8118     if (r > t1) return;
8119     if (r > t0) t0 = r;
8120   } else if (dy > 0) {
8121     if (r < t0) return;
8122     if (r < t1) t1 = r;
8123   }
8124
8125   if (t0 > 0) a[0] = ax + t0 * dx, a[1] = ay + t0 * dy;
8126   if (t1 < 1) b[0] = ax + t1 * dx, b[1] = ay + t1 * dy;
8127   return true;
8128 }
8129
8130 var clipMax = 1e9;
8131 var clipMin = -clipMax;
8132
8133 // TODO Use d3-polygon’s polygonContains here for the ring check?
8134 // TODO Eliminate duplicate buffering in clipBuffer and polygon.push?
8135
8136 function clipRectangle(x0, y0, x1, y1) {
8137
8138   function visible(x, y) {
8139     return x0 <= x && x <= x1 && y0 <= y && y <= y1;
8140   }
8141
8142   function interpolate(from, to, direction, stream) {
8143     var a = 0, a1 = 0;
8144     if (from == null
8145         || (a = corner(from, direction)) !== (a1 = corner(to, direction))
8146         || comparePoint(from, to) < 0 ^ direction > 0) {
8147       do stream.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0);
8148       while ((a = (a + direction + 4) % 4) !== a1);
8149     } else {
8150       stream.point(to[0], to[1]);
8151     }
8152   }
8153
8154   function corner(p, direction) {
8155     return abs(p[0] - x0) < epsilon$2 ? direction > 0 ? 0 : 3
8156         : abs(p[0] - x1) < epsilon$2 ? direction > 0 ? 2 : 1
8157         : abs(p[1] - y0) < epsilon$2 ? direction > 0 ? 1 : 0
8158         : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon
8159   }
8160
8161   function compareIntersection(a, b) {
8162     return comparePoint(a.x, b.x);
8163   }
8164
8165   function comparePoint(a, b) {
8166     var ca = corner(a, 1),
8167         cb = corner(b, 1);
8168     return ca !== cb ? ca - cb
8169         : ca === 0 ? b[1] - a[1]
8170         : ca === 1 ? a[0] - b[0]
8171         : ca === 2 ? a[1] - b[1]
8172         : b[0] - a[0];
8173   }
8174
8175   return function(stream) {
8176     var activeStream = stream,
8177         bufferStream = clipBuffer(),
8178         segments,
8179         polygon,
8180         ring,
8181         x__, y__, v__, // first point
8182         x_, y_, v_, // previous point
8183         first,
8184         clean;
8185
8186     var clipStream = {
8187       point: point,
8188       lineStart: lineStart,
8189       lineEnd: lineEnd,
8190       polygonStart: polygonStart,
8191       polygonEnd: polygonEnd
8192     };
8193
8194     function point(x, y) {
8195       if (visible(x, y)) activeStream.point(x, y);
8196     }
8197
8198     function polygonInside() {
8199       var winding = 0;
8200
8201       for (var i = 0, n = polygon.length; i < n; ++i) {
8202         for (var ring = polygon[i], j = 1, m = ring.length, point = ring[0], a0, a1, b0 = point[0], b1 = point[1]; j < m; ++j) {
8203           a0 = b0, a1 = b1, point = ring[j], b0 = point[0], b1 = point[1];
8204           if (a1 <= y1) { if (b1 > y1 && (b0 - a0) * (y1 - a1) > (b1 - a1) * (x0 - a0)) ++winding; }
8205           else { if (b1 <= y1 && (b0 - a0) * (y1 - a1) < (b1 - a1) * (x0 - a0)) --winding; }
8206         }
8207       }
8208
8209       return winding;
8210     }
8211
8212     // Buffer geometry within a polygon and then clip it en masse.
8213     function polygonStart() {
8214       activeStream = bufferStream, segments = [], polygon = [], clean = true;
8215     }
8216
8217     function polygonEnd() {
8218       var startInside = polygonInside(),
8219           cleanInside = clean && startInside,
8220           visible = (segments = merge(segments)).length;
8221       if (cleanInside || visible) {
8222         stream.polygonStart();
8223         if (cleanInside) {
8224           stream.lineStart();
8225           interpolate(null, null, 1, stream);
8226           stream.lineEnd();
8227         }
8228         if (visible) {
8229           clipRejoin(segments, compareIntersection, startInside, interpolate, stream);
8230         }
8231         stream.polygonEnd();
8232       }
8233       activeStream = stream, segments = polygon = ring = null;
8234     }
8235
8236     function lineStart() {
8237       clipStream.point = linePoint;
8238       if (polygon) polygon.push(ring = []);
8239       first = true;
8240       v_ = false;
8241       x_ = y_ = NaN;
8242     }
8243
8244     // TODO rather than special-case polygons, simply handle them separately.
8245     // Ideally, coincident intersection points should be jittered to avoid
8246     // clipping issues.
8247     function lineEnd() {
8248       if (segments) {
8249         linePoint(x__, y__);
8250         if (v__ && v_) bufferStream.rejoin();
8251         segments.push(bufferStream.result());
8252       }
8253       clipStream.point = point;
8254       if (v_) activeStream.lineEnd();
8255     }
8256
8257     function linePoint(x, y) {
8258       var v = visible(x, y);
8259       if (polygon) ring.push([x, y]);
8260       if (first) {
8261         x__ = x, y__ = y, v__ = v;
8262         first = false;
8263         if (v) {
8264           activeStream.lineStart();
8265           activeStream.point(x, y);
8266         }
8267       } else {
8268         if (v && v_) activeStream.point(x, y);
8269         else {
8270           var a = [x_ = Math.max(clipMin, Math.min(clipMax, x_)), y_ = Math.max(clipMin, Math.min(clipMax, y_))],
8271               b = [x = Math.max(clipMin, Math.min(clipMax, x)), y = Math.max(clipMin, Math.min(clipMax, y))];
8272           if (clipLine(a, b, x0, y0, x1, y1)) {
8273             if (!v_) {
8274               activeStream.lineStart();
8275               activeStream.point(a[0], a[1]);
8276             }
8277             activeStream.point(b[0], b[1]);
8278             if (!v) activeStream.lineEnd();
8279             clean = false;
8280           } else if (v) {
8281             activeStream.lineStart();
8282             activeStream.point(x, y);
8283             clean = false;
8284           }
8285         }
8286       }
8287       x_ = x, y_ = y, v_ = v;
8288     }
8289
8290     return clipStream;
8291   };
8292 }
8293
8294 function extent$1() {
8295   var x0 = 0,
8296       y0 = 0,
8297       x1 = 960,
8298       y1 = 500,
8299       cache,
8300       cacheStream,
8301       clip;
8302
8303   return clip = {
8304     stream: function(stream) {
8305       return cache && cacheStream === stream ? cache : cache = clipRectangle(x0, y0, x1, y1)(cacheStream = stream);
8306     },
8307     extent: function(_) {
8308       return arguments.length ? (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1], cache = cacheStream = null, clip) : [[x0, y0], [x1, y1]];
8309     }
8310   };
8311 }
8312
8313 var lengthSum = adder();
8314 var lambda0$2;
8315 var sinPhi0$1;
8316 var cosPhi0$1;
8317
8318 var lengthStream = {
8319   sphere: noop$1,
8320   point: noop$1,
8321   lineStart: lengthLineStart,
8322   lineEnd: noop$1,
8323   polygonStart: noop$1,
8324   polygonEnd: noop$1
8325 };
8326
8327 function lengthLineStart() {
8328   lengthStream.point = lengthPointFirst;
8329   lengthStream.lineEnd = lengthLineEnd;
8330 }
8331
8332 function lengthLineEnd() {
8333   lengthStream.point = lengthStream.lineEnd = noop$1;
8334 }
8335
8336 function lengthPointFirst(lambda, phi) {
8337   lambda *= radians, phi *= radians;
8338   lambda0$2 = lambda, sinPhi0$1 = sin$1(phi), cosPhi0$1 = cos$1(phi);
8339   lengthStream.point = lengthPoint;
8340 }
8341
8342 function lengthPoint(lambda, phi) {
8343   lambda *= radians, phi *= radians;
8344   var sinPhi = sin$1(phi),
8345       cosPhi = cos$1(phi),
8346       delta = abs(lambda - lambda0$2),
8347       cosDelta = cos$1(delta),
8348       sinDelta = sin$1(delta),
8349       x = cosPhi * sinDelta,
8350       y = cosPhi0$1 * sinPhi - sinPhi0$1 * cosPhi * cosDelta,
8351       z = sinPhi0$1 * sinPhi + cosPhi0$1 * cosPhi * cosDelta;
8352   lengthSum.add(atan2(sqrt(x * x + y * y), z));
8353   lambda0$2 = lambda, sinPhi0$1 = sinPhi, cosPhi0$1 = cosPhi;
8354 }
8355
8356 function d3_geoLength(object) {
8357   lengthSum.reset();
8358   d3_geoStream(object, lengthStream);
8359   return +lengthSum;
8360 }
8361
8362 var coordinates = [null, null];
8363 var object$1 = {type: "LineString", coordinates: coordinates};
8364
8365 function distance(a, b) {
8366   coordinates[0] = a;
8367   coordinates[1] = b;
8368   return d3_geoLength(object$1);
8369 }
8370
8371 var containsObjectType = {
8372   Feature: function(object, point) {
8373     return containsGeometry(object.geometry, point);
8374   },
8375   FeatureCollection: function(object, point) {
8376     var features = object.features, i = -1, n = features.length;
8377     while (++i < n) if (containsGeometry(features[i].geometry, point)) return true;
8378     return false;
8379   }
8380 };
8381
8382 var containsGeometryType = {
8383   Sphere: function() {
8384     return true;
8385   },
8386   Point: function(object, point) {
8387     return containsPoint(object.coordinates, point);
8388   },
8389   MultiPoint: function(object, point) {
8390     var coordinates = object.coordinates, i = -1, n = coordinates.length;
8391     while (++i < n) if (containsPoint(coordinates[i], point)) return true;
8392     return false;
8393   },
8394   LineString: function(object, point) {
8395     return containsLine(object.coordinates, point);
8396   },
8397   MultiLineString: function(object, point) {
8398     var coordinates = object.coordinates, i = -1, n = coordinates.length;
8399     while (++i < n) if (containsLine(coordinates[i], point)) return true;
8400     return false;
8401   },
8402   Polygon: function(object, point) {
8403     return containsPolygon(object.coordinates, point);
8404   },
8405   MultiPolygon: function(object, point) {
8406     var coordinates = object.coordinates, i = -1, n = coordinates.length;
8407     while (++i < n) if (containsPolygon(coordinates[i], point)) return true;
8408     return false;
8409   },
8410   GeometryCollection: function(object, point) {
8411     var geometries = object.geometries, i = -1, n = geometries.length;
8412     while (++i < n) if (containsGeometry(geometries[i], point)) return true;
8413     return false;
8414   }
8415 };
8416
8417 function containsGeometry(geometry, point) {
8418   return geometry && containsGeometryType.hasOwnProperty(geometry.type)
8419       ? containsGeometryType[geometry.type](geometry, point)
8420       : false;
8421 }
8422
8423 function containsPoint(coordinates, point) {
8424   return distance(coordinates, point) === 0;
8425 }
8426
8427 function containsLine(coordinates, point) {
8428   var ab = distance(coordinates[0], coordinates[1]),
8429       ao = distance(coordinates[0], point),
8430       ob = distance(point, coordinates[1]);
8431   return ao + ob <= ab + epsilon$2;
8432 }
8433
8434 function containsPolygon(coordinates, point) {
8435   return !!polygonContains(coordinates.map(ringRadians), pointRadians(point));
8436 }
8437
8438 function ringRadians(ring) {
8439   return ring = ring.map(pointRadians), ring.pop(), ring;
8440 }
8441
8442 function pointRadians(point) {
8443   return [point[0] * radians, point[1] * radians];
8444 }
8445
8446 function contains(object, point) {
8447   return (object && containsObjectType.hasOwnProperty(object.type)
8448       ? containsObjectType[object.type]
8449       : containsGeometry)(object, point);
8450 }
8451
8452 function graticuleX(y0, y1, dy) {
8453   var y = d3_range(y0, y1 - epsilon$2, dy).concat(y1);
8454   return function(x) { return y.map(function(y) { return [x, y]; }); };
8455 }
8456
8457 function graticuleY(x0, x1, dx) {
8458   var x = d3_range(x0, x1 - epsilon$2, dx).concat(x1);
8459   return function(y) { return x.map(function(x) { return [x, y]; }); };
8460 }
8461
8462 function graticule() {
8463   var x1, x0, X1, X0,
8464       y1, y0, Y1, Y0,
8465       dx = 10, dy = dx, DX = 90, DY = 360,
8466       x, y, X, Y,
8467       precision = 2.5;
8468
8469   function graticule() {
8470     return {type: "MultiLineString", coordinates: lines()};
8471   }
8472
8473   function lines() {
8474     return d3_range(ceil(X0 / DX) * DX, X1, DX).map(X)
8475         .concat(d3_range(ceil(Y0 / DY) * DY, Y1, DY).map(Y))
8476         .concat(d3_range(ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return abs(x % DX) > epsilon$2; }).map(x))
8477         .concat(d3_range(ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return abs(y % DY) > epsilon$2; }).map(y));
8478   }
8479
8480   graticule.lines = function() {
8481     return lines().map(function(coordinates) { return {type: "LineString", coordinates: coordinates}; });
8482   };
8483
8484   graticule.outline = function() {
8485     return {
8486       type: "Polygon",
8487       coordinates: [
8488         X(X0).concat(
8489         Y(Y1).slice(1),
8490         X(X1).reverse().slice(1),
8491         Y(Y0).reverse().slice(1))
8492       ]
8493     };
8494   };
8495
8496   graticule.extent = function(_) {
8497     if (!arguments.length) return graticule.extentMinor();
8498     return graticule.extentMajor(_).extentMinor(_);
8499   };
8500
8501   graticule.extentMajor = function(_) {
8502     if (!arguments.length) return [[X0, Y0], [X1, Y1]];
8503     X0 = +_[0][0], X1 = +_[1][0];
8504     Y0 = +_[0][1], Y1 = +_[1][1];
8505     if (X0 > X1) _ = X0, X0 = X1, X1 = _;
8506     if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _;
8507     return graticule.precision(precision);
8508   };
8509
8510   graticule.extentMinor = function(_) {
8511     if (!arguments.length) return [[x0, y0], [x1, y1]];
8512     x0 = +_[0][0], x1 = +_[1][0];
8513     y0 = +_[0][1], y1 = +_[1][1];
8514     if (x0 > x1) _ = x0, x0 = x1, x1 = _;
8515     if (y0 > y1) _ = y0, y0 = y1, y1 = _;
8516     return graticule.precision(precision);
8517   };
8518
8519   graticule.step = function(_) {
8520     if (!arguments.length) return graticule.stepMinor();
8521     return graticule.stepMajor(_).stepMinor(_);
8522   };
8523
8524   graticule.stepMajor = function(_) {
8525     if (!arguments.length) return [DX, DY];
8526     DX = +_[0], DY = +_[1];
8527     return graticule;
8528   };
8529
8530   graticule.stepMinor = function(_) {
8531     if (!arguments.length) return [dx, dy];
8532     dx = +_[0], dy = +_[1];
8533     return graticule;
8534   };
8535
8536   graticule.precision = function(_) {
8537     if (!arguments.length) return precision;
8538     precision = +_;
8539     x = graticuleX(y0, y1, 90);
8540     y = graticuleY(x0, x1, precision);
8541     X = graticuleX(Y0, Y1, 90);
8542     Y = graticuleY(X0, X1, precision);
8543     return graticule;
8544   };
8545
8546   return graticule
8547       .extentMajor([[-180, -90 + epsilon$2], [180, 90 - epsilon$2]])
8548       .extentMinor([[-180, -80 - epsilon$2], [180, 80 + epsilon$2]]);
8549 }
8550
8551 function graticule10() {
8552   return graticule()();
8553 }
8554
8555 function interpolate$1(a, b) {
8556   var x0 = a[0] * radians,
8557       y0 = a[1] * radians,
8558       x1 = b[0] * radians,
8559       y1 = b[1] * radians,
8560       cy0 = cos$1(y0),
8561       sy0 = sin$1(y0),
8562       cy1 = cos$1(y1),
8563       sy1 = sin$1(y1),
8564       kx0 = cy0 * cos$1(x0),
8565       ky0 = cy0 * sin$1(x0),
8566       kx1 = cy1 * cos$1(x1),
8567       ky1 = cy1 * sin$1(x1),
8568       d = 2 * asin(sqrt(haversin(y1 - y0) + cy0 * cy1 * haversin(x1 - x0))),
8569       k = sin$1(d);
8570
8571   var interpolate = d ? function(t) {
8572     var B = sin$1(t *= d) / k,
8573         A = sin$1(d - t) / k,
8574         x = A * kx0 + B * kx1,
8575         y = A * ky0 + B * ky1,
8576         z = A * sy0 + B * sy1;
8577     return [
8578       atan2(y, x) * degrees$1,
8579       atan2(z, sqrt(x * x + y * y)) * degrees$1
8580     ];
8581   } : function() {
8582     return [x0 * degrees$1, y0 * degrees$1];
8583   };
8584
8585   interpolate.distance = d;
8586
8587   return interpolate;
8588 }
8589
8590 function identity$4(x) {
8591   return x;
8592 }
8593
8594 var areaSum$1 = adder();
8595 var areaRingSum$1 = adder();
8596 var x00;
8597 var y00;
8598 var x0$1;
8599 var y0$1;
8600
8601 var areaStream$1 = {
8602   point: noop$1,
8603   lineStart: noop$1,
8604   lineEnd: noop$1,
8605   polygonStart: function() {
8606     areaStream$1.lineStart = areaRingStart$1;
8607     areaStream$1.lineEnd = areaRingEnd$1;
8608   },
8609   polygonEnd: function() {
8610     areaStream$1.lineStart = areaStream$1.lineEnd = areaStream$1.point = noop$1;
8611     areaSum$1.add(abs(areaRingSum$1));
8612     areaRingSum$1.reset();
8613   },
8614   result: function() {
8615     var area = areaSum$1 / 2;
8616     areaSum$1.reset();
8617     return area;
8618   }
8619 };
8620
8621 function areaRingStart$1() {
8622   areaStream$1.point = areaPointFirst$1;
8623 }
8624
8625 function areaPointFirst$1(x, y) {
8626   areaStream$1.point = areaPoint$1;
8627   x00 = x0$1 = x, y00 = y0$1 = y;
8628 }
8629
8630 function areaPoint$1(x, y) {
8631   areaRingSum$1.add(y0$1 * x - x0$1 * y);
8632   x0$1 = x, y0$1 = y;
8633 }
8634
8635 function areaRingEnd$1() {
8636   areaPoint$1(x00, y00);
8637 }
8638
8639 var x0$2 = Infinity;
8640 var y0$2 = x0$2;
8641 var x1 = -x0$2;
8642 var y1 = x1;
8643
8644 var boundsStream$1 = {
8645   point: boundsPoint$1,
8646   lineStart: noop$1,
8647   lineEnd: noop$1,
8648   polygonStart: noop$1,
8649   polygonEnd: noop$1,
8650   result: function() {
8651     var bounds = [[x0$2, y0$2], [x1, y1]];
8652     x1 = y1 = -(y0$2 = x0$2 = Infinity);
8653     return bounds;
8654   }
8655 };
8656
8657 function boundsPoint$1(x, y) {
8658   if (x < x0$2) x0$2 = x;
8659   if (x > x1) x1 = x;
8660   if (y < y0$2) y0$2 = y;
8661   if (y > y1) y1 = y;
8662 }
8663
8664 // TODO Enforce positive area for exterior, negative area for interior?
8665
8666 var X0$1 = 0;
8667 var Y0$1 = 0;
8668 var Z0$1 = 0;
8669 var X1$1 = 0;
8670 var Y1$1 = 0;
8671 var Z1$1 = 0;
8672 var X2$1 = 0;
8673 var Y2$1 = 0;
8674 var Z2$1 = 0;
8675 var x00$1;
8676 var y00$1;
8677 var x0$3;
8678 var y0$3;
8679
8680 var centroidStream$1 = {
8681   point: centroidPoint$1,
8682   lineStart: centroidLineStart$1,
8683   lineEnd: centroidLineEnd$1,
8684   polygonStart: function() {
8685     centroidStream$1.lineStart = centroidRingStart$1;
8686     centroidStream$1.lineEnd = centroidRingEnd$1;
8687   },
8688   polygonEnd: function() {
8689     centroidStream$1.point = centroidPoint$1;
8690     centroidStream$1.lineStart = centroidLineStart$1;
8691     centroidStream$1.lineEnd = centroidLineEnd$1;
8692   },
8693   result: function() {
8694     var centroid = Z2$1 ? [X2$1 / Z2$1, Y2$1 / Z2$1]
8695         : Z1$1 ? [X1$1 / Z1$1, Y1$1 / Z1$1]
8696         : Z0$1 ? [X0$1 / Z0$1, Y0$1 / Z0$1]
8697         : [NaN, NaN];
8698     X0$1 = Y0$1 = Z0$1 =
8699     X1$1 = Y1$1 = Z1$1 =
8700     X2$1 = Y2$1 = Z2$1 = 0;
8701     return centroid;
8702   }
8703 };
8704
8705 function centroidPoint$1(x, y) {
8706   X0$1 += x;
8707   Y0$1 += y;
8708   ++Z0$1;
8709 }
8710
8711 function centroidLineStart$1() {
8712   centroidStream$1.point = centroidPointFirstLine;
8713 }
8714
8715 function centroidPointFirstLine(x, y) {
8716   centroidStream$1.point = centroidPointLine;
8717   centroidPoint$1(x0$3 = x, y0$3 = y);
8718 }
8719
8720 function centroidPointLine(x, y) {
8721   var dx = x - x0$3, dy = y - y0$3, z = sqrt(dx * dx + dy * dy);
8722   X1$1 += z * (x0$3 + x) / 2;
8723   Y1$1 += z * (y0$3 + y) / 2;
8724   Z1$1 += z;
8725   centroidPoint$1(x0$3 = x, y0$3 = y);
8726 }
8727
8728 function centroidLineEnd$1() {
8729   centroidStream$1.point = centroidPoint$1;
8730 }
8731
8732 function centroidRingStart$1() {
8733   centroidStream$1.point = centroidPointFirstRing;
8734 }
8735
8736 function centroidRingEnd$1() {
8737   centroidPointRing(x00$1, y00$1);
8738 }
8739
8740 function centroidPointFirstRing(x, y) {
8741   centroidStream$1.point = centroidPointRing;
8742   centroidPoint$1(x00$1 = x0$3 = x, y00$1 = y0$3 = y);
8743 }
8744
8745 function centroidPointRing(x, y) {
8746   var dx = x - x0$3,
8747       dy = y - y0$3,
8748       z = sqrt(dx * dx + dy * dy);
8749
8750   X1$1 += z * (x0$3 + x) / 2;
8751   Y1$1 += z * (y0$3 + y) / 2;
8752   Z1$1 += z;
8753
8754   z = y0$3 * x - x0$3 * y;
8755   X2$1 += z * (x0$3 + x);
8756   Y2$1 += z * (y0$3 + y);
8757   Z2$1 += z * 3;
8758   centroidPoint$1(x0$3 = x, y0$3 = y);
8759 }
8760
8761 function PathContext(context) {
8762   this._context = context;
8763 }
8764
8765 PathContext.prototype = {
8766   _radius: 4.5,
8767   pointRadius: function(_) {
8768     return this._radius = _, this;
8769   },
8770   polygonStart: function() {
8771     this._line = 0;
8772   },
8773   polygonEnd: function() {
8774     this._line = NaN;
8775   },
8776   lineStart: function() {
8777     this._point = 0;
8778   },
8779   lineEnd: function() {
8780     if (this._line === 0) this._context.closePath();
8781     this._point = NaN;
8782   },
8783   point: function(x, y) {
8784     switch (this._point) {
8785       case 0: {
8786         this._context.moveTo(x, y);
8787         this._point = 1;
8788         break;
8789       }
8790       case 1: {
8791         this._context.lineTo(x, y);
8792         break;
8793       }
8794       default: {
8795         this._context.moveTo(x + this._radius, y);
8796         this._context.arc(x, y, this._radius, 0, tau$3);
8797         break;
8798       }
8799     }
8800   },
8801   result: noop$1
8802 };
8803
8804 var lengthSum$1 = adder();
8805 var lengthRing;
8806 var x00$2;
8807 var y00$2;
8808 var x0$4;
8809 var y0$4;
8810
8811 var lengthStream$1 = {
8812   point: noop$1,
8813   lineStart: function() {
8814     lengthStream$1.point = lengthPointFirst$1;
8815   },
8816   lineEnd: function() {
8817     if (lengthRing) lengthPoint$1(x00$2, y00$2);
8818     lengthStream$1.point = noop$1;
8819   },
8820   polygonStart: function() {
8821     lengthRing = true;
8822   },
8823   polygonEnd: function() {
8824     lengthRing = null;
8825   },
8826   result: function() {
8827     var length = +lengthSum$1;
8828     lengthSum$1.reset();
8829     return length;
8830   }
8831 };
8832
8833 function lengthPointFirst$1(x, y) {
8834   lengthStream$1.point = lengthPoint$1;
8835   x00$2 = x0$4 = x, y00$2 = y0$4 = y;
8836 }
8837
8838 function lengthPoint$1(x, y) {
8839   x0$4 -= x, y0$4 -= y;
8840   lengthSum$1.add(sqrt(x0$4 * x0$4 + y0$4 * y0$4));
8841   x0$4 = x, y0$4 = y;
8842 }
8843
8844 function PathString() {
8845   this._string = [];
8846 }
8847
8848 PathString.prototype = {
8849   _radius: 4.5,
8850   _circle: circle$1(4.5),
8851   pointRadius: function(_) {
8852     if ((_ = +_) !== this._radius) this._radius = _, this._circle = null;
8853     return this;
8854   },
8855   polygonStart: function() {
8856     this._line = 0;
8857   },
8858   polygonEnd: function() {
8859     this._line = NaN;
8860   },
8861   lineStart: function() {
8862     this._point = 0;
8863   },
8864   lineEnd: function() {
8865     if (this._line === 0) this._string.push("Z");
8866     this._point = NaN;
8867   },
8868   point: function(x, y) {
8869     switch (this._point) {
8870       case 0: {
8871         this._string.push("M", x, ",", y);
8872         this._point = 1;
8873         break;
8874       }
8875       case 1: {
8876         this._string.push("L", x, ",", y);
8877         break;
8878       }
8879       default: {
8880         if (this._circle == null) this._circle = circle$1(this._radius);
8881         this._string.push("M", x, ",", y, this._circle);
8882         break;
8883       }
8884     }
8885   },
8886   result: function() {
8887     if (this._string.length) {
8888       var result = this._string.join("");
8889       this._string = [];
8890       return result;
8891     } else {
8892       return null;
8893     }
8894   }
8895 };
8896
8897 function circle$1(radius) {
8898   return "m0," + radius
8899       + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius
8900       + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius
8901       + "z";
8902 }
8903
8904 function d3_geoPath(projection, context) {
8905   var pointRadius = 4.5,
8906       projectionStream,
8907       contextStream;
8908
8909   function path(object) {
8910     if (object) {
8911       if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments));
8912       d3_geoStream(object, projectionStream(contextStream));
8913     }
8914     return contextStream.result();
8915   }
8916
8917   path.area = function(object) {
8918     d3_geoStream(object, projectionStream(areaStream$1));
8919     return areaStream$1.result();
8920   };
8921
8922   path.measure = function(object) {
8923     d3_geoStream(object, projectionStream(lengthStream$1));
8924     return lengthStream$1.result();
8925   };
8926
8927   path.bounds = function(object) {
8928     d3_geoStream(object, projectionStream(boundsStream$1));
8929     return boundsStream$1.result();
8930   };
8931
8932   path.centroid = function(object) {
8933     d3_geoStream(object, projectionStream(centroidStream$1));
8934     return centroidStream$1.result();
8935   };
8936
8937   path.projection = function(_) {
8938     return arguments.length ? (projectionStream = _ == null ? (projection = null, identity$4) : (projection = _).stream, path) : projection;
8939   };
8940
8941   path.context = function(_) {
8942     if (!arguments.length) return context;
8943     contextStream = _ == null ? (context = null, new PathString) : new PathContext(context = _);
8944     if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius);
8945     return path;
8946   };
8947
8948   path.pointRadius = function(_) {
8949     if (!arguments.length) return pointRadius;
8950     pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_);
8951     return path;
8952   };
8953
8954   return path.projection(projection).context(context);
8955 }
8956
8957 function d3_geoTransform(methods) {
8958   return {
8959     stream: transformer(methods)
8960   };
8961 }
8962
8963 function transformer(methods) {
8964   return function(stream) {
8965     var s = new TransformStream;
8966     for (var key in methods) s[key] = methods[key];
8967     s.stream = stream;
8968     return s;
8969   };
8970 }
8971
8972 function TransformStream() {}
8973
8974 TransformStream.prototype = {
8975   constructor: TransformStream,
8976   point: function(x, y) { this.stream.point(x, y); },
8977   sphere: function() { this.stream.sphere(); },
8978   lineStart: function() { this.stream.lineStart(); },
8979   lineEnd: function() { this.stream.lineEnd(); },
8980   polygonStart: function() { this.stream.polygonStart(); },
8981   polygonEnd: function() { this.stream.polygonEnd(); }
8982 };
8983
8984 function fit(projection, fitBounds, object) {
8985   var clip = projection.clipExtent && projection.clipExtent();
8986   projection.scale(150).translate([0, 0]);
8987   if (clip != null) projection.clipExtent(null);
8988   d3_geoStream(object, projection.stream(boundsStream$1));
8989   fitBounds(boundsStream$1.result());
8990   if (clip != null) projection.clipExtent(clip);
8991   return projection;
8992 }
8993
8994 function fitExtent(projection, extent, object) {
8995   return fit(projection, function(b) {
8996     var w = extent[1][0] - extent[0][0],
8997         h = extent[1][1] - extent[0][1],
8998         k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])),
8999         x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2,
9000         y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2;
9001     projection.scale(150 * k).translate([x, y]);
9002   }, object);
9003 }
9004
9005 function fitSize(projection, size, object) {
9006   return fitExtent(projection, [[0, 0], size], object);
9007 }
9008
9009 function fitWidth(projection, width, object) {
9010   return fit(projection, function(b) {
9011     var w = +width,
9012         k = w / (b[1][0] - b[0][0]),
9013         x = (w - k * (b[1][0] + b[0][0])) / 2,
9014         y = -k * b[0][1];
9015     projection.scale(150 * k).translate([x, y]);
9016   }, object);
9017 }
9018
9019 function fitHeight(projection, height, object) {
9020   return fit(projection, function(b) {
9021     var h = +height,
9022         k = h / (b[1][1] - b[0][1]),
9023         x = -k * b[0][0],
9024         y = (h - k * (b[1][1] + b[0][1])) / 2;
9025     projection.scale(150 * k).translate([x, y]);
9026   }, object);
9027 }
9028
9029 var maxDepth = 16;
9030 var cosMinDistance = cos$1(30 * radians); // cos(minimum angular distance)
9031
9032 function resample(project, delta2) {
9033   return +delta2 ? resample$1(project, delta2) : resampleNone(project);
9034 }
9035
9036 function resampleNone(project) {
9037   return transformer({
9038     point: function(x, y) {
9039       x = project(x, y);
9040       this.stream.point(x[0], x[1]);
9041     }
9042   });
9043 }
9044
9045 function resample$1(project, delta2) {
9046
9047   function resampleLineTo(x0, y0, lambda0, a0, b0, c0, x1, y1, lambda1, a1, b1, c1, depth, stream) {
9048     var dx = x1 - x0,
9049         dy = y1 - y0,
9050         d2 = dx * dx + dy * dy;
9051     if (d2 > 4 * delta2 && depth--) {
9052       var a = a0 + a1,
9053           b = b0 + b1,
9054           c = c0 + c1,
9055           m = sqrt(a * a + b * b + c * c),
9056           phi2 = asin(c /= m),
9057           lambda2 = abs(abs(c) - 1) < epsilon$2 || abs(lambda0 - lambda1) < epsilon$2 ? (lambda0 + lambda1) / 2 : atan2(b, a),
9058           p = project(lambda2, phi2),
9059           x2 = p[0],
9060           y2 = p[1],
9061           dx2 = x2 - x0,
9062           dy2 = y2 - y0,
9063           dz = dy * dx2 - dx * dy2;
9064       if (dz * dz / d2 > delta2 // perpendicular projected distance
9065           || abs((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 // midpoint close to an end
9066           || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance
9067         resampleLineTo(x0, y0, lambda0, a0, b0, c0, x2, y2, lambda2, a /= m, b /= m, c, depth, stream);
9068         stream.point(x2, y2);
9069         resampleLineTo(x2, y2, lambda2, a, b, c, x1, y1, lambda1, a1, b1, c1, depth, stream);
9070       }
9071     }
9072   }
9073   return function(stream) {
9074     var lambda00, x00, y00, a00, b00, c00, // first point
9075         lambda0, x0, y0, a0, b0, c0; // previous point
9076
9077     var resampleStream = {
9078       point: point,
9079       lineStart: lineStart,
9080       lineEnd: lineEnd,
9081       polygonStart: function() { stream.polygonStart(); resampleStream.lineStart = ringStart; },
9082       polygonEnd: function() { stream.polygonEnd(); resampleStream.lineStart = lineStart; }
9083     };
9084
9085     function point(x, y) {
9086       x = project(x, y);
9087       stream.point(x[0], x[1]);
9088     }
9089
9090     function lineStart() {
9091       x0 = NaN;
9092       resampleStream.point = linePoint;
9093       stream.lineStart();
9094     }
9095
9096     function linePoint(lambda, phi) {
9097       var c = cartesian([lambda, phi]), p = project(lambda, phi);
9098       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);
9099       stream.point(x0, y0);
9100     }
9101
9102     function lineEnd() {
9103       resampleStream.point = point;
9104       stream.lineEnd();
9105     }
9106
9107     function ringStart() {
9108       lineStart();
9109       resampleStream.point = ringPoint;
9110       resampleStream.lineEnd = ringEnd;
9111     }
9112
9113     function ringPoint(lambda, phi) {
9114       linePoint(lambda00 = lambda, phi), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;
9115       resampleStream.point = linePoint;
9116     }
9117
9118     function ringEnd() {
9119       resampleLineTo(x0, y0, lambda0, a0, b0, c0, x00, y00, lambda00, a00, b00, c00, maxDepth, stream);
9120       resampleStream.lineEnd = lineEnd;
9121       lineEnd();
9122     }
9123
9124     return resampleStream;
9125   };
9126 }
9127
9128 var transformRadians = transformer({
9129   point: function(x, y) {
9130     this.stream.point(x * radians, y * radians);
9131   }
9132 });
9133
9134 function transformRotate(rotate) {
9135   return transformer({
9136     point: function(x, y) {
9137       var r = rotate(x, y);
9138       return this.stream.point(r[0], r[1]);
9139     }
9140   });
9141 }
9142
9143 function projection(project) {
9144   return projectionMutator(function() { return project; })();
9145 }
9146
9147 function projectionMutator(projectAt) {
9148   var project,
9149       k = 150, // scale
9150       x = 480, y = 250, // translate
9151       dx, dy, lambda = 0, phi = 0, // center
9152       deltaLambda = 0, deltaPhi = 0, deltaGamma = 0, rotate, projectRotate, // rotate
9153       theta = null, preclip = clipAntimeridian, // clip angle
9154       x0 = null, y0, x1, y1, postclip = identity$4, // clip extent
9155       delta2 = 0.5, projectResample = resample(projectTransform, delta2), // precision
9156       cache,
9157       cacheStream;
9158
9159   function projection(point) {
9160     point = projectRotate(point[0] * radians, point[1] * radians);
9161     return [point[0] * k + dx, dy - point[1] * k];
9162   }
9163
9164   function invert(point) {
9165     point = projectRotate.invert((point[0] - dx) / k, (dy - point[1]) / k);
9166     return point && [point[0] * degrees$1, point[1] * degrees$1];
9167   }
9168
9169   function projectTransform(x, y) {
9170     return x = project(x, y), [x[0] * k + dx, dy - x[1] * k];
9171   }
9172
9173   projection.stream = function(stream) {
9174     return cache && cacheStream === stream ? cache : cache = transformRadians(transformRotate(rotate)(preclip(projectResample(postclip(cacheStream = stream)))));
9175   };
9176
9177   projection.preclip = function(_) {
9178     return arguments.length ? (preclip = _, theta = undefined, reset()) : preclip;
9179   };
9180
9181   projection.postclip = function(_) {
9182     return arguments.length ? (postclip = _, x0 = y0 = x1 = y1 = null, reset()) : postclip;
9183   };
9184
9185   projection.clipAngle = function(_) {
9186     return arguments.length ? (preclip = +_ ? clipCircle(theta = _ * radians) : (theta = null, clipAntimeridian), reset()) : theta * degrees$1;
9187   };
9188
9189   projection.clipExtent = function(_) {
9190     return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$4) : clipRectangle(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];
9191   };
9192
9193   projection.scale = function(_) {
9194     return arguments.length ? (k = +_, recenter()) : k;
9195   };
9196
9197   projection.translate = function(_) {
9198     return arguments.length ? (x = +_[0], y = +_[1], recenter()) : [x, y];
9199   };
9200
9201   projection.center = function(_) {
9202     return arguments.length ? (lambda = _[0] % 360 * radians, phi = _[1] % 360 * radians, recenter()) : [lambda * degrees$1, phi * degrees$1];
9203   };
9204
9205   projection.rotate = function(_) {
9206     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];
9207   };
9208
9209   projection.precision = function(_) {
9210     return arguments.length ? (projectResample = resample(projectTransform, delta2 = _ * _), reset()) : sqrt(delta2);
9211   };
9212
9213   projection.fitExtent = function(extent, object) {
9214     return fitExtent(projection, extent, object);
9215   };
9216
9217   projection.fitSize = function(size, object) {
9218     return fitSize(projection, size, object);
9219   };
9220
9221   projection.fitWidth = function(width, object) {
9222     return fitWidth(projection, width, object);
9223   };
9224
9225   projection.fitHeight = function(height, object) {
9226     return fitHeight(projection, height, object);
9227   };
9228
9229   function recenter() {
9230     projectRotate = compose(rotate = rotateRadians(deltaLambda, deltaPhi, deltaGamma), project);
9231     var center = project(lambda, phi);
9232     dx = x - center[0] * k;
9233     dy = y + center[1] * k;
9234     return reset();
9235   }
9236
9237   function reset() {
9238     cache = cacheStream = null;
9239     return projection;
9240   }
9241
9242   return function() {
9243     project = projectAt.apply(this, arguments);
9244     projection.invert = project.invert && invert;
9245     return recenter();
9246   };
9247 }
9248
9249 function conicProjection(projectAt) {
9250   var phi0 = 0,
9251       phi1 = pi$3 / 3,
9252       m = projectionMutator(projectAt),
9253       p = m(phi0, phi1);
9254
9255   p.parallels = function(_) {
9256     return arguments.length ? m(phi0 = _[0] * radians, phi1 = _[1] * radians) : [phi0 * degrees$1, phi1 * degrees$1];
9257   };
9258
9259   return p;
9260 }
9261
9262 function cylindricalEqualAreaRaw(phi0) {
9263   var cosPhi0 = cos$1(phi0);
9264
9265   function forward(lambda, phi) {
9266     return [lambda * cosPhi0, sin$1(phi) / cosPhi0];
9267   }
9268
9269   forward.invert = function(x, y) {
9270     return [x / cosPhi0, asin(y * cosPhi0)];
9271   };
9272
9273   return forward;
9274 }
9275
9276 function conicEqualAreaRaw(y0, y1) {
9277   var sy0 = sin$1(y0), n = (sy0 + sin$1(y1)) / 2;
9278
9279   // Are the parallels symmetrical around the Equator?
9280   if (abs(n) < epsilon$2) return cylindricalEqualAreaRaw(y0);
9281
9282   var c = 1 + sy0 * (2 * n - sy0), r0 = sqrt(c) / n;
9283
9284   function project(x, y) {
9285     var r = sqrt(c - 2 * n * sin$1(y)) / n;
9286     return [r * sin$1(x *= n), r0 - r * cos$1(x)];
9287   }
9288
9289   project.invert = function(x, y) {
9290     var r0y = r0 - y;
9291     return [atan2(x, abs(r0y)) / n * sign(r0y), asin((c - (x * x + r0y * r0y) * n * n) / (2 * n))];
9292   };
9293
9294   return project;
9295 }
9296
9297 function conicEqualArea() {
9298   return conicProjection(conicEqualAreaRaw)
9299       .scale(155.424)
9300       .center([0, 33.6442]);
9301 }
9302
9303 function albers() {
9304   return conicEqualArea()
9305       .parallels([29.5, 45.5])
9306       .scale(1070)
9307       .translate([480, 250])
9308       .rotate([96, 0])
9309       .center([-0.6, 38.7]);
9310 }
9311
9312 // The projections must have mutually exclusive clip regions on the sphere,
9313 // as this will avoid emitting interleaving lines and polygons.
9314 function multiplex(streams) {
9315   var n = streams.length;
9316   return {
9317     point: function(x, y) { var i = -1; while (++i < n) streams[i].point(x, y); },
9318     sphere: function() { var i = -1; while (++i < n) streams[i].sphere(); },
9319     lineStart: function() { var i = -1; while (++i < n) streams[i].lineStart(); },
9320     lineEnd: function() { var i = -1; while (++i < n) streams[i].lineEnd(); },
9321     polygonStart: function() { var i = -1; while (++i < n) streams[i].polygonStart(); },
9322     polygonEnd: function() { var i = -1; while (++i < n) streams[i].polygonEnd(); }
9323   };
9324 }
9325
9326 // A composite projection for the United States, configured by default for
9327 // 960×500. The projection also works quite well at 960×600 if you change the
9328 // scale to 1285 and adjust the translate accordingly. The set of standard
9329 // parallels for each region comes from USGS, which is published here:
9330 // http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers
9331 function albersUsa() {
9332   var cache,
9333       cacheStream,
9334       lower48 = albers(), lower48Point,
9335       alaska = conicEqualArea().rotate([154, 0]).center([-2, 58.5]).parallels([55, 65]), alaskaPoint, // EPSG:3338
9336       hawaii = conicEqualArea().rotate([157, 0]).center([-3, 19.9]).parallels([8, 18]), hawaiiPoint, // ESRI:102007
9337       point, pointStream = {point: function(x, y) { point = [x, y]; }};
9338
9339   function albersUsa(coordinates) {
9340     var x = coordinates[0], y = coordinates[1];
9341     return point = null, (lower48Point.point(x, y), point)
9342         || (alaskaPoint.point(x, y), point)
9343         || (hawaiiPoint.point(x, y), point);
9344   }
9345
9346   albersUsa.invert = function(coordinates) {
9347     var k = lower48.scale(),
9348         t = lower48.translate(),
9349         x = (coordinates[0] - t[0]) / k,
9350         y = (coordinates[1] - t[1]) / k;
9351     return (y >= 0.120 && y < 0.234 && x >= -0.425 && x < -0.214 ? alaska
9352         : y >= 0.166 && y < 0.234 && x >= -0.214 && x < -0.115 ? hawaii
9353         : lower48).invert(coordinates);
9354   };
9355
9356   albersUsa.stream = function(stream) {
9357     return cache && cacheStream === stream ? cache : cache = multiplex([lower48.stream(cacheStream = stream), alaska.stream(stream), hawaii.stream(stream)]);
9358   };
9359
9360   albersUsa.precision = function(_) {
9361     if (!arguments.length) return lower48.precision();
9362     lower48.precision(_), alaska.precision(_), hawaii.precision(_);
9363     return reset();
9364   };
9365
9366   albersUsa.scale = function(_) {
9367     if (!arguments.length) return lower48.scale();
9368     lower48.scale(_), alaska.scale(_ * 0.35), hawaii.scale(_);
9369     return albersUsa.translate(lower48.translate());
9370   };
9371
9372   albersUsa.translate = function(_) {
9373     if (!arguments.length) return lower48.translate();
9374     var k = lower48.scale(), x = +_[0], y = +_[1];
9375
9376     lower48Point = lower48
9377         .translate(_)
9378         .clipExtent([[x - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.238 * k]])
9379         .stream(pointStream);
9380
9381     alaskaPoint = alaska
9382         .translate([x - 0.307 * k, y + 0.201 * k])
9383         .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]])
9384         .stream(pointStream);
9385
9386     hawaiiPoint = hawaii
9387         .translate([x - 0.205 * k, y + 0.212 * k])
9388         .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]])
9389         .stream(pointStream);
9390
9391     return reset();
9392   };
9393
9394   albersUsa.fitExtent = function(extent, object) {
9395     return fitExtent(albersUsa, extent, object);
9396   };
9397
9398   albersUsa.fitSize = function(size, object) {
9399     return fitSize(albersUsa, size, object);
9400   };
9401
9402   albersUsa.fitWidth = function(width, object) {
9403     return fitWidth(albersUsa, width, object);
9404   };
9405
9406   albersUsa.fitHeight = function(height, object) {
9407     return fitHeight(albersUsa, height, object);
9408   };
9409
9410   function reset() {
9411     cache = cacheStream = null;
9412     return albersUsa;
9413   }
9414
9415   return albersUsa.scale(1070);
9416 }
9417
9418 function azimuthalRaw(scale) {
9419   return function(x, y) {
9420     var cx = cos$1(x),
9421         cy = cos$1(y),
9422         k = scale(cx * cy);
9423     return [
9424       k * cy * sin$1(x),
9425       k * sin$1(y)
9426     ];
9427   }
9428 }
9429
9430 function azimuthalInvert(angle) {
9431   return function(x, y) {
9432     var z = sqrt(x * x + y * y),
9433         c = angle(z),
9434         sc = sin$1(c),
9435         cc = cos$1(c);
9436     return [
9437       atan2(x * sc, z * cc),
9438       asin(z && y * sc / z)
9439     ];
9440   }
9441 }
9442
9443 var azimuthalEqualAreaRaw = azimuthalRaw(function(cxcy) {
9444   return sqrt(2 / (1 + cxcy));
9445 });
9446
9447 azimuthalEqualAreaRaw.invert = azimuthalInvert(function(z) {
9448   return 2 * asin(z / 2);
9449 });
9450
9451 function azimuthalEqualArea() {
9452   return projection(azimuthalEqualAreaRaw)
9453       .scale(124.75)
9454       .clipAngle(180 - 1e-3);
9455 }
9456
9457 var azimuthalEquidistantRaw = azimuthalRaw(function(c) {
9458   return (c = acos(c)) && c / sin$1(c);
9459 });
9460
9461 azimuthalEquidistantRaw.invert = azimuthalInvert(function(z) {
9462   return z;
9463 });
9464
9465 function azimuthalEquidistant() {
9466   return projection(azimuthalEquidistantRaw)
9467       .scale(79.4188)
9468       .clipAngle(180 - 1e-3);
9469 }
9470
9471 function mercatorRaw(lambda, phi) {
9472   return [lambda, log(tan((halfPi$2 + phi) / 2))];
9473 }
9474
9475 mercatorRaw.invert = function(x, y) {
9476   return [x, 2 * atan(exp(y)) - halfPi$2];
9477 };
9478
9479 function mercator() {
9480   return mercatorProjection(mercatorRaw)
9481       .scale(961 / tau$3);
9482 }
9483
9484 function mercatorProjection(project) {
9485   var m = projection(project),
9486       center = m.center,
9487       scale = m.scale,
9488       translate = m.translate,
9489       clipExtent = m.clipExtent,
9490       x0 = null, y0, x1, y1; // clip extent
9491
9492   m.scale = function(_) {
9493     return arguments.length ? (scale(_), reclip()) : scale();
9494   };
9495
9496   m.translate = function(_) {
9497     return arguments.length ? (translate(_), reclip()) : translate();
9498   };
9499
9500   m.center = function(_) {
9501     return arguments.length ? (center(_), reclip()) : center();
9502   };
9503
9504   m.clipExtent = function(_) {
9505     return arguments.length ? (_ == null ? x0 = y0 = x1 = y1 = null : (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reclip()) : x0 == null ? null : [[x0, y0], [x1, y1]];
9506   };
9507
9508   function reclip() {
9509     var k = pi$3 * scale(),
9510         t = m(rotation(m.rotate()).invert([0, 0]));
9511     return clipExtent(x0 == null
9512         ? [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]] : project === mercatorRaw
9513         ? [[Math.max(t[0] - k, x0), y0], [Math.min(t[0] + k, x1), y1]]
9514         : [[x0, Math.max(t[1] - k, y0)], [x1, Math.min(t[1] + k, y1)]]);
9515   }
9516
9517   return reclip();
9518 }
9519
9520 function tany(y) {
9521   return tan((halfPi$2 + y) / 2);
9522 }
9523
9524 function conicConformalRaw(y0, y1) {
9525   var cy0 = cos$1(y0),
9526       n = y0 === y1 ? sin$1(y0) : log(cy0 / cos$1(y1)) / log(tany(y1) / tany(y0)),
9527       f = cy0 * pow(tany(y0), n) / n;
9528
9529   if (!n) return mercatorRaw;
9530
9531   function project(x, y) {
9532     if (f > 0) { if (y < -halfPi$2 + epsilon$2) y = -halfPi$2 + epsilon$2; }
9533     else { if (y > halfPi$2 - epsilon$2) y = halfPi$2 - epsilon$2; }
9534     var r = f / pow(tany(y), n);
9535     return [r * sin$1(n * x), f - r * cos$1(n * x)];
9536   }
9537
9538   project.invert = function(x, y) {
9539     var fy = f - y, r = sign(n) * sqrt(x * x + fy * fy);
9540     return [atan2(x, abs(fy)) / n * sign(fy), 2 * atan(pow(f / r, 1 / n)) - halfPi$2];
9541   };
9542
9543   return project;
9544 }
9545
9546 function conicConformal() {
9547   return conicProjection(conicConformalRaw)
9548       .scale(109.5)
9549       .parallels([30, 30]);
9550 }
9551
9552 function equirectangularRaw(lambda, phi) {
9553   return [lambda, phi];
9554 }
9555
9556 equirectangularRaw.invert = equirectangularRaw;
9557
9558 function equirectangular() {
9559   return projection(equirectangularRaw)
9560       .scale(152.63);
9561 }
9562
9563 function conicEquidistantRaw(y0, y1) {
9564   var cy0 = cos$1(y0),
9565       n = y0 === y1 ? sin$1(y0) : (cy0 - cos$1(y1)) / (y1 - y0),
9566       g = cy0 / n + y0;
9567
9568   if (abs(n) < epsilon$2) return equirectangularRaw;
9569
9570   function project(x, y) {
9571     var gy = g - y, nx = n * x;
9572     return [gy * sin$1(nx), g - gy * cos$1(nx)];
9573   }
9574
9575   project.invert = function(x, y) {
9576     var gy = g - y;
9577     return [atan2(x, abs(gy)) / n * sign(gy), g - sign(n) * sqrt(x * x + gy * gy)];
9578   };
9579
9580   return project;
9581 }
9582
9583 function conicEquidistant() {
9584   return conicProjection(conicEquidistantRaw)
9585       .scale(131.154)
9586       .center([0, 13.9389]);
9587 }
9588
9589 function gnomonicRaw(x, y) {
9590   var cy = cos$1(y), k = cos$1(x) * cy;
9591   return [cy * sin$1(x) / k, sin$1(y) / k];
9592 }
9593
9594 gnomonicRaw.invert = azimuthalInvert(atan);
9595
9596 function gnomonic() {
9597   return projection(gnomonicRaw)
9598       .scale(144.049)
9599       .clipAngle(60);
9600 }
9601
9602 function scaleTranslate(kx, ky, tx, ty) {
9603   return kx === 1 && ky === 1 && tx === 0 && ty === 0 ? identity$4 : transformer({
9604     point: function(x, y) {
9605       this.stream.point(x * kx + tx, y * ky + ty);
9606     }
9607   });
9608 }
9609
9610 function d3_geoIdentity() {
9611   var k = 1, tx = 0, ty = 0, sx = 1, sy = 1, transform = identity$4, // scale, translate and reflect
9612       x0 = null, y0, x1, y1, // clip extent
9613       postclip = identity$4,
9614       cache,
9615       cacheStream,
9616       projection;
9617
9618   function reset() {
9619     cache = cacheStream = null;
9620     return projection;
9621   }
9622
9623   return projection = {
9624     stream: function(stream) {
9625       return cache && cacheStream === stream ? cache : cache = transform(postclip(cacheStream = stream));
9626     },
9627     postclip: function(_) {
9628       return arguments.length ? (postclip = _, x0 = y0 = x1 = y1 = null, reset()) : postclip;
9629     },
9630     clipExtent: function(_) {
9631       return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$4) : clipRectangle(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];
9632     },
9633     scale: function(_) {
9634       return arguments.length ? (transform = scaleTranslate((k = +_) * sx, k * sy, tx, ty), reset()) : k;
9635     },
9636     translate: function(_) {
9637       return arguments.length ? (transform = scaleTranslate(k * sx, k * sy, tx = +_[0], ty = +_[1]), reset()) : [tx, ty];
9638     },
9639     reflectX: function(_) {
9640       return arguments.length ? (transform = scaleTranslate(k * (sx = _ ? -1 : 1), k * sy, tx, ty), reset()) : sx < 0;
9641     },
9642     reflectY: function(_) {
9643       return arguments.length ? (transform = scaleTranslate(k * sx, k * (sy = _ ? -1 : 1), tx, ty), reset()) : sy < 0;
9644     },
9645     fitExtent: function(extent, object) {
9646       return fitExtent(projection, extent, object);
9647     },
9648     fitSize: function(size, object) {
9649       return fitSize(projection, size, object);
9650     },
9651     fitWidth: function(width, object) {
9652       return fitWidth(projection, width, object);
9653     },
9654     fitHeight: function(height, object) {
9655       return fitHeight(projection, height, object);
9656     }
9657   };
9658 }
9659
9660 function naturalEarth1Raw(lambda, phi) {
9661   var phi2 = phi * phi, phi4 = phi2 * phi2;
9662   return [
9663     lambda * (0.8707 - 0.131979 * phi2 + phi4 * (-0.013791 + phi4 * (0.003971 * phi2 - 0.001529 * phi4))),
9664     phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4)))
9665   ];
9666 }
9667
9668 naturalEarth1Raw.invert = function(x, y) {
9669   var phi = y, i = 25, delta;
9670   do {
9671     var phi2 = phi * phi, phi4 = phi2 * phi2;
9672     phi -= delta = (phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4))) - y) /
9673         (1.007226 + phi2 * (0.015085 * 3 + phi4 * (-0.044475 * 7 + 0.028874 * 9 * phi2 - 0.005916 * 11 * phi4)));
9674   } while (abs(delta) > epsilon$2 && --i > 0);
9675   return [
9676     x / (0.8707 + (phi2 = phi * phi) * (-0.131979 + phi2 * (-0.013791 + phi2 * phi2 * phi2 * (0.003971 - 0.001529 * phi2)))),
9677     phi
9678   ];
9679 };
9680
9681 function naturalEarth1() {
9682   return projection(naturalEarth1Raw)
9683       .scale(175.295);
9684 }
9685
9686 function orthographicRaw(x, y) {
9687   return [cos$1(y) * sin$1(x), sin$1(y)];
9688 }
9689
9690 orthographicRaw.invert = azimuthalInvert(asin);
9691
9692 function orthographic() {
9693   return projection(orthographicRaw)
9694       .scale(249.5)
9695       .clipAngle(90 + epsilon$2);
9696 }
9697
9698 function stereographicRaw(x, y) {
9699   var cy = cos$1(y), k = 1 + cos$1(x) * cy;
9700   return [cy * sin$1(x) / k, sin$1(y) / k];
9701 }
9702
9703 stereographicRaw.invert = azimuthalInvert(function(z) {
9704   return 2 * atan(z);
9705 });
9706
9707 function stereographic() {
9708   return projection(stereographicRaw)
9709       .scale(250)
9710       .clipAngle(142);
9711 }
9712
9713 function transverseMercatorRaw(lambda, phi) {
9714   return [log(tan((halfPi$2 + phi) / 2)), -lambda];
9715 }
9716
9717 transverseMercatorRaw.invert = function(x, y) {
9718   return [-y, 2 * atan(exp(x)) - halfPi$2];
9719 };
9720
9721 function transverseMercator() {
9722   var m = mercatorProjection(transverseMercatorRaw),
9723       center = m.center,
9724       rotate = m.rotate;
9725
9726   m.center = function(_) {
9727     return arguments.length ? center([-_[1], _[0]]) : (_ = center(), [_[1], -_[0]]);
9728   };
9729
9730   m.rotate = function(_) {
9731     return arguments.length ? rotate([_[0], _[1], _.length > 2 ? _[2] + 90 : 90]) : (_ = rotate(), [_[0], _[1], _[2] - 90]);
9732   };
9733
9734   return rotate([0, 0, 90])
9735       .scale(159.155);
9736 }
9737
9738 function defaultSeparation(a, b) {
9739   return a.parent === b.parent ? 1 : 2;
9740 }
9741
9742 function meanX(children) {
9743   return children.reduce(meanXReduce, 0) / children.length;
9744 }
9745
9746 function meanXReduce(x, c) {
9747   return x + c.x;
9748 }
9749
9750 function maxY(children) {
9751   return 1 + children.reduce(maxYReduce, 0);
9752 }
9753
9754 function maxYReduce(y, c) {
9755   return Math.max(y, c.y);
9756 }
9757
9758 function leafLeft(node) {
9759   var children;
9760   while (children = node.children) node = children[0];
9761   return node;
9762 }
9763
9764 function leafRight(node) {
9765   var children;
9766   while (children = node.children) node = children[children.length - 1];
9767   return node;
9768 }
9769
9770 function cluster() {
9771   var separation = defaultSeparation,
9772       dx = 1,
9773       dy = 1,
9774       nodeSize = false;
9775
9776   function cluster(root) {
9777     var previousNode,
9778         x = 0;
9779
9780     // First walk, computing the initial x & y values.
9781     root.eachAfter(function(node) {
9782       var children = node.children;
9783       if (children) {
9784         node.x = meanX(children);
9785         node.y = maxY(children);
9786       } else {
9787         node.x = previousNode ? x += separation(node, previousNode) : 0;
9788         node.y = 0;
9789         previousNode = node;
9790       }
9791     });
9792
9793     var left = leafLeft(root),
9794         right = leafRight(root),
9795         x0 = left.x - separation(left, right) / 2,
9796         x1 = right.x + separation(right, left) / 2;
9797
9798     // Second walk, normalizing x & y to the desired size.
9799     return root.eachAfter(nodeSize ? function(node) {
9800       node.x = (node.x - root.x) * dx;
9801       node.y = (root.y - node.y) * dy;
9802     } : function(node) {
9803       node.x = (node.x - x0) / (x1 - x0) * dx;
9804       node.y = (1 - (root.y ? node.y / root.y : 1)) * dy;
9805     });
9806   }
9807
9808   cluster.separation = function(x) {
9809     return arguments.length ? (separation = x, cluster) : separation;
9810   };
9811
9812   cluster.size = function(x) {
9813     return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? null : [dx, dy]);
9814   };
9815
9816   cluster.nodeSize = function(x) {
9817     return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? [dx, dy] : null);
9818   };
9819
9820   return cluster;
9821 }
9822
9823 function count(node) {
9824   var sum = 0,
9825       children = node.children,
9826       i = children && children.length;
9827   if (!i) sum = 1;
9828   else while (--i >= 0) sum += children[i].value;
9829   node.value = sum;
9830 }
9831
9832 function node_count() {
9833   return this.eachAfter(count);
9834 }
9835
9836 function node_each(callback) {
9837   var node = this, current, next = [node], children, i, n;
9838   do {
9839     current = next.reverse(), next = [];
9840     while (node = current.pop()) {
9841       callback(node), children = node.children;
9842       if (children) for (i = 0, n = children.length; i < n; ++i) {
9843         next.push(children[i]);
9844       }
9845     }
9846   } while (next.length);
9847   return this;
9848 }
9849
9850 function node_eachBefore(callback) {
9851   var node = this, nodes = [node], children, i;
9852   while (node = nodes.pop()) {
9853     callback(node), children = node.children;
9854     if (children) for (i = children.length - 1; i >= 0; --i) {
9855       nodes.push(children[i]);
9856     }
9857   }
9858   return this;
9859 }
9860
9861 function node_eachAfter(callback) {
9862   var node = this, nodes = [node], next = [], children, i, n;
9863   while (node = nodes.pop()) {
9864     next.push(node), children = node.children;
9865     if (children) for (i = 0, n = children.length; i < n; ++i) {
9866       nodes.push(children[i]);
9867     }
9868   }
9869   while (node = next.pop()) {
9870     callback(node);
9871   }
9872   return this;
9873 }
9874
9875 function node_sum(value) {
9876   return this.eachAfter(function(node) {
9877     var sum = +value(node.data) || 0,
9878         children = node.children,
9879         i = children && children.length;
9880     while (--i >= 0) sum += children[i].value;
9881     node.value = sum;
9882   });
9883 }
9884
9885 function node_sort(compare) {
9886   return this.eachBefore(function(node) {
9887     if (node.children) {
9888       node.children.sort(compare);
9889     }
9890   });
9891 }
9892
9893 function node_path(end) {
9894   var start = this,
9895       ancestor = leastCommonAncestor(start, end),
9896       nodes = [start];
9897   while (start !== ancestor) {
9898     start = start.parent;
9899     nodes.push(start);
9900   }
9901   var k = nodes.length;
9902   while (end !== ancestor) {
9903     nodes.splice(k, 0, end);
9904     end = end.parent;
9905   }
9906   return nodes;
9907 }
9908
9909 function leastCommonAncestor(a, b) {
9910   if (a === b) return a;
9911   var aNodes = a.ancestors(),
9912       bNodes = b.ancestors(),
9913       c = null;
9914   a = aNodes.pop();
9915   b = bNodes.pop();
9916   while (a === b) {
9917     c = a;
9918     a = aNodes.pop();
9919     b = bNodes.pop();
9920   }
9921   return c;
9922 }
9923
9924 function node_ancestors() {
9925   var node = this, nodes = [node];
9926   while (node = node.parent) {
9927     nodes.push(node);
9928   }
9929   return nodes;
9930 }
9931
9932 function node_descendants() {
9933   var nodes = [];
9934   this.each(function(node) {
9935     nodes.push(node);
9936   });
9937   return nodes;
9938 }
9939
9940 function node_leaves() {
9941   var leaves = [];
9942   this.eachBefore(function(node) {
9943     if (!node.children) {
9944       leaves.push(node);
9945     }
9946   });
9947   return leaves;
9948 }
9949
9950 function node_links() {
9951   var root = this, links = [];
9952   root.each(function(node) {
9953     if (node !== root) { // Don’t include the root’s parent, if any.
9954       links.push({source: node.parent, target: node});
9955     }
9956   });
9957   return links;
9958 }
9959
9960 function hierarchy(data, children) {
9961   var root = new Node(data),
9962       valued = +data.value && (root.value = data.value),
9963       node,
9964       nodes = [root],
9965       child,
9966       childs,
9967       i,
9968       n;
9969
9970   if (children == null) children = defaultChildren;
9971
9972   while (node = nodes.pop()) {
9973     if (valued) node.value = +node.data.value;
9974     if ((childs = children(node.data)) && (n = childs.length)) {
9975       node.children = new Array(n);
9976       for (i = n - 1; i >= 0; --i) {
9977         nodes.push(child = node.children[i] = new Node(childs[i]));
9978         child.parent = node;
9979         child.depth = node.depth + 1;
9980       }
9981     }
9982   }
9983
9984   return root.eachBefore(computeHeight);
9985 }
9986
9987 function node_copy() {
9988   return hierarchy(this).eachBefore(copyData);
9989 }
9990
9991 function defaultChildren(d) {
9992   return d.children;
9993 }
9994
9995 function copyData(node) {
9996   node.data = node.data.data;
9997 }
9998
9999 function computeHeight(node) {
10000   var height = 0;
10001   do node.height = height;
10002   while ((node = node.parent) && (node.height < ++height));
10003 }
10004
10005 function Node(data) {
10006   this.data = data;
10007   this.depth =
10008   this.height = 0;
10009   this.parent = null;
10010 }
10011
10012 Node.prototype = hierarchy.prototype = {
10013   constructor: Node,
10014   count: node_count,
10015   each: node_each,
10016   eachAfter: node_eachAfter,
10017   eachBefore: node_eachBefore,
10018   sum: node_sum,
10019   sort: node_sort,
10020   path: node_path,
10021   ancestors: node_ancestors,
10022   descendants: node_descendants,
10023   leaves: node_leaves,
10024   links: node_links,
10025   copy: node_copy
10026 };
10027
10028 var slice$3 = Array.prototype.slice;
10029
10030 function shuffle$1(array) {
10031   var m = array.length,
10032       t,
10033       i;
10034
10035   while (m) {
10036     i = Math.random() * m-- | 0;
10037     t = array[m];
10038     array[m] = array[i];
10039     array[i] = t;
10040   }
10041
10042   return array;
10043 }
10044
10045 function enclose(circles) {
10046   var i = 0, n = (circles = shuffle$1(slice$3.call(circles))).length, B = [], p, e;
10047
10048   while (i < n) {
10049     p = circles[i];
10050     if (e && enclosesWeak(e, p)) ++i;
10051     else e = encloseBasis(B = extendBasis(B, p)), i = 0;
10052   }
10053
10054   return e;
10055 }
10056
10057 function extendBasis(B, p) {
10058   var i, j;
10059
10060   if (enclosesWeakAll(p, B)) return [p];
10061
10062   // If we get here then B must have at least one element.
10063   for (i = 0; i < B.length; ++i) {
10064     if (enclosesNot(p, B[i])
10065         && enclosesWeakAll(encloseBasis2(B[i], p), B)) {
10066       return [B[i], p];
10067     }
10068   }
10069
10070   // If we get here then B must have at least two elements.
10071   for (i = 0; i < B.length - 1; ++i) {
10072     for (j = i + 1; j < B.length; ++j) {
10073       if (enclosesNot(encloseBasis2(B[i], B[j]), p)
10074           && enclosesNot(encloseBasis2(B[i], p), B[j])
10075           && enclosesNot(encloseBasis2(B[j], p), B[i])
10076           && enclosesWeakAll(encloseBasis3(B[i], B[j], p), B)) {
10077         return [B[i], B[j], p];
10078       }
10079     }
10080   }
10081
10082   // If we get here then something is very wrong.
10083   throw new Error;
10084 }
10085
10086 function enclosesNot(a, b) {
10087   var dr = a.r - b.r, dx = b.x - a.x, dy = b.y - a.y;
10088   return dr < 0 || dr * dr < dx * dx + dy * dy;
10089 }
10090
10091 function enclosesWeak(a, b) {
10092   var dr = a.r - b.r + 1e-6, dx = b.x - a.x, dy = b.y - a.y;
10093   return dr > 0 && dr * dr > dx * dx + dy * dy;
10094 }
10095
10096 function enclosesWeakAll(a, B) {
10097   for (var i = 0; i < B.length; ++i) {
10098     if (!enclosesWeak(a, B[i])) {
10099       return false;
10100     }
10101   }
10102   return true;
10103 }
10104
10105 function encloseBasis(B) {
10106   switch (B.length) {
10107     case 1: return encloseBasis1(B[0]);
10108     case 2: return encloseBasis2(B[0], B[1]);
10109     case 3: return encloseBasis3(B[0], B[1], B[2]);
10110   }
10111 }
10112
10113 function encloseBasis1(a) {
10114   return {
10115     x: a.x,
10116     y: a.y,
10117     r: a.r
10118   };
10119 }
10120
10121 function encloseBasis2(a, b) {
10122   var x1 = a.x, y1 = a.y, r1 = a.r,
10123       x2 = b.x, y2 = b.y, r2 = b.r,
10124       x21 = x2 - x1, y21 = y2 - y1, r21 = r2 - r1,
10125       l = Math.sqrt(x21 * x21 + y21 * y21);
10126   return {
10127     x: (x1 + x2 + x21 / l * r21) / 2,
10128     y: (y1 + y2 + y21 / l * r21) / 2,
10129     r: (l + r1 + r2) / 2
10130   };
10131 }
10132
10133 function encloseBasis3(a, b, c) {
10134   var x1 = a.x, y1 = a.y, r1 = a.r,
10135       x2 = b.x, y2 = b.y, r2 = b.r,
10136       x3 = c.x, y3 = c.y, r3 = c.r,
10137       a2 = x1 - x2,
10138       a3 = x1 - x3,
10139       b2 = y1 - y2,
10140       b3 = y1 - y3,
10141       c2 = r2 - r1,
10142       c3 = r3 - r1,
10143       d1 = x1 * x1 + y1 * y1 - r1 * r1,
10144       d2 = d1 - x2 * x2 - y2 * y2 + r2 * r2,
10145       d3 = d1 - x3 * x3 - y3 * y3 + r3 * r3,
10146       ab = a3 * b2 - a2 * b3,
10147       xa = (b2 * d3 - b3 * d2) / (ab * 2) - x1,
10148       xb = (b3 * c2 - b2 * c3) / ab,
10149       ya = (a3 * d2 - a2 * d3) / (ab * 2) - y1,
10150       yb = (a2 * c3 - a3 * c2) / ab,
10151       A = xb * xb + yb * yb - 1,
10152       B = 2 * (r1 + xa * xb + ya * yb),
10153       C = xa * xa + ya * ya - r1 * r1,
10154       r = -(A ? (B + Math.sqrt(B * B - 4 * A * C)) / (2 * A) : C / B);
10155   return {
10156     x: x1 + xa + xb * r,
10157     y: y1 + ya + yb * r,
10158     r: r
10159   };
10160 }
10161
10162 function place(a, b, c) {
10163   var ax = a.x,
10164       ay = a.y,
10165       da = b.r + c.r,
10166       db = a.r + c.r,
10167       dx = b.x - ax,
10168       dy = b.y - ay,
10169       dc = dx * dx + dy * dy;
10170   if (dc) {
10171     var x = 0.5 + ((db *= db) - (da *= da)) / (2 * dc),
10172         y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc);
10173     c.x = ax + x * dx + y * dy;
10174     c.y = ay + x * dy - y * dx;
10175   } else {
10176     c.x = ax + db;
10177     c.y = ay;
10178   }
10179 }
10180
10181 function intersects(a, b) {
10182   var dx = b.x - a.x,
10183       dy = b.y - a.y,
10184       dr = a.r + b.r;
10185   return dr * dr - 1e-6 > dx * dx + dy * dy;
10186 }
10187
10188 function score(node) {
10189   var a = node._,
10190       b = node.next._,
10191       ab = a.r + b.r,
10192       dx = (a.x * b.r + b.x * a.r) / ab,
10193       dy = (a.y * b.r + b.y * a.r) / ab;
10194   return dx * dx + dy * dy;
10195 }
10196
10197 function Node$1(circle) {
10198   this._ = circle;
10199   this.next = null;
10200   this.previous = null;
10201 }
10202
10203 function packEnclose(circles) {
10204   if (!(n = circles.length)) return 0;
10205
10206   var a, b, c, n, aa, ca, i, j, k, sj, sk;
10207
10208   // Place the first circle.
10209   a = circles[0], a.x = 0, a.y = 0;
10210   if (!(n > 1)) return a.r;
10211
10212   // Place the second circle.
10213   b = circles[1], a.x = -b.r, b.x = a.r, b.y = 0;
10214   if (!(n > 2)) return a.r + b.r;
10215
10216   // Place the third circle.
10217   place(b, a, c = circles[2]);
10218
10219   // Initialize the front-chain using the first three circles a, b and c.
10220   a = new Node$1(a), b = new Node$1(b), c = new Node$1(c);
10221   a.next = c.previous = b;
10222   b.next = a.previous = c;
10223   c.next = b.previous = a;
10224
10225   // Attempt to place each remaining circle…
10226   pack: for (i = 3; i < n; ++i) {
10227     place(a._, b._, c = circles[i]), c = new Node$1(c);
10228
10229     // Find the closest intersecting circle on the front-chain, if any.
10230     // “Closeness” is determined by linear distance along the front-chain.
10231     // “Ahead” or “behind” is likewise determined by linear distance.
10232     j = b.next, k = a.previous, sj = b._.r, sk = a._.r;
10233     do {
10234       if (sj <= sk) {
10235         if (intersects(j._, c._)) {
10236           b = j, a.next = b, b.previous = a, --i;
10237           continue pack;
10238         }
10239         sj += j._.r, j = j.next;
10240       } else {
10241         if (intersects(k._, c._)) {
10242           a = k, a.next = b, b.previous = a, --i;
10243           continue pack;
10244         }
10245         sk += k._.r, k = k.previous;
10246       }
10247     } while (j !== k.next);
10248
10249     // Success! Insert the new circle c between a and b.
10250     c.previous = a, c.next = b, a.next = b.previous = b = c;
10251
10252     // Compute the new closest circle pair to the centroid.
10253     aa = score(a);
10254     while ((c = c.next) !== b) {
10255       if ((ca = score(c)) < aa) {
10256         a = c, aa = ca;
10257       }
10258     }
10259     b = a.next;
10260   }
10261
10262   // Compute the enclosing circle of the front chain.
10263   a = [b._], c = b; while ((c = c.next) !== b) a.push(c._); c = enclose(a);
10264
10265   // Translate the circles to put the enclosing circle around the origin.
10266   for (i = 0; i < n; ++i) a = circles[i], a.x -= c.x, a.y -= c.y;
10267
10268   return c.r;
10269 }
10270
10271 function siblings(circles) {
10272   packEnclose(circles);
10273   return circles;
10274 }
10275
10276 function optional(f) {
10277   return f == null ? null : required(f);
10278 }
10279
10280 function required(f) {
10281   if (typeof f !== "function") throw new Error;
10282   return f;
10283 }
10284
10285 function constantZero() {
10286   return 0;
10287 }
10288
10289 function constant$8(x) {
10290   return function() {
10291     return x;
10292   };
10293 }
10294
10295 function defaultRadius$1(d) {
10296   return Math.sqrt(d.value);
10297 }
10298
10299 function index$1() {
10300   var radius = null,
10301       dx = 1,
10302       dy = 1,
10303       padding = constantZero;
10304
10305   function pack(root) {
10306     root.x = dx / 2, root.y = dy / 2;
10307     if (radius) {
10308       root.eachBefore(radiusLeaf(radius))
10309           .eachAfter(packChildren(padding, 0.5))
10310           .eachBefore(translateChild(1));
10311     } else {
10312       root.eachBefore(radiusLeaf(defaultRadius$1))
10313           .eachAfter(packChildren(constantZero, 1))
10314           .eachAfter(packChildren(padding, root.r / Math.min(dx, dy)))
10315           .eachBefore(translateChild(Math.min(dx, dy) / (2 * root.r)));
10316     }
10317     return root;
10318   }
10319
10320   pack.radius = function(x) {
10321     return arguments.length ? (radius = optional(x), pack) : radius;
10322   };
10323
10324   pack.size = function(x) {
10325     return arguments.length ? (dx = +x[0], dy = +x[1], pack) : [dx, dy];
10326   };
10327
10328   pack.padding = function(x) {
10329     return arguments.length ? (padding = typeof x === "function" ? x : constant$8(+x), pack) : padding;
10330   };
10331
10332   return pack;
10333 }
10334
10335 function radiusLeaf(radius) {
10336   return function(node) {
10337     if (!node.children) {
10338       node.r = Math.max(0, +radius(node) || 0);
10339     }
10340   };
10341 }
10342
10343 function packChildren(padding, k) {
10344   return function(node) {
10345     if (children = node.children) {
10346       var children,
10347           i,
10348           n = children.length,
10349           r = padding(node) * k || 0,
10350           e;
10351
10352       if (r) for (i = 0; i < n; ++i) children[i].r += r;
10353       e = packEnclose(children);
10354       if (r) for (i = 0; i < n; ++i) children[i].r -= r;
10355       node.r = e + r;
10356     }
10357   };
10358 }
10359
10360 function translateChild(k) {
10361   return function(node) {
10362     var parent = node.parent;
10363     node.r *= k;
10364     if (parent) {
10365       node.x = parent.x + k * node.x;
10366       node.y = parent.y + k * node.y;
10367     }
10368   };
10369 }
10370
10371 function roundNode(node) {
10372   node.x0 = Math.round(node.x0);
10373   node.y0 = Math.round(node.y0);
10374   node.x1 = Math.round(node.x1);
10375   node.y1 = Math.round(node.y1);
10376 }
10377
10378 function treemapDice(parent, x0, y0, x1, y1) {
10379   var nodes = parent.children,
10380       node,
10381       i = -1,
10382       n = nodes.length,
10383       k = parent.value && (x1 - x0) / parent.value;
10384
10385   while (++i < n) {
10386     node = nodes[i], node.y0 = y0, node.y1 = y1;
10387     node.x0 = x0, node.x1 = x0 += node.value * k;
10388   }
10389 }
10390
10391 function partition() {
10392   var dx = 1,
10393       dy = 1,
10394       padding = 0,
10395       round = false;
10396
10397   function partition(root) {
10398     var n = root.height + 1;
10399     root.x0 =
10400     root.y0 = padding;
10401     root.x1 = dx;
10402     root.y1 = dy / n;
10403     root.eachBefore(positionNode(dy, n));
10404     if (round) root.eachBefore(roundNode);
10405     return root;
10406   }
10407
10408   function positionNode(dy, n) {
10409     return function(node) {
10410       if (node.children) {
10411         treemapDice(node, node.x0, dy * (node.depth + 1) / n, node.x1, dy * (node.depth + 2) / n);
10412       }
10413       var x0 = node.x0,
10414           y0 = node.y0,
10415           x1 = node.x1 - padding,
10416           y1 = node.y1 - padding;
10417       if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
10418       if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
10419       node.x0 = x0;
10420       node.y0 = y0;
10421       node.x1 = x1;
10422       node.y1 = y1;
10423     };
10424   }
10425
10426   partition.round = function(x) {
10427     return arguments.length ? (round = !!x, partition) : round;
10428   };
10429
10430   partition.size = function(x) {
10431     return arguments.length ? (dx = +x[0], dy = +x[1], partition) : [dx, dy];
10432   };
10433
10434   partition.padding = function(x) {
10435     return arguments.length ? (padding = +x, partition) : padding;
10436   };
10437
10438   return partition;
10439 }
10440
10441 var keyPrefix$1 = "$";
10442 var preroot = {depth: -1};
10443 var ambiguous = {};
10444
10445 function defaultId(d) {
10446   return d.id;
10447 }
10448
10449 function defaultParentId(d) {
10450   return d.parentId;
10451 }
10452
10453 function stratify() {
10454   var id = defaultId,
10455       parentId = defaultParentId;
10456
10457   function stratify(data) {
10458     var d,
10459         i,
10460         n = data.length,
10461         root,
10462         parent,
10463         node,
10464         nodes = new Array(n),
10465         nodeId,
10466         nodeKey,
10467         nodeByKey = {};
10468
10469     for (i = 0; i < n; ++i) {
10470       d = data[i], node = nodes[i] = new Node(d);
10471       if ((nodeId = id(d, i, data)) != null && (nodeId += "")) {
10472         nodeKey = keyPrefix$1 + (node.id = nodeId);
10473         nodeByKey[nodeKey] = nodeKey in nodeByKey ? ambiguous : node;
10474       }
10475     }
10476
10477     for (i = 0; i < n; ++i) {
10478       node = nodes[i], nodeId = parentId(data[i], i, data);
10479       if (nodeId == null || !(nodeId += "")) {
10480         if (root) throw new Error("multiple roots");
10481         root = node;
10482       } else {
10483         parent = nodeByKey[keyPrefix$1 + nodeId];
10484         if (!parent) throw new Error("missing: " + nodeId);
10485         if (parent === ambiguous) throw new Error("ambiguous: " + nodeId);
10486         if (parent.children) parent.children.push(node);
10487         else parent.children = [node];
10488         node.parent = parent;
10489       }
10490     }
10491
10492     if (!root) throw new Error("no root");
10493     root.parent = preroot;
10494     root.eachBefore(function(node) { node.depth = node.parent.depth + 1; --n; }).eachBefore(computeHeight);
10495     root.parent = null;
10496     if (n > 0) throw new Error("cycle");
10497
10498     return root;
10499   }
10500
10501   stratify.id = function(x) {
10502     return arguments.length ? (id = required(x), stratify) : id;
10503   };
10504
10505   stratify.parentId = function(x) {
10506     return arguments.length ? (parentId = required(x), stratify) : parentId;
10507   };
10508
10509   return stratify;
10510 }
10511
10512 function defaultSeparation$1(a, b) {
10513   return a.parent === b.parent ? 1 : 2;
10514 }
10515
10516 // function radialSeparation(a, b) {
10517 //   return (a.parent === b.parent ? 1 : 2) / a.depth;
10518 // }
10519
10520 // This function is used to traverse the left contour of a subtree (or
10521 // subforest). It returns the successor of v on this contour. This successor is
10522 // either given by the leftmost child of v or by the thread of v. The function
10523 // returns null if and only if v is on the highest level of its subtree.
10524 function nextLeft(v) {
10525   var children = v.children;
10526   return children ? children[0] : v.t;
10527 }
10528
10529 // This function works analogously to nextLeft.
10530 function nextRight(v) {
10531   var children = v.children;
10532   return children ? children[children.length - 1] : v.t;
10533 }
10534
10535 // Shifts the current subtree rooted at w+. This is done by increasing
10536 // prelim(w+) and mod(w+) by shift.
10537 function moveSubtree(wm, wp, shift) {
10538   var change = shift / (wp.i - wm.i);
10539   wp.c -= change;
10540   wp.s += shift;
10541   wm.c += change;
10542   wp.z += shift;
10543   wp.m += shift;
10544 }
10545
10546 // All other shifts, applied to the smaller subtrees between w- and w+, are
10547 // performed by this function. To prepare the shifts, we have to adjust
10548 // change(w+), shift(w+), and change(w-).
10549 function executeShifts(v) {
10550   var shift = 0,
10551       change = 0,
10552       children = v.children,
10553       i = children.length,
10554       w;
10555   while (--i >= 0) {
10556     w = children[i];
10557     w.z += shift;
10558     w.m += shift;
10559     shift += w.s + (change += w.c);
10560   }
10561 }
10562
10563 // If vi-’s ancestor is a sibling of v, returns vi-’s ancestor. Otherwise,
10564 // returns the specified (default) ancestor.
10565 function nextAncestor(vim, v, ancestor) {
10566   return vim.a.parent === v.parent ? vim.a : ancestor;
10567 }
10568
10569 function TreeNode(node, i) {
10570   this._ = node;
10571   this.parent = null;
10572   this.children = null;
10573   this.A = null; // default ancestor
10574   this.a = this; // ancestor
10575   this.z = 0; // prelim
10576   this.m = 0; // mod
10577   this.c = 0; // change
10578   this.s = 0; // shift
10579   this.t = null; // thread
10580   this.i = i; // number
10581 }
10582
10583 TreeNode.prototype = Object.create(Node.prototype);
10584
10585 function treeRoot(root) {
10586   var tree = new TreeNode(root, 0),
10587       node,
10588       nodes = [tree],
10589       child,
10590       children,
10591       i,
10592       n;
10593
10594   while (node = nodes.pop()) {
10595     if (children = node._.children) {
10596       node.children = new Array(n = children.length);
10597       for (i = n - 1; i >= 0; --i) {
10598         nodes.push(child = node.children[i] = new TreeNode(children[i], i));
10599         child.parent = node;
10600       }
10601     }
10602   }
10603
10604   (tree.parent = new TreeNode(null, 0)).children = [tree];
10605   return tree;
10606 }
10607
10608 // Node-link tree diagram using the Reingold-Tilford "tidy" algorithm
10609 function tree() {
10610   var separation = defaultSeparation$1,
10611       dx = 1,
10612       dy = 1,
10613       nodeSize = null;
10614
10615   function tree(root) {
10616     var t = treeRoot(root);
10617
10618     // Compute the layout using Buchheim et al.’s algorithm.
10619     t.eachAfter(firstWalk), t.parent.m = -t.z;
10620     t.eachBefore(secondWalk);
10621
10622     // If a fixed node size is specified, scale x and y.
10623     if (nodeSize) root.eachBefore(sizeNode);
10624
10625     // If a fixed tree size is specified, scale x and y based on the extent.
10626     // Compute the left-most, right-most, and depth-most nodes for extents.
10627     else {
10628       var left = root,
10629           right = root,
10630           bottom = root;
10631       root.eachBefore(function(node) {
10632         if (node.x < left.x) left = node;
10633         if (node.x > right.x) right = node;
10634         if (node.depth > bottom.depth) bottom = node;
10635       });
10636       var s = left === right ? 1 : separation(left, right) / 2,
10637           tx = s - left.x,
10638           kx = dx / (right.x + s + tx),
10639           ky = dy / (bottom.depth || 1);
10640       root.eachBefore(function(node) {
10641         node.x = (node.x + tx) * kx;
10642         node.y = node.depth * ky;
10643       });
10644     }
10645
10646     return root;
10647   }
10648
10649   // Computes a preliminary x-coordinate for v. Before that, FIRST WALK is
10650   // applied recursively to the children of v, as well as the function
10651   // APPORTION. After spacing out the children by calling EXECUTE SHIFTS, the
10652   // node v is placed to the midpoint of its outermost children.
10653   function firstWalk(v) {
10654     var children = v.children,
10655         siblings = v.parent.children,
10656         w = v.i ? siblings[v.i - 1] : null;
10657     if (children) {
10658       executeShifts(v);
10659       var midpoint = (children[0].z + children[children.length - 1].z) / 2;
10660       if (w) {
10661         v.z = w.z + separation(v._, w._);
10662         v.m = v.z - midpoint;
10663       } else {
10664         v.z = midpoint;
10665       }
10666     } else if (w) {
10667       v.z = w.z + separation(v._, w._);
10668     }
10669     v.parent.A = apportion(v, w, v.parent.A || siblings[0]);
10670   }
10671
10672   // Computes all real x-coordinates by summing up the modifiers recursively.
10673   function secondWalk(v) {
10674     v._.x = v.z + v.parent.m;
10675     v.m += v.parent.m;
10676   }
10677
10678   // The core of the algorithm. Here, a new subtree is combined with the
10679   // previous subtrees. Threads are used to traverse the inside and outside
10680   // contours of the left and right subtree up to the highest common level. The
10681   // vertices used for the traversals are vi+, vi-, vo-, and vo+, where the
10682   // superscript o means outside and i means inside, the subscript - means left
10683   // subtree and + means right subtree. For summing up the modifiers along the
10684   // contour, we use respective variables si+, si-, so-, and so+. Whenever two
10685   // nodes of the inside contours conflict, we compute the left one of the
10686   // greatest uncommon ancestors using the function ANCESTOR and call MOVE
10687   // SUBTREE to shift the subtree and prepare the shifts of smaller subtrees.
10688   // Finally, we add a new thread (if necessary).
10689   function apportion(v, w, ancestor) {
10690     if (w) {
10691       var vip = v,
10692           vop = v,
10693           vim = w,
10694           vom = vip.parent.children[0],
10695           sip = vip.m,
10696           sop = vop.m,
10697           sim = vim.m,
10698           som = vom.m,
10699           shift;
10700       while (vim = nextRight(vim), vip = nextLeft(vip), vim && vip) {
10701         vom = nextLeft(vom);
10702         vop = nextRight(vop);
10703         vop.a = v;
10704         shift = vim.z + sim - vip.z - sip + separation(vim._, vip._);
10705         if (shift > 0) {
10706           moveSubtree(nextAncestor(vim, v, ancestor), v, shift);
10707           sip += shift;
10708           sop += shift;
10709         }
10710         sim += vim.m;
10711         sip += vip.m;
10712         som += vom.m;
10713         sop += vop.m;
10714       }
10715       if (vim && !nextRight(vop)) {
10716         vop.t = vim;
10717         vop.m += sim - sop;
10718       }
10719       if (vip && !nextLeft(vom)) {
10720         vom.t = vip;
10721         vom.m += sip - som;
10722         ancestor = v;
10723       }
10724     }
10725     return ancestor;
10726   }
10727
10728   function sizeNode(node) {
10729     node.x *= dx;
10730     node.y = node.depth * dy;
10731   }
10732
10733   tree.separation = function(x) {
10734     return arguments.length ? (separation = x, tree) : separation;
10735   };
10736
10737   tree.size = function(x) {
10738     return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], tree) : (nodeSize ? null : [dx, dy]);
10739   };
10740
10741   tree.nodeSize = function(x) {
10742     return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], tree) : (nodeSize ? [dx, dy] : null);
10743   };
10744
10745   return tree;
10746 }
10747
10748 function treemapSlice(parent, x0, y0, x1, y1) {
10749   var nodes = parent.children,
10750       node,
10751       i = -1,
10752       n = nodes.length,
10753       k = parent.value && (y1 - y0) / parent.value;
10754
10755   while (++i < n) {
10756     node = nodes[i], node.x0 = x0, node.x1 = x1;
10757     node.y0 = y0, node.y1 = y0 += node.value * k;
10758   }
10759 }
10760
10761 var phi = (1 + Math.sqrt(5)) / 2;
10762
10763 function squarifyRatio(ratio, parent, x0, y0, x1, y1) {
10764   var rows = [],
10765       nodes = parent.children,
10766       row,
10767       nodeValue,
10768       i0 = 0,
10769       i1 = 0,
10770       n = nodes.length,
10771       dx, dy,
10772       value = parent.value,
10773       sumValue,
10774       minValue,
10775       maxValue,
10776       newRatio,
10777       minRatio,
10778       alpha,
10779       beta;
10780
10781   while (i0 < n) {
10782     dx = x1 - x0, dy = y1 - y0;
10783
10784     // Find the next non-empty node.
10785     do sumValue = nodes[i1++].value; while (!sumValue && i1 < n);
10786     minValue = maxValue = sumValue;
10787     alpha = Math.max(dy / dx, dx / dy) / (value * ratio);
10788     beta = sumValue * sumValue * alpha;
10789     minRatio = Math.max(maxValue / beta, beta / minValue);
10790
10791     // Keep adding nodes while the aspect ratio maintains or improves.
10792     for (; i1 < n; ++i1) {
10793       sumValue += nodeValue = nodes[i1].value;
10794       if (nodeValue < minValue) minValue = nodeValue;
10795       if (nodeValue > maxValue) maxValue = nodeValue;
10796       beta = sumValue * sumValue * alpha;
10797       newRatio = Math.max(maxValue / beta, beta / minValue);
10798       if (newRatio > minRatio) { sumValue -= nodeValue; break; }
10799       minRatio = newRatio;
10800     }
10801
10802     // Position and record the row orientation.
10803     rows.push(row = {value: sumValue, dice: dx < dy, children: nodes.slice(i0, i1)});
10804     if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1);
10805     else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1);
10806     value -= sumValue, i0 = i1;
10807   }
10808
10809   return rows;
10810 }
10811
10812 var squarify = (function custom(ratio) {
10813
10814   function squarify(parent, x0, y0, x1, y1) {
10815     squarifyRatio(ratio, parent, x0, y0, x1, y1);
10816   }
10817
10818   squarify.ratio = function(x) {
10819     return custom((x = +x) > 1 ? x : 1);
10820   };
10821
10822   return squarify;
10823 })(phi);
10824
10825 function index$2() {
10826   var tile = squarify,
10827       round = false,
10828       dx = 1,
10829       dy = 1,
10830       paddingStack = [0],
10831       paddingInner = constantZero,
10832       paddingTop = constantZero,
10833       paddingRight = constantZero,
10834       paddingBottom = constantZero,
10835       paddingLeft = constantZero;
10836
10837   function treemap(root) {
10838     root.x0 =
10839     root.y0 = 0;
10840     root.x1 = dx;
10841     root.y1 = dy;
10842     root.eachBefore(positionNode);
10843     paddingStack = [0];
10844     if (round) root.eachBefore(roundNode);
10845     return root;
10846   }
10847
10848   function positionNode(node) {
10849     var p = paddingStack[node.depth],
10850         x0 = node.x0 + p,
10851         y0 = node.y0 + p,
10852         x1 = node.x1 - p,
10853         y1 = node.y1 - p;
10854     if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
10855     if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
10856     node.x0 = x0;
10857     node.y0 = y0;
10858     node.x1 = x1;
10859     node.y1 = y1;
10860     if (node.children) {
10861       p = paddingStack[node.depth + 1] = paddingInner(node) / 2;
10862       x0 += paddingLeft(node) - p;
10863       y0 += paddingTop(node) - p;
10864       x1 -= paddingRight(node) - p;
10865       y1 -= paddingBottom(node) - p;
10866       if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
10867       if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
10868       tile(node, x0, y0, x1, y1);
10869     }
10870   }
10871
10872   treemap.round = function(x) {
10873     return arguments.length ? (round = !!x, treemap) : round;
10874   };
10875
10876   treemap.size = function(x) {
10877     return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy];
10878   };
10879
10880   treemap.tile = function(x) {
10881     return arguments.length ? (tile = required(x), treemap) : tile;
10882   };
10883
10884   treemap.padding = function(x) {
10885     return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner();
10886   };
10887
10888   treemap.paddingInner = function(x) {
10889     return arguments.length ? (paddingInner = typeof x === "function" ? x : constant$8(+x), treemap) : paddingInner;
10890   };
10891
10892   treemap.paddingOuter = function(x) {
10893     return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop();
10894   };
10895
10896   treemap.paddingTop = function(x) {
10897     return arguments.length ? (paddingTop = typeof x === "function" ? x : constant$8(+x), treemap) : paddingTop;
10898   };
10899
10900   treemap.paddingRight = function(x) {
10901     return arguments.length ? (paddingRight = typeof x === "function" ? x : constant$8(+x), treemap) : paddingRight;
10902   };
10903
10904   treemap.paddingBottom = function(x) {
10905     return arguments.length ? (paddingBottom = typeof x === "function" ? x : constant$8(+x), treemap) : paddingBottom;
10906   };
10907
10908   treemap.paddingLeft = function(x) {
10909     return arguments.length ? (paddingLeft = typeof x === "function" ? x : constant$8(+x), treemap) : paddingLeft;
10910   };
10911
10912   return treemap;
10913 }
10914
10915 function binary(parent, x0, y0, x1, y1) {
10916   var nodes = parent.children,
10917       i, n = nodes.length,
10918       sum, sums = new Array(n + 1);
10919
10920   for (sums[0] = sum = i = 0; i < n; ++i) {
10921     sums[i + 1] = sum += nodes[i].value;
10922   }
10923
10924   partition(0, n, parent.value, x0, y0, x1, y1);
10925
10926   function partition(i, j, value, x0, y0, x1, y1) {
10927     if (i >= j - 1) {
10928       var node = nodes[i];
10929       node.x0 = x0, node.y0 = y0;
10930       node.x1 = x1, node.y1 = y1;
10931       return;
10932     }
10933
10934     var valueOffset = sums[i],
10935         valueTarget = (value / 2) + valueOffset,
10936         k = i + 1,
10937         hi = j - 1;
10938
10939     while (k < hi) {
10940       var mid = k + hi >>> 1;
10941       if (sums[mid] < valueTarget) k = mid + 1;
10942       else hi = mid;
10943     }
10944
10945     if ((valueTarget - sums[k - 1]) < (sums[k] - valueTarget) && i + 1 < k) --k;
10946
10947     var valueLeft = sums[k] - valueOffset,
10948         valueRight = value - valueLeft;
10949
10950     if ((x1 - x0) > (y1 - y0)) {
10951       var xk = (x0 * valueRight + x1 * valueLeft) / value;
10952       partition(i, k, valueLeft, x0, y0, xk, y1);
10953       partition(k, j, valueRight, xk, y0, x1, y1);
10954     } else {
10955       var yk = (y0 * valueRight + y1 * valueLeft) / value;
10956       partition(i, k, valueLeft, x0, y0, x1, yk);
10957       partition(k, j, valueRight, x0, yk, x1, y1);
10958     }
10959   }
10960 }
10961
10962 function sliceDice(parent, x0, y0, x1, y1) {
10963   (parent.depth & 1 ? treemapSlice : treemapDice)(parent, x0, y0, x1, y1);
10964 }
10965
10966 var resquarify = (function custom(ratio) {
10967
10968   function resquarify(parent, x0, y0, x1, y1) {
10969     if ((rows = parent._squarify) && (rows.ratio === ratio)) {
10970       var rows,
10971           row,
10972           nodes,
10973           i,
10974           j = -1,
10975           n,
10976           m = rows.length,
10977           value = parent.value;
10978
10979       while (++j < m) {
10980         row = rows[j], nodes = row.children;
10981         for (i = row.value = 0, n = nodes.length; i < n; ++i) row.value += nodes[i].value;
10982         if (row.dice) treemapDice(row, x0, y0, x1, y0 += (y1 - y0) * row.value / value);
10983         else treemapSlice(row, x0, y0, x0 += (x1 - x0) * row.value / value, y1);
10984         value -= row.value;
10985       }
10986     } else {
10987       parent._squarify = rows = squarifyRatio(ratio, parent, x0, y0, x1, y1);
10988       rows.ratio = ratio;
10989     }
10990   }
10991
10992   resquarify.ratio = function(x) {
10993     return custom((x = +x) > 1 ? x : 1);
10994   };
10995
10996   return resquarify;
10997 })(phi);
10998
10999 function d3_polygonArea(polygon) {
11000   var i = -1,
11001       n = polygon.length,
11002       a,
11003       b = polygon[n - 1],
11004       area = 0;
11005
11006   while (++i < n) {
11007     a = b;
11008     b = polygon[i];
11009     area += a[1] * b[0] - a[0] * b[1];
11010   }
11011
11012   return area / 2;
11013 }
11014
11015 function d3_polygonCentroid(polygon) {
11016   var i = -1,
11017       n = polygon.length,
11018       x = 0,
11019       y = 0,
11020       a,
11021       b = polygon[n - 1],
11022       c,
11023       k = 0;
11024
11025   while (++i < n) {
11026     a = b;
11027     b = polygon[i];
11028     k += c = a[0] * b[1] - b[0] * a[1];
11029     x += (a[0] + b[0]) * c;
11030     y += (a[1] + b[1]) * c;
11031   }
11032
11033   return k *= 3, [x / k, y / k];
11034 }
11035
11036 // Returns the 2D cross product of AB and AC vectors, i.e., the z-component of
11037 // the 3D cross product in a quadrant I Cartesian coordinate system (+x is
11038 // right, +y is up). Returns a positive value if ABC is counter-clockwise,
11039 // negative if clockwise, and zero if the points are collinear.
11040 function cross$1(a, b, c) {
11041   return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);
11042 }
11043
11044 function lexicographicOrder(a, b) {
11045   return a[0] - b[0] || a[1] - b[1];
11046 }
11047
11048 // Computes the upper convex hull per the monotone chain algorithm.
11049 // Assumes points.length >= 3, is sorted by x, unique in y.
11050 // Returns an array of indices into points in left-to-right order.
11051 function computeUpperHullIndexes(points) {
11052   var n = points.length,
11053       indexes = [0, 1],
11054       size = 2;
11055
11056   for (var i = 2; i < n; ++i) {
11057     while (size > 1 && cross$1(points[indexes[size - 2]], points[indexes[size - 1]], points[i]) <= 0) --size;
11058     indexes[size++] = i;
11059   }
11060
11061   return indexes.slice(0, size); // remove popped points
11062 }
11063
11064 function d3_polygonHull(points) {
11065   if ((n = points.length) < 3) return null;
11066
11067   var i,
11068       n,
11069       sortedPoints = new Array(n),
11070       flippedPoints = new Array(n);
11071
11072   for (i = 0; i < n; ++i) sortedPoints[i] = [+points[i][0], +points[i][1], i];
11073   sortedPoints.sort(lexicographicOrder);
11074   for (i = 0; i < n; ++i) flippedPoints[i] = [sortedPoints[i][0], -sortedPoints[i][1]];
11075
11076   var upperIndexes = computeUpperHullIndexes(sortedPoints),
11077       lowerIndexes = computeUpperHullIndexes(flippedPoints);
11078
11079   // Construct the hull polygon, removing possible duplicate endpoints.
11080   var skipLeft = lowerIndexes[0] === upperIndexes[0],
11081       skipRight = lowerIndexes[lowerIndexes.length - 1] === upperIndexes[upperIndexes.length - 1],
11082       hull = [];
11083
11084   // Add upper hull in right-to-l order.
11085   // Then add lower hull in left-to-right order.
11086   for (i = upperIndexes.length - 1; i >= 0; --i) hull.push(points[sortedPoints[upperIndexes[i]][2]]);
11087   for (i = +skipLeft; i < lowerIndexes.length - skipRight; ++i) hull.push(points[sortedPoints[lowerIndexes[i]][2]]);
11088
11089   return hull;
11090 }
11091
11092 function contains$1(polygon, point) {
11093   var n = polygon.length,
11094       p = polygon[n - 1],
11095       x = point[0], y = point[1],
11096       x0 = p[0], y0 = p[1],
11097       x1, y1,
11098       inside = false;
11099
11100   for (var i = 0; i < n; ++i) {
11101     p = polygon[i], x1 = p[0], y1 = p[1];
11102     if (((y1 > y) !== (y0 > y)) && (x < (x0 - x1) * (y - y1) / (y0 - y1) + x1)) inside = !inside;
11103     x0 = x1, y0 = y1;
11104   }
11105
11106   return inside;
11107 }
11108
11109 function length$1(polygon) {
11110   var i = -1,
11111       n = polygon.length,
11112       b = polygon[n - 1],
11113       xa,
11114       ya,
11115       xb = b[0],
11116       yb = b[1],
11117       perimeter = 0;
11118
11119   while (++i < n) {
11120     xa = xb;
11121     ya = yb;
11122     b = polygon[i];
11123     xb = b[0];
11124     yb = b[1];
11125     xa -= xb;
11126     ya -= yb;
11127     perimeter += Math.sqrt(xa * xa + ya * ya);
11128   }
11129
11130   return perimeter;
11131 }
11132
11133 var slice$4 = [].slice;
11134
11135 var noabort = {};
11136
11137 function Queue(size) {
11138   this._size = size;
11139   this._call =
11140   this._error = null;
11141   this._tasks = [];
11142   this._data = [];
11143   this._waiting =
11144   this._active =
11145   this._ended =
11146   this._start = 0; // inside a synchronous task callback?
11147 }
11148
11149 Queue.prototype = queue.prototype = {
11150   constructor: Queue,
11151   defer: function(callback) {
11152     if (typeof callback !== "function") throw new Error("invalid callback");
11153     if (this._call) throw new Error("defer after await");
11154     if (this._error != null) return this;
11155     var t = slice$4.call(arguments, 1);
11156     t.push(callback);
11157     ++this._waiting, this._tasks.push(t);
11158     poke$1(this);
11159     return this;
11160   },
11161   abort: function() {
11162     if (this._error == null) abort(this, new Error("abort"));
11163     return this;
11164   },
11165   await: function(callback) {
11166     if (typeof callback !== "function") throw new Error("invalid callback");
11167     if (this._call) throw new Error("multiple await");
11168     this._call = function(error, results) { callback.apply(null, [error].concat(results)); };
11169     maybeNotify(this);
11170     return this;
11171   },
11172   awaitAll: function(callback) {
11173     if (typeof callback !== "function") throw new Error("invalid callback");
11174     if (this._call) throw new Error("multiple await");
11175     this._call = callback;
11176     maybeNotify(this);
11177     return this;
11178   }
11179 };
11180
11181 function poke$1(q) {
11182   if (!q._start) {
11183     try { start$1(q); } // let the current task complete
11184     catch (e) {
11185       if (q._tasks[q._ended + q._active - 1]) abort(q, e); // task errored synchronously
11186       else if (!q._data) throw e; // await callback errored synchronously
11187     }
11188   }
11189 }
11190
11191 function start$1(q) {
11192   while (q._start = q._waiting && q._active < q._size) {
11193     var i = q._ended + q._active,
11194         t = q._tasks[i],
11195         j = t.length - 1,
11196         c = t[j];
11197     t[j] = end(q, i);
11198     --q._waiting, ++q._active;
11199     t = c.apply(null, t);
11200     if (!q._tasks[i]) continue; // task finished synchronously
11201     q._tasks[i] = t || noabort;
11202   }
11203 }
11204
11205 function end(q, i) {
11206   return function(e, r) {
11207     if (!q._tasks[i]) return; // ignore multiple callbacks
11208     --q._active, ++q._ended;
11209     q._tasks[i] = null;
11210     if (q._error != null) return; // ignore secondary errors
11211     if (e != null) {
11212       abort(q, e);
11213     } else {
11214       q._data[i] = r;
11215       if (q._waiting) poke$1(q);
11216       else maybeNotify(q);
11217     }
11218   };
11219 }
11220
11221 function abort(q, e) {
11222   var i = q._tasks.length, t;
11223   q._error = e; // ignore active callbacks
11224   q._data = undefined; // allow gc
11225   q._waiting = NaN; // prevent starting
11226
11227   while (--i >= 0) {
11228     if (t = q._tasks[i]) {
11229       q._tasks[i] = null;
11230       if (t.abort) {
11231         try { t.abort(); }
11232         catch (e) { /* ignore */ }
11233       }
11234     }
11235   }
11236
11237   q._active = NaN; // allow notification
11238   maybeNotify(q);
11239 }
11240
11241 function maybeNotify(q) {
11242   if (!q._active && q._call) {
11243     var d = q._data;
11244     q._data = undefined; // allow gc
11245     q._call(q._error, d);
11246   }
11247 }
11248
11249 function queue(concurrency) {
11250   if (concurrency == null) concurrency = Infinity;
11251   else if (!((concurrency = +concurrency) >= 1)) throw new Error("invalid concurrency");
11252   return new Queue(concurrency);
11253 }
11254
11255 function defaultSource$1() {
11256   return Math.random();
11257 }
11258
11259 var uniform = (function sourceRandomUniform(source) {
11260   function randomUniform(min, max) {
11261     min = min == null ? 0 : +min;
11262     max = max == null ? 1 : +max;
11263     if (arguments.length === 1) max = min, min = 0;
11264     else max -= min;
11265     return function() {
11266       return source() * max + min;
11267     };
11268   }
11269
11270   randomUniform.source = sourceRandomUniform;
11271
11272   return randomUniform;
11273 })(defaultSource$1);
11274
11275 var normal = (function sourceRandomNormal(source) {
11276   function randomNormal(mu, sigma) {
11277     var x, r;
11278     mu = mu == null ? 0 : +mu;
11279     sigma = sigma == null ? 1 : +sigma;
11280     return function() {
11281       var y;
11282
11283       // If available, use the second previously-generated uniform random.
11284       if (x != null) y = x, x = null;
11285
11286       // Otherwise, generate a new x and y.
11287       else do {
11288         x = source() * 2 - 1;
11289         y = source() * 2 - 1;
11290         r = x * x + y * y;
11291       } while (!r || r > 1);
11292
11293       return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r);
11294     };
11295   }
11296
11297   randomNormal.source = sourceRandomNormal;
11298
11299   return randomNormal;
11300 })(defaultSource$1);
11301
11302 var logNormal = (function sourceRandomLogNormal(source) {
11303   function randomLogNormal() {
11304     var randomNormal = normal.source(source).apply(this, arguments);
11305     return function() {
11306       return Math.exp(randomNormal());
11307     };
11308   }
11309
11310   randomLogNormal.source = sourceRandomLogNormal;
11311
11312   return randomLogNormal;
11313 })(defaultSource$1);
11314
11315 var irwinHall = (function sourceRandomIrwinHall(source) {
11316   function randomIrwinHall(n) {
11317     return function() {
11318       for (var sum = 0, i = 0; i < n; ++i) sum += source();
11319       return sum;
11320     };
11321   }
11322
11323   randomIrwinHall.source = sourceRandomIrwinHall;
11324
11325   return randomIrwinHall;
11326 })(defaultSource$1);
11327
11328 var bates = (function sourceRandomBates(source) {
11329   function randomBates(n) {
11330     var randomIrwinHall = irwinHall.source(source)(n);
11331     return function() {
11332       return randomIrwinHall() / n;
11333     };
11334   }
11335
11336   randomBates.source = sourceRandomBates;
11337
11338   return randomBates;
11339 })(defaultSource$1);
11340
11341 var exponential$1 = (function sourceRandomExponential(source) {
11342   function randomExponential(lambda) {
11343     return function() {
11344       return -Math.log(1 - source()) / lambda;
11345     };
11346   }
11347
11348   randomExponential.source = sourceRandomExponential;
11349
11350   return randomExponential;
11351 })(defaultSource$1);
11352
11353 function d3_request(url, callback) {
11354   var request,
11355       event = dispatch("beforesend", "progress", "load", "error"),
11356       mimeType,
11357       headers = map$1(),
11358       xhr = new XMLHttpRequest,
11359       user = null,
11360       password = null,
11361       response,
11362       responseType,
11363       timeout = 0;
11364
11365   // If IE does not support CORS, use XDomainRequest.
11366   if (typeof XDomainRequest !== "undefined"
11367       && !("withCredentials" in xhr)
11368       && /^(http(s)?:)?\/\//.test(url)) xhr = new XDomainRequest;
11369
11370   "onload" in xhr
11371       ? xhr.onload = xhr.onerror = xhr.ontimeout = respond
11372       : xhr.onreadystatechange = function(o) { xhr.readyState > 3 && respond(o); };
11373
11374   function respond(o) {
11375     var status = xhr.status, result;
11376     if (!status && hasResponse(xhr)
11377         || status >= 200 && status < 300
11378         || status === 304) {
11379       if (response) {
11380         try {
11381           result = response.call(request, xhr);
11382         } catch (e) {
11383           event.call("error", request, e);
11384           return;
11385         }
11386       } else {
11387         result = xhr;
11388       }
11389       event.call("load", request, result);
11390     } else {
11391       event.call("error", request, o);
11392     }
11393   }
11394
11395   xhr.onprogress = function(e) {
11396     event.call("progress", request, e);
11397   };
11398
11399   request = {
11400     header: function(name, value) {
11401       name = (name + "").toLowerCase();
11402       if (arguments.length < 2) return headers.get(name);
11403       if (value == null) headers.remove(name);
11404       else headers.set(name, value + "");
11405       return request;
11406     },
11407
11408     // If mimeType is non-null and no Accept header is set, a default is used.
11409     mimeType: function(value) {
11410       if (!arguments.length) return mimeType;
11411       mimeType = value == null ? null : value + "";
11412       return request;
11413     },
11414
11415     // Specifies what type the response value should take;
11416     // for instance, arraybuffer, blob, document, or text.
11417     responseType: function(value) {
11418       if (!arguments.length) return responseType;
11419       responseType = value;
11420       return request;
11421     },
11422
11423     timeout: function(value) {
11424       if (!arguments.length) return timeout;
11425       timeout = +value;
11426       return request;
11427     },
11428
11429     user: function(value) {
11430       return arguments.length < 1 ? user : (user = value == null ? null : value + "", request);
11431     },
11432
11433     password: function(value) {
11434       return arguments.length < 1 ? password : (password = value == null ? null : value + "", request);
11435     },
11436
11437     // Specify how to convert the response content to a specific type;
11438     // changes the callback value on "load" events.
11439     response: function(value) {
11440       response = value;
11441       return request;
11442     },
11443
11444     // Alias for send("GET", …).
11445     get: function(data, callback) {
11446       return request.send("GET", data, callback);
11447     },
11448
11449     // Alias for send("POST", …).
11450     post: function(data, callback) {
11451       return request.send("POST", data, callback);
11452     },
11453
11454     // If callback is non-null, it will be used for error and load events.
11455     send: function(method, data, callback) {
11456       xhr.open(method, url, true, user, password);
11457       if (mimeType != null && !headers.has("accept")) headers.set("accept", mimeType + ",*/*");
11458       if (xhr.setRequestHeader) headers.each(function(value, name) { xhr.setRequestHeader(name, value); });
11459       if (mimeType != null && xhr.overrideMimeType) xhr.overrideMimeType(mimeType);
11460       if (responseType != null) xhr.responseType = responseType;
11461       if (timeout > 0) xhr.timeout = timeout;
11462       if (callback == null && typeof data === "function") callback = data, data = null;
11463       if (callback != null && callback.length === 1) callback = fixCallback(callback);
11464       if (callback != null) request.on("error", callback).on("load", function(xhr) { callback(null, xhr); });
11465       event.call("beforesend", request, xhr);
11466       xhr.send(data == null ? null : data);
11467       return request;
11468     },
11469
11470     abort: function() {
11471       xhr.abort();
11472       return request;
11473     },
11474
11475     on: function() {
11476       var value = event.on.apply(event, arguments);
11477       return value === event ? request : value;
11478     }
11479   };
11480
11481   if (callback != null) {
11482     if (typeof callback !== "function") throw new Error("invalid callback: " + callback);
11483     return request.get(callback);
11484   }
11485
11486   return request;
11487 }
11488
11489 function fixCallback(callback) {
11490   return function(error, xhr) {
11491     callback(error == null ? xhr : null);
11492   };
11493 }
11494
11495 function hasResponse(xhr) {
11496   var type = xhr.responseType;
11497   return type && type !== "text"
11498       ? xhr.response // null on error
11499       : xhr.responseText; // "" on error
11500 }
11501
11502 function type$1(defaultMimeType, response) {
11503   return function(url, callback) {
11504     var r = d3_request(url).mimeType(defaultMimeType).response(response);
11505     if (callback != null) {
11506       if (typeof callback !== "function") throw new Error("invalid callback: " + callback);
11507       return r.get(callback);
11508     }
11509     return r;
11510   };
11511 }
11512
11513 var html = type$1("text/html", function(xhr) {
11514   return document.createRange().createContextualFragment(xhr.responseText);
11515 });
11516
11517 var d3_json = type$1("application/json", function(xhr) {
11518   return JSON.parse(xhr.responseText);
11519 });
11520
11521 var d3_text = type$1("text/plain", function(xhr) {
11522   return xhr.responseText;
11523 });
11524
11525 var d3_xml = type$1("application/xml", function(xhr) {
11526   var xml = xhr.responseXML;
11527   if (!xml) throw new Error("parse error");
11528   return xml;
11529 });
11530
11531 function dsv$1(defaultMimeType, parse) {
11532   return function(url, row, callback) {
11533     if (arguments.length < 3) callback = row, row = null;
11534     var r = d3_request(url).mimeType(defaultMimeType);
11535     r.row = function(_) { return arguments.length ? r.response(responseOf(parse, row = _)) : row; };
11536     r.row(row);
11537     return callback ? r.get(callback) : r;
11538   };
11539 }
11540
11541 function responseOf(parse, row) {
11542   return function(request) {
11543     return parse(request.responseText, row);
11544   };
11545 }
11546
11547 var csv$1 = dsv$1("text/csv", csvParse);
11548
11549 var tsv$1 = dsv$1("text/tab-separated-values", tsvParse);
11550
11551 var array$2 = Array.prototype;
11552
11553 var map$3 = array$2.map;
11554 var slice$5 = array$2.slice;
11555
11556 var implicit = {name: "implicit"};
11557
11558 function ordinal(range) {
11559   var index = map$1(),
11560       domain = [],
11561       unknown = implicit;
11562
11563   range = range == null ? [] : slice$5.call(range);
11564
11565   function scale(d) {
11566     var key = d + "", i = index.get(key);
11567     if (!i) {
11568       if (unknown !== implicit) return unknown;
11569       index.set(key, i = domain.push(d));
11570     }
11571     return range[(i - 1) % range.length];
11572   }
11573
11574   scale.domain = function(_) {
11575     if (!arguments.length) return domain.slice();
11576     domain = [], index = map$1();
11577     var i = -1, n = _.length, d, key;
11578     while (++i < n) if (!index.has(key = (d = _[i]) + "")) index.set(key, domain.push(d));
11579     return scale;
11580   };
11581
11582   scale.range = function(_) {
11583     return arguments.length ? (range = slice$5.call(_), scale) : range.slice();
11584   };
11585
11586   scale.unknown = function(_) {
11587     return arguments.length ? (unknown = _, scale) : unknown;
11588   };
11589
11590   scale.copy = function() {
11591     return ordinal()
11592         .domain(domain)
11593         .range(range)
11594         .unknown(unknown);
11595   };
11596
11597   return scale;
11598 }
11599
11600 function band() {
11601   var scale = ordinal().unknown(undefined),
11602       domain = scale.domain,
11603       ordinalRange = scale.range,
11604       range$$1 = [0, 1],
11605       step,
11606       bandwidth,
11607       round = false,
11608       paddingInner = 0,
11609       paddingOuter = 0,
11610       align = 0.5;
11611
11612   delete scale.unknown;
11613
11614   function rescale() {
11615     var n = domain().length,
11616         reverse = range$$1[1] < range$$1[0],
11617         start = range$$1[reverse - 0],
11618         stop = range$$1[1 - reverse];
11619     step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2);
11620     if (round) step = Math.floor(step);
11621     start += (stop - start - step * (n - paddingInner)) * align;
11622     bandwidth = step * (1 - paddingInner);
11623     if (round) start = Math.round(start), bandwidth = Math.round(bandwidth);
11624     var values = d3_range(n).map(function(i) { return start + step * i; });
11625     return ordinalRange(reverse ? values.reverse() : values);
11626   }
11627
11628   scale.domain = function(_) {
11629     return arguments.length ? (domain(_), rescale()) : domain();
11630   };
11631
11632   scale.range = function(_) {
11633     return arguments.length ? (range$$1 = [+_[0], +_[1]], rescale()) : range$$1.slice();
11634   };
11635
11636   scale.rangeRound = function(_) {
11637     return range$$1 = [+_[0], +_[1]], round = true, rescale();
11638   };
11639
11640   scale.bandwidth = function() {
11641     return bandwidth;
11642   };
11643
11644   scale.step = function() {
11645     return step;
11646   };
11647
11648   scale.round = function(_) {
11649     return arguments.length ? (round = !!_, rescale()) : round;
11650   };
11651
11652   scale.padding = function(_) {
11653     return arguments.length ? (paddingInner = paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;
11654   };
11655
11656   scale.paddingInner = function(_) {
11657     return arguments.length ? (paddingInner = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;
11658   };
11659
11660   scale.paddingOuter = function(_) {
11661     return arguments.length ? (paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingOuter;
11662   };
11663
11664   scale.align = function(_) {
11665     return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align;
11666   };
11667
11668   scale.copy = function() {
11669     return band()
11670         .domain(domain())
11671         .range(range$$1)
11672         .round(round)
11673         .paddingInner(paddingInner)
11674         .paddingOuter(paddingOuter)
11675         .align(align);
11676   };
11677
11678   return rescale();
11679 }
11680
11681 function pointish(scale) {
11682   var copy = scale.copy;
11683
11684   scale.padding = scale.paddingOuter;
11685   delete scale.paddingInner;
11686   delete scale.paddingOuter;
11687
11688   scale.copy = function() {
11689     return pointish(copy());
11690   };
11691
11692   return scale;
11693 }
11694
11695 function point$1() {
11696   return pointish(band().paddingInner(1));
11697 }
11698
11699 function constant$9(x) {
11700   return function() {
11701     return x;
11702   };
11703 }
11704
11705 function number$2(x) {
11706   return +x;
11707 }
11708
11709 var unit = [0, 1];
11710
11711 function deinterpolateLinear(a, b) {
11712   return (b -= (a = +a))
11713       ? function(x) { return (x - a) / b; }
11714       : constant$9(b);
11715 }
11716
11717 function deinterpolateClamp(deinterpolate) {
11718   return function(a, b) {
11719     var d = deinterpolate(a = +a, b = +b);
11720     return function(x) { return x <= a ? 0 : x >= b ? 1 : d(x); };
11721   };
11722 }
11723
11724 function reinterpolateClamp(reinterpolate) {
11725   return function(a, b) {
11726     var r = reinterpolate(a = +a, b = +b);
11727     return function(t) { return t <= 0 ? a : t >= 1 ? b : r(t); };
11728   };
11729 }
11730
11731 function bimap(domain, range, deinterpolate, reinterpolate) {
11732   var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1];
11733   if (d1 < d0) d0 = deinterpolate(d1, d0), r0 = reinterpolate(r1, r0);
11734   else d0 = deinterpolate(d0, d1), r0 = reinterpolate(r0, r1);
11735   return function(x) { return r0(d0(x)); };
11736 }
11737
11738 function polymap(domain, range, deinterpolate, reinterpolate) {
11739   var j = Math.min(domain.length, range.length) - 1,
11740       d = new Array(j),
11741       r = new Array(j),
11742       i = -1;
11743
11744   // Reverse descending domains.
11745   if (domain[j] < domain[0]) {
11746     domain = domain.slice().reverse();
11747     range = range.slice().reverse();
11748   }
11749
11750   while (++i < j) {
11751     d[i] = deinterpolate(domain[i], domain[i + 1]);
11752     r[i] = reinterpolate(range[i], range[i + 1]);
11753   }
11754
11755   return function(x) {
11756     var i = bisectRight(domain, x, 1, j) - 1;
11757     return r[i](d[i](x));
11758   };
11759 }
11760
11761 function copy(source, target) {
11762   return target
11763       .domain(source.domain())
11764       .range(source.range())
11765       .interpolate(source.interpolate())
11766       .clamp(source.clamp());
11767 }
11768
11769 // deinterpolate(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1].
11770 // reinterpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding domain value x in [a,b].
11771 function continuous(deinterpolate, reinterpolate) {
11772   var domain = unit,
11773       range = unit,
11774       interpolate$$1 = d3_interpolate,
11775       clamp = false,
11776       piecewise,
11777       output,
11778       input;
11779
11780   function rescale() {
11781     piecewise = Math.min(domain.length, range.length) > 2 ? polymap : bimap;
11782     output = input = null;
11783     return scale;
11784   }
11785
11786   function scale(x) {
11787     return (output || (output = piecewise(domain, range, clamp ? deinterpolateClamp(deinterpolate) : deinterpolate, interpolate$$1)))(+x);
11788   }
11789
11790   scale.invert = function(y) {
11791     return (input || (input = piecewise(range, domain, deinterpolateLinear, clamp ? reinterpolateClamp(reinterpolate) : reinterpolate)))(+y);
11792   };
11793
11794   scale.domain = function(_) {
11795     return arguments.length ? (domain = map$3.call(_, number$2), rescale()) : domain.slice();
11796   };
11797
11798   scale.range = function(_) {
11799     return arguments.length ? (range = slice$5.call(_), rescale()) : range.slice();
11800   };
11801
11802   scale.rangeRound = function(_) {
11803     return range = slice$5.call(_), interpolate$$1 = interpolateRound, rescale();
11804   };
11805
11806   scale.clamp = function(_) {
11807     return arguments.length ? (clamp = !!_, rescale()) : clamp;
11808   };
11809
11810   scale.interpolate = function(_) {
11811     return arguments.length ? (interpolate$$1 = _, rescale()) : interpolate$$1;
11812   };
11813
11814   return rescale();
11815 }
11816
11817 function tickFormat(domain, count, specifier) {
11818   var start = domain[0],
11819       stop = domain[domain.length - 1],
11820       step = tickStep(start, stop, count == null ? 10 : count),
11821       precision;
11822   specifier = formatSpecifier(specifier == null ? ",f" : specifier);
11823   switch (specifier.type) {
11824     case "s": {
11825       var value = Math.max(Math.abs(start), Math.abs(stop));
11826       if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;
11827       return formatPrefix(specifier, value);
11828     }
11829     case "":
11830     case "e":
11831     case "g":
11832     case "p":
11833     case "r": {
11834       if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e");
11835       break;
11836     }
11837     case "f":
11838     case "%": {
11839       if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2;
11840       break;
11841     }
11842   }
11843   return format(specifier);
11844 }
11845
11846 function linearish(scale) {
11847   var domain = scale.domain;
11848
11849   scale.ticks = function(count) {
11850     var d = domain();
11851     return ticks(d[0], d[d.length - 1], count == null ? 10 : count);
11852   };
11853
11854   scale.tickFormat = function(count, specifier) {
11855     return tickFormat(domain(), count, specifier);
11856   };
11857
11858   scale.nice = function(count) {
11859     if (count == null) count = 10;
11860
11861     var d = domain(),
11862         i0 = 0,
11863         i1 = d.length - 1,
11864         start = d[i0],
11865         stop = d[i1],
11866         step;
11867
11868     if (stop < start) {
11869       step = start, start = stop, stop = step;
11870       step = i0, i0 = i1, i1 = step;
11871     }
11872
11873     step = tickIncrement(start, stop, count);
11874
11875     if (step > 0) {
11876       start = Math.floor(start / step) * step;
11877       stop = Math.ceil(stop / step) * step;
11878       step = tickIncrement(start, stop, count);
11879     } else if (step < 0) {
11880       start = Math.ceil(start * step) / step;
11881       stop = Math.floor(stop * step) / step;
11882       step = tickIncrement(start, stop, count);
11883     }
11884
11885     if (step > 0) {
11886       d[i0] = Math.floor(start / step) * step;
11887       d[i1] = Math.ceil(stop / step) * step;
11888       domain(d);
11889     } else if (step < 0) {
11890       d[i0] = Math.ceil(start * step) / step;
11891       d[i1] = Math.floor(stop * step) / step;
11892       domain(d);
11893     }
11894
11895     return scale;
11896   };
11897
11898   return scale;
11899 }
11900
11901 function linear$2() {
11902   var scale = continuous(deinterpolateLinear, d3_interpolateNumber);
11903
11904   scale.copy = function() {
11905     return copy(scale, linear$2());
11906   };
11907
11908   return linearish(scale);
11909 }
11910
11911 function identity$5() {
11912   var domain = [0, 1];
11913
11914   function scale(x) {
11915     return +x;
11916   }
11917
11918   scale.invert = scale;
11919
11920   scale.domain = scale.range = function(_) {
11921     return arguments.length ? (domain = map$3.call(_, number$2), scale) : domain.slice();
11922   };
11923
11924   scale.copy = function() {
11925     return identity$5().domain(domain);
11926   };
11927
11928   return linearish(scale);
11929 }
11930
11931 function nice(domain, interval) {
11932   domain = domain.slice();
11933
11934   var i0 = 0,
11935       i1 = domain.length - 1,
11936       x0 = domain[i0],
11937       x1 = domain[i1],
11938       t;
11939
11940   if (x1 < x0) {
11941     t = i0, i0 = i1, i1 = t;
11942     t = x0, x0 = x1, x1 = t;
11943   }
11944
11945   domain[i0] = interval.floor(x0);
11946   domain[i1] = interval.ceil(x1);
11947   return domain;
11948 }
11949
11950 function deinterpolate(a, b) {
11951   return (b = Math.log(b / a))
11952       ? function(x) { return Math.log(x / a) / b; }
11953       : constant$9(b);
11954 }
11955
11956 function reinterpolate(a, b) {
11957   return a < 0
11958       ? function(t) { return -Math.pow(-b, t) * Math.pow(-a, 1 - t); }
11959       : function(t) { return Math.pow(b, t) * Math.pow(a, 1 - t); };
11960 }
11961
11962 function pow10(x) {
11963   return isFinite(x) ? +("1e" + x) : x < 0 ? 0 : x;
11964 }
11965
11966 function powp(base) {
11967   return base === 10 ? pow10
11968       : base === Math.E ? Math.exp
11969       : function(x) { return Math.pow(base, x); };
11970 }
11971
11972 function logp(base) {
11973   return base === Math.E ? Math.log
11974       : base === 10 && Math.log10
11975       || base === 2 && Math.log2
11976       || (base = Math.log(base), function(x) { return Math.log(x) / base; });
11977 }
11978
11979 function reflect(f) {
11980   return function(x) {
11981     return -f(-x);
11982   };
11983 }
11984
11985 function log$1() {
11986   var scale = continuous(deinterpolate, reinterpolate).domain([1, 10]),
11987       domain = scale.domain,
11988       base = 10,
11989       logs = logp(10),
11990       pows = powp(10);
11991
11992   function rescale() {
11993     logs = logp(base), pows = powp(base);
11994     if (domain()[0] < 0) logs = reflect(logs), pows = reflect(pows);
11995     return scale;
11996   }
11997
11998   scale.base = function(_) {
11999     return arguments.length ? (base = +_, rescale()) : base;
12000   };
12001
12002   scale.domain = function(_) {
12003     return arguments.length ? (domain(_), rescale()) : domain();
12004   };
12005
12006   scale.ticks = function(count) {
12007     var d = domain(),
12008         u = d[0],
12009         v = d[d.length - 1],
12010         r;
12011
12012     if (r = v < u) i = u, u = v, v = i;
12013
12014     var i = logs(u),
12015         j = logs(v),
12016         p,
12017         k,
12018         t,
12019         n = count == null ? 10 : +count,
12020         z = [];
12021
12022     if (!(base % 1) && j - i < n) {
12023       i = Math.round(i) - 1, j = Math.round(j) + 1;
12024       if (u > 0) for (; i < j; ++i) {
12025         for (k = 1, p = pows(i); k < base; ++k) {
12026           t = p * k;
12027           if (t < u) continue;
12028           if (t > v) break;
12029           z.push(t);
12030         }
12031       } else for (; i < j; ++i) {
12032         for (k = base - 1, p = pows(i); k >= 1; --k) {
12033           t = p * k;
12034           if (t < u) continue;
12035           if (t > v) break;
12036           z.push(t);
12037         }
12038       }
12039     } else {
12040       z = ticks(i, j, Math.min(j - i, n)).map(pows);
12041     }
12042
12043     return r ? z.reverse() : z;
12044   };
12045
12046   scale.tickFormat = function(count, specifier) {
12047     if (specifier == null) specifier = base === 10 ? ".0e" : ",";
12048     if (typeof specifier !== "function") specifier = format(specifier);
12049     if (count === Infinity) return specifier;
12050     if (count == null) count = 10;
12051     var k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate?
12052     return function(d) {
12053       var i = d / pows(Math.round(logs(d)));
12054       if (i * base < base - 0.5) i *= base;
12055       return i <= k ? specifier(d) : "";
12056     };
12057   };
12058
12059   scale.nice = function() {
12060     return domain(nice(domain(), {
12061       floor: function(x) { return pows(Math.floor(logs(x))); },
12062       ceil: function(x) { return pows(Math.ceil(logs(x))); }
12063     }));
12064   };
12065
12066   scale.copy = function() {
12067     return copy(scale, log$1().base(base));
12068   };
12069
12070   return scale;
12071 }
12072
12073 function raise$1(x, exponent) {
12074   return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent);
12075 }
12076
12077 function pow$1() {
12078   var exponent = 1,
12079       scale = continuous(deinterpolate, reinterpolate),
12080       domain = scale.domain;
12081
12082   function deinterpolate(a, b) {
12083     return (b = raise$1(b, exponent) - (a = raise$1(a, exponent)))
12084         ? function(x) { return (raise$1(x, exponent) - a) / b; }
12085         : constant$9(b);
12086   }
12087
12088   function reinterpolate(a, b) {
12089     b = raise$1(b, exponent) - (a = raise$1(a, exponent));
12090     return function(t) { return raise$1(a + b * t, 1 / exponent); };
12091   }
12092
12093   scale.exponent = function(_) {
12094     return arguments.length ? (exponent = +_, domain(domain())) : exponent;
12095   };
12096
12097   scale.copy = function() {
12098     return copy(scale, pow$1().exponent(exponent));
12099   };
12100
12101   return linearish(scale);
12102 }
12103
12104 function sqrt$1() {
12105   return pow$1().exponent(0.5);
12106 }
12107
12108 function quantile$$1() {
12109   var domain = [],
12110       range = [],
12111       thresholds = [];
12112
12113   function rescale() {
12114     var i = 0, n = Math.max(1, range.length);
12115     thresholds = new Array(n - 1);
12116     while (++i < n) thresholds[i - 1] = threshold(domain, i / n);
12117     return scale;
12118   }
12119
12120   function scale(x) {
12121     if (!isNaN(x = +x)) return range[bisectRight(thresholds, x)];
12122   }
12123
12124   scale.invertExtent = function(y) {
12125     var i = range.indexOf(y);
12126     return i < 0 ? [NaN, NaN] : [
12127       i > 0 ? thresholds[i - 1] : domain[0],
12128       i < thresholds.length ? thresholds[i] : domain[domain.length - 1]
12129     ];
12130   };
12131
12132   scale.domain = function(_) {
12133     if (!arguments.length) return domain.slice();
12134     domain = [];
12135     for (var i = 0, n = _.length, d; i < n; ++i) if (d = _[i], d != null && !isNaN(d = +d)) domain.push(d);
12136     domain.sort(d3_ascending);
12137     return rescale();
12138   };
12139
12140   scale.range = function(_) {
12141     return arguments.length ? (range = slice$5.call(_), rescale()) : range.slice();
12142   };
12143
12144   scale.quantiles = function() {
12145     return thresholds.slice();
12146   };
12147
12148   scale.copy = function() {
12149     return quantile$$1()
12150         .domain(domain)
12151         .range(range);
12152   };
12153
12154   return scale;
12155 }
12156
12157 function quantize() {
12158   var x0 = 0,
12159       x1 = 1,
12160       n = 1,
12161       domain = [0.5],
12162       range = [0, 1];
12163
12164   function scale(x) {
12165     if (x <= x) return range[bisectRight(domain, x, 0, n)];
12166   }
12167
12168   function rescale() {
12169     var i = -1;
12170     domain = new Array(n);
12171     while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1);
12172     return scale;
12173   }
12174
12175   scale.domain = function(_) {
12176     return arguments.length ? (x0 = +_[0], x1 = +_[1], rescale()) : [x0, x1];
12177   };
12178
12179   scale.range = function(_) {
12180     return arguments.length ? (n = (range = slice$5.call(_)).length - 1, rescale()) : range.slice();
12181   };
12182
12183   scale.invertExtent = function(y) {
12184     var i = range.indexOf(y);
12185     return i < 0 ? [NaN, NaN]
12186         : i < 1 ? [x0, domain[0]]
12187         : i >= n ? [domain[n - 1], x1]
12188         : [domain[i - 1], domain[i]];
12189   };
12190
12191   scale.copy = function() {
12192     return quantize()
12193         .domain([x0, x1])
12194         .range(range);
12195   };
12196
12197   return linearish(scale);
12198 }
12199
12200 function threshold$1() {
12201   var domain = [0.5],
12202       range = [0, 1],
12203       n = 1;
12204
12205   function scale(x) {
12206     if (x <= x) return range[bisectRight(domain, x, 0, n)];
12207   }
12208
12209   scale.domain = function(_) {
12210     return arguments.length ? (domain = slice$5.call(_), n = Math.min(domain.length, range.length - 1), scale) : domain.slice();
12211   };
12212
12213   scale.range = function(_) {
12214     return arguments.length ? (range = slice$5.call(_), n = Math.min(domain.length, range.length - 1), scale) : range.slice();
12215   };
12216
12217   scale.invertExtent = function(y) {
12218     var i = range.indexOf(y);
12219     return [domain[i - 1], domain[i]];
12220   };
12221
12222   scale.copy = function() {
12223     return threshold$1()
12224         .domain(domain)
12225         .range(range);
12226   };
12227
12228   return scale;
12229 }
12230
12231 var t0$1 = new Date;
12232 var t1$1 = new Date;
12233
12234 function newInterval(floori, offseti, count, field) {
12235
12236   function interval(date) {
12237     return floori(date = new Date(+date)), date;
12238   }
12239
12240   interval.floor = interval;
12241
12242   interval.ceil = function(date) {
12243     return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date;
12244   };
12245
12246   interval.round = function(date) {
12247     var d0 = interval(date),
12248         d1 = interval.ceil(date);
12249     return date - d0 < d1 - date ? d0 : d1;
12250   };
12251
12252   interval.offset = function(date, step) {
12253     return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;
12254   };
12255
12256   interval.range = function(start, stop, step) {
12257     var range = [], previous;
12258     start = interval.ceil(start);
12259     step = step == null ? 1 : Math.floor(step);
12260     if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date
12261     do range.push(previous = new Date(+start)), offseti(start, step), floori(start);
12262     while (previous < start && start < stop);
12263     return range;
12264   };
12265
12266   interval.filter = function(test) {
12267     return newInterval(function(date) {
12268       if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1);
12269     }, function(date, step) {
12270       if (date >= date) {
12271         if (step < 0) while (++step <= 0) {
12272           while (offseti(date, -1), !test(date)) {} // eslint-disable-line no-empty
12273         } else while (--step >= 0) {
12274           while (offseti(date, +1), !test(date)) {} // eslint-disable-line no-empty
12275         }
12276       }
12277     });
12278   };
12279
12280   if (count) {
12281     interval.count = function(start, end) {
12282       t0$1.setTime(+start), t1$1.setTime(+end);
12283       floori(t0$1), floori(t1$1);
12284       return Math.floor(count(t0$1, t1$1));
12285     };
12286
12287     interval.every = function(step) {
12288       step = Math.floor(step);
12289       return !isFinite(step) || !(step > 0) ? null
12290           : !(step > 1) ? interval
12291           : interval.filter(field
12292               ? function(d) { return field(d) % step === 0; }
12293               : function(d) { return interval.count(0, d) % step === 0; });
12294     };
12295   }
12296
12297   return interval;
12298 }
12299
12300 var millisecond = newInterval(function() {
12301   // noop
12302 }, function(date, step) {
12303   date.setTime(+date + step);
12304 }, function(start, end) {
12305   return end - start;
12306 });
12307
12308 // An optimized implementation for this simple case.
12309 millisecond.every = function(k) {
12310   k = Math.floor(k);
12311   if (!isFinite(k) || !(k > 0)) return null;
12312   if (!(k > 1)) return millisecond;
12313   return newInterval(function(date) {
12314     date.setTime(Math.floor(date / k) * k);
12315   }, function(date, step) {
12316     date.setTime(+date + step * k);
12317   }, function(start, end) {
12318     return (end - start) / k;
12319   });
12320 };
12321
12322 var milliseconds = millisecond.range;
12323
12324 var durationSecond = 1e3;
12325 var durationMinute = 6e4;
12326 var durationHour = 36e5;
12327 var durationDay = 864e5;
12328 var durationWeek = 6048e5;
12329
12330 var second = newInterval(function(date) {
12331   date.setTime(Math.floor(date / durationSecond) * durationSecond);
12332 }, function(date, step) {
12333   date.setTime(+date + step * durationSecond);
12334 }, function(start, end) {
12335   return (end - start) / durationSecond;
12336 }, function(date) {
12337   return date.getUTCSeconds();
12338 });
12339
12340 var seconds = second.range;
12341
12342 var minute = newInterval(function(date) {
12343   date.setTime(Math.floor(date / durationMinute) * durationMinute);
12344 }, function(date, step) {
12345   date.setTime(+date + step * durationMinute);
12346 }, function(start, end) {
12347   return (end - start) / durationMinute;
12348 }, function(date) {
12349   return date.getMinutes();
12350 });
12351
12352 var minutes = minute.range;
12353
12354 var hour = newInterval(function(date) {
12355   var offset = date.getTimezoneOffset() * durationMinute % durationHour;
12356   if (offset < 0) offset += durationHour;
12357   date.setTime(Math.floor((+date - offset) / durationHour) * durationHour + offset);
12358 }, function(date, step) {
12359   date.setTime(+date + step * durationHour);
12360 }, function(start, end) {
12361   return (end - start) / durationHour;
12362 }, function(date) {
12363   return date.getHours();
12364 });
12365
12366 var hours = hour.range;
12367
12368 var day = newInterval(function(date) {
12369   date.setHours(0, 0, 0, 0);
12370 }, function(date, step) {
12371   date.setDate(date.getDate() + step);
12372 }, function(start, end) {
12373   return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationDay;
12374 }, function(date) {
12375   return date.getDate() - 1;
12376 });
12377
12378 var days = day.range;
12379
12380 function weekday(i) {
12381   return newInterval(function(date) {
12382     date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);
12383     date.setHours(0, 0, 0, 0);
12384   }, function(date, step) {
12385     date.setDate(date.getDate() + step * 7);
12386   }, function(start, end) {
12387     return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationWeek;
12388   });
12389 }
12390
12391 var sunday = weekday(0);
12392 var monday = weekday(1);
12393 var tuesday = weekday(2);
12394 var wednesday = weekday(3);
12395 var thursday = weekday(4);
12396 var friday = weekday(5);
12397 var saturday = weekday(6);
12398
12399 var sundays = sunday.range;
12400 var mondays = monday.range;
12401 var tuesdays = tuesday.range;
12402 var wednesdays = wednesday.range;
12403 var thursdays = thursday.range;
12404 var fridays = friday.range;
12405 var saturdays = saturday.range;
12406
12407 var month = newInterval(function(date) {
12408   date.setDate(1);
12409   date.setHours(0, 0, 0, 0);
12410 }, function(date, step) {
12411   date.setMonth(date.getMonth() + step);
12412 }, function(start, end) {
12413   return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;
12414 }, function(date) {
12415   return date.getMonth();
12416 });
12417
12418 var months = month.range;
12419
12420 var year = newInterval(function(date) {
12421   date.setMonth(0, 1);
12422   date.setHours(0, 0, 0, 0);
12423 }, function(date, step) {
12424   date.setFullYear(date.getFullYear() + step);
12425 }, function(start, end) {
12426   return end.getFullYear() - start.getFullYear();
12427 }, function(date) {
12428   return date.getFullYear();
12429 });
12430
12431 // An optimized implementation for this simple case.
12432 year.every = function(k) {
12433   return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {
12434     date.setFullYear(Math.floor(date.getFullYear() / k) * k);
12435     date.setMonth(0, 1);
12436     date.setHours(0, 0, 0, 0);
12437   }, function(date, step) {
12438     date.setFullYear(date.getFullYear() + step * k);
12439   });
12440 };
12441
12442 var years = year.range;
12443
12444 var utcMinute = newInterval(function(date) {
12445   date.setUTCSeconds(0, 0);
12446 }, function(date, step) {
12447   date.setTime(+date + step * durationMinute);
12448 }, function(start, end) {
12449   return (end - start) / durationMinute;
12450 }, function(date) {
12451   return date.getUTCMinutes();
12452 });
12453
12454 var utcMinutes = utcMinute.range;
12455
12456 var utcHour = newInterval(function(date) {
12457   date.setUTCMinutes(0, 0, 0);
12458 }, function(date, step) {
12459   date.setTime(+date + step * durationHour);
12460 }, function(start, end) {
12461   return (end - start) / durationHour;
12462 }, function(date) {
12463   return date.getUTCHours();
12464 });
12465
12466 var utcHours = utcHour.range;
12467
12468 var utcDay = newInterval(function(date) {
12469   date.setUTCHours(0, 0, 0, 0);
12470 }, function(date, step) {
12471   date.setUTCDate(date.getUTCDate() + step);
12472 }, function(start, end) {
12473   return (end - start) / durationDay;
12474 }, function(date) {
12475   return date.getUTCDate() - 1;
12476 });
12477
12478 var utcDays = utcDay.range;
12479
12480 function utcWeekday(i) {
12481   return newInterval(function(date) {
12482     date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);
12483     date.setUTCHours(0, 0, 0, 0);
12484   }, function(date, step) {
12485     date.setUTCDate(date.getUTCDate() + step * 7);
12486   }, function(start, end) {
12487     return (end - start) / durationWeek;
12488   });
12489 }
12490
12491 var utcSunday = utcWeekday(0);
12492 var utcMonday = utcWeekday(1);
12493 var utcTuesday = utcWeekday(2);
12494 var utcWednesday = utcWeekday(3);
12495 var utcThursday = utcWeekday(4);
12496 var utcFriday = utcWeekday(5);
12497 var utcSaturday = utcWeekday(6);
12498
12499 var utcSundays = utcSunday.range;
12500 var utcMondays = utcMonday.range;
12501 var utcTuesdays = utcTuesday.range;
12502 var utcWednesdays = utcWednesday.range;
12503 var utcThursdays = utcThursday.range;
12504 var utcFridays = utcFriday.range;
12505 var utcSaturdays = utcSaturday.range;
12506
12507 var utcMonth = newInterval(function(date) {
12508   date.setUTCDate(1);
12509   date.setUTCHours(0, 0, 0, 0);
12510 }, function(date, step) {
12511   date.setUTCMonth(date.getUTCMonth() + step);
12512 }, function(start, end) {
12513   return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;
12514 }, function(date) {
12515   return date.getUTCMonth();
12516 });
12517
12518 var utcMonths = utcMonth.range;
12519
12520 var utcYear = newInterval(function(date) {
12521   date.setUTCMonth(0, 1);
12522   date.setUTCHours(0, 0, 0, 0);
12523 }, function(date, step) {
12524   date.setUTCFullYear(date.getUTCFullYear() + step);
12525 }, function(start, end) {
12526   return end.getUTCFullYear() - start.getUTCFullYear();
12527 }, function(date) {
12528   return date.getUTCFullYear();
12529 });
12530
12531 // An optimized implementation for this simple case.
12532 utcYear.every = function(k) {
12533   return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {
12534     date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);
12535     date.setUTCMonth(0, 1);
12536     date.setUTCHours(0, 0, 0, 0);
12537   }, function(date, step) {
12538     date.setUTCFullYear(date.getUTCFullYear() + step * k);
12539   });
12540 };
12541
12542 var utcYears = utcYear.range;
12543
12544 function localDate(d) {
12545   if (0 <= d.y && d.y < 100) {
12546     var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);
12547     date.setFullYear(d.y);
12548     return date;
12549   }
12550   return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);
12551 }
12552
12553 function utcDate(d) {
12554   if (0 <= d.y && d.y < 100) {
12555     var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));
12556     date.setUTCFullYear(d.y);
12557     return date;
12558   }
12559   return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));
12560 }
12561
12562 function newYear(y) {
12563   return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0};
12564 }
12565
12566 function formatLocale$1(locale) {
12567   var locale_dateTime = locale.dateTime,
12568       locale_date = locale.date,
12569       locale_time = locale.time,
12570       locale_periods = locale.periods,
12571       locale_weekdays = locale.days,
12572       locale_shortWeekdays = locale.shortDays,
12573       locale_months = locale.months,
12574       locale_shortMonths = locale.shortMonths;
12575
12576   var periodRe = formatRe(locale_periods),
12577       periodLookup = formatLookup(locale_periods),
12578       weekdayRe = formatRe(locale_weekdays),
12579       weekdayLookup = formatLookup(locale_weekdays),
12580       shortWeekdayRe = formatRe(locale_shortWeekdays),
12581       shortWeekdayLookup = formatLookup(locale_shortWeekdays),
12582       monthRe = formatRe(locale_months),
12583       monthLookup = formatLookup(locale_months),
12584       shortMonthRe = formatRe(locale_shortMonths),
12585       shortMonthLookup = formatLookup(locale_shortMonths);
12586
12587   var formats = {
12588     "a": formatShortWeekday,
12589     "A": formatWeekday,
12590     "b": formatShortMonth,
12591     "B": formatMonth,
12592     "c": null,
12593     "d": formatDayOfMonth,
12594     "e": formatDayOfMonth,
12595     "f": formatMicroseconds,
12596     "H": formatHour24,
12597     "I": formatHour12,
12598     "j": formatDayOfYear,
12599     "L": formatMilliseconds,
12600     "m": formatMonthNumber,
12601     "M": formatMinutes,
12602     "p": formatPeriod,
12603     "Q": formatUnixTimestamp,
12604     "s": formatUnixTimestampSeconds,
12605     "S": formatSeconds,
12606     "u": formatWeekdayNumberMonday,
12607     "U": formatWeekNumberSunday,
12608     "V": formatWeekNumberISO,
12609     "w": formatWeekdayNumberSunday,
12610     "W": formatWeekNumberMonday,
12611     "x": null,
12612     "X": null,
12613     "y": formatYear,
12614     "Y": formatFullYear,
12615     "Z": formatZone,
12616     "%": formatLiteralPercent
12617   };
12618
12619   var utcFormats = {
12620     "a": formatUTCShortWeekday,
12621     "A": formatUTCWeekday,
12622     "b": formatUTCShortMonth,
12623     "B": formatUTCMonth,
12624     "c": null,
12625     "d": formatUTCDayOfMonth,
12626     "e": formatUTCDayOfMonth,
12627     "f": formatUTCMicroseconds,
12628     "H": formatUTCHour24,
12629     "I": formatUTCHour12,
12630     "j": formatUTCDayOfYear,
12631     "L": formatUTCMilliseconds,
12632     "m": formatUTCMonthNumber,
12633     "M": formatUTCMinutes,
12634     "p": formatUTCPeriod,
12635     "Q": formatUnixTimestamp,
12636     "s": formatUnixTimestampSeconds,
12637     "S": formatUTCSeconds,
12638     "u": formatUTCWeekdayNumberMonday,
12639     "U": formatUTCWeekNumberSunday,
12640     "V": formatUTCWeekNumberISO,
12641     "w": formatUTCWeekdayNumberSunday,
12642     "W": formatUTCWeekNumberMonday,
12643     "x": null,
12644     "X": null,
12645     "y": formatUTCYear,
12646     "Y": formatUTCFullYear,
12647     "Z": formatUTCZone,
12648     "%": formatLiteralPercent
12649   };
12650
12651   var parses = {
12652     "a": parseShortWeekday,
12653     "A": parseWeekday,
12654     "b": parseShortMonth,
12655     "B": parseMonth,
12656     "c": parseLocaleDateTime,
12657     "d": parseDayOfMonth,
12658     "e": parseDayOfMonth,
12659     "f": parseMicroseconds,
12660     "H": parseHour24,
12661     "I": parseHour24,
12662     "j": parseDayOfYear,
12663     "L": parseMilliseconds,
12664     "m": parseMonthNumber,
12665     "M": parseMinutes,
12666     "p": parsePeriod,
12667     "Q": parseUnixTimestamp,
12668     "s": parseUnixTimestampSeconds,
12669     "S": parseSeconds,
12670     "u": parseWeekdayNumberMonday,
12671     "U": parseWeekNumberSunday,
12672     "V": parseWeekNumberISO,
12673     "w": parseWeekdayNumberSunday,
12674     "W": parseWeekNumberMonday,
12675     "x": parseLocaleDate,
12676     "X": parseLocaleTime,
12677     "y": parseYear,
12678     "Y": parseFullYear,
12679     "Z": parseZone,
12680     "%": parseLiteralPercent
12681   };
12682
12683   // These recursive directive definitions must be deferred.
12684   formats.x = newFormat(locale_date, formats);
12685   formats.X = newFormat(locale_time, formats);
12686   formats.c = newFormat(locale_dateTime, formats);
12687   utcFormats.x = newFormat(locale_date, utcFormats);
12688   utcFormats.X = newFormat(locale_time, utcFormats);
12689   utcFormats.c = newFormat(locale_dateTime, utcFormats);
12690
12691   function newFormat(specifier, formats) {
12692     return function(date) {
12693       var string = [],
12694           i = -1,
12695           j = 0,
12696           n = specifier.length,
12697           c,
12698           pad,
12699           format;
12700
12701       if (!(date instanceof Date)) date = new Date(+date);
12702
12703       while (++i < n) {
12704         if (specifier.charCodeAt(i) === 37) {
12705           string.push(specifier.slice(j, i));
12706           if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);
12707           else pad = c === "e" ? " " : "0";
12708           if (format = formats[c]) c = format(date, pad);
12709           string.push(c);
12710           j = i + 1;
12711         }
12712       }
12713
12714       string.push(specifier.slice(j, i));
12715       return string.join("");
12716     };
12717   }
12718
12719   function newParse(specifier, newDate) {
12720     return function(string) {
12721       var d = newYear(1900),
12722           i = parseSpecifier(d, specifier, string += "", 0),
12723           week, day$$1;
12724       if (i != string.length) return null;
12725
12726       // If a UNIX timestamp is specified, return it.
12727       if ("Q" in d) return new Date(d.Q);
12728
12729       // The am-pm flag is 0 for AM, and 1 for PM.
12730       if ("p" in d) d.H = d.H % 12 + d.p * 12;
12731
12732       // Convert day-of-week and week-of-year to day-of-year.
12733       if ("V" in d) {
12734         if (d.V < 1 || d.V > 53) return null;
12735         if (!("w" in d)) d.w = 1;
12736         if ("Z" in d) {
12737           week = utcDate(newYear(d.y)), day$$1 = week.getUTCDay();
12738           week = day$$1 > 4 || day$$1 === 0 ? utcMonday.ceil(week) : utcMonday(week);
12739           week = utcDay.offset(week, (d.V - 1) * 7);
12740           d.y = week.getUTCFullYear();
12741           d.m = week.getUTCMonth();
12742           d.d = week.getUTCDate() + (d.w + 6) % 7;
12743         } else {
12744           week = newDate(newYear(d.y)), day$$1 = week.getDay();
12745           week = day$$1 > 4 || day$$1 === 0 ? monday.ceil(week) : monday(week);
12746           week = day.offset(week, (d.V - 1) * 7);
12747           d.y = week.getFullYear();
12748           d.m = week.getMonth();
12749           d.d = week.getDate() + (d.w + 6) % 7;
12750         }
12751       } else if ("W" in d || "U" in d) {
12752         if (!("w" in d)) d.w = "u" in d ? d.u % 7 : "W" in d ? 1 : 0;
12753         day$$1 = "Z" in d ? utcDate(newYear(d.y)).getUTCDay() : newDate(newYear(d.y)).getDay();
12754         d.m = 0;
12755         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;
12756       }
12757
12758       // If a time zone is specified, all fields are interpreted as UTC and then
12759       // offset according to the specified time zone.
12760       if ("Z" in d) {
12761         d.H += d.Z / 100 | 0;
12762         d.M += d.Z % 100;
12763         return utcDate(d);
12764       }
12765
12766       // Otherwise, all fields are in local time.
12767       return newDate(d);
12768     };
12769   }
12770
12771   function parseSpecifier(d, specifier, string, j) {
12772     var i = 0,
12773         n = specifier.length,
12774         m = string.length,
12775         c,
12776         parse;
12777
12778     while (i < n) {
12779       if (j >= m) return -1;
12780       c = specifier.charCodeAt(i++);
12781       if (c === 37) {
12782         c = specifier.charAt(i++);
12783         parse = parses[c in pads ? specifier.charAt(i++) : c];
12784         if (!parse || ((j = parse(d, string, j)) < 0)) return -1;
12785       } else if (c != string.charCodeAt(j++)) {
12786         return -1;
12787       }
12788     }
12789
12790     return j;
12791   }
12792
12793   function parsePeriod(d, string, i) {
12794     var n = periodRe.exec(string.slice(i));
12795     return n ? (d.p = periodLookup[n[0].toLowerCase()], i + n[0].length) : -1;
12796   }
12797
12798   function parseShortWeekday(d, string, i) {
12799     var n = shortWeekdayRe.exec(string.slice(i));
12800     return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;
12801   }
12802
12803   function parseWeekday(d, string, i) {
12804     var n = weekdayRe.exec(string.slice(i));
12805     return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;
12806   }
12807
12808   function parseShortMonth(d, string, i) {
12809     var n = shortMonthRe.exec(string.slice(i));
12810     return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1;
12811   }
12812
12813   function parseMonth(d, string, i) {
12814     var n = monthRe.exec(string.slice(i));
12815     return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1;
12816   }
12817
12818   function parseLocaleDateTime(d, string, i) {
12819     return parseSpecifier(d, locale_dateTime, string, i);
12820   }
12821
12822   function parseLocaleDate(d, string, i) {
12823     return parseSpecifier(d, locale_date, string, i);
12824   }
12825
12826   function parseLocaleTime(d, string, i) {
12827     return parseSpecifier(d, locale_time, string, i);
12828   }
12829
12830   function formatShortWeekday(d) {
12831     return locale_shortWeekdays[d.getDay()];
12832   }
12833
12834   function formatWeekday(d) {
12835     return locale_weekdays[d.getDay()];
12836   }
12837
12838   function formatShortMonth(d) {
12839     return locale_shortMonths[d.getMonth()];
12840   }
12841
12842   function formatMonth(d) {
12843     return locale_months[d.getMonth()];
12844   }
12845
12846   function formatPeriod(d) {
12847     return locale_periods[+(d.getHours() >= 12)];
12848   }
12849
12850   function formatUTCShortWeekday(d) {
12851     return locale_shortWeekdays[d.getUTCDay()];
12852   }
12853
12854   function formatUTCWeekday(d) {
12855     return locale_weekdays[d.getUTCDay()];
12856   }
12857
12858   function formatUTCShortMonth(d) {
12859     return locale_shortMonths[d.getUTCMonth()];
12860   }
12861
12862   function formatUTCMonth(d) {
12863     return locale_months[d.getUTCMonth()];
12864   }
12865
12866   function formatUTCPeriod(d) {
12867     return locale_periods[+(d.getUTCHours() >= 12)];
12868   }
12869
12870   return {
12871     format: function(specifier) {
12872       var f = newFormat(specifier += "", formats);
12873       f.toString = function() { return specifier; };
12874       return f;
12875     },
12876     parse: function(specifier) {
12877       var p = newParse(specifier += "", localDate);
12878       p.toString = function() { return specifier; };
12879       return p;
12880     },
12881     utcFormat: function(specifier) {
12882       var f = newFormat(specifier += "", utcFormats);
12883       f.toString = function() { return specifier; };
12884       return f;
12885     },
12886     utcParse: function(specifier) {
12887       var p = newParse(specifier, utcDate);
12888       p.toString = function() { return specifier; };
12889       return p;
12890     }
12891   };
12892 }
12893
12894 var pads = {"-": "", "_": " ", "0": "0"};
12895 var numberRe = /^\s*\d+/;
12896 var percentRe = /^%/;
12897 var requoteRe = /[\\^$*+?|[\]().{}]/g;
12898
12899 function pad(value, fill, width) {
12900   var sign = value < 0 ? "-" : "",
12901       string = (sign ? -value : value) + "",
12902       length = string.length;
12903   return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);
12904 }
12905
12906 function requote(s) {
12907   return s.replace(requoteRe, "\\$&");
12908 }
12909
12910 function formatRe(names) {
12911   return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i");
12912 }
12913
12914 function formatLookup(names) {
12915   var map = {}, i = -1, n = names.length;
12916   while (++i < n) map[names[i].toLowerCase()] = i;
12917   return map;
12918 }
12919
12920 function parseWeekdayNumberSunday(d, string, i) {
12921   var n = numberRe.exec(string.slice(i, i + 1));
12922   return n ? (d.w = +n[0], i + n[0].length) : -1;
12923 }
12924
12925 function parseWeekdayNumberMonday(d, string, i) {
12926   var n = numberRe.exec(string.slice(i, i + 1));
12927   return n ? (d.u = +n[0], i + n[0].length) : -1;
12928 }
12929
12930 function parseWeekNumberSunday(d, string, i) {
12931   var n = numberRe.exec(string.slice(i, i + 2));
12932   return n ? (d.U = +n[0], i + n[0].length) : -1;
12933 }
12934
12935 function parseWeekNumberISO(d, string, i) {
12936   var n = numberRe.exec(string.slice(i, i + 2));
12937   return n ? (d.V = +n[0], i + n[0].length) : -1;
12938 }
12939
12940 function parseWeekNumberMonday(d, string, i) {
12941   var n = numberRe.exec(string.slice(i, i + 2));
12942   return n ? (d.W = +n[0], i + n[0].length) : -1;
12943 }
12944
12945 function parseFullYear(d, string, i) {
12946   var n = numberRe.exec(string.slice(i, i + 4));
12947   return n ? (d.y = +n[0], i + n[0].length) : -1;
12948 }
12949
12950 function parseYear(d, string, i) {
12951   var n = numberRe.exec(string.slice(i, i + 2));
12952   return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1;
12953 }
12954
12955 function parseZone(d, string, i) {
12956   var n = /^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(string.slice(i, i + 6));
12957   return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || "00")), i + n[0].length) : -1;
12958 }
12959
12960 function parseMonthNumber(d, string, i) {
12961   var n = numberRe.exec(string.slice(i, i + 2));
12962   return n ? (d.m = n[0] - 1, i + n[0].length) : -1;
12963 }
12964
12965 function parseDayOfMonth(d, string, i) {
12966   var n = numberRe.exec(string.slice(i, i + 2));
12967   return n ? (d.d = +n[0], i + n[0].length) : -1;
12968 }
12969
12970 function parseDayOfYear(d, string, i) {
12971   var n = numberRe.exec(string.slice(i, i + 3));
12972   return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;
12973 }
12974
12975 function parseHour24(d, string, i) {
12976   var n = numberRe.exec(string.slice(i, i + 2));
12977   return n ? (d.H = +n[0], i + n[0].length) : -1;
12978 }
12979
12980 function parseMinutes(d, string, i) {
12981   var n = numberRe.exec(string.slice(i, i + 2));
12982   return n ? (d.M = +n[0], i + n[0].length) : -1;
12983 }
12984
12985 function parseSeconds(d, string, i) {
12986   var n = numberRe.exec(string.slice(i, i + 2));
12987   return n ? (d.S = +n[0], i + n[0].length) : -1;
12988 }
12989
12990 function parseMilliseconds(d, string, i) {
12991   var n = numberRe.exec(string.slice(i, i + 3));
12992   return n ? (d.L = +n[0], i + n[0].length) : -1;
12993 }
12994
12995 function parseMicroseconds(d, string, i) {
12996   var n = numberRe.exec(string.slice(i, i + 6));
12997   return n ? (d.L = Math.floor(n[0] / 1000), i + n[0].length) : -1;
12998 }
12999
13000 function parseLiteralPercent(d, string, i) {
13001   var n = percentRe.exec(string.slice(i, i + 1));
13002   return n ? i + n[0].length : -1;
13003 }
13004
13005 function parseUnixTimestamp(d, string, i) {
13006   var n = numberRe.exec(string.slice(i));
13007   return n ? (d.Q = +n[0], i + n[0].length) : -1;
13008 }
13009
13010 function parseUnixTimestampSeconds(d, string, i) {
13011   var n = numberRe.exec(string.slice(i));
13012   return n ? (d.Q = (+n[0]) * 1000, i + n[0].length) : -1;
13013 }
13014
13015 function formatDayOfMonth(d, p) {
13016   return pad(d.getDate(), p, 2);
13017 }
13018
13019 function formatHour24(d, p) {
13020   return pad(d.getHours(), p, 2);
13021 }
13022
13023 function formatHour12(d, p) {
13024   return pad(d.getHours() % 12 || 12, p, 2);
13025 }
13026
13027 function formatDayOfYear(d, p) {
13028   return pad(1 + day.count(year(d), d), p, 3);
13029 }
13030
13031 function formatMilliseconds(d, p) {
13032   return pad(d.getMilliseconds(), p, 3);
13033 }
13034
13035 function formatMicroseconds(d, p) {
13036   return formatMilliseconds(d, p) + "000";
13037 }
13038
13039 function formatMonthNumber(d, p) {
13040   return pad(d.getMonth() + 1, p, 2);
13041 }
13042
13043 function formatMinutes(d, p) {
13044   return pad(d.getMinutes(), p, 2);
13045 }
13046
13047 function formatSeconds(d, p) {
13048   return pad(d.getSeconds(), p, 2);
13049 }
13050
13051 function formatWeekdayNumberMonday(d) {
13052   var day$$1 = d.getDay();
13053   return day$$1 === 0 ? 7 : day$$1;
13054 }
13055
13056 function formatWeekNumberSunday(d, p) {
13057   return pad(sunday.count(year(d), d), p, 2);
13058 }
13059
13060 function formatWeekNumberISO(d, p) {
13061   var day$$1 = d.getDay();
13062   d = (day$$1 >= 4 || day$$1 === 0) ? thursday(d) : thursday.ceil(d);
13063   return pad(thursday.count(year(d), d) + (year(d).getDay() === 4), p, 2);
13064 }
13065
13066 function formatWeekdayNumberSunday(d) {
13067   return d.getDay();
13068 }
13069
13070 function formatWeekNumberMonday(d, p) {
13071   return pad(monday.count(year(d), d), p, 2);
13072 }
13073
13074 function formatYear(d, p) {
13075   return pad(d.getFullYear() % 100, p, 2);
13076 }
13077
13078 function formatFullYear(d, p) {
13079   return pad(d.getFullYear() % 10000, p, 4);
13080 }
13081
13082 function formatZone(d) {
13083   var z = d.getTimezoneOffset();
13084   return (z > 0 ? "-" : (z *= -1, "+"))
13085       + pad(z / 60 | 0, "0", 2)
13086       + pad(z % 60, "0", 2);
13087 }
13088
13089 function formatUTCDayOfMonth(d, p) {
13090   return pad(d.getUTCDate(), p, 2);
13091 }
13092
13093 function formatUTCHour24(d, p) {
13094   return pad(d.getUTCHours(), p, 2);
13095 }
13096
13097 function formatUTCHour12(d, p) {
13098   return pad(d.getUTCHours() % 12 || 12, p, 2);
13099 }
13100
13101 function formatUTCDayOfYear(d, p) {
13102   return pad(1 + utcDay.count(utcYear(d), d), p, 3);
13103 }
13104
13105 function formatUTCMilliseconds(d, p) {
13106   return pad(d.getUTCMilliseconds(), p, 3);
13107 }
13108
13109 function formatUTCMicroseconds(d, p) {
13110   return formatUTCMilliseconds(d, p) + "000";
13111 }
13112
13113 function formatUTCMonthNumber(d, p) {
13114   return pad(d.getUTCMonth() + 1, p, 2);
13115 }
13116
13117 function formatUTCMinutes(d, p) {
13118   return pad(d.getUTCMinutes(), p, 2);
13119 }
13120
13121 function formatUTCSeconds(d, p) {
13122   return pad(d.getUTCSeconds(), p, 2);
13123 }
13124
13125 function formatUTCWeekdayNumberMonday(d) {
13126   var dow = d.getUTCDay();
13127   return dow === 0 ? 7 : dow;
13128 }
13129
13130 function formatUTCWeekNumberSunday(d, p) {
13131   return pad(utcSunday.count(utcYear(d), d), p, 2);
13132 }
13133
13134 function formatUTCWeekNumberISO(d, p) {
13135   var day$$1 = d.getUTCDay();
13136   d = (day$$1 >= 4 || day$$1 === 0) ? utcThursday(d) : utcThursday.ceil(d);
13137   return pad(utcThursday.count(utcYear(d), d) + (utcYear(d).getUTCDay() === 4), p, 2);
13138 }
13139
13140 function formatUTCWeekdayNumberSunday(d) {
13141   return d.getUTCDay();
13142 }
13143
13144 function formatUTCWeekNumberMonday(d, p) {
13145   return pad(utcMonday.count(utcYear(d), d), p, 2);
13146 }
13147
13148 function formatUTCYear(d, p) {
13149   return pad(d.getUTCFullYear() % 100, p, 2);
13150 }
13151
13152 function formatUTCFullYear(d, p) {
13153   return pad(d.getUTCFullYear() % 10000, p, 4);
13154 }
13155
13156 function formatUTCZone() {
13157   return "+0000";
13158 }
13159
13160 function formatLiteralPercent() {
13161   return "%";
13162 }
13163
13164 function formatUnixTimestamp(d) {
13165   return +d;
13166 }
13167
13168 function formatUnixTimestampSeconds(d) {
13169   return Math.floor(+d / 1000);
13170 }
13171
13172 var locale$1;
13173 var timeFormat;
13174 var timeParse;
13175 var utcFormat;
13176 var utcParse;
13177
13178 defaultLocale$1({
13179   dateTime: "%x, %X",
13180   date: "%-m/%-d/%Y",
13181   time: "%-I:%M:%S %p",
13182   periods: ["AM", "PM"],
13183   days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
13184   shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
13185   months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
13186   shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
13187 });
13188
13189 function defaultLocale$1(definition) {
13190   locale$1 = formatLocale$1(definition);
13191   timeFormat = locale$1.format;
13192   timeParse = locale$1.parse;
13193   utcFormat = locale$1.utcFormat;
13194   utcParse = locale$1.utcParse;
13195   return locale$1;
13196 }
13197
13198 var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ";
13199
13200 function formatIsoNative(date) {
13201   return date.toISOString();
13202 }
13203
13204 var formatIso = Date.prototype.toISOString
13205     ? formatIsoNative
13206     : utcFormat(isoSpecifier);
13207
13208 function parseIsoNative(string) {
13209   var date = new Date(string);
13210   return isNaN(date) ? null : date;
13211 }
13212
13213 var parseIso = +new Date("2000-01-01T00:00:00.000Z")
13214     ? parseIsoNative
13215     : utcParse(isoSpecifier);
13216
13217 var durationSecond$1 = 1000;
13218 var durationMinute$1 = durationSecond$1 * 60;
13219 var durationHour$1 = durationMinute$1 * 60;
13220 var durationDay$1 = durationHour$1 * 24;
13221 var durationWeek$1 = durationDay$1 * 7;
13222 var durationMonth = durationDay$1 * 30;
13223 var durationYear = durationDay$1 * 365;
13224
13225 function date$1(t) {
13226   return new Date(t);
13227 }
13228
13229 function number$3(t) {
13230   return t instanceof Date ? +t : +new Date(+t);
13231 }
13232
13233 function calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format) {
13234   var scale = continuous(deinterpolateLinear, d3_interpolateNumber),
13235       invert = scale.invert,
13236       domain = scale.domain;
13237
13238   var formatMillisecond = format(".%L"),
13239       formatSecond = format(":%S"),
13240       formatMinute = format("%I:%M"),
13241       formatHour = format("%I %p"),
13242       formatDay = format("%a %d"),
13243       formatWeek = format("%b %d"),
13244       formatMonth = format("%B"),
13245       formatYear = format("%Y");
13246
13247   var tickIntervals = [
13248     [second$$1,  1,      durationSecond$1],
13249     [second$$1,  5,  5 * durationSecond$1],
13250     [second$$1, 15, 15 * durationSecond$1],
13251     [second$$1, 30, 30 * durationSecond$1],
13252     [minute$$1,  1,      durationMinute$1],
13253     [minute$$1,  5,  5 * durationMinute$1],
13254     [minute$$1, 15, 15 * durationMinute$1],
13255     [minute$$1, 30, 30 * durationMinute$1],
13256     [  hour$$1,  1,      durationHour$1  ],
13257     [  hour$$1,  3,  3 * durationHour$1  ],
13258     [  hour$$1,  6,  6 * durationHour$1  ],
13259     [  hour$$1, 12, 12 * durationHour$1  ],
13260     [   day$$1,  1,      durationDay$1   ],
13261     [   day$$1,  2,  2 * durationDay$1   ],
13262     [  week,  1,      durationWeek$1  ],
13263     [ month$$1,  1,      durationMonth ],
13264     [ month$$1,  3,  3 * durationMonth ],
13265     [  year$$1,  1,      durationYear  ]
13266   ];
13267
13268   function tickFormat(date) {
13269     return (second$$1(date) < date ? formatMillisecond
13270         : minute$$1(date) < date ? formatSecond
13271         : hour$$1(date) < date ? formatMinute
13272         : day$$1(date) < date ? formatHour
13273         : month$$1(date) < date ? (week(date) < date ? formatDay : formatWeek)
13274         : year$$1(date) < date ? formatMonth
13275         : formatYear)(date);
13276   }
13277
13278   function tickInterval(interval, start, stop, step) {
13279     if (interval == null) interval = 10;
13280
13281     // If a desired tick count is specified, pick a reasonable tick interval
13282     // based on the extent of the domain and a rough estimate of tick size.
13283     // Otherwise, assume interval is already a time interval and use it.
13284     if (typeof interval === "number") {
13285       var target = Math.abs(stop - start) / interval,
13286           i = d3_bisector(function(i) { return i[2]; }).right(tickIntervals, target);
13287       if (i === tickIntervals.length) {
13288         step = tickStep(start / durationYear, stop / durationYear, interval);
13289         interval = year$$1;
13290       } else if (i) {
13291         i = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i];
13292         step = i[1];
13293         interval = i[0];
13294       } else {
13295         step = Math.max(tickStep(start, stop, interval), 1);
13296         interval = millisecond$$1;
13297       }
13298     }
13299
13300     return step == null ? interval : interval.every(step);
13301   }
13302
13303   scale.invert = function(y) {
13304     return new Date(invert(y));
13305   };
13306
13307   scale.domain = function(_) {
13308     return arguments.length ? domain(map$3.call(_, number$3)) : domain().map(date$1);
13309   };
13310
13311   scale.ticks = function(interval, step) {
13312     var d = domain(),
13313         t0 = d[0],
13314         t1 = d[d.length - 1],
13315         r = t1 < t0,
13316         t;
13317     if (r) t = t0, t0 = t1, t1 = t;
13318     t = tickInterval(interval, t0, t1, step);
13319     t = t ? t.range(t0, t1 + 1) : []; // inclusive stop
13320     return r ? t.reverse() : t;
13321   };
13322
13323   scale.tickFormat = function(count, specifier) {
13324     return specifier == null ? tickFormat : format(specifier);
13325   };
13326
13327   scale.nice = function(interval, step) {
13328     var d = domain();
13329     return (interval = tickInterval(interval, d[0], d[d.length - 1], step))
13330         ? domain(nice(d, interval))
13331         : scale;
13332   };
13333
13334   scale.copy = function() {
13335     return copy(scale, calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format));
13336   };
13337
13338   return scale;
13339 }
13340
13341 function time() {
13342   return calendar(year, month, sunday, day, hour, minute, second, millisecond, timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]);
13343 }
13344
13345 function utcTime() {
13346   return calendar(utcYear, utcMonth, utcSunday, utcDay, utcHour, utcMinute, second, millisecond, utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]);
13347 }
13348
13349 function colors(s) {
13350   return s.match(/.{6}/g).map(function(x) {
13351     return "#" + x;
13352   });
13353 }
13354
13355 var category10 = colors("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf");
13356
13357 var category20b = colors("393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6");
13358
13359 var category20c = colors("3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9");
13360
13361 var category20 = colors("1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5");
13362
13363 var cubehelix$3 = cubehelixLong(cubehelix(300, 0.5, 0.0), cubehelix(-240, 0.5, 1.0));
13364
13365 var warm = cubehelixLong(cubehelix(-100, 0.75, 0.35), cubehelix(80, 1.50, 0.8));
13366
13367 var cool = cubehelixLong(cubehelix(260, 0.75, 0.35), cubehelix(80, 1.50, 0.8));
13368
13369 var rainbow = cubehelix();
13370
13371 function rainbow$1(t) {
13372   if (t < 0 || t > 1) t -= Math.floor(t);
13373   var ts = Math.abs(t - 0.5);
13374   rainbow.h = 360 * t - 100;
13375   rainbow.s = 1.5 - 1.5 * ts;
13376   rainbow.l = 0.8 - 0.9 * ts;
13377   return rainbow + "";
13378 }
13379
13380 function ramp(range) {
13381   var n = range.length;
13382   return function(t) {
13383     return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))];
13384   };
13385 }
13386
13387 var viridis = ramp(colors("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));
13388
13389 var magma = ramp(colors("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf"));
13390
13391 var inferno = ramp(colors("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4"));
13392
13393 var plasma = ramp(colors("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921"));
13394
13395 function sequential(interpolator) {
13396   var x0 = 0,
13397       x1 = 1,
13398       clamp = false;
13399
13400   function scale(x) {
13401     var t = (x - x0) / (x1 - x0);
13402     return interpolator(clamp ? Math.max(0, Math.min(1, t)) : t);
13403   }
13404
13405   scale.domain = function(_) {
13406     return arguments.length ? (x0 = +_[0], x1 = +_[1], scale) : [x0, x1];
13407   };
13408
13409   scale.clamp = function(_) {
13410     return arguments.length ? (clamp = !!_, scale) : clamp;
13411   };
13412
13413   scale.interpolator = function(_) {
13414     return arguments.length ? (interpolator = _, scale) : interpolator;
13415   };
13416
13417   scale.copy = function() {
13418     return sequential(interpolator).domain([x0, x1]).clamp(clamp);
13419   };
13420
13421   return linearish(scale);
13422 }
13423
13424 function constant$10(x) {
13425   return function constant() {
13426     return x;
13427   };
13428 }
13429
13430 var abs$1 = Math.abs;
13431 var atan2$1 = Math.atan2;
13432 var cos$2 = Math.cos;
13433 var max$2 = Math.max;
13434 var min$1 = Math.min;
13435 var sin$2 = Math.sin;
13436 var sqrt$2 = Math.sqrt;
13437
13438 var epsilon$3 = 1e-12;
13439 var pi$4 = Math.PI;
13440 var halfPi$3 = pi$4 / 2;
13441 var tau$4 = 2 * pi$4;
13442
13443 function acos$1(x) {
13444   return x > 1 ? 0 : x < -1 ? pi$4 : Math.acos(x);
13445 }
13446
13447 function asin$1(x) {
13448   return x >= 1 ? halfPi$3 : x <= -1 ? -halfPi$3 : Math.asin(x);
13449 }
13450
13451 function arcInnerRadius(d) {
13452   return d.innerRadius;
13453 }
13454
13455 function arcOuterRadius(d) {
13456   return d.outerRadius;
13457 }
13458
13459 function arcStartAngle(d) {
13460   return d.startAngle;
13461 }
13462
13463 function arcEndAngle(d) {
13464   return d.endAngle;
13465 }
13466
13467 function arcPadAngle(d) {
13468   return d && d.padAngle; // Note: optional!
13469 }
13470
13471 function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
13472   var x10 = x1 - x0, y10 = y1 - y0,
13473       x32 = x3 - x2, y32 = y3 - y2,
13474       t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / (y32 * x10 - x32 * y10);
13475   return [x0 + t * x10, y0 + t * y10];
13476 }
13477
13478 // Compute perpendicular offset line of length rc.
13479 // http://mathworld.wolfram.com/Circle-LineIntersection.html
13480 function cornerTangents(x0, y0, x1, y1, r1, rc, cw) {
13481   var x01 = x0 - x1,
13482       y01 = y0 - y1,
13483       lo = (cw ? rc : -rc) / sqrt$2(x01 * x01 + y01 * y01),
13484       ox = lo * y01,
13485       oy = -lo * x01,
13486       x11 = x0 + ox,
13487       y11 = y0 + oy,
13488       x10 = x1 + ox,
13489       y10 = y1 + oy,
13490       x00 = (x11 + x10) / 2,
13491       y00 = (y11 + y10) / 2,
13492       dx = x10 - x11,
13493       dy = y10 - y11,
13494       d2 = dx * dx + dy * dy,
13495       r = r1 - rc,
13496       D = x11 * y10 - x10 * y11,
13497       d = (dy < 0 ? -1 : 1) * sqrt$2(max$2(0, r * r * d2 - D * D)),
13498       cx0 = (D * dy - dx * d) / d2,
13499       cy0 = (-D * dx - dy * d) / d2,
13500       cx1 = (D * dy + dx * d) / d2,
13501       cy1 = (-D * dx + dy * d) / d2,
13502       dx0 = cx0 - x00,
13503       dy0 = cy0 - y00,
13504       dx1 = cx1 - x00,
13505       dy1 = cy1 - y00;
13506
13507   // Pick the closer of the two intersection points.
13508   // TODO Is there a faster way to determine which intersection to use?
13509   if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;
13510
13511   return {
13512     cx: cx0,
13513     cy: cy0,
13514     x01: -ox,
13515     y01: -oy,
13516     x11: cx0 * (r1 / r - 1),
13517     y11: cy0 * (r1 / r - 1)
13518   };
13519 }
13520
13521 function arc() {
13522   var innerRadius = arcInnerRadius,
13523       outerRadius = arcOuterRadius,
13524       cornerRadius = constant$10(0),
13525       padRadius = null,
13526       startAngle = arcStartAngle,
13527       endAngle = arcEndAngle,
13528       padAngle = arcPadAngle,
13529       context = null;
13530
13531   function arc() {
13532     var buffer,
13533         r,
13534         r0 = +innerRadius.apply(this, arguments),
13535         r1 = +outerRadius.apply(this, arguments),
13536         a0 = startAngle.apply(this, arguments) - halfPi$3,
13537         a1 = endAngle.apply(this, arguments) - halfPi$3,
13538         da = abs$1(a1 - a0),
13539         cw = a1 > a0;
13540
13541     if (!context) context = buffer = path();
13542
13543     // Ensure that the outer radius is always larger than the inner radius.
13544     if (r1 < r0) r = r1, r1 = r0, r0 = r;
13545
13546     // Is it a point?
13547     if (!(r1 > epsilon$3)) context.moveTo(0, 0);
13548
13549     // Or is it a circle or annulus?
13550     else if (da > tau$4 - epsilon$3) {
13551       context.moveTo(r1 * cos$2(a0), r1 * sin$2(a0));
13552       context.arc(0, 0, r1, a0, a1, !cw);
13553       if (r0 > epsilon$3) {
13554         context.moveTo(r0 * cos$2(a1), r0 * sin$2(a1));
13555         context.arc(0, 0, r0, a1, a0, cw);
13556       }
13557     }
13558
13559     // Or is it a circular or annular sector?
13560     else {
13561       var a01 = a0,
13562           a11 = a1,
13563           a00 = a0,
13564           a10 = a1,
13565           da0 = da,
13566           da1 = da,
13567           ap = padAngle.apply(this, arguments) / 2,
13568           rp = (ap > epsilon$3) && (padRadius ? +padRadius.apply(this, arguments) : sqrt$2(r0 * r0 + r1 * r1)),
13569           rc = min$1(abs$1(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),
13570           rc0 = rc,
13571           rc1 = rc,
13572           t0,
13573           t1;
13574
13575       // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.
13576       if (rp > epsilon$3) {
13577         var p0 = asin$1(rp / r0 * sin$2(ap)),
13578             p1 = asin$1(rp / r1 * sin$2(ap));
13579         if ((da0 -= p0 * 2) > epsilon$3) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;
13580         else da0 = 0, a00 = a10 = (a0 + a1) / 2;
13581         if ((da1 -= p1 * 2) > epsilon$3) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;
13582         else da1 = 0, a01 = a11 = (a0 + a1) / 2;
13583       }
13584
13585       var x01 = r1 * cos$2(a01),
13586           y01 = r1 * sin$2(a01),
13587           x10 = r0 * cos$2(a10),
13588           y10 = r0 * sin$2(a10);
13589
13590       // Apply rounded corners?
13591       if (rc > epsilon$3) {
13592         var x11 = r1 * cos$2(a11),
13593             y11 = r1 * sin$2(a11),
13594             x00 = r0 * cos$2(a00),
13595             y00 = r0 * sin$2(a00);
13596
13597         // Restrict the corner radius according to the sector angle.
13598         if (da < pi$4) {
13599           var oc = da0 > epsilon$3 ? intersect(x01, y01, x00, y00, x11, y11, x10, y10) : [x10, y10],
13600               ax = x01 - oc[0],
13601               ay = y01 - oc[1],
13602               bx = x11 - oc[0],
13603               by = y11 - oc[1],
13604               kc = 1 / sin$2(acos$1((ax * bx + ay * by) / (sqrt$2(ax * ax + ay * ay) * sqrt$2(bx * bx + by * by))) / 2),
13605               lc = sqrt$2(oc[0] * oc[0] + oc[1] * oc[1]);
13606           rc0 = min$1(rc, (r0 - lc) / (kc - 1));
13607           rc1 = min$1(rc, (r1 - lc) / (kc + 1));
13608         }
13609       }
13610
13611       // Is the sector collapsed to a line?
13612       if (!(da1 > epsilon$3)) context.moveTo(x01, y01);
13613
13614       // Does the sector’s outer ring have rounded corners?
13615       else if (rc1 > epsilon$3) {
13616         t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);
13617         t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);
13618
13619         context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);
13620
13621         // Have the corners merged?
13622         if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01), atan2$1(t1.y01, t1.x01), !cw);
13623
13624         // Otherwise, draw the two corners and the ring.
13625         else {
13626           context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01), atan2$1(t0.y11, t0.x11), !cw);
13627           context.arc(0, 0, r1, atan2$1(t0.cy + t0.y11, t0.cx + t0.x11), atan2$1(t1.cy + t1.y11, t1.cx + t1.x11), !cw);
13628           context.arc(t1.cx, t1.cy, rc1, atan2$1(t1.y11, t1.x11), atan2$1(t1.y01, t1.x01), !cw);
13629         }
13630       }
13631
13632       // Or is the outer ring just a circular arc?
13633       else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);
13634
13635       // Is there no inner ring, and it’s a circular sector?
13636       // Or perhaps it’s an annular sector collapsed due to padding?
13637       if (!(r0 > epsilon$3) || !(da0 > epsilon$3)) context.lineTo(x10, y10);
13638
13639       // Does the sector’s inner ring (or point) have rounded corners?
13640       else if (rc0 > epsilon$3) {
13641         t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);
13642         t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);
13643
13644         context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);
13645
13646         // Have the corners merged?
13647         if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01), atan2$1(t1.y01, t1.x01), !cw);
13648
13649         // Otherwise, draw the two corners and the ring.
13650         else {
13651           context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01), atan2$1(t0.y11, t0.x11), !cw);
13652           context.arc(0, 0, r0, atan2$1(t0.cy + t0.y11, t0.cx + t0.x11), atan2$1(t1.cy + t1.y11, t1.cx + t1.x11), cw);
13653           context.arc(t1.cx, t1.cy, rc0, atan2$1(t1.y11, t1.x11), atan2$1(t1.y01, t1.x01), !cw);
13654         }
13655       }
13656
13657       // Or is the inner ring just a circular arc?
13658       else context.arc(0, 0, r0, a10, a00, cw);
13659     }
13660
13661     context.closePath();
13662
13663     if (buffer) return context = null, buffer + "" || null;
13664   }
13665
13666   arc.centroid = function() {
13667     var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,
13668         a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi$4 / 2;
13669     return [cos$2(a) * r, sin$2(a) * r];
13670   };
13671
13672   arc.innerRadius = function(_) {
13673     return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant$10(+_), arc) : innerRadius;
13674   };
13675
13676   arc.outerRadius = function(_) {
13677     return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant$10(+_), arc) : outerRadius;
13678   };
13679
13680   arc.cornerRadius = function(_) {
13681     return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant$10(+_), arc) : cornerRadius;
13682   };
13683
13684   arc.padRadius = function(_) {
13685     return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant$10(+_), arc) : padRadius;
13686   };
13687
13688   arc.startAngle = function(_) {
13689     return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$10(+_), arc) : startAngle;
13690   };
13691
13692   arc.endAngle = function(_) {
13693     return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$10(+_), arc) : endAngle;
13694   };
13695
13696   arc.padAngle = function(_) {
13697     return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$10(+_), arc) : padAngle;
13698   };
13699
13700   arc.context = function(_) {
13701     return arguments.length ? (context = _ == null ? null : _, arc) : context;
13702   };
13703
13704   return arc;
13705 }
13706
13707 function Linear(context) {
13708   this._context = context;
13709 }
13710
13711 Linear.prototype = {
13712   areaStart: function() {
13713     this._line = 0;
13714   },
13715   areaEnd: function() {
13716     this._line = NaN;
13717   },
13718   lineStart: function() {
13719     this._point = 0;
13720   },
13721   lineEnd: function() {
13722     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
13723     this._line = 1 - this._line;
13724   },
13725   point: function(x, y) {
13726     x = +x, y = +y;
13727     switch (this._point) {
13728       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
13729       case 1: this._point = 2; // proceed
13730       default: this._context.lineTo(x, y); break;
13731     }
13732   }
13733 };
13734
13735 function curveLinear(context) {
13736   return new Linear(context);
13737 }
13738
13739 function x$3(p) {
13740   return p[0];
13741 }
13742
13743 function y$3(p) {
13744   return p[1];
13745 }
13746
13747 function line() {
13748   var x$$1 = x$3,
13749       y$$1 = y$3,
13750       defined = constant$10(true),
13751       context = null,
13752       curve = curveLinear,
13753       output = null;
13754
13755   function line(data) {
13756     var i,
13757         n = data.length,
13758         d,
13759         defined0 = false,
13760         buffer;
13761
13762     if (context == null) output = curve(buffer = path());
13763
13764     for (i = 0; i <= n; ++i) {
13765       if (!(i < n && defined(d = data[i], i, data)) === defined0) {
13766         if (defined0 = !defined0) output.lineStart();
13767         else output.lineEnd();
13768       }
13769       if (defined0) output.point(+x$$1(d, i, data), +y$$1(d, i, data));
13770     }
13771
13772     if (buffer) return output = null, buffer + "" || null;
13773   }
13774
13775   line.x = function(_) {
13776     return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$10(+_), line) : x$$1;
13777   };
13778
13779   line.y = function(_) {
13780     return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$10(+_), line) : y$$1;
13781   };
13782
13783   line.defined = function(_) {
13784     return arguments.length ? (defined = typeof _ === "function" ? _ : constant$10(!!_), line) : defined;
13785   };
13786
13787   line.curve = function(_) {
13788     return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;
13789   };
13790
13791   line.context = function(_) {
13792     return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;
13793   };
13794
13795   return line;
13796 }
13797
13798 function area() {
13799   var x0 = x$3,
13800       x1 = null,
13801       y0 = constant$10(0),
13802       y1 = y$3,
13803       defined = constant$10(true),
13804       context = null,
13805       curve = curveLinear,
13806       output = null;
13807
13808   function area(data) {
13809     var i,
13810         j,
13811         k,
13812         n = data.length,
13813         d,
13814         defined0 = false,
13815         buffer,
13816         x0z = new Array(n),
13817         y0z = new Array(n);
13818
13819     if (context == null) output = curve(buffer = path());
13820
13821     for (i = 0; i <= n; ++i) {
13822       if (!(i < n && defined(d = data[i], i, data)) === defined0) {
13823         if (defined0 = !defined0) {
13824           j = i;
13825           output.areaStart();
13826           output.lineStart();
13827         } else {
13828           output.lineEnd();
13829           output.lineStart();
13830           for (k = i - 1; k >= j; --k) {
13831             output.point(x0z[k], y0z[k]);
13832           }
13833           output.lineEnd();
13834           output.areaEnd();
13835         }
13836       }
13837       if (defined0) {
13838         x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);
13839         output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);
13840       }
13841     }
13842
13843     if (buffer) return output = null, buffer + "" || null;
13844   }
13845
13846   function arealine() {
13847     return line().defined(defined).curve(curve).context(context);
13848   }
13849
13850   area.x = function(_) {
13851     return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$10(+_), x1 = null, area) : x0;
13852   };
13853
13854   area.x0 = function(_) {
13855     return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$10(+_), area) : x0;
13856   };
13857
13858   area.x1 = function(_) {
13859     return arguments.length ? (x1 = _ == null ? null : typeof _ === "function" ? _ : constant$10(+_), area) : x1;
13860   };
13861
13862   area.y = function(_) {
13863     return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$10(+_), y1 = null, area) : y0;
13864   };
13865
13866   area.y0 = function(_) {
13867     return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$10(+_), area) : y0;
13868   };
13869
13870   area.y1 = function(_) {
13871     return arguments.length ? (y1 = _ == null ? null : typeof _ === "function" ? _ : constant$10(+_), area) : y1;
13872   };
13873
13874   area.lineX0 =
13875   area.lineY0 = function() {
13876     return arealine().x(x0).y(y0);
13877   };
13878
13879   area.lineY1 = function() {
13880     return arealine().x(x0).y(y1);
13881   };
13882
13883   area.lineX1 = function() {
13884     return arealine().x(x1).y(y0);
13885   };
13886
13887   area.defined = function(_) {
13888     return arguments.length ? (defined = typeof _ === "function" ? _ : constant$10(!!_), area) : defined;
13889   };
13890
13891   area.curve = function(_) {
13892     return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve;
13893   };
13894
13895   area.context = function(_) {
13896     return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;
13897   };
13898
13899   return area;
13900 }
13901
13902 function descending(a, b) {
13903   return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
13904 }
13905
13906 function identity$6(d) {
13907   return d;
13908 }
13909
13910 function pie() {
13911   var value = identity$6,
13912       sortValues = descending,
13913       sort = null,
13914       startAngle = constant$10(0),
13915       endAngle = constant$10(tau$4),
13916       padAngle = constant$10(0);
13917
13918   function pie(data) {
13919     var i,
13920         n = data.length,
13921         j,
13922         k,
13923         sum = 0,
13924         index = new Array(n),
13925         arcs = new Array(n),
13926         a0 = +startAngle.apply(this, arguments),
13927         da = Math.min(tau$4, Math.max(-tau$4, endAngle.apply(this, arguments) - a0)),
13928         a1,
13929         p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)),
13930         pa = p * (da < 0 ? -1 : 1),
13931         v;
13932
13933     for (i = 0; i < n; ++i) {
13934       if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) {
13935         sum += v;
13936       }
13937     }
13938
13939     // Optionally sort the arcs by previously-computed values or by data.
13940     if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); });
13941     else if (sort != null) index.sort(function(i, j) { return sort(data[i], data[j]); });
13942
13943     // Compute the arcs! They are stored in the original data's order.
13944     for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) {
13945       j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = {
13946         data: data[j],
13947         index: i,
13948         value: v,
13949         startAngle: a0,
13950         endAngle: a1,
13951         padAngle: p
13952       };
13953     }
13954
13955     return arcs;
13956   }
13957
13958   pie.value = function(_) {
13959     return arguments.length ? (value = typeof _ === "function" ? _ : constant$10(+_), pie) : value;
13960   };
13961
13962   pie.sortValues = function(_) {
13963     return arguments.length ? (sortValues = _, sort = null, pie) : sortValues;
13964   };
13965
13966   pie.sort = function(_) {
13967     return arguments.length ? (sort = _, sortValues = null, pie) : sort;
13968   };
13969
13970   pie.startAngle = function(_) {
13971     return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$10(+_), pie) : startAngle;
13972   };
13973
13974   pie.endAngle = function(_) {
13975     return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$10(+_), pie) : endAngle;
13976   };
13977
13978   pie.padAngle = function(_) {
13979     return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$10(+_), pie) : padAngle;
13980   };
13981
13982   return pie;
13983 }
13984
13985 var curveRadialLinear = curveRadial(curveLinear);
13986
13987 function Radial(curve) {
13988   this._curve = curve;
13989 }
13990
13991 Radial.prototype = {
13992   areaStart: function() {
13993     this._curve.areaStart();
13994   },
13995   areaEnd: function() {
13996     this._curve.areaEnd();
13997   },
13998   lineStart: function() {
13999     this._curve.lineStart();
14000   },
14001   lineEnd: function() {
14002     this._curve.lineEnd();
14003   },
14004   point: function(a, r) {
14005     this._curve.point(r * Math.sin(a), r * -Math.cos(a));
14006   }
14007 };
14008
14009 function curveRadial(curve) {
14010
14011   function radial(context) {
14012     return new Radial(curve(context));
14013   }
14014
14015   radial._curve = curve;
14016
14017   return radial;
14018 }
14019
14020 function lineRadial(l) {
14021   var c = l.curve;
14022
14023   l.angle = l.x, delete l.x;
14024   l.radius = l.y, delete l.y;
14025
14026   l.curve = function(_) {
14027     return arguments.length ? c(curveRadial(_)) : c()._curve;
14028   };
14029
14030   return l;
14031 }
14032
14033 function lineRadial$1() {
14034   return lineRadial(line().curve(curveRadialLinear));
14035 }
14036
14037 function areaRadial() {
14038   var a = area().curve(curveRadialLinear),
14039       c = a.curve,
14040       x0 = a.lineX0,
14041       x1 = a.lineX1,
14042       y0 = a.lineY0,
14043       y1 = a.lineY1;
14044
14045   a.angle = a.x, delete a.x;
14046   a.startAngle = a.x0, delete a.x0;
14047   a.endAngle = a.x1, delete a.x1;
14048   a.radius = a.y, delete a.y;
14049   a.innerRadius = a.y0, delete a.y0;
14050   a.outerRadius = a.y1, delete a.y1;
14051   a.lineStartAngle = function() { return lineRadial(x0()); }, delete a.lineX0;
14052   a.lineEndAngle = function() { return lineRadial(x1()); }, delete a.lineX1;
14053   a.lineInnerRadius = function() { return lineRadial(y0()); }, delete a.lineY0;
14054   a.lineOuterRadius = function() { return lineRadial(y1()); }, delete a.lineY1;
14055
14056   a.curve = function(_) {
14057     return arguments.length ? c(curveRadial(_)) : c()._curve;
14058   };
14059
14060   return a;
14061 }
14062
14063 function pointRadial(x, y) {
14064   return [(y = +y) * Math.cos(x -= Math.PI / 2), y * Math.sin(x)];
14065 }
14066
14067 var slice$6 = Array.prototype.slice;
14068
14069 function linkSource(d) {
14070   return d.source;
14071 }
14072
14073 function linkTarget(d) {
14074   return d.target;
14075 }
14076
14077 function link$2(curve) {
14078   var source = linkSource,
14079       target = linkTarget,
14080       x$$1 = x$3,
14081       y$$1 = y$3,
14082       context = null;
14083
14084   function link() {
14085     var buffer, argv = slice$6.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv);
14086     if (!context) context = buffer = path();
14087     curve(context, +x$$1.apply(this, (argv[0] = s, argv)), +y$$1.apply(this, argv), +x$$1.apply(this, (argv[0] = t, argv)), +y$$1.apply(this, argv));
14088     if (buffer) return context = null, buffer + "" || null;
14089   }
14090
14091   link.source = function(_) {
14092     return arguments.length ? (source = _, link) : source;
14093   };
14094
14095   link.target = function(_) {
14096     return arguments.length ? (target = _, link) : target;
14097   };
14098
14099   link.x = function(_) {
14100     return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$10(+_), link) : x$$1;
14101   };
14102
14103   link.y = function(_) {
14104     return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$10(+_), link) : y$$1;
14105   };
14106
14107   link.context = function(_) {
14108     return arguments.length ? (context = _ == null ? null : _, link) : context;
14109   };
14110
14111   return link;
14112 }
14113
14114 function curveHorizontal(context, x0, y0, x1, y1) {
14115   context.moveTo(x0, y0);
14116   context.bezierCurveTo(x0 = (x0 + x1) / 2, y0, x0, y1, x1, y1);
14117 }
14118
14119 function curveVertical(context, x0, y0, x1, y1) {
14120   context.moveTo(x0, y0);
14121   context.bezierCurveTo(x0, y0 = (y0 + y1) / 2, x1, y0, x1, y1);
14122 }
14123
14124 function curveRadial$1(context, x0, y0, x1, y1) {
14125   var p0 = pointRadial(x0, y0),
14126       p1 = pointRadial(x0, y0 = (y0 + y1) / 2),
14127       p2 = pointRadial(x1, y0),
14128       p3 = pointRadial(x1, y1);
14129   context.moveTo(p0[0], p0[1]);
14130   context.bezierCurveTo(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]);
14131 }
14132
14133 function linkHorizontal() {
14134   return link$2(curveHorizontal);
14135 }
14136
14137 function linkVertical() {
14138   return link$2(curveVertical);
14139 }
14140
14141 function linkRadial() {
14142   var l = link$2(curveRadial$1);
14143   l.angle = l.x, delete l.x;
14144   l.radius = l.y, delete l.y;
14145   return l;
14146 }
14147
14148 var circle$2 = {
14149   draw: function(context, size) {
14150     var r = Math.sqrt(size / pi$4);
14151     context.moveTo(r, 0);
14152     context.arc(0, 0, r, 0, tau$4);
14153   }
14154 };
14155
14156 var cross$2 = {
14157   draw: function(context, size) {
14158     var r = Math.sqrt(size / 5) / 2;
14159     context.moveTo(-3 * r, -r);
14160     context.lineTo(-r, -r);
14161     context.lineTo(-r, -3 * r);
14162     context.lineTo(r, -3 * r);
14163     context.lineTo(r, -r);
14164     context.lineTo(3 * r, -r);
14165     context.lineTo(3 * r, r);
14166     context.lineTo(r, r);
14167     context.lineTo(r, 3 * r);
14168     context.lineTo(-r, 3 * r);
14169     context.lineTo(-r, r);
14170     context.lineTo(-3 * r, r);
14171     context.closePath();
14172   }
14173 };
14174
14175 var tan30 = Math.sqrt(1 / 3);
14176 var tan30_2 = tan30 * 2;
14177
14178 var diamond = {
14179   draw: function(context, size) {
14180     var y = Math.sqrt(size / tan30_2),
14181         x = y * tan30;
14182     context.moveTo(0, -y);
14183     context.lineTo(x, 0);
14184     context.lineTo(0, y);
14185     context.lineTo(-x, 0);
14186     context.closePath();
14187   }
14188 };
14189
14190 var ka = 0.89081309152928522810;
14191 var kr = Math.sin(pi$4 / 10) / Math.sin(7 * pi$4 / 10);
14192 var kx = Math.sin(tau$4 / 10) * kr;
14193 var ky = -Math.cos(tau$4 / 10) * kr;
14194
14195 var star = {
14196   draw: function(context, size) {
14197     var r = Math.sqrt(size * ka),
14198         x = kx * r,
14199         y = ky * r;
14200     context.moveTo(0, -r);
14201     context.lineTo(x, y);
14202     for (var i = 1; i < 5; ++i) {
14203       var a = tau$4 * i / 5,
14204           c = Math.cos(a),
14205           s = Math.sin(a);
14206       context.lineTo(s * r, -c * r);
14207       context.lineTo(c * x - s * y, s * x + c * y);
14208     }
14209     context.closePath();
14210   }
14211 };
14212
14213 var square = {
14214   draw: function(context, size) {
14215     var w = Math.sqrt(size),
14216         x = -w / 2;
14217     context.rect(x, x, w, w);
14218   }
14219 };
14220
14221 var sqrt3 = Math.sqrt(3);
14222
14223 var triangle = {
14224   draw: function(context, size) {
14225     var y = -Math.sqrt(size / (sqrt3 * 3));
14226     context.moveTo(0, y * 2);
14227     context.lineTo(-sqrt3 * y, -y);
14228     context.lineTo(sqrt3 * y, -y);
14229     context.closePath();
14230   }
14231 };
14232
14233 var c = -0.5;
14234 var s = Math.sqrt(3) / 2;
14235 var k = 1 / Math.sqrt(12);
14236 var a = (k / 2 + 1) * 3;
14237
14238 var wye = {
14239   draw: function(context, size) {
14240     var r = Math.sqrt(size / a),
14241         x0 = r / 2,
14242         y0 = r * k,
14243         x1 = x0,
14244         y1 = r * k + r,
14245         x2 = -x1,
14246         y2 = y1;
14247     context.moveTo(x0, y0);
14248     context.lineTo(x1, y1);
14249     context.lineTo(x2, y2);
14250     context.lineTo(c * x0 - s * y0, s * x0 + c * y0);
14251     context.lineTo(c * x1 - s * y1, s * x1 + c * y1);
14252     context.lineTo(c * x2 - s * y2, s * x2 + c * y2);
14253     context.lineTo(c * x0 + s * y0, c * y0 - s * x0);
14254     context.lineTo(c * x1 + s * y1, c * y1 - s * x1);
14255     context.lineTo(c * x2 + s * y2, c * y2 - s * x2);
14256     context.closePath();
14257   }
14258 };
14259
14260 var symbols = [
14261   circle$2,
14262   cross$2,
14263   diamond,
14264   square,
14265   star,
14266   triangle,
14267   wye
14268 ];
14269
14270 function symbol() {
14271   var type = constant$10(circle$2),
14272       size = constant$10(64),
14273       context = null;
14274
14275   function symbol() {
14276     var buffer;
14277     if (!context) context = buffer = path();
14278     type.apply(this, arguments).draw(context, +size.apply(this, arguments));
14279     if (buffer) return context = null, buffer + "" || null;
14280   }
14281
14282   symbol.type = function(_) {
14283     return arguments.length ? (type = typeof _ === "function" ? _ : constant$10(_), symbol) : type;
14284   };
14285
14286   symbol.size = function(_) {
14287     return arguments.length ? (size = typeof _ === "function" ? _ : constant$10(+_), symbol) : size;
14288   };
14289
14290   symbol.context = function(_) {
14291     return arguments.length ? (context = _ == null ? null : _, symbol) : context;
14292   };
14293
14294   return symbol;
14295 }
14296
14297 function noop$2() {}
14298
14299 function point$2(that, x, y) {
14300   that._context.bezierCurveTo(
14301     (2 * that._x0 + that._x1) / 3,
14302     (2 * that._y0 + that._y1) / 3,
14303     (that._x0 + 2 * that._x1) / 3,
14304     (that._y0 + 2 * that._y1) / 3,
14305     (that._x0 + 4 * that._x1 + x) / 6,
14306     (that._y0 + 4 * that._y1 + y) / 6
14307   );
14308 }
14309
14310 function Basis(context) {
14311   this._context = context;
14312 }
14313
14314 Basis.prototype = {
14315   areaStart: function() {
14316     this._line = 0;
14317   },
14318   areaEnd: function() {
14319     this._line = NaN;
14320   },
14321   lineStart: function() {
14322     this._x0 = this._x1 =
14323     this._y0 = this._y1 = NaN;
14324     this._point = 0;
14325   },
14326   lineEnd: function() {
14327     switch (this._point) {
14328       case 3: point$2(this, this._x1, this._y1); // proceed
14329       case 2: this._context.lineTo(this._x1, this._y1); break;
14330     }
14331     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
14332     this._line = 1 - this._line;
14333   },
14334   point: function(x, y) {
14335     x = +x, y = +y;
14336     switch (this._point) {
14337       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
14338       case 1: this._point = 2; break;
14339       case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed
14340       default: point$2(this, x, y); break;
14341     }
14342     this._x0 = this._x1, this._x1 = x;
14343     this._y0 = this._y1, this._y1 = y;
14344   }
14345 };
14346
14347 function basis$2(context) {
14348   return new Basis(context);
14349 }
14350
14351 function BasisClosed(context) {
14352   this._context = context;
14353 }
14354
14355 BasisClosed.prototype = {
14356   areaStart: noop$2,
14357   areaEnd: noop$2,
14358   lineStart: function() {
14359     this._x0 = this._x1 = this._x2 = this._x3 = this._x4 =
14360     this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;
14361     this._point = 0;
14362   },
14363   lineEnd: function() {
14364     switch (this._point) {
14365       case 1: {
14366         this._context.moveTo(this._x2, this._y2);
14367         this._context.closePath();
14368         break;
14369       }
14370       case 2: {
14371         this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3);
14372         this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3);
14373         this._context.closePath();
14374         break;
14375       }
14376       case 3: {
14377         this.point(this._x2, this._y2);
14378         this.point(this._x3, this._y3);
14379         this.point(this._x4, this._y4);
14380         break;
14381       }
14382     }
14383   },
14384   point: function(x, y) {
14385     x = +x, y = +y;
14386     switch (this._point) {
14387       case 0: this._point = 1; this._x2 = x, this._y2 = y; break;
14388       case 1: this._point = 2; this._x3 = x, this._y3 = y; break;
14389       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;
14390       default: point$2(this, x, y); break;
14391     }
14392     this._x0 = this._x1, this._x1 = x;
14393     this._y0 = this._y1, this._y1 = y;
14394   }
14395 };
14396
14397 function basisClosed$1(context) {
14398   return new BasisClosed(context);
14399 }
14400
14401 function BasisOpen(context) {
14402   this._context = context;
14403 }
14404
14405 BasisOpen.prototype = {
14406   areaStart: function() {
14407     this._line = 0;
14408   },
14409   areaEnd: function() {
14410     this._line = NaN;
14411   },
14412   lineStart: function() {
14413     this._x0 = this._x1 =
14414     this._y0 = this._y1 = NaN;
14415     this._point = 0;
14416   },
14417   lineEnd: function() {
14418     if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
14419     this._line = 1 - this._line;
14420   },
14421   point: function(x, y) {
14422     x = +x, y = +y;
14423     switch (this._point) {
14424       case 0: this._point = 1; break;
14425       case 1: this._point = 2; break;
14426       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;
14427       case 3: this._point = 4; // proceed
14428       default: point$2(this, x, y); break;
14429     }
14430     this._x0 = this._x1, this._x1 = x;
14431     this._y0 = this._y1, this._y1 = y;
14432   }
14433 };
14434
14435 function basisOpen(context) {
14436   return new BasisOpen(context);
14437 }
14438
14439 function Bundle(context, beta) {
14440   this._basis = new Basis(context);
14441   this._beta = beta;
14442 }
14443
14444 Bundle.prototype = {
14445   lineStart: function() {
14446     this._x = [];
14447     this._y = [];
14448     this._basis.lineStart();
14449   },
14450   lineEnd: function() {
14451     var x = this._x,
14452         y = this._y,
14453         j = x.length - 1;
14454
14455     if (j > 0) {
14456       var x0 = x[0],
14457           y0 = y[0],
14458           dx = x[j] - x0,
14459           dy = y[j] - y0,
14460           i = -1,
14461           t;
14462
14463       while (++i <= j) {
14464         t = i / j;
14465         this._basis.point(
14466           this._beta * x[i] + (1 - this._beta) * (x0 + t * dx),
14467           this._beta * y[i] + (1 - this._beta) * (y0 + t * dy)
14468         );
14469       }
14470     }
14471
14472     this._x = this._y = null;
14473     this._basis.lineEnd();
14474   },
14475   point: function(x, y) {
14476     this._x.push(+x);
14477     this._y.push(+y);
14478   }
14479 };
14480
14481 var bundle = (function custom(beta) {
14482
14483   function bundle(context) {
14484     return beta === 1 ? new Basis(context) : new Bundle(context, beta);
14485   }
14486
14487   bundle.beta = function(beta) {
14488     return custom(+beta);
14489   };
14490
14491   return bundle;
14492 })(0.85);
14493
14494 function point$3(that, x, y) {
14495   that._context.bezierCurveTo(
14496     that._x1 + that._k * (that._x2 - that._x0),
14497     that._y1 + that._k * (that._y2 - that._y0),
14498     that._x2 + that._k * (that._x1 - x),
14499     that._y2 + that._k * (that._y1 - y),
14500     that._x2,
14501     that._y2
14502   );
14503 }
14504
14505 function Cardinal(context, tension) {
14506   this._context = context;
14507   this._k = (1 - tension) / 6;
14508 }
14509
14510 Cardinal.prototype = {
14511   areaStart: function() {
14512     this._line = 0;
14513   },
14514   areaEnd: function() {
14515     this._line = NaN;
14516   },
14517   lineStart: function() {
14518     this._x0 = this._x1 = this._x2 =
14519     this._y0 = this._y1 = this._y2 = NaN;
14520     this._point = 0;
14521   },
14522   lineEnd: function() {
14523     switch (this._point) {
14524       case 2: this._context.lineTo(this._x2, this._y2); break;
14525       case 3: point$3(this, this._x1, this._y1); break;
14526     }
14527     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
14528     this._line = 1 - this._line;
14529   },
14530   point: function(x, y) {
14531     x = +x, y = +y;
14532     switch (this._point) {
14533       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
14534       case 1: this._point = 2; this._x1 = x, this._y1 = y; break;
14535       case 2: this._point = 3; // proceed
14536       default: point$3(this, x, y); break;
14537     }
14538     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
14539     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
14540   }
14541 };
14542
14543 var cardinal = (function custom(tension) {
14544
14545   function cardinal(context) {
14546     return new Cardinal(context, tension);
14547   }
14548
14549   cardinal.tension = function(tension) {
14550     return custom(+tension);
14551   };
14552
14553   return cardinal;
14554 })(0);
14555
14556 function CardinalClosed(context, tension) {
14557   this._context = context;
14558   this._k = (1 - tension) / 6;
14559 }
14560
14561 CardinalClosed.prototype = {
14562   areaStart: noop$2,
14563   areaEnd: noop$2,
14564   lineStart: function() {
14565     this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
14566     this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
14567     this._point = 0;
14568   },
14569   lineEnd: function() {
14570     switch (this._point) {
14571       case 1: {
14572         this._context.moveTo(this._x3, this._y3);
14573         this._context.closePath();
14574         break;
14575       }
14576       case 2: {
14577         this._context.lineTo(this._x3, this._y3);
14578         this._context.closePath();
14579         break;
14580       }
14581       case 3: {
14582         this.point(this._x3, this._y3);
14583         this.point(this._x4, this._y4);
14584         this.point(this._x5, this._y5);
14585         break;
14586       }
14587     }
14588   },
14589   point: function(x, y) {
14590     x = +x, y = +y;
14591     switch (this._point) {
14592       case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
14593       case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
14594       case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
14595       default: point$3(this, x, y); break;
14596     }
14597     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
14598     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
14599   }
14600 };
14601
14602 var cardinalClosed = (function custom(tension) {
14603
14604   function cardinal$$1(context) {
14605     return new CardinalClosed(context, tension);
14606   }
14607
14608   cardinal$$1.tension = function(tension) {
14609     return custom(+tension);
14610   };
14611
14612   return cardinal$$1;
14613 })(0);
14614
14615 function CardinalOpen(context, tension) {
14616   this._context = context;
14617   this._k = (1 - tension) / 6;
14618 }
14619
14620 CardinalOpen.prototype = {
14621   areaStart: function() {
14622     this._line = 0;
14623   },
14624   areaEnd: function() {
14625     this._line = NaN;
14626   },
14627   lineStart: function() {
14628     this._x0 = this._x1 = this._x2 =
14629     this._y0 = this._y1 = this._y2 = NaN;
14630     this._point = 0;
14631   },
14632   lineEnd: function() {
14633     if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
14634     this._line = 1 - this._line;
14635   },
14636   point: function(x, y) {
14637     x = +x, y = +y;
14638     switch (this._point) {
14639       case 0: this._point = 1; break;
14640       case 1: this._point = 2; break;
14641       case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
14642       case 3: this._point = 4; // proceed
14643       default: point$3(this, x, y); break;
14644     }
14645     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
14646     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
14647   }
14648 };
14649
14650 var cardinalOpen = (function custom(tension) {
14651
14652   function cardinal$$1(context) {
14653     return new CardinalOpen(context, tension);
14654   }
14655
14656   cardinal$$1.tension = function(tension) {
14657     return custom(+tension);
14658   };
14659
14660   return cardinal$$1;
14661 })(0);
14662
14663 function point$4(that, x, y) {
14664   var x1 = that._x1,
14665       y1 = that._y1,
14666       x2 = that._x2,
14667       y2 = that._y2;
14668
14669   if (that._l01_a > epsilon$3) {
14670     var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a,
14671         n = 3 * that._l01_a * (that._l01_a + that._l12_a);
14672     x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n;
14673     y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n;
14674   }
14675
14676   if (that._l23_a > epsilon$3) {
14677     var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a,
14678         m = 3 * that._l23_a * (that._l23_a + that._l12_a);
14679     x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m;
14680     y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m;
14681   }
14682
14683   that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);
14684 }
14685
14686 function CatmullRom(context, alpha) {
14687   this._context = context;
14688   this._alpha = alpha;
14689 }
14690
14691 CatmullRom.prototype = {
14692   areaStart: function() {
14693     this._line = 0;
14694   },
14695   areaEnd: function() {
14696     this._line = NaN;
14697   },
14698   lineStart: function() {
14699     this._x0 = this._x1 = this._x2 =
14700     this._y0 = this._y1 = this._y2 = NaN;
14701     this._l01_a = this._l12_a = this._l23_a =
14702     this._l01_2a = this._l12_2a = this._l23_2a =
14703     this._point = 0;
14704   },
14705   lineEnd: function() {
14706     switch (this._point) {
14707       case 2: this._context.lineTo(this._x2, this._y2); break;
14708       case 3: this.point(this._x2, this._y2); break;
14709     }
14710     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
14711     this._line = 1 - this._line;
14712   },
14713   point: function(x, y) {
14714     x = +x, y = +y;
14715
14716     if (this._point) {
14717       var x23 = this._x2 - x,
14718           y23 = this._y2 - y;
14719       this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
14720     }
14721
14722     switch (this._point) {
14723       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
14724       case 1: this._point = 2; break;
14725       case 2: this._point = 3; // proceed
14726       default: point$4(this, x, y); break;
14727     }
14728
14729     this._l01_a = this._l12_a, this._l12_a = this._l23_a;
14730     this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
14731     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
14732     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
14733   }
14734 };
14735
14736 var catmullRom = (function custom(alpha) {
14737
14738   function catmullRom(context) {
14739     return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0);
14740   }
14741
14742   catmullRom.alpha = function(alpha) {
14743     return custom(+alpha);
14744   };
14745
14746   return catmullRom;
14747 })(0.5);
14748
14749 function CatmullRomClosed(context, alpha) {
14750   this._context = context;
14751   this._alpha = alpha;
14752 }
14753
14754 CatmullRomClosed.prototype = {
14755   areaStart: noop$2,
14756   areaEnd: noop$2,
14757   lineStart: function() {
14758     this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
14759     this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
14760     this._l01_a = this._l12_a = this._l23_a =
14761     this._l01_2a = this._l12_2a = this._l23_2a =
14762     this._point = 0;
14763   },
14764   lineEnd: function() {
14765     switch (this._point) {
14766       case 1: {
14767         this._context.moveTo(this._x3, this._y3);
14768         this._context.closePath();
14769         break;
14770       }
14771       case 2: {
14772         this._context.lineTo(this._x3, this._y3);
14773         this._context.closePath();
14774         break;
14775       }
14776       case 3: {
14777         this.point(this._x3, this._y3);
14778         this.point(this._x4, this._y4);
14779         this.point(this._x5, this._y5);
14780         break;
14781       }
14782     }
14783   },
14784   point: function(x, y) {
14785     x = +x, y = +y;
14786
14787     if (this._point) {
14788       var x23 = this._x2 - x,
14789           y23 = this._y2 - y;
14790       this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
14791     }
14792
14793     switch (this._point) {
14794       case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
14795       case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
14796       case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
14797       default: point$4(this, x, y); break;
14798     }
14799
14800     this._l01_a = this._l12_a, this._l12_a = this._l23_a;
14801     this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
14802     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
14803     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
14804   }
14805 };
14806
14807 var catmullRomClosed = (function custom(alpha) {
14808
14809   function catmullRom$$1(context) {
14810     return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0);
14811   }
14812
14813   catmullRom$$1.alpha = function(alpha) {
14814     return custom(+alpha);
14815   };
14816
14817   return catmullRom$$1;
14818 })(0.5);
14819
14820 function CatmullRomOpen(context, alpha) {
14821   this._context = context;
14822   this._alpha = alpha;
14823 }
14824
14825 CatmullRomOpen.prototype = {
14826   areaStart: function() {
14827     this._line = 0;
14828   },
14829   areaEnd: function() {
14830     this._line = NaN;
14831   },
14832   lineStart: function() {
14833     this._x0 = this._x1 = this._x2 =
14834     this._y0 = this._y1 = this._y2 = NaN;
14835     this._l01_a = this._l12_a = this._l23_a =
14836     this._l01_2a = this._l12_2a = this._l23_2a =
14837     this._point = 0;
14838   },
14839   lineEnd: function() {
14840     if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
14841     this._line = 1 - this._line;
14842   },
14843   point: function(x, y) {
14844     x = +x, y = +y;
14845
14846     if (this._point) {
14847       var x23 = this._x2 - x,
14848           y23 = this._y2 - y;
14849       this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
14850     }
14851
14852     switch (this._point) {
14853       case 0: this._point = 1; break;
14854       case 1: this._point = 2; break;
14855       case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
14856       case 3: this._point = 4; // proceed
14857       default: point$4(this, x, y); break;
14858     }
14859
14860     this._l01_a = this._l12_a, this._l12_a = this._l23_a;
14861     this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
14862     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
14863     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
14864   }
14865 };
14866
14867 var catmullRomOpen = (function custom(alpha) {
14868
14869   function catmullRom$$1(context) {
14870     return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0);
14871   }
14872
14873   catmullRom$$1.alpha = function(alpha) {
14874     return custom(+alpha);
14875   };
14876
14877   return catmullRom$$1;
14878 })(0.5);
14879
14880 function LinearClosed(context) {
14881   this._context = context;
14882 }
14883
14884 LinearClosed.prototype = {
14885   areaStart: noop$2,
14886   areaEnd: noop$2,
14887   lineStart: function() {
14888     this._point = 0;
14889   },
14890   lineEnd: function() {
14891     if (this._point) this._context.closePath();
14892   },
14893   point: function(x, y) {
14894     x = +x, y = +y;
14895     if (this._point) this._context.lineTo(x, y);
14896     else this._point = 1, this._context.moveTo(x, y);
14897   }
14898 };
14899
14900 function linearClosed(context) {
14901   return new LinearClosed(context);
14902 }
14903
14904 function sign$1(x) {
14905   return x < 0 ? -1 : 1;
14906 }
14907
14908 // Calculate the slopes of the tangents (Hermite-type interpolation) based on
14909 // the following paper: Steffen, M. 1990. A Simple Method for Monotonic
14910 // Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.
14911 // NOV(II), P. 443, 1990.
14912 function slope3(that, x2, y2) {
14913   var h0 = that._x1 - that._x0,
14914       h1 = x2 - that._x1,
14915       s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),
14916       s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),
14917       p = (s0 * h1 + s1 * h0) / (h0 + h1);
14918   return (sign$1(s0) + sign$1(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;
14919 }
14920
14921 // Calculate a one-sided slope.
14922 function slope2(that, t) {
14923   var h = that._x1 - that._x0;
14924   return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;
14925 }
14926
14927 // According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations
14928 // "you can express cubic Hermite interpolation in terms of cubic Bézier curves
14929 // with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1".
14930 function point$5(that, t0, t1) {
14931   var x0 = that._x0,
14932       y0 = that._y0,
14933       x1 = that._x1,
14934       y1 = that._y1,
14935       dx = (x1 - x0) / 3;
14936   that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);
14937 }
14938
14939 function MonotoneX(context) {
14940   this._context = context;
14941 }
14942
14943 MonotoneX.prototype = {
14944   areaStart: function() {
14945     this._line = 0;
14946   },
14947   areaEnd: function() {
14948     this._line = NaN;
14949   },
14950   lineStart: function() {
14951     this._x0 = this._x1 =
14952     this._y0 = this._y1 =
14953     this._t0 = NaN;
14954     this._point = 0;
14955   },
14956   lineEnd: function() {
14957     switch (this._point) {
14958       case 2: this._context.lineTo(this._x1, this._y1); break;
14959       case 3: point$5(this, this._t0, slope2(this, this._t0)); break;
14960     }
14961     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
14962     this._line = 1 - this._line;
14963   },
14964   point: function(x, y) {
14965     var t1 = NaN;
14966
14967     x = +x, y = +y;
14968     if (x === this._x1 && y === this._y1) return; // Ignore coincident points.
14969     switch (this._point) {
14970       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
14971       case 1: this._point = 2; break;
14972       case 2: this._point = 3; point$5(this, slope2(this, t1 = slope3(this, x, y)), t1); break;
14973       default: point$5(this, this._t0, t1 = slope3(this, x, y)); break;
14974     }
14975
14976     this._x0 = this._x1, this._x1 = x;
14977     this._y0 = this._y1, this._y1 = y;
14978     this._t0 = t1;
14979   }
14980 };
14981
14982 function MonotoneY(context) {
14983   this._context = new ReflectContext(context);
14984 }
14985
14986 (MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {
14987   MonotoneX.prototype.point.call(this, y, x);
14988 };
14989
14990 function ReflectContext(context) {
14991   this._context = context;
14992 }
14993
14994 ReflectContext.prototype = {
14995   moveTo: function(x, y) { this._context.moveTo(y, x); },
14996   closePath: function() { this._context.closePath(); },
14997   lineTo: function(x, y) { this._context.lineTo(y, x); },
14998   bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }
14999 };
15000
15001 function monotoneX(context) {
15002   return new MonotoneX(context);
15003 }
15004
15005 function monotoneY(context) {
15006   return new MonotoneY(context);
15007 }
15008
15009 function Natural(context) {
15010   this._context = context;
15011 }
15012
15013 Natural.prototype = {
15014   areaStart: function() {
15015     this._line = 0;
15016   },
15017   areaEnd: function() {
15018     this._line = NaN;
15019   },
15020   lineStart: function() {
15021     this._x = [];
15022     this._y = [];
15023   },
15024   lineEnd: function() {
15025     var x = this._x,
15026         y = this._y,
15027         n = x.length;
15028
15029     if (n) {
15030       this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);
15031       if (n === 2) {
15032         this._context.lineTo(x[1], y[1]);
15033       } else {
15034         var px = controlPoints(x),
15035             py = controlPoints(y);
15036         for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {
15037           this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);
15038         }
15039       }
15040     }
15041
15042     if (this._line || (this._line !== 0 && n === 1)) this._context.closePath();
15043     this._line = 1 - this._line;
15044     this._x = this._y = null;
15045   },
15046   point: function(x, y) {
15047     this._x.push(+x);
15048     this._y.push(+y);
15049   }
15050 };
15051
15052 // See https://www.particleincell.com/2012/bezier-splines/ for derivation.
15053 function controlPoints(x) {
15054   var i,
15055       n = x.length - 1,
15056       m,
15057       a = new Array(n),
15058       b = new Array(n),
15059       r = new Array(n);
15060   a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];
15061   for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];
15062   a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];
15063   for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];
15064   a[n - 1] = r[n - 1] / b[n - 1];
15065   for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];
15066   b[n - 1] = (x[n] + a[n - 1]) / 2;
15067   for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];
15068   return [a, b];
15069 }
15070
15071 function natural(context) {
15072   return new Natural(context);
15073 }
15074
15075 function Step(context, t) {
15076   this._context = context;
15077   this._t = t;
15078 }
15079
15080 Step.prototype = {
15081   areaStart: function() {
15082     this._line = 0;
15083   },
15084   areaEnd: function() {
15085     this._line = NaN;
15086   },
15087   lineStart: function() {
15088     this._x = this._y = NaN;
15089     this._point = 0;
15090   },
15091   lineEnd: function() {
15092     if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);
15093     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
15094     if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;
15095   },
15096   point: function(x, y) {
15097     x = +x, y = +y;
15098     switch (this._point) {
15099       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
15100       case 1: this._point = 2; // proceed
15101       default: {
15102         if (this._t <= 0) {
15103           this._context.lineTo(this._x, y);
15104           this._context.lineTo(x, y);
15105         } else {
15106           var x1 = this._x * (1 - this._t) + x * this._t;
15107           this._context.lineTo(x1, this._y);
15108           this._context.lineTo(x1, y);
15109         }
15110         break;
15111       }
15112     }
15113     this._x = x, this._y = y;
15114   }
15115 };
15116
15117 function step(context) {
15118   return new Step(context, 0.5);
15119 }
15120
15121 function stepBefore(context) {
15122   return new Step(context, 0);
15123 }
15124
15125 function stepAfter(context) {
15126   return new Step(context, 1);
15127 }
15128
15129 function none$1(series, order) {
15130   if (!((n = series.length) > 1)) return;
15131   for (var i = 1, j, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) {
15132     s0 = s1, s1 = series[order[i]];
15133     for (j = 0; j < m; ++j) {
15134       s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1];
15135     }
15136   }
15137 }
15138
15139 function none$2(series) {
15140   var n = series.length, o = new Array(n);
15141   while (--n >= 0) o[n] = n;
15142   return o;
15143 }
15144
15145 function stackValue(d, key) {
15146   return d[key];
15147 }
15148
15149 function stack() {
15150   var keys = constant$10([]),
15151       order = none$2,
15152       offset = none$1,
15153       value = stackValue;
15154
15155   function stack(data) {
15156     var kz = keys.apply(this, arguments),
15157         i,
15158         m = data.length,
15159         n = kz.length,
15160         sz = new Array(n),
15161         oz;
15162
15163     for (i = 0; i < n; ++i) {
15164       for (var ki = kz[i], si = sz[i] = new Array(m), j = 0, sij; j < m; ++j) {
15165         si[j] = sij = [0, +value(data[j], ki, j, data)];
15166         sij.data = data[j];
15167       }
15168       si.key = ki;
15169     }
15170
15171     for (i = 0, oz = order(sz); i < n; ++i) {
15172       sz[oz[i]].index = i;
15173     }
15174
15175     offset(sz, oz);
15176     return sz;
15177   }
15178
15179   stack.keys = function(_) {
15180     return arguments.length ? (keys = typeof _ === "function" ? _ : constant$10(slice$6.call(_)), stack) : keys;
15181   };
15182
15183   stack.value = function(_) {
15184     return arguments.length ? (value = typeof _ === "function" ? _ : constant$10(+_), stack) : value;
15185   };
15186
15187   stack.order = function(_) {
15188     return arguments.length ? (order = _ == null ? none$2 : typeof _ === "function" ? _ : constant$10(slice$6.call(_)), stack) : order;
15189   };
15190
15191   stack.offset = function(_) {
15192     return arguments.length ? (offset = _ == null ? none$1 : _, stack) : offset;
15193   };
15194
15195   return stack;
15196 }
15197
15198 function expand(series, order) {
15199   if (!((n = series.length) > 0)) return;
15200   for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) {
15201     for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0;
15202     if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y;
15203   }
15204   none$1(series, order);
15205 }
15206
15207 function diverging(series, order) {
15208   if (!((n = series.length) > 1)) return;
15209   for (var i, j = 0, d, dy, yp, yn, n, m = series[order[0]].length; j < m; ++j) {
15210     for (yp = yn = 0, i = 0; i < n; ++i) {
15211       if ((dy = (d = series[order[i]][j])[1] - d[0]) >= 0) {
15212         d[0] = yp, d[1] = yp += dy;
15213       } else if (dy < 0) {
15214         d[1] = yn, d[0] = yn += dy;
15215       } else {
15216         d[0] = yp;
15217       }
15218     }
15219   }
15220 }
15221
15222 function silhouette(series, order) {
15223   if (!((n = series.length) > 0)) return;
15224   for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) {
15225     for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0;
15226     s0[j][1] += s0[j][0] = -y / 2;
15227   }
15228   none$1(series, order);
15229 }
15230
15231 function wiggle(series, order) {
15232   if (!((n = series.length) > 0) || !((m = (s0 = series[order[0]]).length) > 0)) return;
15233   for (var y = 0, j = 1, s0, m, n; j < m; ++j) {
15234     for (var i = 0, s1 = 0, s2 = 0; i < n; ++i) {
15235       var si = series[order[i]],
15236           sij0 = si[j][1] || 0,
15237           sij1 = si[j - 1][1] || 0,
15238           s3 = (sij0 - sij1) / 2;
15239       for (var k = 0; k < i; ++k) {
15240         var sk = series[order[k]],
15241             skj0 = sk[j][1] || 0,
15242             skj1 = sk[j - 1][1] || 0;
15243         s3 += skj0 - skj1;
15244       }
15245       s1 += sij0, s2 += s3 * sij0;
15246     }
15247     s0[j - 1][1] += s0[j - 1][0] = y;
15248     if (s1) y -= s2 / s1;
15249   }
15250   s0[j - 1][1] += s0[j - 1][0] = y;
15251   none$1(series, order);
15252 }
15253
15254 function ascending$1(series) {
15255   var sums = series.map(sum$2);
15256   return none$2(series).sort(function(a, b) { return sums[a] - sums[b]; });
15257 }
15258
15259 function sum$2(series) {
15260   var s = 0, i = -1, n = series.length, v;
15261   while (++i < n) if (v = +series[i][1]) s += v;
15262   return s;
15263 }
15264
15265 function descending$1(series) {
15266   return ascending$1(series).reverse();
15267 }
15268
15269 function insideOut(series) {
15270   var n = series.length,
15271       i,
15272       j,
15273       sums = series.map(sum$2),
15274       order = none$2(series).sort(function(a, b) { return sums[b] - sums[a]; }),
15275       top = 0,
15276       bottom = 0,
15277       tops = [],
15278       bottoms = [];
15279
15280   for (i = 0; i < n; ++i) {
15281     j = order[i];
15282     if (top < bottom) {
15283       top += sums[j];
15284       tops.push(j);
15285     } else {
15286       bottom += sums[j];
15287       bottoms.push(j);
15288     }
15289   }
15290
15291   return bottoms.reverse().concat(tops);
15292 }
15293
15294 function reverse(series) {
15295   return none$2(series).reverse();
15296 }
15297
15298 function constant$11(x) {
15299   return function() {
15300     return x;
15301   };
15302 }
15303
15304 function x$4(d) {
15305   return d[0];
15306 }
15307
15308 function y$4(d) {
15309   return d[1];
15310 }
15311
15312 function RedBlackTree() {
15313   this._ = null; // root node
15314 }
15315
15316 function RedBlackNode(node) {
15317   node.U = // parent node
15318   node.C = // color - true for red, false for black
15319   node.L = // left node
15320   node.R = // right node
15321   node.P = // previous node
15322   node.N = null; // next node
15323 }
15324
15325 RedBlackTree.prototype = {
15326   constructor: RedBlackTree,
15327
15328   insert: function(after, node) {
15329     var parent, grandpa, uncle;
15330
15331     if (after) {
15332       node.P = after;
15333       node.N = after.N;
15334       if (after.N) after.N.P = node;
15335       after.N = node;
15336       if (after.R) {
15337         after = after.R;
15338         while (after.L) after = after.L;
15339         after.L = node;
15340       } else {
15341         after.R = node;
15342       }
15343       parent = after;
15344     } else if (this._) {
15345       after = RedBlackFirst(this._);
15346       node.P = null;
15347       node.N = after;
15348       after.P = after.L = node;
15349       parent = after;
15350     } else {
15351       node.P = node.N = null;
15352       this._ = node;
15353       parent = null;
15354     }
15355     node.L = node.R = null;
15356     node.U = parent;
15357     node.C = true;
15358
15359     after = node;
15360     while (parent && parent.C) {
15361       grandpa = parent.U;
15362       if (parent === grandpa.L) {
15363         uncle = grandpa.R;
15364         if (uncle && uncle.C) {
15365           parent.C = uncle.C = false;
15366           grandpa.C = true;
15367           after = grandpa;
15368         } else {
15369           if (after === parent.R) {
15370             RedBlackRotateLeft(this, parent);
15371             after = parent;
15372             parent = after.U;
15373           }
15374           parent.C = false;
15375           grandpa.C = true;
15376           RedBlackRotateRight(this, grandpa);
15377         }
15378       } else {
15379         uncle = grandpa.L;
15380         if (uncle && uncle.C) {
15381           parent.C = uncle.C = false;
15382           grandpa.C = true;
15383           after = grandpa;
15384         } else {
15385           if (after === parent.L) {
15386             RedBlackRotateRight(this, parent);
15387             after = parent;
15388             parent = after.U;
15389           }
15390           parent.C = false;
15391           grandpa.C = true;
15392           RedBlackRotateLeft(this, grandpa);
15393         }
15394       }
15395       parent = after.U;
15396     }
15397     this._.C = false;
15398   },
15399
15400   remove: function(node) {
15401     if (node.N) node.N.P = node.P;
15402     if (node.P) node.P.N = node.N;
15403     node.N = node.P = null;
15404
15405     var parent = node.U,
15406         sibling,
15407         left = node.L,
15408         right = node.R,
15409         next,
15410         red;
15411
15412     if (!left) next = right;
15413     else if (!right) next = left;
15414     else next = RedBlackFirst(right);
15415
15416     if (parent) {
15417       if (parent.L === node) parent.L = next;
15418       else parent.R = next;
15419     } else {
15420       this._ = next;
15421     }
15422
15423     if (left && right) {
15424       red = next.C;
15425       next.C = node.C;
15426       next.L = left;
15427       left.U = next;
15428       if (next !== right) {
15429         parent = next.U;
15430         next.U = node.U;
15431         node = next.R;
15432         parent.L = node;
15433         next.R = right;
15434         right.U = next;
15435       } else {
15436         next.U = parent;
15437         parent = next;
15438         node = next.R;
15439       }
15440     } else {
15441       red = node.C;
15442       node = next;
15443     }
15444
15445     if (node) node.U = parent;
15446     if (red) return;
15447     if (node && node.C) { node.C = false; return; }
15448
15449     do {
15450       if (node === this._) break;
15451       if (node === parent.L) {
15452         sibling = parent.R;
15453         if (sibling.C) {
15454           sibling.C = false;
15455           parent.C = true;
15456           RedBlackRotateLeft(this, parent);
15457           sibling = parent.R;
15458         }
15459         if ((sibling.L && sibling.L.C)
15460             || (sibling.R && sibling.R.C)) {
15461           if (!sibling.R || !sibling.R.C) {
15462             sibling.L.C = false;
15463             sibling.C = true;
15464             RedBlackRotateRight(this, sibling);
15465             sibling = parent.R;
15466           }
15467           sibling.C = parent.C;
15468           parent.C = sibling.R.C = false;
15469           RedBlackRotateLeft(this, parent);
15470           node = this._;
15471           break;
15472         }
15473       } else {
15474         sibling = parent.L;
15475         if (sibling.C) {
15476           sibling.C = false;
15477           parent.C = true;
15478           RedBlackRotateRight(this, parent);
15479           sibling = parent.L;
15480         }
15481         if ((sibling.L && sibling.L.C)
15482           || (sibling.R && sibling.R.C)) {
15483           if (!sibling.L || !sibling.L.C) {
15484             sibling.R.C = false;
15485             sibling.C = true;
15486             RedBlackRotateLeft(this, sibling);
15487             sibling = parent.L;
15488           }
15489           sibling.C = parent.C;
15490           parent.C = sibling.L.C = false;
15491           RedBlackRotateRight(this, parent);
15492           node = this._;
15493           break;
15494         }
15495       }
15496       sibling.C = true;
15497       node = parent;
15498       parent = parent.U;
15499     } while (!node.C);
15500
15501     if (node) node.C = false;
15502   }
15503 };
15504
15505 function RedBlackRotateLeft(tree, node) {
15506   var p = node,
15507       q = node.R,
15508       parent = p.U;
15509
15510   if (parent) {
15511     if (parent.L === p) parent.L = q;
15512     else parent.R = q;
15513   } else {
15514     tree._ = q;
15515   }
15516
15517   q.U = parent;
15518   p.U = q;
15519   p.R = q.L;
15520   if (p.R) p.R.U = p;
15521   q.L = p;
15522 }
15523
15524 function RedBlackRotateRight(tree, node) {
15525   var p = node,
15526       q = node.L,
15527       parent = p.U;
15528
15529   if (parent) {
15530     if (parent.L === p) parent.L = q;
15531     else parent.R = q;
15532   } else {
15533     tree._ = q;
15534   }
15535
15536   q.U = parent;
15537   p.U = q;
15538   p.L = q.R;
15539   if (p.L) p.L.U = p;
15540   q.R = p;
15541 }
15542
15543 function RedBlackFirst(node) {
15544   while (node.L) node = node.L;
15545   return node;
15546 }
15547
15548 function createEdge(left, right, v0, v1) {
15549   var edge = [null, null],
15550       index = edges.push(edge) - 1;
15551   edge.left = left;
15552   edge.right = right;
15553   if (v0) setEdgeEnd(edge, left, right, v0);
15554   if (v1) setEdgeEnd(edge, right, left, v1);
15555   cells[left.index].halfedges.push(index);
15556   cells[right.index].halfedges.push(index);
15557   return edge;
15558 }
15559
15560 function createBorderEdge(left, v0, v1) {
15561   var edge = [v0, v1];
15562   edge.left = left;
15563   return edge;
15564 }
15565
15566 function setEdgeEnd(edge, left, right, vertex) {
15567   if (!edge[0] && !edge[1]) {
15568     edge[0] = vertex;
15569     edge.left = left;
15570     edge.right = right;
15571   } else if (edge.left === right) {
15572     edge[1] = vertex;
15573   } else {
15574     edge[0] = vertex;
15575   }
15576 }
15577
15578 // Liang–Barsky line clipping.
15579 function clipEdge(edge, x0, y0, x1, y1) {
15580   var a = edge[0],
15581       b = edge[1],
15582       ax = a[0],
15583       ay = a[1],
15584       bx = b[0],
15585       by = b[1],
15586       t0 = 0,
15587       t1 = 1,
15588       dx = bx - ax,
15589       dy = by - ay,
15590       r;
15591
15592   r = x0 - ax;
15593   if (!dx && r > 0) return;
15594   r /= dx;
15595   if (dx < 0) {
15596     if (r < t0) return;
15597     if (r < t1) t1 = r;
15598   } else if (dx > 0) {
15599     if (r > t1) return;
15600     if (r > t0) t0 = r;
15601   }
15602
15603   r = x1 - ax;
15604   if (!dx && r < 0) return;
15605   r /= dx;
15606   if (dx < 0) {
15607     if (r > t1) return;
15608     if (r > t0) t0 = r;
15609   } else if (dx > 0) {
15610     if (r < t0) return;
15611     if (r < t1) t1 = r;
15612   }
15613
15614   r = y0 - ay;
15615   if (!dy && r > 0) return;
15616   r /= dy;
15617   if (dy < 0) {
15618     if (r < t0) return;
15619     if (r < t1) t1 = r;
15620   } else if (dy > 0) {
15621     if (r > t1) return;
15622     if (r > t0) t0 = r;
15623   }
15624
15625   r = y1 - ay;
15626   if (!dy && r < 0) return;
15627   r /= dy;
15628   if (dy < 0) {
15629     if (r > t1) return;
15630     if (r > t0) t0 = r;
15631   } else if (dy > 0) {
15632     if (r < t0) return;
15633     if (r < t1) t1 = r;
15634   }
15635
15636   if (!(t0 > 0) && !(t1 < 1)) return true; // TODO Better check?
15637
15638   if (t0 > 0) edge[0] = [ax + t0 * dx, ay + t0 * dy];
15639   if (t1 < 1) edge[1] = [ax + t1 * dx, ay + t1 * dy];
15640   return true;
15641 }
15642
15643 function connectEdge(edge, x0, y0, x1, y1) {
15644   var v1 = edge[1];
15645   if (v1) return true;
15646
15647   var v0 = edge[0],
15648       left = edge.left,
15649       right = edge.right,
15650       lx = left[0],
15651       ly = left[1],
15652       rx = right[0],
15653       ry = right[1],
15654       fx = (lx + rx) / 2,
15655       fy = (ly + ry) / 2,
15656       fm,
15657       fb;
15658
15659   if (ry === ly) {
15660     if (fx < x0 || fx >= x1) return;
15661     if (lx > rx) {
15662       if (!v0) v0 = [fx, y0];
15663       else if (v0[1] >= y1) return;
15664       v1 = [fx, y1];
15665     } else {
15666       if (!v0) v0 = [fx, y1];
15667       else if (v0[1] < y0) return;
15668       v1 = [fx, y0];
15669     }
15670   } else {
15671     fm = (lx - rx) / (ry - ly);
15672     fb = fy - fm * fx;
15673     if (fm < -1 || fm > 1) {
15674       if (lx > rx) {
15675         if (!v0) v0 = [(y0 - fb) / fm, y0];
15676         else if (v0[1] >= y1) return;
15677         v1 = [(y1 - fb) / fm, y1];
15678       } else {
15679         if (!v0) v0 = [(y1 - fb) / fm, y1];
15680         else if (v0[1] < y0) return;
15681         v1 = [(y0 - fb) / fm, y0];
15682       }
15683     } else {
15684       if (ly < ry) {
15685         if (!v0) v0 = [x0, fm * x0 + fb];
15686         else if (v0[0] >= x1) return;
15687         v1 = [x1, fm * x1 + fb];
15688       } else {
15689         if (!v0) v0 = [x1, fm * x1 + fb];
15690         else if (v0[0] < x0) return;
15691         v1 = [x0, fm * x0 + fb];
15692       }
15693     }
15694   }
15695
15696   edge[0] = v0;
15697   edge[1] = v1;
15698   return true;
15699 }
15700
15701 function clipEdges(x0, y0, x1, y1) {
15702   var i = edges.length,
15703       edge;
15704
15705   while (i--) {
15706     if (!connectEdge(edge = edges[i], x0, y0, x1, y1)
15707         || !clipEdge(edge, x0, y0, x1, y1)
15708         || !(Math.abs(edge[0][0] - edge[1][0]) > epsilon$4
15709             || Math.abs(edge[0][1] - edge[1][1]) > epsilon$4)) {
15710       delete edges[i];
15711     }
15712   }
15713 }
15714
15715 function createCell(site) {
15716   return cells[site.index] = {
15717     site: site,
15718     halfedges: []
15719   };
15720 }
15721
15722 function cellHalfedgeAngle(cell, edge) {
15723   var site = cell.site,
15724       va = edge.left,
15725       vb = edge.right;
15726   if (site === vb) vb = va, va = site;
15727   if (vb) return Math.atan2(vb[1] - va[1], vb[0] - va[0]);
15728   if (site === va) va = edge[1], vb = edge[0];
15729   else va = edge[0], vb = edge[1];
15730   return Math.atan2(va[0] - vb[0], vb[1] - va[1]);
15731 }
15732
15733 function cellHalfedgeStart(cell, edge) {
15734   return edge[+(edge.left !== cell.site)];
15735 }
15736
15737 function cellHalfedgeEnd(cell, edge) {
15738   return edge[+(edge.left === cell.site)];
15739 }
15740
15741 function sortCellHalfedges() {
15742   for (var i = 0, n = cells.length, cell, halfedges, j, m; i < n; ++i) {
15743     if ((cell = cells[i]) && (m = (halfedges = cell.halfedges).length)) {
15744       var index = new Array(m),
15745           array = new Array(m);
15746       for (j = 0; j < m; ++j) index[j] = j, array[j] = cellHalfedgeAngle(cell, edges[halfedges[j]]);
15747       index.sort(function(i, j) { return array[j] - array[i]; });
15748       for (j = 0; j < m; ++j) array[j] = halfedges[index[j]];
15749       for (j = 0; j < m; ++j) halfedges[j] = array[j];
15750     }
15751   }
15752 }
15753
15754 function clipCells(x0, y0, x1, y1) {
15755   var nCells = cells.length,
15756       iCell,
15757       cell,
15758       site,
15759       iHalfedge,
15760       halfedges,
15761       nHalfedges,
15762       start,
15763       startX,
15764       startY,
15765       end,
15766       endX,
15767       endY,
15768       cover = true;
15769
15770   for (iCell = 0; iCell < nCells; ++iCell) {
15771     if (cell = cells[iCell]) {
15772       site = cell.site;
15773       halfedges = cell.halfedges;
15774       iHalfedge = halfedges.length;
15775
15776       // Remove any dangling clipped edges.
15777       while (iHalfedge--) {
15778         if (!edges[halfedges[iHalfedge]]) {
15779           halfedges.splice(iHalfedge, 1);
15780         }
15781       }
15782
15783       // Insert any border edges as necessary.
15784       iHalfedge = 0, nHalfedges = halfedges.length;
15785       while (iHalfedge < nHalfedges) {
15786         end = cellHalfedgeEnd(cell, edges[halfedges[iHalfedge]]), endX = end[0], endY = end[1];
15787         start = cellHalfedgeStart(cell, edges[halfedges[++iHalfedge % nHalfedges]]), startX = start[0], startY = start[1];
15788         if (Math.abs(endX - startX) > epsilon$4 || Math.abs(endY - startY) > epsilon$4) {
15789           halfedges.splice(iHalfedge, 0, edges.push(createBorderEdge(site, end,
15790               Math.abs(endX - x0) < epsilon$4 && y1 - endY > epsilon$4 ? [x0, Math.abs(startX - x0) < epsilon$4 ? startY : y1]
15791               : Math.abs(endY - y1) < epsilon$4 && x1 - endX > epsilon$4 ? [Math.abs(startY - y1) < epsilon$4 ? startX : x1, y1]
15792               : Math.abs(endX - x1) < epsilon$4 && endY - y0 > epsilon$4 ? [x1, Math.abs(startX - x1) < epsilon$4 ? startY : y0]
15793               : Math.abs(endY - y0) < epsilon$4 && endX - x0 > epsilon$4 ? [Math.abs(startY - y0) < epsilon$4 ? startX : x0, y0]
15794               : null)) - 1);
15795           ++nHalfedges;
15796         }
15797       }
15798
15799       if (nHalfedges) cover = false;
15800     }
15801   }
15802
15803   // If there weren’t any edges, have the closest site cover the extent.
15804   // It doesn’t matter which corner of the extent we measure!
15805   if (cover) {
15806     var dx, dy, d2, dc = Infinity;
15807
15808     for (iCell = 0, cover = null; iCell < nCells; ++iCell) {
15809       if (cell = cells[iCell]) {
15810         site = cell.site;
15811         dx = site[0] - x0;
15812         dy = site[1] - y0;
15813         d2 = dx * dx + dy * dy;
15814         if (d2 < dc) dc = d2, cover = cell;
15815       }
15816     }
15817
15818     if (cover) {
15819       var v00 = [x0, y0], v01 = [x0, y1], v11 = [x1, y1], v10 = [x1, y0];
15820       cover.halfedges.push(
15821         edges.push(createBorderEdge(site = cover.site, v00, v01)) - 1,
15822         edges.push(createBorderEdge(site, v01, v11)) - 1,
15823         edges.push(createBorderEdge(site, v11, v10)) - 1,
15824         edges.push(createBorderEdge(site, v10, v00)) - 1
15825       );
15826     }
15827   }
15828
15829   // Lastly delete any cells with no edges; these were entirely clipped.
15830   for (iCell = 0; iCell < nCells; ++iCell) {
15831     if (cell = cells[iCell]) {
15832       if (!cell.halfedges.length) {
15833         delete cells[iCell];
15834       }
15835     }
15836   }
15837 }
15838
15839 var circlePool = [];
15840
15841 var firstCircle;
15842
15843 function Circle() {
15844   RedBlackNode(this);
15845   this.x =
15846   this.y =
15847   this.arc =
15848   this.site =
15849   this.cy = null;
15850 }
15851
15852 function attachCircle(arc) {
15853   var lArc = arc.P,
15854       rArc = arc.N;
15855
15856   if (!lArc || !rArc) return;
15857
15858   var lSite = lArc.site,
15859       cSite = arc.site,
15860       rSite = rArc.site;
15861
15862   if (lSite === rSite) return;
15863
15864   var bx = cSite[0],
15865       by = cSite[1],
15866       ax = lSite[0] - bx,
15867       ay = lSite[1] - by,
15868       cx = rSite[0] - bx,
15869       cy = rSite[1] - by;
15870
15871   var d = 2 * (ax * cy - ay * cx);
15872   if (d >= -epsilon2$2) return;
15873
15874   var ha = ax * ax + ay * ay,
15875       hc = cx * cx + cy * cy,
15876       x = (cy * ha - ay * hc) / d,
15877       y = (ax * hc - cx * ha) / d;
15878
15879   var circle = circlePool.pop() || new Circle;
15880   circle.arc = arc;
15881   circle.site = cSite;
15882   circle.x = x + bx;
15883   circle.y = (circle.cy = y + by) + Math.sqrt(x * x + y * y); // y bottom
15884
15885   arc.circle = circle;
15886
15887   var before = null,
15888       node = circles._;
15889
15890   while (node) {
15891     if (circle.y < node.y || (circle.y === node.y && circle.x <= node.x)) {
15892       if (node.L) node = node.L;
15893       else { before = node.P; break; }
15894     } else {
15895       if (node.R) node = node.R;
15896       else { before = node; break; }
15897     }
15898   }
15899
15900   circles.insert(before, circle);
15901   if (!before) firstCircle = circle;
15902 }
15903
15904 function detachCircle(arc) {
15905   var circle = arc.circle;
15906   if (circle) {
15907     if (!circle.P) firstCircle = circle.N;
15908     circles.remove(circle);
15909     circlePool.push(circle);
15910     RedBlackNode(circle);
15911     arc.circle = null;
15912   }
15913 }
15914
15915 var beachPool = [];
15916
15917 function Beach() {
15918   RedBlackNode(this);
15919   this.edge =
15920   this.site =
15921   this.circle = null;
15922 }
15923
15924 function createBeach(site) {
15925   var beach = beachPool.pop() || new Beach;
15926   beach.site = site;
15927   return beach;
15928 }
15929
15930 function detachBeach(beach) {
15931   detachCircle(beach);
15932   beaches.remove(beach);
15933   beachPool.push(beach);
15934   RedBlackNode(beach);
15935 }
15936
15937 function removeBeach(beach) {
15938   var circle = beach.circle,
15939       x = circle.x,
15940       y = circle.cy,
15941       vertex = [x, y],
15942       previous = beach.P,
15943       next = beach.N,
15944       disappearing = [beach];
15945
15946   detachBeach(beach);
15947
15948   var lArc = previous;
15949   while (lArc.circle
15950       && Math.abs(x - lArc.circle.x) < epsilon$4
15951       && Math.abs(y - lArc.circle.cy) < epsilon$4) {
15952     previous = lArc.P;
15953     disappearing.unshift(lArc);
15954     detachBeach(lArc);
15955     lArc = previous;
15956   }
15957
15958   disappearing.unshift(lArc);
15959   detachCircle(lArc);
15960
15961   var rArc = next;
15962   while (rArc.circle
15963       && Math.abs(x - rArc.circle.x) < epsilon$4
15964       && Math.abs(y - rArc.circle.cy) < epsilon$4) {
15965     next = rArc.N;
15966     disappearing.push(rArc);
15967     detachBeach(rArc);
15968     rArc = next;
15969   }
15970
15971   disappearing.push(rArc);
15972   detachCircle(rArc);
15973
15974   var nArcs = disappearing.length,
15975       iArc;
15976   for (iArc = 1; iArc < nArcs; ++iArc) {
15977     rArc = disappearing[iArc];
15978     lArc = disappearing[iArc - 1];
15979     setEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex);
15980   }
15981
15982   lArc = disappearing[0];
15983   rArc = disappearing[nArcs - 1];
15984   rArc.edge = createEdge(lArc.site, rArc.site, null, vertex);
15985
15986   attachCircle(lArc);
15987   attachCircle(rArc);
15988 }
15989
15990 function addBeach(site) {
15991   var x = site[0],
15992       directrix = site[1],
15993       lArc,
15994       rArc,
15995       dxl,
15996       dxr,
15997       node = beaches._;
15998
15999   while (node) {
16000     dxl = leftBreakPoint(node, directrix) - x;
16001     if (dxl > epsilon$4) node = node.L; else {
16002       dxr = x - rightBreakPoint(node, directrix);
16003       if (dxr > epsilon$4) {
16004         if (!node.R) {
16005           lArc = node;
16006           break;
16007         }
16008         node = node.R;
16009       } else {
16010         if (dxl > -epsilon$4) {
16011           lArc = node.P;
16012           rArc = node;
16013         } else if (dxr > -epsilon$4) {
16014           lArc = node;
16015           rArc = node.N;
16016         } else {
16017           lArc = rArc = node;
16018         }
16019         break;
16020       }
16021     }
16022   }
16023
16024   createCell(site);
16025   var newArc = createBeach(site);
16026   beaches.insert(lArc, newArc);
16027
16028   if (!lArc && !rArc) return;
16029
16030   if (lArc === rArc) {
16031     detachCircle(lArc);
16032     rArc = createBeach(lArc.site);
16033     beaches.insert(newArc, rArc);
16034     newArc.edge = rArc.edge = createEdge(lArc.site, newArc.site);
16035     attachCircle(lArc);
16036     attachCircle(rArc);
16037     return;
16038   }
16039
16040   if (!rArc) { // && lArc
16041     newArc.edge = createEdge(lArc.site, newArc.site);
16042     return;
16043   }
16044
16045   // else lArc !== rArc
16046   detachCircle(lArc);
16047   detachCircle(rArc);
16048
16049   var lSite = lArc.site,
16050       ax = lSite[0],
16051       ay = lSite[1],
16052       bx = site[0] - ax,
16053       by = site[1] - ay,
16054       rSite = rArc.site,
16055       cx = rSite[0] - ax,
16056       cy = rSite[1] - ay,
16057       d = 2 * (bx * cy - by * cx),
16058       hb = bx * bx + by * by,
16059       hc = cx * cx + cy * cy,
16060       vertex = [(cy * hb - by * hc) / d + ax, (bx * hc - cx * hb) / d + ay];
16061
16062   setEdgeEnd(rArc.edge, lSite, rSite, vertex);
16063   newArc.edge = createEdge(lSite, site, null, vertex);
16064   rArc.edge = createEdge(site, rSite, null, vertex);
16065   attachCircle(lArc);
16066   attachCircle(rArc);
16067 }
16068
16069 function leftBreakPoint(arc, directrix) {
16070   var site = arc.site,
16071       rfocx = site[0],
16072       rfocy = site[1],
16073       pby2 = rfocy - directrix;
16074
16075   if (!pby2) return rfocx;
16076
16077   var lArc = arc.P;
16078   if (!lArc) return -Infinity;
16079
16080   site = lArc.site;
16081   var lfocx = site[0],
16082       lfocy = site[1],
16083       plby2 = lfocy - directrix;
16084
16085   if (!plby2) return lfocx;
16086
16087   var hl = lfocx - rfocx,
16088       aby2 = 1 / pby2 - 1 / plby2,
16089       b = hl / plby2;
16090
16091   if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx;
16092
16093   return (rfocx + lfocx) / 2;
16094 }
16095
16096 function rightBreakPoint(arc, directrix) {
16097   var rArc = arc.N;
16098   if (rArc) return leftBreakPoint(rArc, directrix);
16099   var site = arc.site;
16100   return site[1] === directrix ? site[0] : Infinity;
16101 }
16102
16103 var epsilon$4 = 1e-6;
16104 var epsilon2$2 = 1e-12;
16105 var beaches;
16106 var cells;
16107 var circles;
16108 var edges;
16109
16110 function triangleArea(a, b, c) {
16111   return (a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]);
16112 }
16113
16114 function lexicographic(a, b) {
16115   return b[1] - a[1]
16116       || b[0] - a[0];
16117 }
16118
16119 function Diagram(sites, extent) {
16120   var site = sites.sort(lexicographic).pop(),
16121       x,
16122       y,
16123       circle;
16124
16125   edges = [];
16126   cells = new Array(sites.length);
16127   beaches = new RedBlackTree;
16128   circles = new RedBlackTree;
16129
16130   while (true) {
16131     circle = firstCircle;
16132     if (site && (!circle || site[1] < circle.y || (site[1] === circle.y && site[0] < circle.x))) {
16133       if (site[0] !== x || site[1] !== y) {
16134         addBeach(site);
16135         x = site[0], y = site[1];
16136       }
16137       site = sites.pop();
16138     } else if (circle) {
16139       removeBeach(circle.arc);
16140     } else {
16141       break;
16142     }
16143   }
16144
16145   sortCellHalfedges();
16146
16147   if (extent) {
16148     var x0 = +extent[0][0],
16149         y0 = +extent[0][1],
16150         x1 = +extent[1][0],
16151         y1 = +extent[1][1];
16152     clipEdges(x0, y0, x1, y1);
16153     clipCells(x0, y0, x1, y1);
16154   }
16155
16156   this.edges = edges;
16157   this.cells = cells;
16158
16159   beaches =
16160   circles =
16161   edges =
16162   cells = null;
16163 }
16164
16165 Diagram.prototype = {
16166   constructor: Diagram,
16167
16168   polygons: function() {
16169     var edges = this.edges;
16170
16171     return this.cells.map(function(cell) {
16172       var polygon = cell.halfedges.map(function(i) { return cellHalfedgeStart(cell, edges[i]); });
16173       polygon.data = cell.site.data;
16174       return polygon;
16175     });
16176   },
16177
16178   triangles: function() {
16179     var triangles = [],
16180         edges = this.edges;
16181
16182     this.cells.forEach(function(cell, i) {
16183       if (!(m = (halfedges = cell.halfedges).length)) return;
16184       var site = cell.site,
16185           halfedges,
16186           j = -1,
16187           m,
16188           s0,
16189           e1 = edges[halfedges[m - 1]],
16190           s1 = e1.left === site ? e1.right : e1.left;
16191
16192       while (++j < m) {
16193         s0 = s1;
16194         e1 = edges[halfedges[j]];
16195         s1 = e1.left === site ? e1.right : e1.left;
16196         if (s0 && s1 && i < s0.index && i < s1.index && triangleArea(site, s0, s1) < 0) {
16197           triangles.push([site.data, s0.data, s1.data]);
16198         }
16199       }
16200     });
16201
16202     return triangles;
16203   },
16204
16205   links: function() {
16206     return this.edges.filter(function(edge) {
16207       return edge.right;
16208     }).map(function(edge) {
16209       return {
16210         source: edge.left.data,
16211         target: edge.right.data
16212       };
16213     });
16214   },
16215
16216   find: function(x, y, radius) {
16217     var that = this, i0, i1 = that._found || 0, n = that.cells.length, cell;
16218
16219     // Use the previously-found cell, or start with an arbitrary one.
16220     while (!(cell = that.cells[i1])) if (++i1 >= n) return null;
16221     var dx = x - cell.site[0], dy = y - cell.site[1], d2 = dx * dx + dy * dy;
16222
16223     // Traverse the half-edges to find a closer cell, if any.
16224     do {
16225       cell = that.cells[i0 = i1], i1 = null;
16226       cell.halfedges.forEach(function(e) {
16227         var edge = that.edges[e], v = edge.left;
16228         if ((v === cell.site || !v) && !(v = edge.right)) return;
16229         var vx = x - v[0], vy = y - v[1], v2 = vx * vx + vy * vy;
16230         if (v2 < d2) d2 = v2, i1 = v.index;
16231       });
16232     } while (i1 !== null);
16233
16234     that._found = i0;
16235
16236     return radius == null || d2 <= radius * radius ? cell.site : null;
16237   }
16238 };
16239
16240 function voronoi() {
16241   var x$$1 = x$4,
16242       y$$1 = y$4,
16243       extent = null;
16244
16245   function voronoi(data) {
16246     return new Diagram(data.map(function(d, i) {
16247       var s = [Math.round(x$$1(d, i, data) / epsilon$4) * epsilon$4, Math.round(y$$1(d, i, data) / epsilon$4) * epsilon$4];
16248       s.index = i;
16249       s.data = d;
16250       return s;
16251     }), extent);
16252   }
16253
16254   voronoi.polygons = function(data) {
16255     return voronoi(data).polygons();
16256   };
16257
16258   voronoi.links = function(data) {
16259     return voronoi(data).links();
16260   };
16261
16262   voronoi.triangles = function(data) {
16263     return voronoi(data).triangles();
16264   };
16265
16266   voronoi.x = function(_) {
16267     return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$11(+_), voronoi) : x$$1;
16268   };
16269
16270   voronoi.y = function(_) {
16271     return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$11(+_), voronoi) : y$$1;
16272   };
16273
16274   voronoi.extent = function(_) {
16275     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]]];
16276   };
16277
16278   voronoi.size = function(_) {
16279     return arguments.length ? (extent = _ == null ? null : [[0, 0], [+_[0], +_[1]]], voronoi) : extent && [extent[1][0] - extent[0][0], extent[1][1] - extent[0][1]];
16280   };
16281
16282   return voronoi;
16283 }
16284
16285 function constant$12(x) {
16286   return function() {
16287     return x;
16288   };
16289 }
16290
16291 function ZoomEvent(target, type, transform) {
16292   this.target = target;
16293   this.type = type;
16294   this.transform = transform;
16295 }
16296
16297 function Transform(k, x, y) {
16298   this.k = k;
16299   this.x = x;
16300   this.y = y;
16301 }
16302
16303 Transform.prototype = {
16304   constructor: Transform,
16305   scale: function(k) {
16306     return k === 1 ? this : new Transform(this.k * k, this.x, this.y);
16307   },
16308   translate: function(x, y) {
16309     return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y);
16310   },
16311   apply: function(point) {
16312     return [point[0] * this.k + this.x, point[1] * this.k + this.y];
16313   },
16314   applyX: function(x) {
16315     return x * this.k + this.x;
16316   },
16317   applyY: function(y) {
16318     return y * this.k + this.y;
16319   },
16320   invert: function(location) {
16321     return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k];
16322   },
16323   invertX: function(x) {
16324     return (x - this.x) / this.k;
16325   },
16326   invertY: function(y) {
16327     return (y - this.y) / this.k;
16328   },
16329   rescaleX: function(x) {
16330     return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x));
16331   },
16332   rescaleY: function(y) {
16333     return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y));
16334   },
16335   toString: function() {
16336     return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")";
16337   }
16338 };
16339
16340 var identity$7 = new Transform(1, 0, 0);
16341
16342 transform.prototype = Transform.prototype;
16343
16344 function transform(node) {
16345   return node.__zoom || identity$7;
16346 }
16347
16348 function nopropagation$2() {
16349   event.stopImmediatePropagation();
16350 }
16351
16352 function noevent$2() {
16353   event.preventDefault();
16354   event.stopImmediatePropagation();
16355 }
16356
16357 // Ignore right-click, since that should open the context menu.
16358 function defaultFilter$2() {
16359   return !event.button;
16360 }
16361
16362 function defaultExtent$1() {
16363   var e = this, w, h;
16364   if (e instanceof SVGElement) {
16365     e = e.ownerSVGElement || e;
16366     w = e.width.baseVal.value;
16367     h = e.height.baseVal.value;
16368   } else {
16369     w = e.clientWidth;
16370     h = e.clientHeight;
16371   }
16372   return [[0, 0], [w, h]];
16373 }
16374
16375 function defaultTransform() {
16376   return this.__zoom || identity$7;
16377 }
16378
16379 function defaultWheelDelta() {
16380   return -event.deltaY * (event.deltaMode ? 120 : 1) / 500;
16381 }
16382
16383 function defaultTouchable$1() {
16384   return "ontouchstart" in this;
16385 }
16386
16387 function defaultConstrain(transform$$1, extent, translateExtent) {
16388   var dx0 = transform$$1.invertX(extent[0][0]) - translateExtent[0][0],
16389       dx1 = transform$$1.invertX(extent[1][0]) - translateExtent[1][0],
16390       dy0 = transform$$1.invertY(extent[0][1]) - translateExtent[0][1],
16391       dy1 = transform$$1.invertY(extent[1][1]) - translateExtent[1][1];
16392   return transform$$1.translate(
16393     dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1),
16394     dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1)
16395   );
16396 }
16397
16398 function d3_zoom() {
16399   var filter = defaultFilter$2,
16400       extent = defaultExtent$1,
16401       constrain = defaultConstrain,
16402       wheelDelta = defaultWheelDelta,
16403       touchable = defaultTouchable$1,
16404       scaleExtent = [0, Infinity],
16405       translateExtent = [[-Infinity, -Infinity], [Infinity, Infinity]],
16406       duration = 250,
16407       interpolate = interpolateZoom,
16408       gestures = [],
16409       listeners = dispatch("start", "zoom", "end"),
16410       touchstarting,
16411       touchending,
16412       touchDelay = 500,
16413       wheelDelay = 150,
16414       clickDistance2 = 0;
16415
16416   function zoom(selection) {
16417     selection
16418         .property("__zoom", defaultTransform)
16419         .on("wheel.zoom", wheeled)
16420         .on("mousedown.zoom", mousedowned)
16421         .on("dblclick.zoom", dblclicked)
16422       .filter(touchable)
16423         .on("touchstart.zoom", touchstarted)
16424         .on("touchmove.zoom", touchmoved)
16425         .on("touchend.zoom touchcancel.zoom", touchended)
16426         .style("touch-action", "none")
16427         .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
16428   }
16429
16430   zoom.transform = function(collection, transform$$1) {
16431     var selection = collection.selection ? collection.selection() : collection;
16432     selection.property("__zoom", defaultTransform);
16433     if (collection !== selection) {
16434       schedule(collection, transform$$1);
16435     } else {
16436       selection.interrupt().each(function() {
16437         gesture(this, arguments)
16438             .start()
16439             .zoom(null, typeof transform$$1 === "function" ? transform$$1.apply(this, arguments) : transform$$1)
16440             .end();
16441       });
16442     }
16443   };
16444
16445   zoom.scaleBy = function(selection, k) {
16446     zoom.scaleTo(selection, function() {
16447       var k0 = this.__zoom.k,
16448           k1 = typeof k === "function" ? k.apply(this, arguments) : k;
16449       return k0 * k1;
16450     });
16451   };
16452
16453   zoom.scaleTo = function(selection, k) {
16454     zoom.transform(selection, function() {
16455       var e = extent.apply(this, arguments),
16456           t0 = this.__zoom,
16457           p0 = centroid(e),
16458           p1 = t0.invert(p0),
16459           k1 = typeof k === "function" ? k.apply(this, arguments) : k;
16460       return constrain(translate(scale(t0, k1), p0, p1), e, translateExtent);
16461     });
16462   };
16463
16464   zoom.translateBy = function(selection, x, y) {
16465     zoom.transform(selection, function() {
16466       return constrain(this.__zoom.translate(
16467         typeof x === "function" ? x.apply(this, arguments) : x,
16468         typeof y === "function" ? y.apply(this, arguments) : y
16469       ), extent.apply(this, arguments), translateExtent);
16470     });
16471   };
16472
16473   zoom.translateTo = function(selection, x, y) {
16474     zoom.transform(selection, function() {
16475       var e = extent.apply(this, arguments),
16476           t = this.__zoom,
16477           p = centroid(e);
16478       return constrain(identity$7.translate(p[0], p[1]).scale(t.k).translate(
16479         typeof x === "function" ? -x.apply(this, arguments) : -x,
16480         typeof y === "function" ? -y.apply(this, arguments) : -y
16481       ), e, translateExtent);
16482     });
16483   };
16484
16485   function scale(transform$$1, k) {
16486     k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], k));
16487     return k === transform$$1.k ? transform$$1 : new Transform(k, transform$$1.x, transform$$1.y);
16488   }
16489
16490   function translate(transform$$1, p0, p1) {
16491     var x = p0[0] - p1[0] * transform$$1.k, y = p0[1] - p1[1] * transform$$1.k;
16492     return x === transform$$1.x && y === transform$$1.y ? transform$$1 : new Transform(transform$$1.k, x, y);
16493   }
16494
16495   function centroid(extent) {
16496     return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2];
16497   }
16498
16499   function schedule(transition, transform$$1, center) {
16500     transition
16501         .on("start.zoom", function() { gesture(this, arguments).start(); })
16502         .on("interrupt.zoom end.zoom", function() { gesture(this, arguments).end(); })
16503         .tween("zoom", function() {
16504           var that = this,
16505               args = arguments,
16506               g = gesture(that, args),
16507               e = extent.apply(that, args),
16508               p = center || centroid(e),
16509               w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]),
16510               a = that.__zoom,
16511               b = typeof transform$$1 === "function" ? transform$$1.apply(that, args) : transform$$1,
16512               i = interpolate(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k));
16513           return function(t) {
16514             if (t === 1) t = b; // Avoid rounding error on end.
16515             else { var l = i(t), k = w / l[2]; t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); }
16516             g.zoom(null, t);
16517           };
16518         });
16519   }
16520
16521   function gesture(that, args) {
16522     for (var i = 0, n = gestures.length, g; i < n; ++i) {
16523       if ((g = gestures[i]).that === that) {
16524         return g;
16525       }
16526     }
16527     return new Gesture(that, args);
16528   }
16529
16530   function Gesture(that, args) {
16531     this.that = that;
16532     this.args = args;
16533     this.index = -1;
16534     this.active = 0;
16535     this.extent = extent.apply(that, args);
16536   }
16537
16538   Gesture.prototype = {
16539     start: function() {
16540       if (++this.active === 1) {
16541         this.index = gestures.push(this) - 1;
16542         this.emit("start");
16543       }
16544       return this;
16545     },
16546     zoom: function(key, transform$$1) {
16547       if (this.mouse && key !== "mouse") this.mouse[1] = transform$$1.invert(this.mouse[0]);
16548       if (this.touch0 && key !== "touch") this.touch0[1] = transform$$1.invert(this.touch0[0]);
16549       if (this.touch1 && key !== "touch") this.touch1[1] = transform$$1.invert(this.touch1[0]);
16550       this.that.__zoom = transform$$1;
16551       this.emit("zoom");
16552       return this;
16553     },
16554     end: function() {
16555       if (--this.active === 0) {
16556         gestures.splice(this.index, 1);
16557         this.index = -1;
16558         this.emit("end");
16559       }
16560       return this;
16561     },
16562     emit: function(type) {
16563       customEvent(new ZoomEvent(zoom, type, this.that.__zoom), listeners.apply, listeners, [type, this.that, this.args]);
16564     }
16565   };
16566
16567   function wheeled() {
16568     if (!filter.apply(this, arguments)) return;
16569     var g = gesture(this, arguments),
16570         t = this.__zoom,
16571         k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], t.k * Math.pow(2, wheelDelta.apply(this, arguments)))),
16572         p = d3_mouse(this);
16573
16574     // If the mouse is in the same location as before, reuse it.
16575     // If there were recent wheel events, reset the wheel idle timeout.
16576     if (g.wheel) {
16577       if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) {
16578         g.mouse[1] = t.invert(g.mouse[0] = p);
16579       }
16580       clearTimeout(g.wheel);
16581     }
16582
16583     // If this wheel event won’t trigger a transform change, ignore it.
16584     else if (t.k === k) return;
16585
16586     // Otherwise, capture the mouse point and location at the start.
16587     else {
16588       g.mouse = [p, t.invert(p)];
16589       interrupt(this);
16590       g.start();
16591     }
16592
16593     noevent$2();
16594     g.wheel = setTimeout(wheelidled, wheelDelay);
16595     g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent, translateExtent));
16596
16597     function wheelidled() {
16598       g.wheel = null;
16599       g.end();
16600     }
16601   }
16602
16603   function mousedowned() {
16604     if (touchending || !filter.apply(this, arguments)) return;
16605     var g = gesture(this, arguments),
16606         v = d3_select(event.view).on("mousemove.zoom", mousemoved, true).on("mouseup.zoom", mouseupped, true),
16607         p = d3_mouse(this),
16608         x0 = event.clientX,
16609         y0 = event.clientY;
16610
16611     dragDisable(event.view);
16612     nopropagation$2();
16613     g.mouse = [p, this.__zoom.invert(p)];
16614     interrupt(this);
16615     g.start();
16616
16617     function mousemoved() {
16618       noevent$2();
16619       if (!g.moved) {
16620         var dx = event.clientX - x0, dy = event.clientY - y0;
16621         g.moved = dx * dx + dy * dy > clickDistance2;
16622       }
16623       g.zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = d3_mouse(g.that), g.mouse[1]), g.extent, translateExtent));
16624     }
16625
16626     function mouseupped() {
16627       v.on("mousemove.zoom mouseup.zoom", null);
16628       yesdrag(event.view, g.moved);
16629       noevent$2();
16630       g.end();
16631     }
16632   }
16633
16634   function dblclicked() {
16635     if (!filter.apply(this, arguments)) return;
16636     var t0 = this.__zoom,
16637         p0 = d3_mouse(this),
16638         p1 = t0.invert(p0),
16639         k1 = t0.k * (event.shiftKey ? 0.5 : 2),
16640         t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, arguments), translateExtent);
16641
16642     noevent$2();
16643     if (duration > 0) d3_select(this).transition().duration(duration).call(schedule, t1, p0);
16644     else d3_select(this).call(zoom.transform, t1);
16645   }
16646
16647   function touchstarted() {
16648     if (!filter.apply(this, arguments)) return;
16649     var g = gesture(this, arguments),
16650         touches = event.changedTouches,
16651         started,
16652         n = touches.length, i, t, p;
16653
16654     nopropagation$2();
16655     for (i = 0; i < n; ++i) {
16656       t = touches[i], p = touch(this, touches, t.identifier);
16657       p = [p, this.__zoom.invert(p), t.identifier];
16658       if (!g.touch0) g.touch0 = p, started = true;
16659       else if (!g.touch1) g.touch1 = p;
16660     }
16661
16662     // If this is a dbltap, reroute to the (optional) dblclick.zoom handler.
16663     if (touchstarting) {
16664       touchstarting = clearTimeout(touchstarting);
16665       if (!g.touch1) {
16666         g.end();
16667         p = d3_select(this).on("dblclick.zoom");
16668         if (p) p.apply(this, arguments);
16669         return;
16670       }
16671     }
16672
16673     if (started) {
16674       touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay);
16675       interrupt(this);
16676       g.start();
16677     }
16678   }
16679
16680   function touchmoved() {
16681     var g = gesture(this, arguments),
16682         touches = event.changedTouches,
16683         n = touches.length, i, t, p, l;
16684
16685     noevent$2();
16686     if (touchstarting) touchstarting = clearTimeout(touchstarting);
16687     for (i = 0; i < n; ++i) {
16688       t = touches[i], p = touch(this, touches, t.identifier);
16689       if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p;
16690       else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p;
16691     }
16692     t = g.that.__zoom;
16693     if (g.touch1) {
16694       var p0 = g.touch0[0], l0 = g.touch0[1],
16695           p1 = g.touch1[0], l1 = g.touch1[1],
16696           dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp,
16697           dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl;
16698       t = scale(t, Math.sqrt(dp / dl));
16699       p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2];
16700       l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];
16701     }
16702     else if (g.touch0) p = g.touch0[0], l = g.touch0[1];
16703     else return;
16704     g.zoom("touch", constrain(translate(t, p, l), g.extent, translateExtent));
16705   }
16706
16707   function touchended() {
16708     var g = gesture(this, arguments),
16709         touches = event.changedTouches,
16710         n = touches.length, i, t;
16711
16712     nopropagation$2();
16713     if (touchending) clearTimeout(touchending);
16714     touchending = setTimeout(function() { touchending = null; }, touchDelay);
16715     for (i = 0; i < n; ++i) {
16716       t = touches[i];
16717       if (g.touch0 && g.touch0[2] === t.identifier) delete g.touch0;
16718       else if (g.touch1 && g.touch1[2] === t.identifier) delete g.touch1;
16719     }
16720     if (g.touch1 && !g.touch0) g.touch0 = g.touch1, delete g.touch1;
16721     if (g.touch0) g.touch0[1] = this.__zoom.invert(g.touch0[0]);
16722     else g.end();
16723   }
16724
16725   zoom.wheelDelta = function(_) {
16726     return arguments.length ? (wheelDelta = typeof _ === "function" ? _ : constant$12(+_), zoom) : wheelDelta;
16727   };
16728
16729   zoom.filter = function(_) {
16730     return arguments.length ? (filter = typeof _ === "function" ? _ : constant$12(!!_), zoom) : filter;
16731   };
16732
16733   zoom.touchable = function(_) {
16734     return arguments.length ? (touchable = typeof _ === "function" ? _ : constant$12(!!_), zoom) : touchable;
16735   };
16736
16737   zoom.extent = function(_) {
16738     return arguments.length ? (extent = typeof _ === "function" ? _ : constant$12([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent;
16739   };
16740
16741   zoom.scaleExtent = function(_) {
16742     return arguments.length ? (scaleExtent[0] = +_[0], scaleExtent[1] = +_[1], zoom) : [scaleExtent[0], scaleExtent[1]];
16743   };
16744
16745   zoom.translateExtent = function(_) {
16746     return arguments.length ? (translateExtent[0][0] = +_[0][0], translateExtent[1][0] = +_[1][0], translateExtent[0][1] = +_[0][1], translateExtent[1][1] = +_[1][1], zoom) : [[translateExtent[0][0], translateExtent[0][1]], [translateExtent[1][0], translateExtent[1][1]]];
16747   };
16748
16749   zoom.constrain = function(_) {
16750     return arguments.length ? (constrain = _, zoom) : constrain;
16751   };
16752
16753   zoom.duration = function(_) {
16754     return arguments.length ? (duration = +_, zoom) : duration;
16755   };
16756
16757   zoom.interpolate = function(_) {
16758     return arguments.length ? (interpolate = _, zoom) : interpolate;
16759   };
16760
16761   zoom.on = function() {
16762     var value = listeners.on.apply(listeners, arguments);
16763     return value === listeners ? zoom : value;
16764   };
16765
16766   zoom.clickDistance = function(_) {
16767     return arguments.length ? (clickDistance2 = (_ = +_) * _, zoom) : Math.sqrt(clickDistance2);
16768   };
16769
16770   return zoom;
16771 }
16772
16773
16774
16775 var index$3 = Object.freeze({
16776         version: version,
16777         bisect: bisectRight,
16778         bisectRight: bisectRight,
16779         bisectLeft: bisectLeft,
16780         ascending: d3_ascending,
16781         bisector: d3_bisector,
16782         cross: cross,
16783         descending: d3_descending,
16784         deviation: deviation,
16785         extent: extent,
16786         histogram: histogram,
16787         thresholdFreedmanDiaconis: freedmanDiaconis,
16788         thresholdScott: scott,
16789         thresholdSturges: sturges,
16790         max: max,
16791         mean: mean,
16792         median: d3_median,
16793         merge: merge,
16794         min: min,
16795         pairs: pairs,
16796         permute: permute,
16797         quantile: threshold,
16798         range: d3_range,
16799         scan: scan,
16800         shuffle: shuffle,
16801         sum: sum,
16802         ticks: ticks,
16803         tickIncrement: tickIncrement,
16804         tickStep: tickStep,
16805         transpose: transpose,
16806         variance: variance,
16807         zip: zip,
16808         axisTop: axisTop,
16809         axisRight: axisRight,
16810         axisBottom: axisBottom,
16811         axisLeft: axisLeft,
16812         brush: brush,
16813         brushX: brushX,
16814         brushY: brushY,
16815         brushSelection: brushSelection,
16816         chord: chord,
16817         ribbon: ribbon,
16818         nest: nest,
16819         set: set$2,
16820         map: map$1,
16821         keys: keys,
16822         values: values,
16823         entries: entries,
16824         color: color,
16825         rgb: rgb,
16826         hsl: hsl,
16827         lab: lab,
16828         hcl: hcl,
16829         cubehelix: cubehelix,
16830         dispatch: dispatch,
16831         drag: drag,
16832         dragDisable: dragDisable,
16833         dragEnable: yesdrag,
16834         dsvFormat: dsv,
16835         csvParse: csvParse,
16836         csvParseRows: csvParseRows,
16837         csvFormat: csvFormat,
16838         csvFormatRows: csvFormatRows,
16839         tsvParse: tsvParse,
16840         tsvParseRows: tsvParseRows,
16841         tsvFormat: tsvFormat,
16842         tsvFormatRows: tsvFormatRows,
16843         easeLinear: linear$1,
16844         easeQuad: quadInOut,
16845         easeQuadIn: quadIn,
16846         easeQuadOut: quadOut,
16847         easeQuadInOut: quadInOut,
16848         easeCubic: cubicInOut,
16849         easeCubicIn: cubicIn,
16850         easeCubicOut: cubicOut,
16851         easeCubicInOut: cubicInOut,
16852         easePoly: polyInOut,
16853         easePolyIn: polyIn,
16854         easePolyOut: polyOut,
16855         easePolyInOut: polyInOut,
16856         easeSin: sinInOut,
16857         easeSinIn: sinIn,
16858         easeSinOut: sinOut,
16859         easeSinInOut: sinInOut,
16860         easeExp: expInOut,
16861         easeExpIn: expIn,
16862         easeExpOut: expOut,
16863         easeExpInOut: expInOut,
16864         easeCircle: circleInOut,
16865         easeCircleIn: circleIn,
16866         easeCircleOut: circleOut,
16867         easeCircleInOut: circleInOut,
16868         easeBounce: bounceOut,
16869         easeBounceIn: bounceIn,
16870         easeBounceOut: bounceOut,
16871         easeBounceInOut: bounceInOut,
16872         easeBack: backInOut,
16873         easeBackIn: backIn,
16874         easeBackOut: backOut,
16875         easeBackInOut: backInOut,
16876         easeElastic: elasticOut,
16877         easeElasticIn: elasticIn,
16878         easeElasticOut: elasticOut,
16879         easeElasticInOut: elasticInOut,
16880         forceCenter: center$1,
16881         forceCollide: collide,
16882         forceLink: link,
16883         forceManyBody: manyBody,
16884         forceRadial: radial,
16885         forceSimulation: simulation,
16886         forceX: x$2,
16887         forceY: y$2,
16888         formatDefaultLocale: defaultLocale,
16889         get format () { return format; },
16890         get formatPrefix () { return formatPrefix; },
16891         formatLocale: formatLocale,
16892         formatSpecifier: formatSpecifier,
16893         precisionFixed: precisionFixed,
16894         precisionPrefix: precisionPrefix,
16895         precisionRound: precisionRound,
16896         geoArea: d3_geoArea,
16897         geoBounds: d3_geoBounds,
16898         geoCentroid: d3_geoCentroid,
16899         geoCircle: circle,
16900         geoClipAntimeridian: clipAntimeridian,
16901         geoClipCircle: clipCircle,
16902         geoClipExtent: extent$1,
16903         geoClipRectangle: clipRectangle,
16904         geoContains: contains,
16905         geoDistance: distance,
16906         geoGraticule: graticule,
16907         geoGraticule10: graticule10,
16908         geoInterpolate: interpolate$1,
16909         geoLength: d3_geoLength,
16910         geoPath: d3_geoPath,
16911         geoAlbers: albers,
16912         geoAlbersUsa: albersUsa,
16913         geoAzimuthalEqualArea: azimuthalEqualArea,
16914         geoAzimuthalEqualAreaRaw: azimuthalEqualAreaRaw,
16915         geoAzimuthalEquidistant: azimuthalEquidistant,
16916         geoAzimuthalEquidistantRaw: azimuthalEquidistantRaw,
16917         geoConicConformal: conicConformal,
16918         geoConicConformalRaw: conicConformalRaw,
16919         geoConicEqualArea: conicEqualArea,
16920         geoConicEqualAreaRaw: conicEqualAreaRaw,
16921         geoConicEquidistant: conicEquidistant,
16922         geoConicEquidistantRaw: conicEquidistantRaw,
16923         geoEquirectangular: equirectangular,
16924         geoEquirectangularRaw: equirectangularRaw,
16925         geoGnomonic: gnomonic,
16926         geoGnomonicRaw: gnomonicRaw,
16927         geoIdentity: d3_geoIdentity,
16928         geoProjection: projection,
16929         geoProjectionMutator: projectionMutator,
16930         geoMercator: mercator,
16931         geoMercatorRaw: mercatorRaw,
16932         geoNaturalEarth1: naturalEarth1,
16933         geoNaturalEarth1Raw: naturalEarth1Raw,
16934         geoOrthographic: orthographic,
16935         geoOrthographicRaw: orthographicRaw,
16936         geoStereographic: stereographic,
16937         geoStereographicRaw: stereographicRaw,
16938         geoTransverseMercator: transverseMercator,
16939         geoTransverseMercatorRaw: transverseMercatorRaw,
16940         geoRotation: rotation,
16941         geoStream: d3_geoStream,
16942         geoTransform: d3_geoTransform,
16943         cluster: cluster,
16944         hierarchy: hierarchy,
16945         pack: index$1,
16946         packSiblings: siblings,
16947         packEnclose: enclose,
16948         partition: partition,
16949         stratify: stratify,
16950         tree: tree,
16951         treemap: index$2,
16952         treemapBinary: binary,
16953         treemapDice: treemapDice,
16954         treemapSlice: treemapSlice,
16955         treemapSliceDice: sliceDice,
16956         treemapSquarify: squarify,
16957         treemapResquarify: resquarify,
16958         interpolate: d3_interpolate,
16959         interpolateArray: array$1,
16960         interpolateBasis: basis$1,
16961         interpolateBasisClosed: basisClosed,
16962         interpolateDate: date,
16963         interpolateNumber: d3_interpolateNumber,
16964         interpolateObject: object,
16965         interpolateRound: interpolateRound,
16966         interpolateString: interpolateString,
16967         interpolateTransformCss: interpolateTransformCss,
16968         interpolateTransformSvg: interpolateTransformSvg,
16969         interpolateZoom: interpolateZoom,
16970         interpolateRgb: d3_interpolateRgb,
16971         interpolateRgbBasis: rgbBasis,
16972         interpolateRgbBasisClosed: rgbBasisClosed,
16973         interpolateHsl: hsl$2,
16974         interpolateHslLong: hslLong,
16975         interpolateLab: lab$1,
16976         interpolateHcl: hcl$2,
16977         interpolateHclLong: hclLong,
16978         interpolateCubehelix: cubehelix$2,
16979         interpolateCubehelixLong: cubehelixLong,
16980         quantize: d3_quantize,
16981         path: path,
16982         polygonArea: d3_polygonArea,
16983         polygonCentroid: d3_polygonCentroid,
16984         polygonHull: d3_polygonHull,
16985         polygonContains: contains$1,
16986         polygonLength: length$1,
16987         quadtree: quadtree,
16988         queue: queue,
16989         randomUniform: uniform,
16990         randomNormal: normal,
16991         randomLogNormal: logNormal,
16992         randomBates: bates,
16993         randomIrwinHall: irwinHall,
16994         randomExponential: exponential$1,
16995         request: d3_request,
16996         html: html,
16997         json: d3_json,
16998         text: d3_text,
16999         xml: d3_xml,
17000         csv: csv$1,
17001         tsv: tsv$1,
17002         scaleBand: band,
17003         scalePoint: point$1,
17004         scaleIdentity: identity$5,
17005         scaleLinear: linear$2,
17006         scaleLog: log$1,
17007         scaleOrdinal: ordinal,
17008         scaleImplicit: implicit,
17009         scalePow: pow$1,
17010         scaleSqrt: sqrt$1,
17011         scaleQuantile: quantile$$1,
17012         scaleQuantize: quantize,
17013         scaleThreshold: threshold$1,
17014         scaleTime: time,
17015         scaleUtc: utcTime,
17016         schemeCategory10: category10,
17017         schemeCategory20b: category20b,
17018         schemeCategory20c: category20c,
17019         schemeCategory20: category20,
17020         interpolateCubehelixDefault: cubehelix$3,
17021         interpolateRainbow: rainbow$1,
17022         interpolateWarm: warm,
17023         interpolateCool: cool,
17024         interpolateViridis: viridis,
17025         interpolateMagma: magma,
17026         interpolateInferno: inferno,
17027         interpolatePlasma: plasma,
17028         scaleSequential: sequential,
17029         create: create,
17030         creator: creator,
17031         local: local,
17032         matcher: matcher$1,
17033         mouse: d3_mouse,
17034         namespace: namespace,
17035         namespaces: namespaces,
17036         clientPoint: point,
17037         select: d3_select,
17038         selectAll: d3_selectAll,
17039         selection: selection,
17040         selector: selector,
17041         selectorAll: selectorAll,
17042         style: styleValue,
17043         touch: touch,
17044         touches: d3_touches,
17045         window: defaultView,
17046         get event () { return event; },
17047         customEvent: customEvent,
17048         arc: arc,
17049         area: area,
17050         line: line,
17051         pie: pie,
17052         areaRadial: areaRadial,
17053         radialArea: areaRadial,
17054         lineRadial: lineRadial$1,
17055         radialLine: lineRadial$1,
17056         pointRadial: pointRadial,
17057         linkHorizontal: linkHorizontal,
17058         linkVertical: linkVertical,
17059         linkRadial: linkRadial,
17060         symbol: symbol,
17061         symbols: symbols,
17062         symbolCircle: circle$2,
17063         symbolCross: cross$2,
17064         symbolDiamond: diamond,
17065         symbolSquare: square,
17066         symbolStar: star,
17067         symbolTriangle: triangle,
17068         symbolWye: wye,
17069         curveBasisClosed: basisClosed$1,
17070         curveBasisOpen: basisOpen,
17071         curveBasis: basis$2,
17072         curveBundle: bundle,
17073         curveCardinalClosed: cardinalClosed,
17074         curveCardinalOpen: cardinalOpen,
17075         curveCardinal: cardinal,
17076         curveCatmullRomClosed: catmullRomClosed,
17077         curveCatmullRomOpen: catmullRomOpen,
17078         curveCatmullRom: catmullRom,
17079         curveLinearClosed: linearClosed,
17080         curveLinear: curveLinear,
17081         curveMonotoneX: monotoneX,
17082         curveMonotoneY: monotoneY,
17083         curveNatural: natural,
17084         curveStep: step,
17085         curveStepAfter: stepAfter,
17086         curveStepBefore: stepBefore,
17087         stack: stack,
17088         stackOffsetExpand: expand,
17089         stackOffsetDiverging: diverging,
17090         stackOffsetNone: none$1,
17091         stackOffsetSilhouette: silhouette,
17092         stackOffsetWiggle: wiggle,
17093         stackOrderAscending: ascending$1,
17094         stackOrderDescending: descending$1,
17095         stackOrderInsideOut: insideOut,
17096         stackOrderNone: none$2,
17097         stackOrderReverse: reverse,
17098         timeInterval: newInterval,
17099         timeMillisecond: millisecond,
17100         timeMilliseconds: milliseconds,
17101         utcMillisecond: millisecond,
17102         utcMilliseconds: milliseconds,
17103         timeSecond: second,
17104         timeSeconds: seconds,
17105         utcSecond: second,
17106         utcSeconds: seconds,
17107         timeMinute: minute,
17108         timeMinutes: minutes,
17109         timeHour: hour,
17110         timeHours: hours,
17111         timeDay: day,
17112         timeDays: days,
17113         timeWeek: sunday,
17114         timeWeeks: sundays,
17115         timeSunday: sunday,
17116         timeSundays: sundays,
17117         timeMonday: monday,
17118         timeMondays: mondays,
17119         timeTuesday: tuesday,
17120         timeTuesdays: tuesdays,
17121         timeWednesday: wednesday,
17122         timeWednesdays: wednesdays,
17123         timeThursday: thursday,
17124         timeThursdays: thursdays,
17125         timeFriday: friday,
17126         timeFridays: fridays,
17127         timeSaturday: saturday,
17128         timeSaturdays: saturdays,
17129         timeMonth: month,
17130         timeMonths: months,
17131         timeYear: year,
17132         timeYears: years,
17133         utcMinute: utcMinute,
17134         utcMinutes: utcMinutes,
17135         utcHour: utcHour,
17136         utcHours: utcHours,
17137         utcDay: utcDay,
17138         utcDays: utcDays,
17139         utcWeek: utcSunday,
17140         utcWeeks: utcSundays,
17141         utcSunday: utcSunday,
17142         utcSundays: utcSundays,
17143         utcMonday: utcMonday,
17144         utcMondays: utcMondays,
17145         utcTuesday: utcTuesday,
17146         utcTuesdays: utcTuesdays,
17147         utcWednesday: utcWednesday,
17148         utcWednesdays: utcWednesdays,
17149         utcThursday: utcThursday,
17150         utcThursdays: utcThursdays,
17151         utcFriday: utcFriday,
17152         utcFridays: utcFridays,
17153         utcSaturday: utcSaturday,
17154         utcSaturdays: utcSaturdays,
17155         utcMonth: utcMonth,
17156         utcMonths: utcMonths,
17157         utcYear: utcYear,
17158         utcYears: utcYears,
17159         timeFormatDefaultLocale: defaultLocale$1,
17160         get timeFormat () { return timeFormat; },
17161         get timeParse () { return timeParse; },
17162         get utcFormat () { return utcFormat; },
17163         get utcParse () { return utcParse; },
17164         timeFormatLocale: formatLocale$1,
17165         isoFormat: formatIso,
17166         isoParse: parseIso,
17167         now: now,
17168         timer: timer,
17169         timerFlush: timerFlush,
17170         timeout: d3_timeout,
17171         interval: interval$1,
17172         transition: transition,
17173         active: active,
17174         interrupt: interrupt,
17175         voronoi: voronoi,
17176         zoom: d3_zoom,
17177         zoomTransform: transform,
17178         zoomIdentity: identity$7
17179 });
17180
17181 function actionAddEntity(way) {
17182     return function(graph) {
17183         return graph.replace(way);
17184     };
17185 }
17186
17187 /**
17188  * Removes all key-value entries from the list cache.
17189  *
17190  * @private
17191  * @name clear
17192  * @memberOf ListCache
17193  */
17194 function listCacheClear() {
17195   this.__data__ = [];
17196   this.size = 0;
17197 }
17198
17199 /**
17200  * Performs a
17201  * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
17202  * comparison between two values to determine if they are equivalent.
17203  *
17204  * @static
17205  * @memberOf _
17206  * @since 4.0.0
17207  * @category Lang
17208  * @param {*} value The value to compare.
17209  * @param {*} other The other value to compare.
17210  * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
17211  * @example
17212  *
17213  * var object = { 'a': 1 };
17214  * var other = { 'a': 1 };
17215  *
17216  * _.eq(object, object);
17217  * // => true
17218  *
17219  * _.eq(object, other);
17220  * // => false
17221  *
17222  * _.eq('a', 'a');
17223  * // => true
17224  *
17225  * _.eq('a', Object('a'));
17226  * // => false
17227  *
17228  * _.eq(NaN, NaN);
17229  * // => true
17230  */
17231 function eq(value, other) {
17232   return value === other || (value !== value && other !== other);
17233 }
17234
17235 /**
17236  * Gets the index at which the `key` is found in `array` of key-value pairs.
17237  *
17238  * @private
17239  * @param {Array} array The array to inspect.
17240  * @param {*} key The key to search for.
17241  * @returns {number} Returns the index of the matched value, else `-1`.
17242  */
17243 function assocIndexOf(array, key) {
17244   var length = array.length;
17245   while (length--) {
17246     if (eq(array[length][0], key)) {
17247       return length;
17248     }
17249   }
17250   return -1;
17251 }
17252
17253 /** Used for built-in method references. */
17254 var arrayProto = Array.prototype;
17255
17256 /** Built-in value references. */
17257 var splice = arrayProto.splice;
17258
17259 /**
17260  * Removes `key` and its value from the list cache.
17261  *
17262  * @private
17263  * @name delete
17264  * @memberOf ListCache
17265  * @param {string} key The key of the value to remove.
17266  * @returns {boolean} Returns `true` if the entry was removed, else `false`.
17267  */
17268 function listCacheDelete(key) {
17269   var data = this.__data__,
17270       index = assocIndexOf(data, key);
17271
17272   if (index < 0) {
17273     return false;
17274   }
17275   var lastIndex = data.length - 1;
17276   if (index == lastIndex) {
17277     data.pop();
17278   } else {
17279     splice.call(data, index, 1);
17280   }
17281   --this.size;
17282   return true;
17283 }
17284
17285 /**
17286  * Gets the list cache value for `key`.
17287  *
17288  * @private
17289  * @name get
17290  * @memberOf ListCache
17291  * @param {string} key The key of the value to get.
17292  * @returns {*} Returns the entry value.
17293  */
17294 function listCacheGet(key) {
17295   var data = this.__data__,
17296       index = assocIndexOf(data, key);
17297
17298   return index < 0 ? undefined : data[index][1];
17299 }
17300
17301 /**
17302  * Checks if a list cache value for `key` exists.
17303  *
17304  * @private
17305  * @name has
17306  * @memberOf ListCache
17307  * @param {string} key The key of the entry to check.
17308  * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
17309  */
17310 function listCacheHas(key) {
17311   return assocIndexOf(this.__data__, key) > -1;
17312 }
17313
17314 /**
17315  * Sets the list cache `key` to `value`.
17316  *
17317  * @private
17318  * @name set
17319  * @memberOf ListCache
17320  * @param {string} key The key of the value to set.
17321  * @param {*} value The value to set.
17322  * @returns {Object} Returns the list cache instance.
17323  */
17324 function listCacheSet(key, value) {
17325   var data = this.__data__,
17326       index = assocIndexOf(data, key);
17327
17328   if (index < 0) {
17329     ++this.size;
17330     data.push([key, value]);
17331   } else {
17332     data[index][1] = value;
17333   }
17334   return this;
17335 }
17336
17337 /**
17338  * Creates an list cache object.
17339  *
17340  * @private
17341  * @constructor
17342  * @param {Array} [entries] The key-value pairs to cache.
17343  */
17344 function ListCache(entries) {
17345   var index = -1,
17346       length = entries == null ? 0 : entries.length;
17347
17348   this.clear();
17349   while (++index < length) {
17350     var entry = entries[index];
17351     this.set(entry[0], entry[1]);
17352   }
17353 }
17354
17355 // Add methods to `ListCache`.
17356 ListCache.prototype.clear = listCacheClear;
17357 ListCache.prototype['delete'] = listCacheDelete;
17358 ListCache.prototype.get = listCacheGet;
17359 ListCache.prototype.has = listCacheHas;
17360 ListCache.prototype.set = listCacheSet;
17361
17362 /**
17363  * Removes all key-value entries from the stack.
17364  *
17365  * @private
17366  * @name clear
17367  * @memberOf Stack
17368  */
17369 function stackClear() {
17370   this.__data__ = new ListCache;
17371   this.size = 0;
17372 }
17373
17374 /**
17375  * Removes `key` and its value from the stack.
17376  *
17377  * @private
17378  * @name delete
17379  * @memberOf Stack
17380  * @param {string} key The key of the value to remove.
17381  * @returns {boolean} Returns `true` if the entry was removed, else `false`.
17382  */
17383 function stackDelete(key) {
17384   var data = this.__data__,
17385       result = data['delete'](key);
17386
17387   this.size = data.size;
17388   return result;
17389 }
17390
17391 /**
17392  * Gets the stack value for `key`.
17393  *
17394  * @private
17395  * @name get
17396  * @memberOf Stack
17397  * @param {string} key The key of the value to get.
17398  * @returns {*} Returns the entry value.
17399  */
17400 function stackGet(key) {
17401   return this.__data__.get(key);
17402 }
17403
17404 /**
17405  * Checks if a stack value for `key` exists.
17406  *
17407  * @private
17408  * @name has
17409  * @memberOf Stack
17410  * @param {string} key The key of the entry to check.
17411  * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
17412  */
17413 function stackHas(key) {
17414   return this.__data__.has(key);
17415 }
17416
17417 /** Detect free variable `global` from Node.js. */
17418 var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
17419
17420 /** Detect free variable `self`. */
17421 var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
17422
17423 /** Used as a reference to the global object. */
17424 var root$2 = freeGlobal || freeSelf || Function('return this')();
17425
17426 /** Built-in value references. */
17427 var Symbol = root$2.Symbol;
17428
17429 /** Used for built-in method references. */
17430 var objectProto = Object.prototype;
17431
17432 /** Used to check objects for own properties. */
17433 var hasOwnProperty = objectProto.hasOwnProperty;
17434
17435 /**
17436  * Used to resolve the
17437  * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
17438  * of values.
17439  */
17440 var nativeObjectToString = objectProto.toString;
17441
17442 /** Built-in value references. */
17443 var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
17444
17445 /**
17446  * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
17447  *
17448  * @private
17449  * @param {*} value The value to query.
17450  * @returns {string} Returns the raw `toStringTag`.
17451  */
17452 function getRawTag(value) {
17453   var isOwn = hasOwnProperty.call(value, symToStringTag),
17454       tag = value[symToStringTag];
17455
17456   try {
17457     value[symToStringTag] = undefined;
17458     var unmasked = true;
17459   } catch (e) {}
17460
17461   var result = nativeObjectToString.call(value);
17462   if (unmasked) {
17463     if (isOwn) {
17464       value[symToStringTag] = tag;
17465     } else {
17466       delete value[symToStringTag];
17467     }
17468   }
17469   return result;
17470 }
17471
17472 /** Used for built-in method references. */
17473 var objectProto$1 = Object.prototype;
17474
17475 /**
17476  * Used to resolve the
17477  * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
17478  * of values.
17479  */
17480 var nativeObjectToString$1 = objectProto$1.toString;
17481
17482 /**
17483  * Converts `value` to a string using `Object.prototype.toString`.
17484  *
17485  * @private
17486  * @param {*} value The value to convert.
17487  * @returns {string} Returns the converted string.
17488  */
17489 function objectToString(value) {
17490   return nativeObjectToString$1.call(value);
17491 }
17492
17493 /** `Object#toString` result references. */
17494 var nullTag = '[object Null]';
17495 var undefinedTag = '[object Undefined]';
17496
17497 /** Built-in value references. */
17498 var symToStringTag$1 = Symbol ? Symbol.toStringTag : undefined;
17499
17500 /**
17501  * The base implementation of `getTag` without fallbacks for buggy environments.
17502  *
17503  * @private
17504  * @param {*} value The value to query.
17505  * @returns {string} Returns the `toStringTag`.
17506  */
17507 function baseGetTag(value) {
17508   if (value == null) {
17509     return value === undefined ? undefinedTag : nullTag;
17510   }
17511   return (symToStringTag$1 && symToStringTag$1 in Object(value))
17512     ? getRawTag(value)
17513     : objectToString(value);
17514 }
17515
17516 /**
17517  * Checks if `value` is the
17518  * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
17519  * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
17520  *
17521  * @static
17522  * @memberOf _
17523  * @since 0.1.0
17524  * @category Lang
17525  * @param {*} value The value to check.
17526  * @returns {boolean} Returns `true` if `value` is an object, else `false`.
17527  * @example
17528  *
17529  * _.isObject({});
17530  * // => true
17531  *
17532  * _.isObject([1, 2, 3]);
17533  * // => true
17534  *
17535  * _.isObject(_.noop);
17536  * // => true
17537  *
17538  * _.isObject(null);
17539  * // => false
17540  */
17541 function isObject(value) {
17542   var type = typeof value;
17543   return value != null && (type == 'object' || type == 'function');
17544 }
17545
17546 /** `Object#toString` result references. */
17547 var asyncTag = '[object AsyncFunction]';
17548 var funcTag = '[object Function]';
17549 var genTag = '[object GeneratorFunction]';
17550 var proxyTag = '[object Proxy]';
17551
17552 /**
17553  * Checks if `value` is classified as a `Function` object.
17554  *
17555  * @static
17556  * @memberOf _
17557  * @since 0.1.0
17558  * @category Lang
17559  * @param {*} value The value to check.
17560  * @returns {boolean} Returns `true` if `value` is a function, else `false`.
17561  * @example
17562  *
17563  * _.isFunction(_);
17564  * // => true
17565  *
17566  * _.isFunction(/abc/);
17567  * // => false
17568  */
17569 function isFunction(value) {
17570   if (!isObject(value)) {
17571     return false;
17572   }
17573   // The use of `Object#toString` avoids issues with the `typeof` operator
17574   // in Safari 9 which returns 'object' for typed arrays and other constructors.
17575   var tag = baseGetTag(value);
17576   return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
17577 }
17578
17579 /** Used to detect overreaching core-js shims. */
17580 var coreJsData = root$2['__core-js_shared__'];
17581
17582 /** Used to detect methods masquerading as native. */
17583 var maskSrcKey = (function() {
17584   var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
17585   return uid ? ('Symbol(src)_1.' + uid) : '';
17586 }());
17587
17588 /**
17589  * Checks if `func` has its source masked.
17590  *
17591  * @private
17592  * @param {Function} func The function to check.
17593  * @returns {boolean} Returns `true` if `func` is masked, else `false`.
17594  */
17595 function isMasked(func) {
17596   return !!maskSrcKey && (maskSrcKey in func);
17597 }
17598
17599 /** Used for built-in method references. */
17600 var funcProto = Function.prototype;
17601
17602 /** Used to resolve the decompiled source of functions. */
17603 var funcToString = funcProto.toString;
17604
17605 /**
17606  * Converts `func` to its source code.
17607  *
17608  * @private
17609  * @param {Function} func The function to convert.
17610  * @returns {string} Returns the source code.
17611  */
17612 function toSource(func) {
17613   if (func != null) {
17614     try {
17615       return funcToString.call(func);
17616     } catch (e) {}
17617     try {
17618       return (func + '');
17619     } catch (e) {}
17620   }
17621   return '';
17622 }
17623
17624 /**
17625  * Used to match `RegExp`
17626  * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
17627  */
17628 var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
17629
17630 /** Used to detect host constructors (Safari). */
17631 var reIsHostCtor = /^\[object .+?Constructor\]$/;
17632
17633 /** Used for built-in method references. */
17634 var funcProto$1 = Function.prototype;
17635 var objectProto$2 = Object.prototype;
17636
17637 /** Used to resolve the decompiled source of functions. */
17638 var funcToString$1 = funcProto$1.toString;
17639
17640 /** Used to check objects for own properties. */
17641 var hasOwnProperty$1 = objectProto$2.hasOwnProperty;
17642
17643 /** Used to detect if a method is native. */
17644 var reIsNative = RegExp('^' +
17645   funcToString$1.call(hasOwnProperty$1).replace(reRegExpChar, '\\$&')
17646   .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
17647 );
17648
17649 /**
17650  * The base implementation of `_.isNative` without bad shim checks.
17651  *
17652  * @private
17653  * @param {*} value The value to check.
17654  * @returns {boolean} Returns `true` if `value` is a native function,
17655  *  else `false`.
17656  */
17657 function baseIsNative(value) {
17658   if (!isObject(value) || isMasked(value)) {
17659     return false;
17660   }
17661   var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
17662   return pattern.test(toSource(value));
17663 }
17664
17665 /**
17666  * Gets the value at `key` of `object`.
17667  *
17668  * @private
17669  * @param {Object} [object] The object to query.
17670  * @param {string} key The key of the property to get.
17671  * @returns {*} Returns the property value.
17672  */
17673 function getValue(object, key) {
17674   return object == null ? undefined : object[key];
17675 }
17676
17677 /**
17678  * Gets the native function at `key` of `object`.
17679  *
17680  * @private
17681  * @param {Object} object The object to query.
17682  * @param {string} key The key of the method to get.
17683  * @returns {*} Returns the function if it's native, else `undefined`.
17684  */
17685 function getNative(object, key) {
17686   var value = getValue(object, key);
17687   return baseIsNative(value) ? value : undefined;
17688 }
17689
17690 /* Built-in method references that are verified to be native. */
17691 var Map$1 = getNative(root$2, 'Map');
17692
17693 /* Built-in method references that are verified to be native. */
17694 var nativeCreate = getNative(Object, 'create');
17695
17696 /**
17697  * Removes all key-value entries from the hash.
17698  *
17699  * @private
17700  * @name clear
17701  * @memberOf Hash
17702  */
17703 function hashClear() {
17704   this.__data__ = nativeCreate ? nativeCreate(null) : {};
17705   this.size = 0;
17706 }
17707
17708 /**
17709  * Removes `key` and its value from the hash.
17710  *
17711  * @private
17712  * @name delete
17713  * @memberOf Hash
17714  * @param {Object} hash The hash to modify.
17715  * @param {string} key The key of the value to remove.
17716  * @returns {boolean} Returns `true` if the entry was removed, else `false`.
17717  */
17718 function hashDelete(key) {
17719   var result = this.has(key) && delete this.__data__[key];
17720   this.size -= result ? 1 : 0;
17721   return result;
17722 }
17723
17724 /** Used to stand-in for `undefined` hash values. */
17725 var HASH_UNDEFINED = '__lodash_hash_undefined__';
17726
17727 /** Used for built-in method references. */
17728 var objectProto$3 = Object.prototype;
17729
17730 /** Used to check objects for own properties. */
17731 var hasOwnProperty$2 = objectProto$3.hasOwnProperty;
17732
17733 /**
17734  * Gets the hash value for `key`.
17735  *
17736  * @private
17737  * @name get
17738  * @memberOf Hash
17739  * @param {string} key The key of the value to get.
17740  * @returns {*} Returns the entry value.
17741  */
17742 function hashGet(key) {
17743   var data = this.__data__;
17744   if (nativeCreate) {
17745     var result = data[key];
17746     return result === HASH_UNDEFINED ? undefined : result;
17747   }
17748   return hasOwnProperty$2.call(data, key) ? data[key] : undefined;
17749 }
17750
17751 /** Used for built-in method references. */
17752 var objectProto$4 = Object.prototype;
17753
17754 /** Used to check objects for own properties. */
17755 var hasOwnProperty$3 = objectProto$4.hasOwnProperty;
17756
17757 /**
17758  * Checks if a hash value for `key` exists.
17759  *
17760  * @private
17761  * @name has
17762  * @memberOf Hash
17763  * @param {string} key The key of the entry to check.
17764  * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
17765  */
17766 function hashHas(key) {
17767   var data = this.__data__;
17768   return nativeCreate ? (data[key] !== undefined) : hasOwnProperty$3.call(data, key);
17769 }
17770
17771 /** Used to stand-in for `undefined` hash values. */
17772 var HASH_UNDEFINED$1 = '__lodash_hash_undefined__';
17773
17774 /**
17775  * Sets the hash `key` to `value`.
17776  *
17777  * @private
17778  * @name set
17779  * @memberOf Hash
17780  * @param {string} key The key of the value to set.
17781  * @param {*} value The value to set.
17782  * @returns {Object} Returns the hash instance.
17783  */
17784 function hashSet(key, value) {
17785   var data = this.__data__;
17786   this.size += this.has(key) ? 0 : 1;
17787   data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED$1 : value;
17788   return this;
17789 }
17790
17791 /**
17792  * Creates a hash object.
17793  *
17794  * @private
17795  * @constructor
17796  * @param {Array} [entries] The key-value pairs to cache.
17797  */
17798 function Hash(entries) {
17799   var index = -1,
17800       length = entries == null ? 0 : entries.length;
17801
17802   this.clear();
17803   while (++index < length) {
17804     var entry = entries[index];
17805     this.set(entry[0], entry[1]);
17806   }
17807 }
17808
17809 // Add methods to `Hash`.
17810 Hash.prototype.clear = hashClear;
17811 Hash.prototype['delete'] = hashDelete;
17812 Hash.prototype.get = hashGet;
17813 Hash.prototype.has = hashHas;
17814 Hash.prototype.set = hashSet;
17815
17816 /**
17817  * Removes all key-value entries from the map.
17818  *
17819  * @private
17820  * @name clear
17821  * @memberOf MapCache
17822  */
17823 function mapCacheClear() {
17824   this.size = 0;
17825   this.__data__ = {
17826     'hash': new Hash,
17827     'map': new (Map$1 || ListCache),
17828     'string': new Hash
17829   };
17830 }
17831
17832 /**
17833  * Checks if `value` is suitable for use as unique object key.
17834  *
17835  * @private
17836  * @param {*} value The value to check.
17837  * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
17838  */
17839 function isKeyable(value) {
17840   var type = typeof value;
17841   return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
17842     ? (value !== '__proto__')
17843     : (value === null);
17844 }
17845
17846 /**
17847  * Gets the data for `map`.
17848  *
17849  * @private
17850  * @param {Object} map The map to query.
17851  * @param {string} key The reference key.
17852  * @returns {*} Returns the map data.
17853  */
17854 function getMapData(map, key) {
17855   var data = map.__data__;
17856   return isKeyable(key)
17857     ? data[typeof key == 'string' ? 'string' : 'hash']
17858     : data.map;
17859 }
17860
17861 /**
17862  * Removes `key` and its value from the map.
17863  *
17864  * @private
17865  * @name delete
17866  * @memberOf MapCache
17867  * @param {string} key The key of the value to remove.
17868  * @returns {boolean} Returns `true` if the entry was removed, else `false`.
17869  */
17870 function mapCacheDelete(key) {
17871   var result = getMapData(this, key)['delete'](key);
17872   this.size -= result ? 1 : 0;
17873   return result;
17874 }
17875
17876 /**
17877  * Gets the map value for `key`.
17878  *
17879  * @private
17880  * @name get
17881  * @memberOf MapCache
17882  * @param {string} key The key of the value to get.
17883  * @returns {*} Returns the entry value.
17884  */
17885 function mapCacheGet(key) {
17886   return getMapData(this, key).get(key);
17887 }
17888
17889 /**
17890  * Checks if a map value for `key` exists.
17891  *
17892  * @private
17893  * @name has
17894  * @memberOf MapCache
17895  * @param {string} key The key of the entry to check.
17896  * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
17897  */
17898 function mapCacheHas(key) {
17899   return getMapData(this, key).has(key);
17900 }
17901
17902 /**
17903  * Sets the map `key` to `value`.
17904  *
17905  * @private
17906  * @name set
17907  * @memberOf MapCache
17908  * @param {string} key The key of the value to set.
17909  * @param {*} value The value to set.
17910  * @returns {Object} Returns the map cache instance.
17911  */
17912 function mapCacheSet(key, value) {
17913   var data = getMapData(this, key),
17914       size = data.size;
17915
17916   data.set(key, value);
17917   this.size += data.size == size ? 0 : 1;
17918   return this;
17919 }
17920
17921 /**
17922  * Creates a map cache object to store key-value pairs.
17923  *
17924  * @private
17925  * @constructor
17926  * @param {Array} [entries] The key-value pairs to cache.
17927  */
17928 function MapCache(entries) {
17929   var index = -1,
17930       length = entries == null ? 0 : entries.length;
17931
17932   this.clear();
17933   while (++index < length) {
17934     var entry = entries[index];
17935     this.set(entry[0], entry[1]);
17936   }
17937 }
17938
17939 // Add methods to `MapCache`.
17940 MapCache.prototype.clear = mapCacheClear;
17941 MapCache.prototype['delete'] = mapCacheDelete;
17942 MapCache.prototype.get = mapCacheGet;
17943 MapCache.prototype.has = mapCacheHas;
17944 MapCache.prototype.set = mapCacheSet;
17945
17946 /** Used as the size to enable large array optimizations. */
17947 var LARGE_ARRAY_SIZE = 200;
17948
17949 /**
17950  * Sets the stack `key` to `value`.
17951  *
17952  * @private
17953  * @name set
17954  * @memberOf Stack
17955  * @param {string} key The key of the value to set.
17956  * @param {*} value The value to set.
17957  * @returns {Object} Returns the stack cache instance.
17958  */
17959 function stackSet(key, value) {
17960   var data = this.__data__;
17961   if (data instanceof ListCache) {
17962     var pairs = data.__data__;
17963     if (!Map$1 || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
17964       pairs.push([key, value]);
17965       this.size = ++data.size;
17966       return this;
17967     }
17968     data = this.__data__ = new MapCache(pairs);
17969   }
17970   data.set(key, value);
17971   this.size = data.size;
17972   return this;
17973 }
17974
17975 /**
17976  * Creates a stack cache object to store key-value pairs.
17977  *
17978  * @private
17979  * @constructor
17980  * @param {Array} [entries] The key-value pairs to cache.
17981  */
17982 function Stack(entries) {
17983   var data = this.__data__ = new ListCache(entries);
17984   this.size = data.size;
17985 }
17986
17987 // Add methods to `Stack`.
17988 Stack.prototype.clear = stackClear;
17989 Stack.prototype['delete'] = stackDelete;
17990 Stack.prototype.get = stackGet;
17991 Stack.prototype.has = stackHas;
17992 Stack.prototype.set = stackSet;
17993
17994 /**
17995  * A specialized version of `_.forEach` for arrays without support for
17996  * iteratee shorthands.
17997  *
17998  * @private
17999  * @param {Array} [array] The array to iterate over.
18000  * @param {Function} iteratee The function invoked per iteration.
18001  * @returns {Array} Returns `array`.
18002  */
18003 function arrayEach(array, iteratee) {
18004   var index = -1,
18005       length = array == null ? 0 : array.length;
18006
18007   while (++index < length) {
18008     if (iteratee(array[index], index, array) === false) {
18009       break;
18010     }
18011   }
18012   return array;
18013 }
18014
18015 var defineProperty = (function() {
18016   try {
18017     var func = getNative(Object, 'defineProperty');
18018     func({}, '', {});
18019     return func;
18020   } catch (e) {}
18021 }());
18022
18023 /**
18024  * The base implementation of `assignValue` and `assignMergeValue` without
18025  * value checks.
18026  *
18027  * @private
18028  * @param {Object} object The object to modify.
18029  * @param {string} key The key of the property to assign.
18030  * @param {*} value The value to assign.
18031  */
18032 function baseAssignValue(object, key, value) {
18033   if (key == '__proto__' && defineProperty) {
18034     defineProperty(object, key, {
18035       'configurable': true,
18036       'enumerable': true,
18037       'value': value,
18038       'writable': true
18039     });
18040   } else {
18041     object[key] = value;
18042   }
18043 }
18044
18045 /** Used for built-in method references. */
18046 var objectProto$5 = Object.prototype;
18047
18048 /** Used to check objects for own properties. */
18049 var hasOwnProperty$4 = objectProto$5.hasOwnProperty;
18050
18051 /**
18052  * Assigns `value` to `key` of `object` if the existing value is not equivalent
18053  * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
18054  * for equality comparisons.
18055  *
18056  * @private
18057  * @param {Object} object The object to modify.
18058  * @param {string} key The key of the property to assign.
18059  * @param {*} value The value to assign.
18060  */
18061 function assignValue(object, key, value) {
18062   var objValue = object[key];
18063   if (!(hasOwnProperty$4.call(object, key) && eq(objValue, value)) ||
18064       (value === undefined && !(key in object))) {
18065     baseAssignValue(object, key, value);
18066   }
18067 }
18068
18069 /**
18070  * Copies properties of `source` to `object`.
18071  *
18072  * @private
18073  * @param {Object} source The object to copy properties from.
18074  * @param {Array} props The property identifiers to copy.
18075  * @param {Object} [object={}] The object to copy properties to.
18076  * @param {Function} [customizer] The function to customize copied values.
18077  * @returns {Object} Returns `object`.
18078  */
18079 function copyObject(source, props, object, customizer) {
18080   var isNew = !object;
18081   object || (object = {});
18082
18083   var index = -1,
18084       length = props.length;
18085
18086   while (++index < length) {
18087     var key = props[index];
18088
18089     var newValue = customizer
18090       ? customizer(object[key], source[key], key, object, source)
18091       : undefined;
18092
18093     if (newValue === undefined) {
18094       newValue = source[key];
18095     }
18096     if (isNew) {
18097       baseAssignValue(object, key, newValue);
18098     } else {
18099       assignValue(object, key, newValue);
18100     }
18101   }
18102   return object;
18103 }
18104
18105 /**
18106  * The base implementation of `_.times` without support for iteratee shorthands
18107  * or max array length checks.
18108  *
18109  * @private
18110  * @param {number} n The number of times to invoke `iteratee`.
18111  * @param {Function} iteratee The function invoked per iteration.
18112  * @returns {Array} Returns the array of results.
18113  */
18114 function baseTimes(n, iteratee) {
18115   var index = -1,
18116       result = Array(n);
18117
18118   while (++index < n) {
18119     result[index] = iteratee(index);
18120   }
18121   return result;
18122 }
18123
18124 /**
18125  * Checks if `value` is object-like. A value is object-like if it's not `null`
18126  * and has a `typeof` result of "object".
18127  *
18128  * @static
18129  * @memberOf _
18130  * @since 4.0.0
18131  * @category Lang
18132  * @param {*} value The value to check.
18133  * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
18134  * @example
18135  *
18136  * _.isObjectLike({});
18137  * // => true
18138  *
18139  * _.isObjectLike([1, 2, 3]);
18140  * // => true
18141  *
18142  * _.isObjectLike(_.noop);
18143  * // => false
18144  *
18145  * _.isObjectLike(null);
18146  * // => false
18147  */
18148 function isObjectLike(value) {
18149   return value != null && typeof value == 'object';
18150 }
18151
18152 /** `Object#toString` result references. */
18153 var argsTag = '[object Arguments]';
18154
18155 /**
18156  * The base implementation of `_.isArguments`.
18157  *
18158  * @private
18159  * @param {*} value The value to check.
18160  * @returns {boolean} Returns `true` if `value` is an `arguments` object,
18161  */
18162 function baseIsArguments(value) {
18163   return isObjectLike(value) && baseGetTag(value) == argsTag;
18164 }
18165
18166 /** Used for built-in method references. */
18167 var objectProto$6 = Object.prototype;
18168
18169 /** Used to check objects for own properties. */
18170 var hasOwnProperty$5 = objectProto$6.hasOwnProperty;
18171
18172 /** Built-in value references. */
18173 var propertyIsEnumerable = objectProto$6.propertyIsEnumerable;
18174
18175 /**
18176  * Checks if `value` is likely an `arguments` object.
18177  *
18178  * @static
18179  * @memberOf _
18180  * @since 0.1.0
18181  * @category Lang
18182  * @param {*} value The value to check.
18183  * @returns {boolean} Returns `true` if `value` is an `arguments` object,
18184  *  else `false`.
18185  * @example
18186  *
18187  * _.isArguments(function() { return arguments; }());
18188  * // => true
18189  *
18190  * _.isArguments([1, 2, 3]);
18191  * // => false
18192  */
18193 var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
18194   return isObjectLike(value) && hasOwnProperty$5.call(value, 'callee') &&
18195     !propertyIsEnumerable.call(value, 'callee');
18196 };
18197
18198 /**
18199  * Checks if `value` is classified as an `Array` object.
18200  *
18201  * @static
18202  * @memberOf _
18203  * @since 0.1.0
18204  * @category Lang
18205  * @param {*} value The value to check.
18206  * @returns {boolean} Returns `true` if `value` is an array, else `false`.
18207  * @example
18208  *
18209  * _.isArray([1, 2, 3]);
18210  * // => true
18211  *
18212  * _.isArray(document.body.children);
18213  * // => false
18214  *
18215  * _.isArray('abc');
18216  * // => false
18217  *
18218  * _.isArray(_.noop);
18219  * // => false
18220  */
18221 var isArray = Array.isArray;
18222
18223 /**
18224  * This method returns `false`.
18225  *
18226  * @static
18227  * @memberOf _
18228  * @since 4.13.0
18229  * @category Util
18230  * @returns {boolean} Returns `false`.
18231  * @example
18232  *
18233  * _.times(2, _.stubFalse);
18234  * // => [false, false]
18235  */
18236 function stubFalse() {
18237   return false;
18238 }
18239
18240 /** Detect free variable `exports`. */
18241 var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
18242
18243 /** Detect free variable `module`. */
18244 var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
18245
18246 /** Detect the popular CommonJS extension `module.exports`. */
18247 var moduleExports = freeModule && freeModule.exports === freeExports;
18248
18249 /** Built-in value references. */
18250 var Buffer = moduleExports ? root$2.Buffer : undefined;
18251
18252 /* Built-in method references for those with the same name as other `lodash` methods. */
18253 var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;
18254
18255 /**
18256  * Checks if `value` is a buffer.
18257  *
18258  * @static
18259  * @memberOf _
18260  * @since 4.3.0
18261  * @category Lang
18262  * @param {*} value The value to check.
18263  * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
18264  * @example
18265  *
18266  * _.isBuffer(new Buffer(2));
18267  * // => true
18268  *
18269  * _.isBuffer(new Uint8Array(2));
18270  * // => false
18271  */
18272 var isBuffer = nativeIsBuffer || stubFalse;
18273
18274 /** Used as references for various `Number` constants. */
18275 var MAX_SAFE_INTEGER = 9007199254740991;
18276
18277 /** Used to detect unsigned integer values. */
18278 var reIsUint = /^(?:0|[1-9]\d*)$/;
18279
18280 /**
18281  * Checks if `value` is a valid array-like index.
18282  *
18283  * @private
18284  * @param {*} value The value to check.
18285  * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
18286  * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
18287  */
18288 function isIndex(value, length) {
18289   length = length == null ? MAX_SAFE_INTEGER : length;
18290   return !!length &&
18291     (typeof value == 'number' || reIsUint.test(value)) &&
18292     (value > -1 && value % 1 == 0 && value < length);
18293 }
18294
18295 /** Used as references for various `Number` constants. */
18296 var MAX_SAFE_INTEGER$1 = 9007199254740991;
18297
18298 /**
18299  * Checks if `value` is a valid array-like length.
18300  *
18301  * **Note:** This method is loosely based on
18302  * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
18303  *
18304  * @static
18305  * @memberOf _
18306  * @since 4.0.0
18307  * @category Lang
18308  * @param {*} value The value to check.
18309  * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
18310  * @example
18311  *
18312  * _.isLength(3);
18313  * // => true
18314  *
18315  * _.isLength(Number.MIN_VALUE);
18316  * // => false
18317  *
18318  * _.isLength(Infinity);
18319  * // => false
18320  *
18321  * _.isLength('3');
18322  * // => false
18323  */
18324 function isLength(value) {
18325   return typeof value == 'number' &&
18326     value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$1;
18327 }
18328
18329 /** `Object#toString` result references. */
18330 var argsTag$1 = '[object Arguments]';
18331 var arrayTag = '[object Array]';
18332 var boolTag = '[object Boolean]';
18333 var dateTag = '[object Date]';
18334 var errorTag = '[object Error]';
18335 var funcTag$1 = '[object Function]';
18336 var mapTag = '[object Map]';
18337 var numberTag = '[object Number]';
18338 var objectTag = '[object Object]';
18339 var regexpTag = '[object RegExp]';
18340 var setTag = '[object Set]';
18341 var stringTag = '[object String]';
18342 var weakMapTag = '[object WeakMap]';
18343
18344 var arrayBufferTag = '[object ArrayBuffer]';
18345 var dataViewTag = '[object DataView]';
18346 var float32Tag = '[object Float32Array]';
18347 var float64Tag = '[object Float64Array]';
18348 var int8Tag = '[object Int8Array]';
18349 var int16Tag = '[object Int16Array]';
18350 var int32Tag = '[object Int32Array]';
18351 var uint8Tag = '[object Uint8Array]';
18352 var uint8ClampedTag = '[object Uint8ClampedArray]';
18353 var uint16Tag = '[object Uint16Array]';
18354 var uint32Tag = '[object Uint32Array]';
18355
18356 /** Used to identify `toStringTag` values of typed arrays. */
18357 var typedArrayTags = {};
18358 typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
18359 typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
18360 typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
18361 typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
18362 typedArrayTags[uint32Tag] = true;
18363 typedArrayTags[argsTag$1] = typedArrayTags[arrayTag] =
18364 typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
18365 typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
18366 typedArrayTags[errorTag] = typedArrayTags[funcTag$1] =
18367 typedArrayTags[mapTag] = typedArrayTags[numberTag] =
18368 typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
18369 typedArrayTags[setTag] = typedArrayTags[stringTag] =
18370 typedArrayTags[weakMapTag] = false;
18371
18372 /**
18373  * The base implementation of `_.isTypedArray` without Node.js optimizations.
18374  *
18375  * @private
18376  * @param {*} value The value to check.
18377  * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
18378  */
18379 function baseIsTypedArray(value) {
18380   return isObjectLike(value) &&
18381     isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
18382 }
18383
18384 /**
18385  * The base implementation of `_.unary` without support for storing metadata.
18386  *
18387  * @private
18388  * @param {Function} func The function to cap arguments for.
18389  * @returns {Function} Returns the new capped function.
18390  */
18391 function baseUnary(func) {
18392   return function(value) {
18393     return func(value);
18394   };
18395 }
18396
18397 /** Detect free variable `exports`. */
18398 var freeExports$1 = typeof exports == 'object' && exports && !exports.nodeType && exports;
18399
18400 /** Detect free variable `module`. */
18401 var freeModule$1 = freeExports$1 && typeof module == 'object' && module && !module.nodeType && module;
18402
18403 /** Detect the popular CommonJS extension `module.exports`. */
18404 var moduleExports$1 = freeModule$1 && freeModule$1.exports === freeExports$1;
18405
18406 /** Detect free variable `process` from Node.js. */
18407 var freeProcess = moduleExports$1 && freeGlobal.process;
18408
18409 /** Used to access faster Node.js helpers. */
18410 var nodeUtil = (function() {
18411   try {
18412     return freeProcess && freeProcess.binding && freeProcess.binding('util');
18413   } catch (e) {}
18414 }());
18415
18416 /* Node.js helper references. */
18417 var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
18418
18419 /**
18420  * Checks if `value` is classified as a typed array.
18421  *
18422  * @static
18423  * @memberOf _
18424  * @since 3.0.0
18425  * @category Lang
18426  * @param {*} value The value to check.
18427  * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
18428  * @example
18429  *
18430  * _.isTypedArray(new Uint8Array);
18431  * // => true
18432  *
18433  * _.isTypedArray([]);
18434  * // => false
18435  */
18436 var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
18437
18438 /** Used for built-in method references. */
18439 var objectProto$7 = Object.prototype;
18440
18441 /** Used to check objects for own properties. */
18442 var hasOwnProperty$6 = objectProto$7.hasOwnProperty;
18443
18444 /**
18445  * Creates an array of the enumerable property names of the array-like `value`.
18446  *
18447  * @private
18448  * @param {*} value The value to query.
18449  * @param {boolean} inherited Specify returning inherited property names.
18450  * @returns {Array} Returns the array of property names.
18451  */
18452 function arrayLikeKeys(value, inherited) {
18453   var isArr = isArray(value),
18454       isArg = !isArr && isArguments(value),
18455       isBuff = !isArr && !isArg && isBuffer(value),
18456       isType = !isArr && !isArg && !isBuff && isTypedArray(value),
18457       skipIndexes = isArr || isArg || isBuff || isType,
18458       result = skipIndexes ? baseTimes(value.length, String) : [],
18459       length = result.length;
18460
18461   for (var key in value) {
18462     if ((inherited || hasOwnProperty$6.call(value, key)) &&
18463         !(skipIndexes && (
18464            // Safari 9 has enumerable `arguments.length` in strict mode.
18465            key == 'length' ||
18466            // Node.js 0.10 has enumerable non-index properties on buffers.
18467            (isBuff && (key == 'offset' || key == 'parent')) ||
18468            // PhantomJS 2 has enumerable non-index properties on typed arrays.
18469            (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
18470            // Skip index properties.
18471            isIndex(key, length)
18472         ))) {
18473       result.push(key);
18474     }
18475   }
18476   return result;
18477 }
18478
18479 /** Used for built-in method references. */
18480 var objectProto$8 = Object.prototype;
18481
18482 /**
18483  * Checks if `value` is likely a prototype object.
18484  *
18485  * @private
18486  * @param {*} value The value to check.
18487  * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
18488  */
18489 function isPrototype(value) {
18490   var Ctor = value && value.constructor,
18491       proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$8;
18492
18493   return value === proto;
18494 }
18495
18496 /**
18497  * Creates a unary function that invokes `func` with its argument transformed.
18498  *
18499  * @private
18500  * @param {Function} func The function to wrap.
18501  * @param {Function} transform The argument transform.
18502  * @returns {Function} Returns the new function.
18503  */
18504 function overArg(func, transform) {
18505   return function(arg) {
18506     return func(transform(arg));
18507   };
18508 }
18509
18510 /* Built-in method references for those with the same name as other `lodash` methods. */
18511 var nativeKeys = overArg(Object.keys, Object);
18512
18513 /** Used for built-in method references. */
18514 var objectProto$9 = Object.prototype;
18515
18516 /** Used to check objects for own properties. */
18517 var hasOwnProperty$7 = objectProto$9.hasOwnProperty;
18518
18519 /**
18520  * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
18521  *
18522  * @private
18523  * @param {Object} object The object to query.
18524  * @returns {Array} Returns the array of property names.
18525  */
18526 function baseKeys(object) {
18527   if (!isPrototype(object)) {
18528     return nativeKeys(object);
18529   }
18530   var result = [];
18531   for (var key in Object(object)) {
18532     if (hasOwnProperty$7.call(object, key) && key != 'constructor') {
18533       result.push(key);
18534     }
18535   }
18536   return result;
18537 }
18538
18539 /**
18540  * Checks if `value` is array-like. A value is considered array-like if it's
18541  * not a function and has a `value.length` that's an integer greater than or
18542  * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
18543  *
18544  * @static
18545  * @memberOf _
18546  * @since 4.0.0
18547  * @category Lang
18548  * @param {*} value The value to check.
18549  * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
18550  * @example
18551  *
18552  * _.isArrayLike([1, 2, 3]);
18553  * // => true
18554  *
18555  * _.isArrayLike(document.body.children);
18556  * // => true
18557  *
18558  * _.isArrayLike('abc');
18559  * // => true
18560  *
18561  * _.isArrayLike(_.noop);
18562  * // => false
18563  */
18564 function isArrayLike(value) {
18565   return value != null && isLength(value.length) && !isFunction(value);
18566 }
18567
18568 /**
18569  * Creates an array of the own enumerable property names of `object`.
18570  *
18571  * **Note:** Non-object values are coerced to objects. See the
18572  * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
18573  * for more details.
18574  *
18575  * @static
18576  * @since 0.1.0
18577  * @memberOf _
18578  * @category Object
18579  * @param {Object} object The object to query.
18580  * @returns {Array} Returns the array of property names.
18581  * @example
18582  *
18583  * function Foo() {
18584  *   this.a = 1;
18585  *   this.b = 2;
18586  * }
18587  *
18588  * Foo.prototype.c = 3;
18589  *
18590  * _.keys(new Foo);
18591  * // => ['a', 'b'] (iteration order is not guaranteed)
18592  *
18593  * _.keys('hi');
18594  * // => ['0', '1']
18595  */
18596 function keys$1(object) {
18597   return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
18598 }
18599
18600 /**
18601  * The base implementation of `_.assign` without support for multiple sources
18602  * or `customizer` functions.
18603  *
18604  * @private
18605  * @param {Object} object The destination object.
18606  * @param {Object} source The source object.
18607  * @returns {Object} Returns `object`.
18608  */
18609 function baseAssign(object, source) {
18610   return object && copyObject(source, keys$1(source), object);
18611 }
18612
18613 /**
18614  * This function is like
18615  * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
18616  * except that it includes inherited enumerable properties.
18617  *
18618  * @private
18619  * @param {Object} object The object to query.
18620  * @returns {Array} Returns the array of property names.
18621  */
18622 function nativeKeysIn(object) {
18623   var result = [];
18624   if (object != null) {
18625     for (var key in Object(object)) {
18626       result.push(key);
18627     }
18628   }
18629   return result;
18630 }
18631
18632 /** Used for built-in method references. */
18633 var objectProto$10 = Object.prototype;
18634
18635 /** Used to check objects for own properties. */
18636 var hasOwnProperty$8 = objectProto$10.hasOwnProperty;
18637
18638 /**
18639  * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
18640  *
18641  * @private
18642  * @param {Object} object The object to query.
18643  * @returns {Array} Returns the array of property names.
18644  */
18645 function baseKeysIn(object) {
18646   if (!isObject(object)) {
18647     return nativeKeysIn(object);
18648   }
18649   var isProto = isPrototype(object),
18650       result = [];
18651
18652   for (var key in object) {
18653     if (!(key == 'constructor' && (isProto || !hasOwnProperty$8.call(object, key)))) {
18654       result.push(key);
18655     }
18656   }
18657   return result;
18658 }
18659
18660 /**
18661  * Creates an array of the own and inherited enumerable property names of `object`.
18662  *
18663  * **Note:** Non-object values are coerced to objects.
18664  *
18665  * @static
18666  * @memberOf _
18667  * @since 3.0.0
18668  * @category Object
18669  * @param {Object} object The object to query.
18670  * @returns {Array} Returns the array of property names.
18671  * @example
18672  *
18673  * function Foo() {
18674  *   this.a = 1;
18675  *   this.b = 2;
18676  * }
18677  *
18678  * Foo.prototype.c = 3;
18679  *
18680  * _.keysIn(new Foo);
18681  * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
18682  */
18683 function keysIn$1(object) {
18684   return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
18685 }
18686
18687 /**
18688  * The base implementation of `_.assignIn` without support for multiple sources
18689  * or `customizer` functions.
18690  *
18691  * @private
18692  * @param {Object} object The destination object.
18693  * @param {Object} source The source object.
18694  * @returns {Object} Returns `object`.
18695  */
18696 function baseAssignIn(object, source) {
18697   return object && copyObject(source, keysIn$1(source), object);
18698 }
18699
18700 /** Detect free variable `exports`. */
18701 var freeExports$2 = typeof exports == 'object' && exports && !exports.nodeType && exports;
18702
18703 /** Detect free variable `module`. */
18704 var freeModule$2 = freeExports$2 && typeof module == 'object' && module && !module.nodeType && module;
18705
18706 /** Detect the popular CommonJS extension `module.exports`. */
18707 var moduleExports$2 = freeModule$2 && freeModule$2.exports === freeExports$2;
18708
18709 /** Built-in value references. */
18710 var Buffer$1 = moduleExports$2 ? root$2.Buffer : undefined;
18711 var allocUnsafe = Buffer$1 ? Buffer$1.allocUnsafe : undefined;
18712
18713 /**
18714  * Creates a clone of  `buffer`.
18715  *
18716  * @private
18717  * @param {Buffer} buffer The buffer to clone.
18718  * @param {boolean} [isDeep] Specify a deep clone.
18719  * @returns {Buffer} Returns the cloned buffer.
18720  */
18721 function cloneBuffer(buffer, isDeep) {
18722   if (isDeep) {
18723     return buffer.slice();
18724   }
18725   var length = buffer.length,
18726       result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
18727
18728   buffer.copy(result);
18729   return result;
18730 }
18731
18732 /**
18733  * Copies the values of `source` to `array`.
18734  *
18735  * @private
18736  * @param {Array} source The array to copy values from.
18737  * @param {Array} [array=[]] The array to copy values to.
18738  * @returns {Array} Returns `array`.
18739  */
18740 function copyArray(source, array) {
18741   var index = -1,
18742       length = source.length;
18743
18744   array || (array = Array(length));
18745   while (++index < length) {
18746     array[index] = source[index];
18747   }
18748   return array;
18749 }
18750
18751 /**
18752  * A specialized version of `_.filter` for arrays without support for
18753  * iteratee shorthands.
18754  *
18755  * @private
18756  * @param {Array} [array] The array to iterate over.
18757  * @param {Function} predicate The function invoked per iteration.
18758  * @returns {Array} Returns the new filtered array.
18759  */
18760 function arrayFilter(array, predicate) {
18761   var index = -1,
18762       length = array == null ? 0 : array.length,
18763       resIndex = 0,
18764       result = [];
18765
18766   while (++index < length) {
18767     var value = array[index];
18768     if (predicate(value, index, array)) {
18769       result[resIndex++] = value;
18770     }
18771   }
18772   return result;
18773 }
18774
18775 /**
18776  * This method returns a new empty array.
18777  *
18778  * @static
18779  * @memberOf _
18780  * @since 4.13.0
18781  * @category Util
18782  * @returns {Array} Returns the new empty array.
18783  * @example
18784  *
18785  * var arrays = _.times(2, _.stubArray);
18786  *
18787  * console.log(arrays);
18788  * // => [[], []]
18789  *
18790  * console.log(arrays[0] === arrays[1]);
18791  * // => false
18792  */
18793 function stubArray() {
18794   return [];
18795 }
18796
18797 /** Used for built-in method references. */
18798 var objectProto$11 = Object.prototype;
18799
18800 /** Built-in value references. */
18801 var propertyIsEnumerable$1 = objectProto$11.propertyIsEnumerable;
18802
18803 /* Built-in method references for those with the same name as other `lodash` methods. */
18804 var nativeGetSymbols = Object.getOwnPropertySymbols;
18805
18806 /**
18807  * Creates an array of the own enumerable symbols of `object`.
18808  *
18809  * @private
18810  * @param {Object} object The object to query.
18811  * @returns {Array} Returns the array of symbols.
18812  */
18813 var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
18814   if (object == null) {
18815     return [];
18816   }
18817   object = Object(object);
18818   return arrayFilter(nativeGetSymbols(object), function(symbol) {
18819     return propertyIsEnumerable$1.call(object, symbol);
18820   });
18821 };
18822
18823 /**
18824  * Copies own symbols of `source` to `object`.
18825  *
18826  * @private
18827  * @param {Object} source The object to copy symbols from.
18828  * @param {Object} [object={}] The object to copy symbols to.
18829  * @returns {Object} Returns `object`.
18830  */
18831 function copySymbols(source, object) {
18832   return copyObject(source, getSymbols(source), object);
18833 }
18834
18835 /**
18836  * Appends the elements of `values` to `array`.
18837  *
18838  * @private
18839  * @param {Array} array The array to modify.
18840  * @param {Array} values The values to append.
18841  * @returns {Array} Returns `array`.
18842  */
18843 function arrayPush(array, values) {
18844   var index = -1,
18845       length = values.length,
18846       offset = array.length;
18847
18848   while (++index < length) {
18849     array[offset + index] = values[index];
18850   }
18851   return array;
18852 }
18853
18854 /** Built-in value references. */
18855 var getPrototype = overArg(Object.getPrototypeOf, Object);
18856
18857 /* Built-in method references for those with the same name as other `lodash` methods. */
18858 var nativeGetSymbols$1 = Object.getOwnPropertySymbols;
18859
18860 /**
18861  * Creates an array of the own and inherited enumerable symbols of `object`.
18862  *
18863  * @private
18864  * @param {Object} object The object to query.
18865  * @returns {Array} Returns the array of symbols.
18866  */
18867 var getSymbolsIn = !nativeGetSymbols$1 ? stubArray : function(object) {
18868   var result = [];
18869   while (object) {
18870     arrayPush(result, getSymbols(object));
18871     object = getPrototype(object);
18872   }
18873   return result;
18874 };
18875
18876 /**
18877  * Copies own and inherited symbols of `source` to `object`.
18878  *
18879  * @private
18880  * @param {Object} source The object to copy symbols from.
18881  * @param {Object} [object={}] The object to copy symbols to.
18882  * @returns {Object} Returns `object`.
18883  */
18884 function copySymbolsIn(source, object) {
18885   return copyObject(source, getSymbolsIn(source), object);
18886 }
18887
18888 /**
18889  * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
18890  * `keysFunc` and `symbolsFunc` to get the enumerable property names and
18891  * symbols of `object`.
18892  *
18893  * @private
18894  * @param {Object} object The object to query.
18895  * @param {Function} keysFunc The function to get the keys of `object`.
18896  * @param {Function} symbolsFunc The function to get the symbols of `object`.
18897  * @returns {Array} Returns the array of property names and symbols.
18898  */
18899 function baseGetAllKeys(object, keysFunc, symbolsFunc) {
18900   var result = keysFunc(object);
18901   return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
18902 }
18903
18904 /**
18905  * Creates an array of own enumerable property names and symbols of `object`.
18906  *
18907  * @private
18908  * @param {Object} object The object to query.
18909  * @returns {Array} Returns the array of property names and symbols.
18910  */
18911 function getAllKeys(object) {
18912   return baseGetAllKeys(object, keys$1, getSymbols);
18913 }
18914
18915 /**
18916  * Creates an array of own and inherited enumerable property names and
18917  * symbols of `object`.
18918  *
18919  * @private
18920  * @param {Object} object The object to query.
18921  * @returns {Array} Returns the array of property names and symbols.
18922  */
18923 function getAllKeysIn(object) {
18924   return baseGetAllKeys(object, keysIn$1, getSymbolsIn);
18925 }
18926
18927 /* Built-in method references that are verified to be native. */
18928 var DataView = getNative(root$2, 'DataView');
18929
18930 /* Built-in method references that are verified to be native. */
18931 var Promise = getNative(root$2, 'Promise');
18932
18933 /* Built-in method references that are verified to be native. */
18934 var Set$1 = getNative(root$2, 'Set');
18935
18936 /* Built-in method references that are verified to be native. */
18937 var WeakMap = getNative(root$2, 'WeakMap');
18938
18939 /** `Object#toString` result references. */
18940 var mapTag$1 = '[object Map]';
18941 var objectTag$1 = '[object Object]';
18942 var promiseTag = '[object Promise]';
18943 var setTag$1 = '[object Set]';
18944 var weakMapTag$1 = '[object WeakMap]';
18945
18946 var dataViewTag$1 = '[object DataView]';
18947
18948 /** Used to detect maps, sets, and weakmaps. */
18949 var dataViewCtorString = toSource(DataView);
18950 var mapCtorString = toSource(Map$1);
18951 var promiseCtorString = toSource(Promise);
18952 var setCtorString = toSource(Set$1);
18953 var weakMapCtorString = toSource(WeakMap);
18954
18955 /**
18956  * Gets the `toStringTag` of `value`.
18957  *
18958  * @private
18959  * @param {*} value The value to query.
18960  * @returns {string} Returns the `toStringTag`.
18961  */
18962 var getTag = baseGetTag;
18963
18964 // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
18965 if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag$1) ||
18966     (Map$1 && getTag(new Map$1) != mapTag$1) ||
18967     (Promise && getTag(Promise.resolve()) != promiseTag) ||
18968     (Set$1 && getTag(new Set$1) != setTag$1) ||
18969     (WeakMap && getTag(new WeakMap) != weakMapTag$1)) {
18970   getTag = function(value) {
18971     var result = baseGetTag(value),
18972         Ctor = result == objectTag$1 ? value.constructor : undefined,
18973         ctorString = Ctor ? toSource(Ctor) : '';
18974
18975     if (ctorString) {
18976       switch (ctorString) {
18977         case dataViewCtorString: return dataViewTag$1;
18978         case mapCtorString: return mapTag$1;
18979         case promiseCtorString: return promiseTag;
18980         case setCtorString: return setTag$1;
18981         case weakMapCtorString: return weakMapTag$1;
18982       }
18983     }
18984     return result;
18985   };
18986 }
18987
18988 var getTag$1 = getTag;
18989
18990 /** Used for built-in method references. */
18991 var objectProto$12 = Object.prototype;
18992
18993 /** Used to check objects for own properties. */
18994 var hasOwnProperty$9 = objectProto$12.hasOwnProperty;
18995
18996 /**
18997  * Initializes an array clone.
18998  *
18999  * @private
19000  * @param {Array} array The array to clone.
19001  * @returns {Array} Returns the initialized clone.
19002  */
19003 function initCloneArray(array) {
19004   var length = array.length,
19005       result = array.constructor(length);
19006
19007   // Add properties assigned by `RegExp#exec`.
19008   if (length && typeof array[0] == 'string' && hasOwnProperty$9.call(array, 'index')) {
19009     result.index = array.index;
19010     result.input = array.input;
19011   }
19012   return result;
19013 }
19014
19015 /** Built-in value references. */
19016 var Uint8Array = root$2.Uint8Array;
19017
19018 /**
19019  * Creates a clone of `arrayBuffer`.
19020  *
19021  * @private
19022  * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
19023  * @returns {ArrayBuffer} Returns the cloned array buffer.
19024  */
19025 function cloneArrayBuffer(arrayBuffer) {
19026   var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
19027   new Uint8Array(result).set(new Uint8Array(arrayBuffer));
19028   return result;
19029 }
19030
19031 /**
19032  * Creates a clone of `dataView`.
19033  *
19034  * @private
19035  * @param {Object} dataView The data view to clone.
19036  * @param {boolean} [isDeep] Specify a deep clone.
19037  * @returns {Object} Returns the cloned data view.
19038  */
19039 function cloneDataView(dataView, isDeep) {
19040   var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
19041   return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
19042 }
19043
19044 /**
19045  * Adds the key-value `pair` to `map`.
19046  *
19047  * @private
19048  * @param {Object} map The map to modify.
19049  * @param {Array} pair The key-value pair to add.
19050  * @returns {Object} Returns `map`.
19051  */
19052 function addMapEntry(map, pair) {
19053   // Don't return `map.set` because it's not chainable in IE 11.
19054   map.set(pair[0], pair[1]);
19055   return map;
19056 }
19057
19058 /**
19059  * A specialized version of `_.reduce` for arrays without support for
19060  * iteratee shorthands.
19061  *
19062  * @private
19063  * @param {Array} [array] The array to iterate over.
19064  * @param {Function} iteratee The function invoked per iteration.
19065  * @param {*} [accumulator] The initial value.
19066  * @param {boolean} [initAccum] Specify using the first element of `array` as
19067  *  the initial value.
19068  * @returns {*} Returns the accumulated value.
19069  */
19070 function arrayReduce(array, iteratee, accumulator, initAccum) {
19071   var index = -1,
19072       length = array == null ? 0 : array.length;
19073
19074   if (initAccum && length) {
19075     accumulator = array[++index];
19076   }
19077   while (++index < length) {
19078     accumulator = iteratee(accumulator, array[index], index, array);
19079   }
19080   return accumulator;
19081 }
19082
19083 /**
19084  * Converts `map` to its key-value pairs.
19085  *
19086  * @private
19087  * @param {Object} map The map to convert.
19088  * @returns {Array} Returns the key-value pairs.
19089  */
19090 function mapToArray(map) {
19091   var index = -1,
19092       result = Array(map.size);
19093
19094   map.forEach(function(value, key) {
19095     result[++index] = [key, value];
19096   });
19097   return result;
19098 }
19099
19100 /** Used to compose bitmasks for cloning. */
19101 var CLONE_DEEP_FLAG = 1;
19102
19103 /**
19104  * Creates a clone of `map`.
19105  *
19106  * @private
19107  * @param {Object} map The map to clone.
19108  * @param {Function} cloneFunc The function to clone values.
19109  * @param {boolean} [isDeep] Specify a deep clone.
19110  * @returns {Object} Returns the cloned map.
19111  */
19112 function cloneMap(map, isDeep, cloneFunc) {
19113   var array = isDeep ? cloneFunc(mapToArray(map), CLONE_DEEP_FLAG) : mapToArray(map);
19114   return arrayReduce(array, addMapEntry, new map.constructor);
19115 }
19116
19117 /** Used to match `RegExp` flags from their coerced string values. */
19118 var reFlags = /\w*$/;
19119
19120 /**
19121  * Creates a clone of `regexp`.
19122  *
19123  * @private
19124  * @param {Object} regexp The regexp to clone.
19125  * @returns {Object} Returns the cloned regexp.
19126  */
19127 function cloneRegExp(regexp) {
19128   var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
19129   result.lastIndex = regexp.lastIndex;
19130   return result;
19131 }
19132
19133 /**
19134  * Adds `value` to `set`.
19135  *
19136  * @private
19137  * @param {Object} set The set to modify.
19138  * @param {*} value The value to add.
19139  * @returns {Object} Returns `set`.
19140  */
19141 function addSetEntry(set, value) {
19142   // Don't return `set.add` because it's not chainable in IE 11.
19143   set.add(value);
19144   return set;
19145 }
19146
19147 /**
19148  * Converts `set` to an array of its values.
19149  *
19150  * @private
19151  * @param {Object} set The set to convert.
19152  * @returns {Array} Returns the values.
19153  */
19154 function setToArray(set) {
19155   var index = -1,
19156       result = Array(set.size);
19157
19158   set.forEach(function(value) {
19159     result[++index] = value;
19160   });
19161   return result;
19162 }
19163
19164 /** Used to compose bitmasks for cloning. */
19165 var CLONE_DEEP_FLAG$1 = 1;
19166
19167 /**
19168  * Creates a clone of `set`.
19169  *
19170  * @private
19171  * @param {Object} set The set to clone.
19172  * @param {Function} cloneFunc The function to clone values.
19173  * @param {boolean} [isDeep] Specify a deep clone.
19174  * @returns {Object} Returns the cloned set.
19175  */
19176 function cloneSet(set, isDeep, cloneFunc) {
19177   var array = isDeep ? cloneFunc(setToArray(set), CLONE_DEEP_FLAG$1) : setToArray(set);
19178   return arrayReduce(array, addSetEntry, new set.constructor);
19179 }
19180
19181 /** Used to convert symbols to primitives and strings. */
19182 var symbolProto = Symbol ? Symbol.prototype : undefined;
19183 var symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;
19184
19185 /**
19186  * Creates a clone of the `symbol` object.
19187  *
19188  * @private
19189  * @param {Object} symbol The symbol object to clone.
19190  * @returns {Object} Returns the cloned symbol object.
19191  */
19192 function cloneSymbol(symbol) {
19193   return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
19194 }
19195
19196 /**
19197  * Creates a clone of `typedArray`.
19198  *
19199  * @private
19200  * @param {Object} typedArray The typed array to clone.
19201  * @param {boolean} [isDeep] Specify a deep clone.
19202  * @returns {Object} Returns the cloned typed array.
19203  */
19204 function cloneTypedArray(typedArray, isDeep) {
19205   var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
19206   return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
19207 }
19208
19209 /** `Object#toString` result references. */
19210 var boolTag$1 = '[object Boolean]';
19211 var dateTag$1 = '[object Date]';
19212 var mapTag$2 = '[object Map]';
19213 var numberTag$1 = '[object Number]';
19214 var regexpTag$1 = '[object RegExp]';
19215 var setTag$2 = '[object Set]';
19216 var stringTag$1 = '[object String]';
19217 var symbolTag = '[object Symbol]';
19218
19219 var arrayBufferTag$1 = '[object ArrayBuffer]';
19220 var dataViewTag$2 = '[object DataView]';
19221 var float32Tag$1 = '[object Float32Array]';
19222 var float64Tag$1 = '[object Float64Array]';
19223 var int8Tag$1 = '[object Int8Array]';
19224 var int16Tag$1 = '[object Int16Array]';
19225 var int32Tag$1 = '[object Int32Array]';
19226 var uint8Tag$1 = '[object Uint8Array]';
19227 var uint8ClampedTag$1 = '[object Uint8ClampedArray]';
19228 var uint16Tag$1 = '[object Uint16Array]';
19229 var uint32Tag$1 = '[object Uint32Array]';
19230
19231 /**
19232  * Initializes an object clone based on its `toStringTag`.
19233  *
19234  * **Note:** This function only supports cloning values with tags of
19235  * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
19236  *
19237  * @private
19238  * @param {Object} object The object to clone.
19239  * @param {string} tag The `toStringTag` of the object to clone.
19240  * @param {Function} cloneFunc The function to clone values.
19241  * @param {boolean} [isDeep] Specify a deep clone.
19242  * @returns {Object} Returns the initialized clone.
19243  */
19244 function initCloneByTag(object, tag, cloneFunc, isDeep) {
19245   var Ctor = object.constructor;
19246   switch (tag) {
19247     case arrayBufferTag$1:
19248       return cloneArrayBuffer(object);
19249
19250     case boolTag$1:
19251     case dateTag$1:
19252       return new Ctor(+object);
19253
19254     case dataViewTag$2:
19255       return cloneDataView(object, isDeep);
19256
19257     case float32Tag$1: case float64Tag$1:
19258     case int8Tag$1: case int16Tag$1: case int32Tag$1:
19259     case uint8Tag$1: case uint8ClampedTag$1: case uint16Tag$1: case uint32Tag$1:
19260       return cloneTypedArray(object, isDeep);
19261
19262     case mapTag$2:
19263       return cloneMap(object, isDeep, cloneFunc);
19264
19265     case numberTag$1:
19266     case stringTag$1:
19267       return new Ctor(object);
19268
19269     case regexpTag$1:
19270       return cloneRegExp(object);
19271
19272     case setTag$2:
19273       return cloneSet(object, isDeep, cloneFunc);
19274
19275     case symbolTag:
19276       return cloneSymbol(object);
19277   }
19278 }
19279
19280 /** Built-in value references. */
19281 var objectCreate = Object.create;
19282
19283 /**
19284  * The base implementation of `_.create` without support for assigning
19285  * properties to the created object.
19286  *
19287  * @private
19288  * @param {Object} proto The object to inherit from.
19289  * @returns {Object} Returns the new object.
19290  */
19291 var baseCreate = (function() {
19292   function object() {}
19293   return function(proto) {
19294     if (!isObject(proto)) {
19295       return {};
19296     }
19297     if (objectCreate) {
19298       return objectCreate(proto);
19299     }
19300     object.prototype = proto;
19301     var result = new object;
19302     object.prototype = undefined;
19303     return result;
19304   };
19305 }());
19306
19307 /**
19308  * Initializes an object clone.
19309  *
19310  * @private
19311  * @param {Object} object The object to clone.
19312  * @returns {Object} Returns the initialized clone.
19313  */
19314 function initCloneObject(object) {
19315   return (typeof object.constructor == 'function' && !isPrototype(object))
19316     ? baseCreate(getPrototype(object))
19317     : {};
19318 }
19319
19320 /** Used to compose bitmasks for cloning. */
19321 var CLONE_DEEP_FLAG$2 = 1;
19322 var CLONE_FLAT_FLAG = 2;
19323 var CLONE_SYMBOLS_FLAG = 4;
19324
19325 /** `Object#toString` result references. */
19326 var argsTag$2 = '[object Arguments]';
19327 var arrayTag$1 = '[object Array]';
19328 var boolTag$2 = '[object Boolean]';
19329 var dateTag$2 = '[object Date]';
19330 var errorTag$1 = '[object Error]';
19331 var funcTag$2 = '[object Function]';
19332 var genTag$1 = '[object GeneratorFunction]';
19333 var mapTag$3 = '[object Map]';
19334 var numberTag$2 = '[object Number]';
19335 var objectTag$2 = '[object Object]';
19336 var regexpTag$2 = '[object RegExp]';
19337 var setTag$3 = '[object Set]';
19338 var stringTag$2 = '[object String]';
19339 var symbolTag$1 = '[object Symbol]';
19340 var weakMapTag$2 = '[object WeakMap]';
19341
19342 var arrayBufferTag$2 = '[object ArrayBuffer]';
19343 var dataViewTag$3 = '[object DataView]';
19344 var float32Tag$2 = '[object Float32Array]';
19345 var float64Tag$2 = '[object Float64Array]';
19346 var int8Tag$2 = '[object Int8Array]';
19347 var int16Tag$2 = '[object Int16Array]';
19348 var int32Tag$2 = '[object Int32Array]';
19349 var uint8Tag$2 = '[object Uint8Array]';
19350 var uint8ClampedTag$2 = '[object Uint8ClampedArray]';
19351 var uint16Tag$2 = '[object Uint16Array]';
19352 var uint32Tag$2 = '[object Uint32Array]';
19353
19354 /** Used to identify `toStringTag` values supported by `_.clone`. */
19355 var cloneableTags = {};
19356 cloneableTags[argsTag$2] = cloneableTags[arrayTag$1] =
19357 cloneableTags[arrayBufferTag$2] = cloneableTags[dataViewTag$3] =
19358 cloneableTags[boolTag$2] = cloneableTags[dateTag$2] =
19359 cloneableTags[float32Tag$2] = cloneableTags[float64Tag$2] =
19360 cloneableTags[int8Tag$2] = cloneableTags[int16Tag$2] =
19361 cloneableTags[int32Tag$2] = cloneableTags[mapTag$3] =
19362 cloneableTags[numberTag$2] = cloneableTags[objectTag$2] =
19363 cloneableTags[regexpTag$2] = cloneableTags[setTag$3] =
19364 cloneableTags[stringTag$2] = cloneableTags[symbolTag$1] =
19365 cloneableTags[uint8Tag$2] = cloneableTags[uint8ClampedTag$2] =
19366 cloneableTags[uint16Tag$2] = cloneableTags[uint32Tag$2] = true;
19367 cloneableTags[errorTag$1] = cloneableTags[funcTag$2] =
19368 cloneableTags[weakMapTag$2] = false;
19369
19370 /**
19371  * The base implementation of `_.clone` and `_.cloneDeep` which tracks
19372  * traversed objects.
19373  *
19374  * @private
19375  * @param {*} value The value to clone.
19376  * @param {boolean} bitmask The bitmask flags.
19377  *  1 - Deep clone
19378  *  2 - Flatten inherited properties
19379  *  4 - Clone symbols
19380  * @param {Function} [customizer] The function to customize cloning.
19381  * @param {string} [key] The key of `value`.
19382  * @param {Object} [object] The parent object of `value`.
19383  * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
19384  * @returns {*} Returns the cloned value.
19385  */
19386 function baseClone(value, bitmask, customizer, key, object, stack) {
19387   var result,
19388       isDeep = bitmask & CLONE_DEEP_FLAG$2,
19389       isFlat = bitmask & CLONE_FLAT_FLAG,
19390       isFull = bitmask & CLONE_SYMBOLS_FLAG;
19391
19392   if (customizer) {
19393     result = object ? customizer(value, key, object, stack) : customizer(value);
19394   }
19395   if (result !== undefined) {
19396     return result;
19397   }
19398   if (!isObject(value)) {
19399     return value;
19400   }
19401   var isArr = isArray(value);
19402   if (isArr) {
19403     result = initCloneArray(value);
19404     if (!isDeep) {
19405       return copyArray(value, result);
19406     }
19407   } else {
19408     var tag = getTag$1(value),
19409         isFunc = tag == funcTag$2 || tag == genTag$1;
19410
19411     if (isBuffer(value)) {
19412       return cloneBuffer(value, isDeep);
19413     }
19414     if (tag == objectTag$2 || tag == argsTag$2 || (isFunc && !object)) {
19415       result = (isFlat || isFunc) ? {} : initCloneObject(value);
19416       if (!isDeep) {
19417         return isFlat
19418           ? copySymbolsIn(value, baseAssignIn(result, value))
19419           : copySymbols(value, baseAssign(result, value));
19420       }
19421     } else {
19422       if (!cloneableTags[tag]) {
19423         return object ? value : {};
19424       }
19425       result = initCloneByTag(value, tag, baseClone, isDeep);
19426     }
19427   }
19428   // Check for circular references and return its corresponding clone.
19429   stack || (stack = new Stack);
19430   var stacked = stack.get(value);
19431   if (stacked) {
19432     return stacked;
19433   }
19434   stack.set(value, result);
19435
19436   var keysFunc = isFull
19437     ? (isFlat ? getAllKeysIn : getAllKeys)
19438     : (isFlat ? keysIn : keys$1);
19439
19440   var props = isArr ? undefined : keysFunc(value);
19441   arrayEach(props || value, function(subValue, key) {
19442     if (props) {
19443       key = subValue;
19444       subValue = value[key];
19445     }
19446     // Recursively populate clone (susceptible to call stack limits).
19447     assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
19448   });
19449   return result;
19450 }
19451
19452 /** Used to compose bitmasks for cloning. */
19453 var CLONE_SYMBOLS_FLAG$1 = 4;
19454
19455 /**
19456  * Creates a shallow clone of `value`.
19457  *
19458  * **Note:** This method is loosely based on the
19459  * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
19460  * and supports cloning arrays, array buffers, booleans, date objects, maps,
19461  * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
19462  * arrays. The own enumerable properties of `arguments` objects are cloned
19463  * as plain objects. An empty object is returned for uncloneable values such
19464  * as error objects, functions, DOM nodes, and WeakMaps.
19465  *
19466  * @static
19467  * @memberOf _
19468  * @since 0.1.0
19469  * @category Lang
19470  * @param {*} value The value to clone.
19471  * @returns {*} Returns the cloned value.
19472  * @see _.cloneDeep
19473  * @example
19474  *
19475  * var objects = [{ 'a': 1 }, { 'b': 2 }];
19476  *
19477  * var shallow = _.clone(objects);
19478  * console.log(shallow[0] === objects[0]);
19479  * // => true
19480  */
19481 function clone(value) {
19482   return baseClone(value, CLONE_SYMBOLS_FLAG$1);
19483 }
19484
19485 /**
19486  * A specialized version of `baseAggregator` for arrays.
19487  *
19488  * @private
19489  * @param {Array} [array] The array to iterate over.
19490  * @param {Function} setter The function to set `accumulator` values.
19491  * @param {Function} iteratee The iteratee to transform keys.
19492  * @param {Object} accumulator The initial aggregated object.
19493  * @returns {Function} Returns `accumulator`.
19494  */
19495 function arrayAggregator(array, setter, iteratee, accumulator) {
19496   var index = -1,
19497       length = array == null ? 0 : array.length;
19498
19499   while (++index < length) {
19500     var value = array[index];
19501     setter(accumulator, value, iteratee(value), array);
19502   }
19503   return accumulator;
19504 }
19505
19506 /**
19507  * Creates a base function for methods like `_.forIn` and `_.forOwn`.
19508  *
19509  * @private
19510  * @param {boolean} [fromRight] Specify iterating from right to left.
19511  * @returns {Function} Returns the new base function.
19512  */
19513 function createBaseFor(fromRight) {
19514   return function(object, iteratee, keysFunc) {
19515     var index = -1,
19516         iterable = Object(object),
19517         props = keysFunc(object),
19518         length = props.length;
19519
19520     while (length--) {
19521       var key = props[fromRight ? length : ++index];
19522       if (iteratee(iterable[key], key, iterable) === false) {
19523         break;
19524       }
19525     }
19526     return object;
19527   };
19528 }
19529
19530 /**
19531  * The base implementation of `baseForOwn` which iterates over `object`
19532  * properties returned by `keysFunc` and invokes `iteratee` for each property.
19533  * Iteratee functions may exit iteration early by explicitly returning `false`.
19534  *
19535  * @private
19536  * @param {Object} object The object to iterate over.
19537  * @param {Function} iteratee The function invoked per iteration.
19538  * @param {Function} keysFunc The function to get the keys of `object`.
19539  * @returns {Object} Returns `object`.
19540  */
19541 var baseFor = createBaseFor();
19542
19543 /**
19544  * The base implementation of `_.forOwn` without support for iteratee shorthands.
19545  *
19546  * @private
19547  * @param {Object} object The object to iterate over.
19548  * @param {Function} iteratee The function invoked per iteration.
19549  * @returns {Object} Returns `object`.
19550  */
19551 function baseForOwn(object, iteratee) {
19552   return object && baseFor(object, iteratee, keys$1);
19553 }
19554
19555 /**
19556  * Creates a `baseEach` or `baseEachRight` function.
19557  *
19558  * @private
19559  * @param {Function} eachFunc The function to iterate over a collection.
19560  * @param {boolean} [fromRight] Specify iterating from right to left.
19561  * @returns {Function} Returns the new base function.
19562  */
19563 function createBaseEach(eachFunc, fromRight) {
19564   return function(collection, iteratee) {
19565     if (collection == null) {
19566       return collection;
19567     }
19568     if (!isArrayLike(collection)) {
19569       return eachFunc(collection, iteratee);
19570     }
19571     var length = collection.length,
19572         index = fromRight ? length : -1,
19573         iterable = Object(collection);
19574
19575     while ((fromRight ? index-- : ++index < length)) {
19576       if (iteratee(iterable[index], index, iterable) === false) {
19577         break;
19578       }
19579     }
19580     return collection;
19581   };
19582 }
19583
19584 /**
19585  * The base implementation of `_.forEach` without support for iteratee shorthands.
19586  *
19587  * @private
19588  * @param {Array|Object} collection The collection to iterate over.
19589  * @param {Function} iteratee The function invoked per iteration.
19590  * @returns {Array|Object} Returns `collection`.
19591  */
19592 var baseEach = createBaseEach(baseForOwn);
19593
19594 /**
19595  * Aggregates elements of `collection` on `accumulator` with keys transformed
19596  * by `iteratee` and values set by `setter`.
19597  *
19598  * @private
19599  * @param {Array|Object} collection The collection to iterate over.
19600  * @param {Function} setter The function to set `accumulator` values.
19601  * @param {Function} iteratee The iteratee to transform keys.
19602  * @param {Object} accumulator The initial aggregated object.
19603  * @returns {Function} Returns `accumulator`.
19604  */
19605 function baseAggregator(collection, setter, iteratee, accumulator) {
19606   baseEach(collection, function(value, key, collection) {
19607     setter(accumulator, value, iteratee(value), collection);
19608   });
19609   return accumulator;
19610 }
19611
19612 /** Used to stand-in for `undefined` hash values. */
19613 var HASH_UNDEFINED$2 = '__lodash_hash_undefined__';
19614
19615 /**
19616  * Adds `value` to the array cache.
19617  *
19618  * @private
19619  * @name add
19620  * @memberOf SetCache
19621  * @alias push
19622  * @param {*} value The value to cache.
19623  * @returns {Object} Returns the cache instance.
19624  */
19625 function setCacheAdd(value) {
19626   this.__data__.set(value, HASH_UNDEFINED$2);
19627   return this;
19628 }
19629
19630 /**
19631  * Checks if `value` is in the array cache.
19632  *
19633  * @private
19634  * @name has
19635  * @memberOf SetCache
19636  * @param {*} value The value to search for.
19637  * @returns {number} Returns `true` if `value` is found, else `false`.
19638  */
19639 function setCacheHas(value) {
19640   return this.__data__.has(value);
19641 }
19642
19643 /**
19644  *
19645  * Creates an array cache object to store unique values.
19646  *
19647  * @private
19648  * @constructor
19649  * @param {Array} [values] The values to cache.
19650  */
19651 function SetCache(values) {
19652   var index = -1,
19653       length = values == null ? 0 : values.length;
19654
19655   this.__data__ = new MapCache;
19656   while (++index < length) {
19657     this.add(values[index]);
19658   }
19659 }
19660
19661 // Add methods to `SetCache`.
19662 SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
19663 SetCache.prototype.has = setCacheHas;
19664
19665 /**
19666  * A specialized version of `_.some` for arrays without support for iteratee
19667  * shorthands.
19668  *
19669  * @private
19670  * @param {Array} [array] The array to iterate over.
19671  * @param {Function} predicate The function invoked per iteration.
19672  * @returns {boolean} Returns `true` if any element passes the predicate check,
19673  *  else `false`.
19674  */
19675 function arraySome(array, predicate) {
19676   var index = -1,
19677       length = array == null ? 0 : array.length;
19678
19679   while (++index < length) {
19680     if (predicate(array[index], index, array)) {
19681       return true;
19682     }
19683   }
19684   return false;
19685 }
19686
19687 /**
19688  * Checks if a `cache` value for `key` exists.
19689  *
19690  * @private
19691  * @param {Object} cache The cache to query.
19692  * @param {string} key The key of the entry to check.
19693  * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
19694  */
19695 function cacheHas(cache, key) {
19696   return cache.has(key);
19697 }
19698
19699 /** Used to compose bitmasks for value comparisons. */
19700 var COMPARE_PARTIAL_FLAG = 1;
19701 var COMPARE_UNORDERED_FLAG = 2;
19702
19703 /**
19704  * A specialized version of `baseIsEqualDeep` for arrays with support for
19705  * partial deep comparisons.
19706  *
19707  * @private
19708  * @param {Array} array The array to compare.
19709  * @param {Array} other The other array to compare.
19710  * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
19711  * @param {Function} customizer The function to customize comparisons.
19712  * @param {Function} equalFunc The function to determine equivalents of values.
19713  * @param {Object} stack Tracks traversed `array` and `other` objects.
19714  * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
19715  */
19716 function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
19717   var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
19718       arrLength = array.length,
19719       othLength = other.length;
19720
19721   if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
19722     return false;
19723   }
19724   // Assume cyclic values are equal.
19725   var stacked = stack.get(array);
19726   if (stacked && stack.get(other)) {
19727     return stacked == other;
19728   }
19729   var index = -1,
19730       result = true,
19731       seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
19732
19733   stack.set(array, other);
19734   stack.set(other, array);
19735
19736   // Ignore non-index properties.
19737   while (++index < arrLength) {
19738     var arrValue = array[index],
19739         othValue = other[index];
19740
19741     if (customizer) {
19742       var compared = isPartial
19743         ? customizer(othValue, arrValue, index, other, array, stack)
19744         : customizer(arrValue, othValue, index, array, other, stack);
19745     }
19746     if (compared !== undefined) {
19747       if (compared) {
19748         continue;
19749       }
19750       result = false;
19751       break;
19752     }
19753     // Recursively compare arrays (susceptible to call stack limits).
19754     if (seen) {
19755       if (!arraySome(other, function(othValue, othIndex) {
19756             if (!cacheHas(seen, othIndex) &&
19757                 (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
19758               return seen.push(othIndex);
19759             }
19760           })) {
19761         result = false;
19762         break;
19763       }
19764     } else if (!(
19765           arrValue === othValue ||
19766             equalFunc(arrValue, othValue, bitmask, customizer, stack)
19767         )) {
19768       result = false;
19769       break;
19770     }
19771   }
19772   stack['delete'](array);
19773   stack['delete'](other);
19774   return result;
19775 }
19776
19777 /** Used to compose bitmasks for value comparisons. */
19778 var COMPARE_PARTIAL_FLAG$1 = 1;
19779 var COMPARE_UNORDERED_FLAG$1 = 2;
19780
19781 /** `Object#toString` result references. */
19782 var boolTag$3 = '[object Boolean]';
19783 var dateTag$3 = '[object Date]';
19784 var errorTag$2 = '[object Error]';
19785 var mapTag$4 = '[object Map]';
19786 var numberTag$3 = '[object Number]';
19787 var regexpTag$3 = '[object RegExp]';
19788 var setTag$4 = '[object Set]';
19789 var stringTag$3 = '[object String]';
19790 var symbolTag$2 = '[object Symbol]';
19791
19792 var arrayBufferTag$3 = '[object ArrayBuffer]';
19793 var dataViewTag$4 = '[object DataView]';
19794
19795 /** Used to convert symbols to primitives and strings. */
19796 var symbolProto$1 = Symbol ? Symbol.prototype : undefined;
19797 var symbolValueOf$1 = symbolProto$1 ? symbolProto$1.valueOf : undefined;
19798
19799 /**
19800  * A specialized version of `baseIsEqualDeep` for comparing objects of
19801  * the same `toStringTag`.
19802  *
19803  * **Note:** This function only supports comparing values with tags of
19804  * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
19805  *
19806  * @private
19807  * @param {Object} object The object to compare.
19808  * @param {Object} other The other object to compare.
19809  * @param {string} tag The `toStringTag` of the objects to compare.
19810  * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
19811  * @param {Function} customizer The function to customize comparisons.
19812  * @param {Function} equalFunc The function to determine equivalents of values.
19813  * @param {Object} stack Tracks traversed `object` and `other` objects.
19814  * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
19815  */
19816 function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
19817   switch (tag) {
19818     case dataViewTag$4:
19819       if ((object.byteLength != other.byteLength) ||
19820           (object.byteOffset != other.byteOffset)) {
19821         return false;
19822       }
19823       object = object.buffer;
19824       other = other.buffer;
19825
19826     case arrayBufferTag$3:
19827       if ((object.byteLength != other.byteLength) ||
19828           !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
19829         return false;
19830       }
19831       return true;
19832
19833     case boolTag$3:
19834     case dateTag$3:
19835     case numberTag$3:
19836       // Coerce booleans to `1` or `0` and dates to milliseconds.
19837       // Invalid dates are coerced to `NaN`.
19838       return eq(+object, +other);
19839
19840     case errorTag$2:
19841       return object.name == other.name && object.message == other.message;
19842
19843     case regexpTag$3:
19844     case stringTag$3:
19845       // Coerce regexes to strings and treat strings, primitives and objects,
19846       // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
19847       // for more details.
19848       return object == (other + '');
19849
19850     case mapTag$4:
19851       var convert = mapToArray;
19852
19853     case setTag$4:
19854       var isPartial = bitmask & COMPARE_PARTIAL_FLAG$1;
19855       convert || (convert = setToArray);
19856
19857       if (object.size != other.size && !isPartial) {
19858         return false;
19859       }
19860       // Assume cyclic values are equal.
19861       var stacked = stack.get(object);
19862       if (stacked) {
19863         return stacked == other;
19864       }
19865       bitmask |= COMPARE_UNORDERED_FLAG$1;
19866
19867       // Recursively compare objects (susceptible to call stack limits).
19868       stack.set(object, other);
19869       var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
19870       stack['delete'](object);
19871       return result;
19872
19873     case symbolTag$2:
19874       if (symbolValueOf$1) {
19875         return symbolValueOf$1.call(object) == symbolValueOf$1.call(other);
19876       }
19877   }
19878   return false;
19879 }
19880
19881 /** Used to compose bitmasks for value comparisons. */
19882 var COMPARE_PARTIAL_FLAG$2 = 1;
19883
19884 /** Used for built-in method references. */
19885 var objectProto$13 = Object.prototype;
19886
19887 /** Used to check objects for own properties. */
19888 var hasOwnProperty$10 = objectProto$13.hasOwnProperty;
19889
19890 /**
19891  * A specialized version of `baseIsEqualDeep` for objects with support for
19892  * partial deep comparisons.
19893  *
19894  * @private
19895  * @param {Object} object The object to compare.
19896  * @param {Object} other The other object to compare.
19897  * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
19898  * @param {Function} customizer The function to customize comparisons.
19899  * @param {Function} equalFunc The function to determine equivalents of values.
19900  * @param {Object} stack Tracks traversed `object` and `other` objects.
19901  * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
19902  */
19903 function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
19904   var isPartial = bitmask & COMPARE_PARTIAL_FLAG$2,
19905       objProps = getAllKeys(object),
19906       objLength = objProps.length,
19907       othProps = getAllKeys(other),
19908       othLength = othProps.length;
19909
19910   if (objLength != othLength && !isPartial) {
19911     return false;
19912   }
19913   var index = objLength;
19914   while (index--) {
19915     var key = objProps[index];
19916     if (!(isPartial ? key in other : hasOwnProperty$10.call(other, key))) {
19917       return false;
19918     }
19919   }
19920   // Assume cyclic values are equal.
19921   var stacked = stack.get(object);
19922   if (stacked && stack.get(other)) {
19923     return stacked == other;
19924   }
19925   var result = true;
19926   stack.set(object, other);
19927   stack.set(other, object);
19928
19929   var skipCtor = isPartial;
19930   while (++index < objLength) {
19931     key = objProps[index];
19932     var objValue = object[key],
19933         othValue = other[key];
19934
19935     if (customizer) {
19936       var compared = isPartial
19937         ? customizer(othValue, objValue, key, other, object, stack)
19938         : customizer(objValue, othValue, key, object, other, stack);
19939     }
19940     // Recursively compare objects (susceptible to call stack limits).
19941     if (!(compared === undefined
19942           ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
19943           : compared
19944         )) {
19945       result = false;
19946       break;
19947     }
19948     skipCtor || (skipCtor = key == 'constructor');
19949   }
19950   if (result && !skipCtor) {
19951     var objCtor = object.constructor,
19952         othCtor = other.constructor;
19953
19954     // Non `Object` object instances with different constructors are not equal.
19955     if (objCtor != othCtor &&
19956         ('constructor' in object && 'constructor' in other) &&
19957         !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
19958           typeof othCtor == 'function' && othCtor instanceof othCtor)) {
19959       result = false;
19960     }
19961   }
19962   stack['delete'](object);
19963   stack['delete'](other);
19964   return result;
19965 }
19966
19967 /** Used to compose bitmasks for value comparisons. */
19968 var COMPARE_PARTIAL_FLAG$3 = 1;
19969
19970 /** `Object#toString` result references. */
19971 var argsTag$3 = '[object Arguments]';
19972 var arrayTag$2 = '[object Array]';
19973 var objectTag$3 = '[object Object]';
19974
19975 /** Used for built-in method references. */
19976 var objectProto$14 = Object.prototype;
19977
19978 /** Used to check objects for own properties. */
19979 var hasOwnProperty$11 = objectProto$14.hasOwnProperty;
19980
19981 /**
19982  * A specialized version of `baseIsEqual` for arrays and objects which performs
19983  * deep comparisons and tracks traversed objects enabling objects with circular
19984  * references to be compared.
19985  *
19986  * @private
19987  * @param {Object} object The object to compare.
19988  * @param {Object} other The other object to compare.
19989  * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
19990  * @param {Function} customizer The function to customize comparisons.
19991  * @param {Function} equalFunc The function to determine equivalents of values.
19992  * @param {Object} [stack] Tracks traversed `object` and `other` objects.
19993  * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
19994  */
19995 function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
19996   var objIsArr = isArray(object),
19997       othIsArr = isArray(other),
19998       objTag = objIsArr ? arrayTag$2 : getTag$1(object),
19999       othTag = othIsArr ? arrayTag$2 : getTag$1(other);
20000
20001   objTag = objTag == argsTag$3 ? objectTag$3 : objTag;
20002   othTag = othTag == argsTag$3 ? objectTag$3 : othTag;
20003
20004   var objIsObj = objTag == objectTag$3,
20005       othIsObj = othTag == objectTag$3,
20006       isSameTag = objTag == othTag;
20007
20008   if (isSameTag && isBuffer(object)) {
20009     if (!isBuffer(other)) {
20010       return false;
20011     }
20012     objIsArr = true;
20013     objIsObj = false;
20014   }
20015   if (isSameTag && !objIsObj) {
20016     stack || (stack = new Stack);
20017     return (objIsArr || isTypedArray(object))
20018       ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
20019       : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
20020   }
20021   if (!(bitmask & COMPARE_PARTIAL_FLAG$3)) {
20022     var objIsWrapped = objIsObj && hasOwnProperty$11.call(object, '__wrapped__'),
20023         othIsWrapped = othIsObj && hasOwnProperty$11.call(other, '__wrapped__');
20024
20025     if (objIsWrapped || othIsWrapped) {
20026       var objUnwrapped = objIsWrapped ? object.value() : object,
20027           othUnwrapped = othIsWrapped ? other.value() : other;
20028
20029       stack || (stack = new Stack);
20030       return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
20031     }
20032   }
20033   if (!isSameTag) {
20034     return false;
20035   }
20036   stack || (stack = new Stack);
20037   return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
20038 }
20039
20040 /**
20041  * The base implementation of `_.isEqual` which supports partial comparisons
20042  * and tracks traversed objects.
20043  *
20044  * @private
20045  * @param {*} value The value to compare.
20046  * @param {*} other The other value to compare.
20047  * @param {boolean} bitmask The bitmask flags.
20048  *  1 - Unordered comparison
20049  *  2 - Partial comparison
20050  * @param {Function} [customizer] The function to customize comparisons.
20051  * @param {Object} [stack] Tracks traversed `value` and `other` objects.
20052  * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
20053  */
20054 function baseIsEqual(value, other, bitmask, customizer, stack) {
20055   if (value === other) {
20056     return true;
20057   }
20058   if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
20059     return value !== value && other !== other;
20060   }
20061   return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
20062 }
20063
20064 /** Used to compose bitmasks for value comparisons. */
20065 var COMPARE_PARTIAL_FLAG$4 = 1;
20066 var COMPARE_UNORDERED_FLAG$2 = 2;
20067
20068 /**
20069  * The base implementation of `_.isMatch` without support for iteratee shorthands.
20070  *
20071  * @private
20072  * @param {Object} object The object to inspect.
20073  * @param {Object} source The object of property values to match.
20074  * @param {Array} matchData The property names, values, and compare flags to match.
20075  * @param {Function} [customizer] The function to customize comparisons.
20076  * @returns {boolean} Returns `true` if `object` is a match, else `false`.
20077  */
20078 function baseIsMatch(object, source, matchData, customizer) {
20079   var index = matchData.length,
20080       length = index,
20081       noCustomizer = !customizer;
20082
20083   if (object == null) {
20084     return !length;
20085   }
20086   object = Object(object);
20087   while (index--) {
20088     var data = matchData[index];
20089     if ((noCustomizer && data[2])
20090           ? data[1] !== object[data[0]]
20091           : !(data[0] in object)
20092         ) {
20093       return false;
20094     }
20095   }
20096   while (++index < length) {
20097     data = matchData[index];
20098     var key = data[0],
20099         objValue = object[key],
20100         srcValue = data[1];
20101
20102     if (noCustomizer && data[2]) {
20103       if (objValue === undefined && !(key in object)) {
20104         return false;
20105       }
20106     } else {
20107       var stack = new Stack;
20108       if (customizer) {
20109         var result = customizer(objValue, srcValue, key, object, source, stack);
20110       }
20111       if (!(result === undefined
20112             ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$4 | COMPARE_UNORDERED_FLAG$2, customizer, stack)
20113             : result
20114           )) {
20115         return false;
20116       }
20117     }
20118   }
20119   return true;
20120 }
20121
20122 /**
20123  * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
20124  *
20125  * @private
20126  * @param {*} value The value to check.
20127  * @returns {boolean} Returns `true` if `value` if suitable for strict
20128  *  equality comparisons, else `false`.
20129  */
20130 function isStrictComparable(value) {
20131   return value === value && !isObject(value);
20132 }
20133
20134 /**
20135  * Gets the property names, values, and compare flags of `object`.
20136  *
20137  * @private
20138  * @param {Object} object The object to query.
20139  * @returns {Array} Returns the match data of `object`.
20140  */
20141 function getMatchData(object) {
20142   var result = keys$1(object),
20143       length = result.length;
20144
20145   while (length--) {
20146     var key = result[length],
20147         value = object[key];
20148
20149     result[length] = [key, value, isStrictComparable(value)];
20150   }
20151   return result;
20152 }
20153
20154 /**
20155  * A specialized version of `matchesProperty` for source values suitable
20156  * for strict equality comparisons, i.e. `===`.
20157  *
20158  * @private
20159  * @param {string} key The key of the property to get.
20160  * @param {*} srcValue The value to match.
20161  * @returns {Function} Returns the new spec function.
20162  */
20163 function matchesStrictComparable(key, srcValue) {
20164   return function(object) {
20165     if (object == null) {
20166       return false;
20167     }
20168     return object[key] === srcValue &&
20169       (srcValue !== undefined || (key in Object(object)));
20170   };
20171 }
20172
20173 /**
20174  * The base implementation of `_.matches` which doesn't clone `source`.
20175  *
20176  * @private
20177  * @param {Object} source The object of property values to match.
20178  * @returns {Function} Returns the new spec function.
20179  */
20180 function baseMatches(source) {
20181   var matchData = getMatchData(source);
20182   if (matchData.length == 1 && matchData[0][2]) {
20183     return matchesStrictComparable(matchData[0][0], matchData[0][1]);
20184   }
20185   return function(object) {
20186     return object === source || baseIsMatch(object, source, matchData);
20187   };
20188 }
20189
20190 /** `Object#toString` result references. */
20191 var symbolTag$3 = '[object Symbol]';
20192
20193 /**
20194  * Checks if `value` is classified as a `Symbol` primitive or object.
20195  *
20196  * @static
20197  * @memberOf _
20198  * @since 4.0.0
20199  * @category Lang
20200  * @param {*} value The value to check.
20201  * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
20202  * @example
20203  *
20204  * _.isSymbol(Symbol.iterator);
20205  * // => true
20206  *
20207  * _.isSymbol('abc');
20208  * // => false
20209  */
20210 function isSymbol(value) {
20211   return typeof value == 'symbol' ||
20212     (isObjectLike(value) && baseGetTag(value) == symbolTag$3);
20213 }
20214
20215 /** Used to match property names within property paths. */
20216 var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/;
20217 var reIsPlainProp = /^\w*$/;
20218
20219 /**
20220  * Checks if `value` is a property name and not a property path.
20221  *
20222  * @private
20223  * @param {*} value The value to check.
20224  * @param {Object} [object] The object to query keys on.
20225  * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
20226  */
20227 function isKey(value, object) {
20228   if (isArray(value)) {
20229     return false;
20230   }
20231   var type = typeof value;
20232   if (type == 'number' || type == 'symbol' || type == 'boolean' ||
20233       value == null || isSymbol(value)) {
20234     return true;
20235   }
20236   return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
20237     (object != null && value in Object(object));
20238 }
20239
20240 /** Error message constants. */
20241 var FUNC_ERROR_TEXT = 'Expected a function';
20242
20243 /**
20244  * Creates a function that memoizes the result of `func`. If `resolver` is
20245  * provided, it determines the cache key for storing the result based on the
20246  * arguments provided to the memoized function. By default, the first argument
20247  * provided to the memoized function is used as the map cache key. The `func`
20248  * is invoked with the `this` binding of the memoized function.
20249  *
20250  * **Note:** The cache is exposed as the `cache` property on the memoized
20251  * function. Its creation may be customized by replacing the `_.memoize.Cache`
20252  * constructor with one whose instances implement the
20253  * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
20254  * method interface of `clear`, `delete`, `get`, `has`, and `set`.
20255  *
20256  * @static
20257  * @memberOf _
20258  * @since 0.1.0
20259  * @category Function
20260  * @param {Function} func The function to have its output memoized.
20261  * @param {Function} [resolver] The function to resolve the cache key.
20262  * @returns {Function} Returns the new memoized function.
20263  * @example
20264  *
20265  * var object = { 'a': 1, 'b': 2 };
20266  * var other = { 'c': 3, 'd': 4 };
20267  *
20268  * var values = _.memoize(_.values);
20269  * values(object);
20270  * // => [1, 2]
20271  *
20272  * values(other);
20273  * // => [3, 4]
20274  *
20275  * object.a = 2;
20276  * values(object);
20277  * // => [1, 2]
20278  *
20279  * // Modify the result cache.
20280  * values.cache.set(object, ['a', 'b']);
20281  * values(object);
20282  * // => ['a', 'b']
20283  *
20284  * // Replace `_.memoize.Cache`.
20285  * _.memoize.Cache = WeakMap;
20286  */
20287 function memoize(func, resolver) {
20288   if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
20289     throw new TypeError(FUNC_ERROR_TEXT);
20290   }
20291   var memoized = function() {
20292     var args = arguments,
20293         key = resolver ? resolver.apply(this, args) : args[0],
20294         cache = memoized.cache;
20295
20296     if (cache.has(key)) {
20297       return cache.get(key);
20298     }
20299     var result = func.apply(this, args);
20300     memoized.cache = cache.set(key, result) || cache;
20301     return result;
20302   };
20303   memoized.cache = new (memoize.Cache || MapCache);
20304   return memoized;
20305 }
20306
20307 // Expose `MapCache`.
20308 memoize.Cache = MapCache;
20309
20310 /** Used as the maximum memoize cache size. */
20311 var MAX_MEMOIZE_SIZE = 500;
20312
20313 /**
20314  * A specialized version of `_.memoize` which clears the memoized function's
20315  * cache when it exceeds `MAX_MEMOIZE_SIZE`.
20316  *
20317  * @private
20318  * @param {Function} func The function to have its output memoized.
20319  * @returns {Function} Returns the new memoized function.
20320  */
20321 function memoizeCapped(func) {
20322   var result = memoize(func, function(key) {
20323     if (cache.size === MAX_MEMOIZE_SIZE) {
20324       cache.clear();
20325     }
20326     return key;
20327   });
20328
20329   var cache = result.cache;
20330   return result;
20331 }
20332
20333 /** Used to match property names within property paths. */
20334 var reLeadingDot = /^\./;
20335 var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
20336
20337 /** Used to match backslashes in property paths. */
20338 var reEscapeChar = /\\(\\)?/g;
20339
20340 /**
20341  * Converts `string` to a property path array.
20342  *
20343  * @private
20344  * @param {string} string The string to convert.
20345  * @returns {Array} Returns the property path array.
20346  */
20347 var stringToPath = memoizeCapped(function(string) {
20348   var result = [];
20349   if (reLeadingDot.test(string)) {
20350     result.push('');
20351   }
20352   string.replace(rePropName, function(match, number, quote, string) {
20353     result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
20354   });
20355   return result;
20356 });
20357
20358 /**
20359  * A specialized version of `_.map` for arrays without support for iteratee
20360  * shorthands.
20361  *
20362  * @private
20363  * @param {Array} [array] The array to iterate over.
20364  * @param {Function} iteratee The function invoked per iteration.
20365  * @returns {Array} Returns the new mapped array.
20366  */
20367 function arrayMap(array, iteratee) {
20368   var index = -1,
20369       length = array == null ? 0 : array.length,
20370       result = Array(length);
20371
20372   while (++index < length) {
20373     result[index] = iteratee(array[index], index, array);
20374   }
20375   return result;
20376 }
20377
20378 /** Used as references for various `Number` constants. */
20379 var INFINITY = 1 / 0;
20380
20381 /** Used to convert symbols to primitives and strings. */
20382 var symbolProto$2 = Symbol ? Symbol.prototype : undefined;
20383 var symbolToString = symbolProto$2 ? symbolProto$2.toString : undefined;
20384
20385 /**
20386  * The base implementation of `_.toString` which doesn't convert nullish
20387  * values to empty strings.
20388  *
20389  * @private
20390  * @param {*} value The value to process.
20391  * @returns {string} Returns the string.
20392  */
20393 function baseToString(value) {
20394   // Exit early for strings to avoid a performance hit in some environments.
20395   if (typeof value == 'string') {
20396     return value;
20397   }
20398   if (isArray(value)) {
20399     // Recursively convert values (susceptible to call stack limits).
20400     return arrayMap(value, baseToString) + '';
20401   }
20402   if (isSymbol(value)) {
20403     return symbolToString ? symbolToString.call(value) : '';
20404   }
20405   var result = (value + '');
20406   return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
20407 }
20408
20409 /**
20410  * Converts `value` to a string. An empty string is returned for `null`
20411  * and `undefined` values. The sign of `-0` is preserved.
20412  *
20413  * @static
20414  * @memberOf _
20415  * @since 4.0.0
20416  * @category Lang
20417  * @param {*} value The value to convert.
20418  * @returns {string} Returns the converted string.
20419  * @example
20420  *
20421  * _.toString(null);
20422  * // => ''
20423  *
20424  * _.toString(-0);
20425  * // => '-0'
20426  *
20427  * _.toString([1, 2, 3]);
20428  * // => '1,2,3'
20429  */
20430 function toString(value) {
20431   return value == null ? '' : baseToString(value);
20432 }
20433
20434 /**
20435  * Casts `value` to a path array if it's not one.
20436  *
20437  * @private
20438  * @param {*} value The value to inspect.
20439  * @param {Object} [object] The object to query keys on.
20440  * @returns {Array} Returns the cast property path array.
20441  */
20442 function castPath(value, object) {
20443   if (isArray(value)) {
20444     return value;
20445   }
20446   return isKey(value, object) ? [value] : stringToPath(toString(value));
20447 }
20448
20449 /** Used as references for various `Number` constants. */
20450 var INFINITY$1 = 1 / 0;
20451
20452 /**
20453  * Converts `value` to a string key if it's not a string or symbol.
20454  *
20455  * @private
20456  * @param {*} value The value to inspect.
20457  * @returns {string|symbol} Returns the key.
20458  */
20459 function toKey(value) {
20460   if (typeof value == 'string' || isSymbol(value)) {
20461     return value;
20462   }
20463   var result = (value + '');
20464   return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result;
20465 }
20466
20467 /**
20468  * The base implementation of `_.get` without support for default values.
20469  *
20470  * @private
20471  * @param {Object} object The object to query.
20472  * @param {Array|string} path The path of the property to get.
20473  * @returns {*} Returns the resolved value.
20474  */
20475 function baseGet(object, path) {
20476   path = castPath(path, object);
20477
20478   var index = 0,
20479       length = path.length;
20480
20481   while (object != null && index < length) {
20482     object = object[toKey(path[index++])];
20483   }
20484   return (index && index == length) ? object : undefined;
20485 }
20486
20487 /**
20488  * Gets the value at `path` of `object`. If the resolved value is
20489  * `undefined`, the `defaultValue` is returned in its place.
20490  *
20491  * @static
20492  * @memberOf _
20493  * @since 3.7.0
20494  * @category Object
20495  * @param {Object} object The object to query.
20496  * @param {Array|string} path The path of the property to get.
20497  * @param {*} [defaultValue] The value returned for `undefined` resolved values.
20498  * @returns {*} Returns the resolved value.
20499  * @example
20500  *
20501  * var object = { 'a': [{ 'b': { 'c': 3 } }] };
20502  *
20503  * _.get(object, 'a[0].b.c');
20504  * // => 3
20505  *
20506  * _.get(object, ['a', '0', 'b', 'c']);
20507  * // => 3
20508  *
20509  * _.get(object, 'a.b.c', 'default');
20510  * // => 'default'
20511  */
20512 function get$2(object, path, defaultValue) {
20513   var result = object == null ? undefined : baseGet(object, path);
20514   return result === undefined ? defaultValue : result;
20515 }
20516
20517 /**
20518  * The base implementation of `_.hasIn` without support for deep paths.
20519  *
20520  * @private
20521  * @param {Object} [object] The object to query.
20522  * @param {Array|string} key The key to check.
20523  * @returns {boolean} Returns `true` if `key` exists, else `false`.
20524  */
20525 function baseHasIn(object, key) {
20526   return object != null && key in Object(object);
20527 }
20528
20529 /**
20530  * Checks if `path` exists on `object`.
20531  *
20532  * @private
20533  * @param {Object} object The object to query.
20534  * @param {Array|string} path The path to check.
20535  * @param {Function} hasFunc The function to check properties.
20536  * @returns {boolean} Returns `true` if `path` exists, else `false`.
20537  */
20538 function hasPath(object, path, hasFunc) {
20539   path = castPath(path, object);
20540
20541   var index = -1,
20542       length = path.length,
20543       result = false;
20544
20545   while (++index < length) {
20546     var key = toKey(path[index]);
20547     if (!(result = object != null && hasFunc(object, key))) {
20548       break;
20549     }
20550     object = object[key];
20551   }
20552   if (result || ++index != length) {
20553     return result;
20554   }
20555   length = object == null ? 0 : object.length;
20556   return !!length && isLength(length) && isIndex(key, length) &&
20557     (isArray(object) || isArguments(object));
20558 }
20559
20560 /**
20561  * Checks if `path` is a direct or inherited property of `object`.
20562  *
20563  * @static
20564  * @memberOf _
20565  * @since 4.0.0
20566  * @category Object
20567  * @param {Object} object The object to query.
20568  * @param {Array|string} path The path to check.
20569  * @returns {boolean} Returns `true` if `path` exists, else `false`.
20570  * @example
20571  *
20572  * var object = _.create({ 'a': _.create({ 'b': 2 }) });
20573  *
20574  * _.hasIn(object, 'a');
20575  * // => true
20576  *
20577  * _.hasIn(object, 'a.b');
20578  * // => true
20579  *
20580  * _.hasIn(object, ['a', 'b']);
20581  * // => true
20582  *
20583  * _.hasIn(object, 'b');
20584  * // => false
20585  */
20586 function hasIn(object, path) {
20587   return object != null && hasPath(object, path, baseHasIn);
20588 }
20589
20590 /** Used to compose bitmasks for value comparisons. */
20591 var COMPARE_PARTIAL_FLAG$5 = 1;
20592 var COMPARE_UNORDERED_FLAG$3 = 2;
20593
20594 /**
20595  * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
20596  *
20597  * @private
20598  * @param {string} path The path of the property to get.
20599  * @param {*} srcValue The value to match.
20600  * @returns {Function} Returns the new spec function.
20601  */
20602 function baseMatchesProperty(path, srcValue) {
20603   if (isKey(path) && isStrictComparable(srcValue)) {
20604     return matchesStrictComparable(toKey(path), srcValue);
20605   }
20606   return function(object) {
20607     var objValue = get$2(object, path);
20608     return (objValue === undefined && objValue === srcValue)
20609       ? hasIn(object, path)
20610       : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$5 | COMPARE_UNORDERED_FLAG$3);
20611   };
20612 }
20613
20614 /**
20615  * This method returns the first argument it receives.
20616  *
20617  * @static
20618  * @since 0.1.0
20619  * @memberOf _
20620  * @category Util
20621  * @param {*} value Any value.
20622  * @returns {*} Returns `value`.
20623  * @example
20624  *
20625  * var object = { 'a': 1 };
20626  *
20627  * console.log(_.identity(object) === object);
20628  * // => true
20629  */
20630 function identity$8(value) {
20631   return value;
20632 }
20633
20634 /**
20635  * The base implementation of `_.property` without support for deep paths.
20636  *
20637  * @private
20638  * @param {string} key The key of the property to get.
20639  * @returns {Function} Returns the new accessor function.
20640  */
20641 function baseProperty(key) {
20642   return function(object) {
20643     return object == null ? undefined : object[key];
20644   };
20645 }
20646
20647 /**
20648  * A specialized version of `baseProperty` which supports deep paths.
20649  *
20650  * @private
20651  * @param {Array|string} path The path of the property to get.
20652  * @returns {Function} Returns the new accessor function.
20653  */
20654 function basePropertyDeep(path) {
20655   return function(object) {
20656     return baseGet(object, path);
20657   };
20658 }
20659
20660 /**
20661  * Creates a function that returns the value at `path` of a given object.
20662  *
20663  * @static
20664  * @memberOf _
20665  * @since 2.4.0
20666  * @category Util
20667  * @param {Array|string} path The path of the property to get.
20668  * @returns {Function} Returns the new accessor function.
20669  * @example
20670  *
20671  * var objects = [
20672  *   { 'a': { 'b': 2 } },
20673  *   { 'a': { 'b': 1 } }
20674  * ];
20675  *
20676  * _.map(objects, _.property('a.b'));
20677  * // => [2, 1]
20678  *
20679  * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
20680  * // => [1, 2]
20681  */
20682 function property(path) {
20683   return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
20684 }
20685
20686 /**
20687  * The base implementation of `_.iteratee`.
20688  *
20689  * @private
20690  * @param {*} [value=_.identity] The value to convert to an iteratee.
20691  * @returns {Function} Returns the iteratee.
20692  */
20693 function baseIteratee(value) {
20694   // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
20695   // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
20696   if (typeof value == 'function') {
20697     return value;
20698   }
20699   if (value == null) {
20700     return identity$8;
20701   }
20702   if (typeof value == 'object') {
20703     return isArray(value)
20704       ? baseMatchesProperty(value[0], value[1])
20705       : baseMatches(value);
20706   }
20707   return property(value);
20708 }
20709
20710 /**
20711  * Creates a function like `_.groupBy`.
20712  *
20713  * @private
20714  * @param {Function} setter The function to set accumulator values.
20715  * @param {Function} [initializer] The accumulator object initializer.
20716  * @returns {Function} Returns the new aggregator function.
20717  */
20718 function createAggregator(setter, initializer) {
20719   return function(collection, iteratee) {
20720     var func = isArray(collection) ? arrayAggregator : baseAggregator,
20721         accumulator = initializer ? initializer() : {};
20722
20723     return func(collection, setter, baseIteratee(iteratee, 2), accumulator);
20724   };
20725 }
20726
20727 /** Used for built-in method references. */
20728 var objectProto$15 = Object.prototype;
20729
20730 /** Used to check objects for own properties. */
20731 var hasOwnProperty$12 = objectProto$15.hasOwnProperty;
20732
20733 /**
20734  * Creates an object composed of keys generated from the results of running
20735  * each element of `collection` thru `iteratee`. The order of grouped values
20736  * is determined by the order they occur in `collection`. The corresponding
20737  * value of each key is an array of elements responsible for generating the
20738  * key. The iteratee is invoked with one argument: (value).
20739  *
20740  * @static
20741  * @memberOf _
20742  * @since 0.1.0
20743  * @category Collection
20744  * @param {Array|Object} collection The collection to iterate over.
20745  * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
20746  * @returns {Object} Returns the composed aggregate object.
20747  * @example
20748  *
20749  * _.groupBy([6.1, 4.2, 6.3], Math.floor);
20750  * // => { '4': [4.2], '6': [6.1, 6.3] }
20751  *
20752  * // The `_.property` iteratee shorthand.
20753  * _.groupBy(['one', 'two', 'three'], 'length');
20754  * // => { '3': ['one', 'two'], '5': ['three'] }
20755  */
20756 var groupBy = createAggregator(function(result, value, key) {
20757   if (hasOwnProperty$12.call(result, key)) {
20758     result[key].push(value);
20759   } else {
20760     baseAssignValue(result, key, [value]);
20761   }
20762 });
20763
20764 /**
20765  * Gets the last element of `array`.
20766  *
20767  * @static
20768  * @memberOf _
20769  * @since 0.1.0
20770  * @category Array
20771  * @param {Array} array The array to query.
20772  * @returns {*} Returns the last element of `array`.
20773  * @example
20774  *
20775  * _.last([1, 2, 3]);
20776  * // => 3
20777  */
20778 function last(array) {
20779   var length = array == null ? 0 : array.length;
20780   return length ? array[length - 1] : undefined;
20781 }
20782
20783 /**
20784  * The base implementation of `_.slice` without an iteratee call guard.
20785  *
20786  * @private
20787  * @param {Array} array The array to slice.
20788  * @param {number} [start=0] The start position.
20789  * @param {number} [end=array.length] The end position.
20790  * @returns {Array} Returns the slice of `array`.
20791  */
20792 function baseSlice(array, start, end) {
20793   var index = -1,
20794       length = array.length;
20795
20796   if (start < 0) {
20797     start = -start > length ? 0 : (length + start);
20798   }
20799   end = end > length ? length : end;
20800   if (end < 0) {
20801     end += length;
20802   }
20803   length = start > end ? 0 : ((end - start) >>> 0);
20804   start >>>= 0;
20805
20806   var result = Array(length);
20807   while (++index < length) {
20808     result[index] = array[index + start];
20809   }
20810   return result;
20811 }
20812
20813 /**
20814  * Gets the parent value at `path` of `object`.
20815  *
20816  * @private
20817  * @param {Object} object The object to query.
20818  * @param {Array} path The path to get the parent value of.
20819  * @returns {*} Returns the parent value.
20820  */
20821 function parent(object, path) {
20822   return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
20823 }
20824
20825 /**
20826  * The base implementation of `_.unset`.
20827  *
20828  * @private
20829  * @param {Object} object The object to modify.
20830  * @param {Array|string} path The property path to unset.
20831  * @returns {boolean} Returns `true` if the property is deleted, else `false`.
20832  */
20833 function baseUnset(object, path) {
20834   path = castPath(path, object);
20835   object = parent(object, path);
20836   return object == null || delete object[toKey(last(path))];
20837 }
20838
20839 /** `Object#toString` result references. */
20840 var objectTag$4 = '[object Object]';
20841
20842 /** Used for built-in method references. */
20843 var funcProto$2 = Function.prototype;
20844 var objectProto$16 = Object.prototype;
20845
20846 /** Used to resolve the decompiled source of functions. */
20847 var funcToString$2 = funcProto$2.toString;
20848
20849 /** Used to check objects for own properties. */
20850 var hasOwnProperty$13 = objectProto$16.hasOwnProperty;
20851
20852 /** Used to infer the `Object` constructor. */
20853 var objectCtorString = funcToString$2.call(Object);
20854
20855 /**
20856  * Checks if `value` is a plain object, that is, an object created by the
20857  * `Object` constructor or one with a `[[Prototype]]` of `null`.
20858  *
20859  * @static
20860  * @memberOf _
20861  * @since 0.8.0
20862  * @category Lang
20863  * @param {*} value The value to check.
20864  * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
20865  * @example
20866  *
20867  * function Foo() {
20868  *   this.a = 1;
20869  * }
20870  *
20871  * _.isPlainObject(new Foo);
20872  * // => false
20873  *
20874  * _.isPlainObject([1, 2, 3]);
20875  * // => false
20876  *
20877  * _.isPlainObject({ 'x': 0, 'y': 0 });
20878  * // => true
20879  *
20880  * _.isPlainObject(Object.create(null));
20881  * // => true
20882  */
20883 function isPlainObject(value) {
20884   if (!isObjectLike(value) || baseGetTag(value) != objectTag$4) {
20885     return false;
20886   }
20887   var proto = getPrototype(value);
20888   if (proto === null) {
20889     return true;
20890   }
20891   var Ctor = hasOwnProperty$13.call(proto, 'constructor') && proto.constructor;
20892   return typeof Ctor == 'function' && Ctor instanceof Ctor &&
20893     funcToString$2.call(Ctor) == objectCtorString;
20894 }
20895
20896 /**
20897  * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
20898  * objects.
20899  *
20900  * @private
20901  * @param {*} value The value to inspect.
20902  * @param {string} key The key of the property to inspect.
20903  * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
20904  */
20905 function customOmitClone(value) {
20906   return isPlainObject(value) ? undefined : value;
20907 }
20908
20909 /** Built-in value references. */
20910 var spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;
20911
20912 /**
20913  * Checks if `value` is a flattenable `arguments` object or array.
20914  *
20915  * @private
20916  * @param {*} value The value to check.
20917  * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
20918  */
20919 function isFlattenable(value) {
20920   return isArray(value) || isArguments(value) ||
20921     !!(spreadableSymbol && value && value[spreadableSymbol]);
20922 }
20923
20924 /**
20925  * The base implementation of `_.flatten` with support for restricting flattening.
20926  *
20927  * @private
20928  * @param {Array} array The array to flatten.
20929  * @param {number} depth The maximum recursion depth.
20930  * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
20931  * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
20932  * @param {Array} [result=[]] The initial result value.
20933  * @returns {Array} Returns the new flattened array.
20934  */
20935 function baseFlatten(array, depth, predicate, isStrict, result) {
20936   var index = -1,
20937       length = array.length;
20938
20939   predicate || (predicate = isFlattenable);
20940   result || (result = []);
20941
20942   while (++index < length) {
20943     var value = array[index];
20944     if (depth > 0 && predicate(value)) {
20945       if (depth > 1) {
20946         // Recursively flatten arrays (susceptible to call stack limits).
20947         baseFlatten(value, depth - 1, predicate, isStrict, result);
20948       } else {
20949         arrayPush(result, value);
20950       }
20951     } else if (!isStrict) {
20952       result[result.length] = value;
20953     }
20954   }
20955   return result;
20956 }
20957
20958 /**
20959  * Flattens `array` a single level deep.
20960  *
20961  * @static
20962  * @memberOf _
20963  * @since 0.1.0
20964  * @category Array
20965  * @param {Array} array The array to flatten.
20966  * @returns {Array} Returns the new flattened array.
20967  * @example
20968  *
20969  * _.flatten([1, [2, [3, [4]], 5]]);
20970  * // => [1, 2, [3, [4]], 5]
20971  */
20972 function flatten(array) {
20973   var length = array == null ? 0 : array.length;
20974   return length ? baseFlatten(array, 1) : [];
20975 }
20976
20977 /**
20978  * A faster alternative to `Function#apply`, this function invokes `func`
20979  * with the `this` binding of `thisArg` and the arguments of `args`.
20980  *
20981  * @private
20982  * @param {Function} func The function to invoke.
20983  * @param {*} thisArg The `this` binding of `func`.
20984  * @param {Array} args The arguments to invoke `func` with.
20985  * @returns {*} Returns the result of `func`.
20986  */
20987 function apply(func, thisArg, args) {
20988   switch (args.length) {
20989     case 0: return func.call(thisArg);
20990     case 1: return func.call(thisArg, args[0]);
20991     case 2: return func.call(thisArg, args[0], args[1]);
20992     case 3: return func.call(thisArg, args[0], args[1], args[2]);
20993   }
20994   return func.apply(thisArg, args);
20995 }
20996
20997 /* Built-in method references for those with the same name as other `lodash` methods. */
20998 var nativeMax = Math.max;
20999
21000 /**
21001  * A specialized version of `baseRest` which transforms the rest array.
21002  *
21003  * @private
21004  * @param {Function} func The function to apply a rest parameter to.
21005  * @param {number} [start=func.length-1] The start position of the rest parameter.
21006  * @param {Function} transform The rest array transform.
21007  * @returns {Function} Returns the new function.
21008  */
21009 function overRest(func, start, transform) {
21010   start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
21011   return function() {
21012     var args = arguments,
21013         index = -1,
21014         length = nativeMax(args.length - start, 0),
21015         array = Array(length);
21016
21017     while (++index < length) {
21018       array[index] = args[start + index];
21019     }
21020     index = -1;
21021     var otherArgs = Array(start + 1);
21022     while (++index < start) {
21023       otherArgs[index] = args[index];
21024     }
21025     otherArgs[start] = transform(array);
21026     return apply(func, this, otherArgs);
21027   };
21028 }
21029
21030 /**
21031  * Creates a function that returns `value`.
21032  *
21033  * @static
21034  * @memberOf _
21035  * @since 2.4.0
21036  * @category Util
21037  * @param {*} value The value to return from the new function.
21038  * @returns {Function} Returns the new constant function.
21039  * @example
21040  *
21041  * var objects = _.times(2, _.constant({ 'a': 1 }));
21042  *
21043  * console.log(objects);
21044  * // => [{ 'a': 1 }, { 'a': 1 }]
21045  *
21046  * console.log(objects[0] === objects[1]);
21047  * // => true
21048  */
21049 function constant$13(value) {
21050   return function() {
21051     return value;
21052   };
21053 }
21054
21055 /**
21056  * The base implementation of `setToString` without support for hot loop shorting.
21057  *
21058  * @private
21059  * @param {Function} func The function to modify.
21060  * @param {Function} string The `toString` result.
21061  * @returns {Function} Returns `func`.
21062  */
21063 var baseSetToString = !defineProperty ? identity$8 : function(func, string) {
21064   return defineProperty(func, 'toString', {
21065     'configurable': true,
21066     'enumerable': false,
21067     'value': constant$13(string),
21068     'writable': true
21069   });
21070 };
21071
21072 /** Used to detect hot functions by number of calls within a span of milliseconds. */
21073 var HOT_COUNT = 800;
21074 var HOT_SPAN = 16;
21075
21076 /* Built-in method references for those with the same name as other `lodash` methods. */
21077 var nativeNow = Date.now;
21078
21079 /**
21080  * Creates a function that'll short out and invoke `identity` instead
21081  * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
21082  * milliseconds.
21083  *
21084  * @private
21085  * @param {Function} func The function to restrict.
21086  * @returns {Function} Returns the new shortable function.
21087  */
21088 function shortOut(func) {
21089   var count = 0,
21090       lastCalled = 0;
21091
21092   return function() {
21093     var stamp = nativeNow(),
21094         remaining = HOT_SPAN - (stamp - lastCalled);
21095
21096     lastCalled = stamp;
21097     if (remaining > 0) {
21098       if (++count >= HOT_COUNT) {
21099         return arguments[0];
21100       }
21101     } else {
21102       count = 0;
21103     }
21104     return func.apply(undefined, arguments);
21105   };
21106 }
21107
21108 /**
21109  * Sets the `toString` method of `func` to return `string`.
21110  *
21111  * @private
21112  * @param {Function} func The function to modify.
21113  * @param {Function} string The `toString` result.
21114  * @returns {Function} Returns `func`.
21115  */
21116 var setToString = shortOut(baseSetToString);
21117
21118 /**
21119  * A specialized version of `baseRest` which flattens the rest array.
21120  *
21121  * @private
21122  * @param {Function} func The function to apply a rest parameter to.
21123  * @returns {Function} Returns the new function.
21124  */
21125 function flatRest(func) {
21126   return setToString(overRest(func, undefined, flatten), func + '');
21127 }
21128
21129 /** Used to compose bitmasks for cloning. */
21130 var CLONE_DEEP_FLAG$3 = 1;
21131 var CLONE_FLAT_FLAG$1 = 2;
21132 var CLONE_SYMBOLS_FLAG$2 = 4;
21133
21134 /**
21135  * The opposite of `_.pick`; this method creates an object composed of the
21136  * own and inherited enumerable property paths of `object` that are not omitted.
21137  *
21138  * **Note:** This method is considerably slower than `_.pick`.
21139  *
21140  * @static
21141  * @since 0.1.0
21142  * @memberOf _
21143  * @category Object
21144  * @param {Object} object The source object.
21145  * @param {...(string|string[])} [paths] The property paths to omit.
21146  * @returns {Object} Returns the new object.
21147  * @example
21148  *
21149  * var object = { 'a': 1, 'b': '2', 'c': 3 };
21150  *
21151  * _.omit(object, ['a', 'c']);
21152  * // => { 'b': '2' }
21153  */
21154 var omit = flatRest(function(object, paths) {
21155   var result = {};
21156   if (object == null) {
21157     return result;
21158   }
21159   var isDeep = false;
21160   paths = arrayMap(paths, function(path) {
21161     path = castPath(path, object);
21162     isDeep || (isDeep = path.length > 1);
21163     return path;
21164   });
21165   copyObject(object, getAllKeysIn(object), result);
21166   if (isDeep) {
21167     result = baseClone(result, CLONE_DEEP_FLAG$3 | CLONE_FLAT_FLAG$1 | CLONE_SYMBOLS_FLAG$2, customOmitClone);
21168   }
21169   var length = paths.length;
21170   while (length--) {
21171     baseUnset(result, paths[length]);
21172   }
21173   return result;
21174 });
21175
21176 /**
21177  * Creates an array with all falsey values removed. The values `false`, `null`,
21178  * `0`, `""`, `undefined`, and `NaN` are falsey.
21179  *
21180  * @static
21181  * @memberOf _
21182  * @since 0.1.0
21183  * @category Array
21184  * @param {Array} array The array to compact.
21185  * @returns {Array} Returns the new array of filtered values.
21186  * @example
21187  *
21188  * _.compact([0, 1, false, 2, '', 3]);
21189  * // => [1, 2, 3]
21190  */
21191 function compact(array) {
21192   var index = -1,
21193       length = array == null ? 0 : array.length,
21194       resIndex = 0,
21195       result = [];
21196
21197   while (++index < length) {
21198     var value = array[index];
21199     if (value) {
21200       result[resIndex++] = value;
21201     }
21202   }
21203   return result;
21204 }
21205
21206 /**
21207  * The base implementation of `_.rest` which doesn't validate or coerce arguments.
21208  *
21209  * @private
21210  * @param {Function} func The function to apply a rest parameter to.
21211  * @param {number} [start=func.length-1] The start position of the rest parameter.
21212  * @returns {Function} Returns the new function.
21213  */
21214 function baseRest(func, start) {
21215   return setToString(overRest(func, start, identity$8), func + '');
21216 }
21217
21218 /**
21219  * Checks if the given arguments are from an iteratee call.
21220  *
21221  * @private
21222  * @param {*} value The potential iteratee value argument.
21223  * @param {*} index The potential iteratee index or key argument.
21224  * @param {*} object The potential iteratee object argument.
21225  * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
21226  *  else `false`.
21227  */
21228 function isIterateeCall(value, index, object) {
21229   if (!isObject(object)) {
21230     return false;
21231   }
21232   var type = typeof index;
21233   if (type == 'number'
21234         ? (isArrayLike(object) && isIndex(index, object.length))
21235         : (type == 'string' && index in object)
21236       ) {
21237     return eq(object[index], value);
21238   }
21239   return false;
21240 }
21241
21242 /**
21243  * Creates a function like `_.assign`.
21244  *
21245  * @private
21246  * @param {Function} assigner The function to assign values.
21247  * @returns {Function} Returns the new assigner function.
21248  */
21249 function createAssigner(assigner) {
21250   return baseRest(function(object, sources) {
21251     var index = -1,
21252         length = sources.length,
21253         customizer = length > 1 ? sources[length - 1] : undefined,
21254         guard = length > 2 ? sources[2] : undefined;
21255
21256     customizer = (assigner.length > 3 && typeof customizer == 'function')
21257       ? (length--, customizer)
21258       : undefined;
21259
21260     if (guard && isIterateeCall(sources[0], sources[1], guard)) {
21261       customizer = length < 3 ? undefined : customizer;
21262       length = 1;
21263     }
21264     object = Object(object);
21265     while (++index < length) {
21266       var source = sources[index];
21267       if (source) {
21268         assigner(object, source, index, customizer);
21269       }
21270     }
21271     return object;
21272   });
21273 }
21274
21275 /**
21276  * This method is like `_.assign` except that it iterates over own and
21277  * inherited source properties.
21278  *
21279  * **Note:** This method mutates `object`.
21280  *
21281  * @static
21282  * @memberOf _
21283  * @since 4.0.0
21284  * @alias extend
21285  * @category Object
21286  * @param {Object} object The destination object.
21287  * @param {...Object} [sources] The source objects.
21288  * @returns {Object} Returns `object`.
21289  * @see _.assign
21290  * @example
21291  *
21292  * function Foo() {
21293  *   this.a = 1;
21294  * }
21295  *
21296  * function Bar() {
21297  *   this.c = 3;
21298  * }
21299  *
21300  * Foo.prototype.b = 2;
21301  * Bar.prototype.d = 4;
21302  *
21303  * _.assignIn({ 'a': 0 }, new Foo, new Bar);
21304  * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
21305  */
21306 var assignIn = createAssigner(function(object, source) {
21307   copyObject(source, keysIn$1(source), object);
21308 });
21309
21310 /**
21311  * The base implementation of `_.filter` without support for iteratee shorthands.
21312  *
21313  * @private
21314  * @param {Array|Object} collection The collection to iterate over.
21315  * @param {Function} predicate The function invoked per iteration.
21316  * @returns {Array} Returns the new filtered array.
21317  */
21318 function baseFilter(collection, predicate) {
21319   var result = [];
21320   baseEach(collection, function(value, index, collection) {
21321     if (predicate(value, index, collection)) {
21322       result.push(value);
21323     }
21324   });
21325   return result;
21326 }
21327
21328 /**
21329  * Iterates over elements of `collection`, returning an array of all elements
21330  * `predicate` returns truthy for. The predicate is invoked with three
21331  * arguments: (value, index|key, collection).
21332  *
21333  * **Note:** Unlike `_.remove`, this method returns a new array.
21334  *
21335  * @static
21336  * @memberOf _
21337  * @since 0.1.0
21338  * @category Collection
21339  * @param {Array|Object} collection The collection to iterate over.
21340  * @param {Function} [predicate=_.identity] The function invoked per iteration.
21341  * @returns {Array} Returns the new filtered array.
21342  * @see _.reject
21343  * @example
21344  *
21345  * var users = [
21346  *   { 'user': 'barney', 'age': 36, 'active': true },
21347  *   { 'user': 'fred',   'age': 40, 'active': false }
21348  * ];
21349  *
21350  * _.filter(users, function(o) { return !o.active; });
21351  * // => objects for ['fred']
21352  *
21353  * // The `_.matches` iteratee shorthand.
21354  * _.filter(users, { 'age': 36, 'active': true });
21355  * // => objects for ['barney']
21356  *
21357  * // The `_.matchesProperty` iteratee shorthand.
21358  * _.filter(users, ['active', false]);
21359  * // => objects for ['fred']
21360  *
21361  * // The `_.property` iteratee shorthand.
21362  * _.filter(users, 'active');
21363  * // => objects for ['barney']
21364  */
21365 function filter(collection, predicate) {
21366   var func = isArray(collection) ? arrayFilter : baseFilter;
21367   return func(collection, baseIteratee(predicate, 3));
21368 }
21369
21370 /**
21371  * Creates a `_.find` or `_.findLast` function.
21372  *
21373  * @private
21374  * @param {Function} findIndexFunc The function to find the collection index.
21375  * @returns {Function} Returns the new find function.
21376  */
21377 function createFind(findIndexFunc) {
21378   return function(collection, predicate, fromIndex) {
21379     var iterable = Object(collection);
21380     if (!isArrayLike(collection)) {
21381       var iteratee = baseIteratee(predicate, 3);
21382       collection = keys$1(collection);
21383       predicate = function(key) { return iteratee(iterable[key], key, iterable); };
21384     }
21385     var index = findIndexFunc(collection, predicate, fromIndex);
21386     return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
21387   };
21388 }
21389
21390 /**
21391  * The base implementation of `_.findIndex` and `_.findLastIndex` without
21392  * support for iteratee shorthands.
21393  *
21394  * @private
21395  * @param {Array} array The array to inspect.
21396  * @param {Function} predicate The function invoked per iteration.
21397  * @param {number} fromIndex The index to search from.
21398  * @param {boolean} [fromRight] Specify iterating from right to left.
21399  * @returns {number} Returns the index of the matched value, else `-1`.
21400  */
21401 function baseFindIndex(array, predicate, fromIndex, fromRight) {
21402   var length = array.length,
21403       index = fromIndex + (fromRight ? 1 : -1);
21404
21405   while ((fromRight ? index-- : ++index < length)) {
21406     if (predicate(array[index], index, array)) {
21407       return index;
21408     }
21409   }
21410   return -1;
21411 }
21412
21413 /** Used as references for various `Number` constants. */
21414 var NAN = 0 / 0;
21415
21416 /** Used to match leading and trailing whitespace. */
21417 var reTrim = /^\s+|\s+$/g;
21418
21419 /** Used to detect bad signed hexadecimal string values. */
21420 var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
21421
21422 /** Used to detect binary string values. */
21423 var reIsBinary = /^0b[01]+$/i;
21424
21425 /** Used to detect octal string values. */
21426 var reIsOctal = /^0o[0-7]+$/i;
21427
21428 /** Built-in method references without a dependency on `root`. */
21429 var freeParseInt = parseInt;
21430
21431 /**
21432  * Converts `value` to a number.
21433  *
21434  * @static
21435  * @memberOf _
21436  * @since 4.0.0
21437  * @category Lang
21438  * @param {*} value The value to process.
21439  * @returns {number} Returns the number.
21440  * @example
21441  *
21442  * _.toNumber(3.2);
21443  * // => 3.2
21444  *
21445  * _.toNumber(Number.MIN_VALUE);
21446  * // => 5e-324
21447  *
21448  * _.toNumber(Infinity);
21449  * // => Infinity
21450  *
21451  * _.toNumber('3.2');
21452  * // => 3.2
21453  */
21454 function toNumber(value) {
21455   if (typeof value == 'number') {
21456     return value;
21457   }
21458   if (isSymbol(value)) {
21459     return NAN;
21460   }
21461   if (isObject(value)) {
21462     var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
21463     value = isObject(other) ? (other + '') : other;
21464   }
21465   if (typeof value != 'string') {
21466     return value === 0 ? value : +value;
21467   }
21468   value = value.replace(reTrim, '');
21469   var isBinary = reIsBinary.test(value);
21470   return (isBinary || reIsOctal.test(value))
21471     ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
21472     : (reIsBadHex.test(value) ? NAN : +value);
21473 }
21474
21475 /** Used as references for various `Number` constants. */
21476 var INFINITY$2 = 1 / 0;
21477 var MAX_INTEGER = 1.7976931348623157e+308;
21478
21479 /**
21480  * Converts `value` to a finite number.
21481  *
21482  * @static
21483  * @memberOf _
21484  * @since 4.12.0
21485  * @category Lang
21486  * @param {*} value The value to convert.
21487  * @returns {number} Returns the converted number.
21488  * @example
21489  *
21490  * _.toFinite(3.2);
21491  * // => 3.2
21492  *
21493  * _.toFinite(Number.MIN_VALUE);
21494  * // => 5e-324
21495  *
21496  * _.toFinite(Infinity);
21497  * // => 1.7976931348623157e+308
21498  *
21499  * _.toFinite('3.2');
21500  * // => 3.2
21501  */
21502 function toFinite(value) {
21503   if (!value) {
21504     return value === 0 ? value : 0;
21505   }
21506   value = toNumber(value);
21507   if (value === INFINITY$2 || value === -INFINITY$2) {
21508     var sign = (value < 0 ? -1 : 1);
21509     return sign * MAX_INTEGER;
21510   }
21511   return value === value ? value : 0;
21512 }
21513
21514 /**
21515  * Converts `value` to an integer.
21516  *
21517  * **Note:** This method is loosely based on
21518  * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
21519  *
21520  * @static
21521  * @memberOf _
21522  * @since 4.0.0
21523  * @category Lang
21524  * @param {*} value The value to convert.
21525  * @returns {number} Returns the converted integer.
21526  * @example
21527  *
21528  * _.toInteger(3.2);
21529  * // => 3
21530  *
21531  * _.toInteger(Number.MIN_VALUE);
21532  * // => 0
21533  *
21534  * _.toInteger(Infinity);
21535  * // => 1.7976931348623157e+308
21536  *
21537  * _.toInteger('3.2');
21538  * // => 3
21539  */
21540 function toInteger(value) {
21541   var result = toFinite(value),
21542       remainder = result % 1;
21543
21544   return result === result ? (remainder ? result - remainder : result) : 0;
21545 }
21546
21547 /* Built-in method references for those with the same name as other `lodash` methods. */
21548 var nativeMax$1 = Math.max;
21549
21550 /**
21551  * This method is like `_.find` except that it returns the index of the first
21552  * element `predicate` returns truthy for instead of the element itself.
21553  *
21554  * @static
21555  * @memberOf _
21556  * @since 1.1.0
21557  * @category Array
21558  * @param {Array} array The array to inspect.
21559  * @param {Function} [predicate=_.identity] The function invoked per iteration.
21560  * @param {number} [fromIndex=0] The index to search from.
21561  * @returns {number} Returns the index of the found element, else `-1`.
21562  * @example
21563  *
21564  * var users = [
21565  *   { 'user': 'barney',  'active': false },
21566  *   { 'user': 'fred',    'active': false },
21567  *   { 'user': 'pebbles', 'active': true }
21568  * ];
21569  *
21570  * _.findIndex(users, function(o) { return o.user == 'barney'; });
21571  * // => 0
21572  *
21573  * // The `_.matches` iteratee shorthand.
21574  * _.findIndex(users, { 'user': 'fred', 'active': false });
21575  * // => 1
21576  *
21577  * // The `_.matchesProperty` iteratee shorthand.
21578  * _.findIndex(users, ['active', false]);
21579  * // => 0
21580  *
21581  * // The `_.property` iteratee shorthand.
21582  * _.findIndex(users, 'active');
21583  * // => 2
21584  */
21585 function findIndex(array, predicate, fromIndex) {
21586   var length = array == null ? 0 : array.length;
21587   if (!length) {
21588     return -1;
21589   }
21590   var index = fromIndex == null ? 0 : toInteger(fromIndex);
21591   if (index < 0) {
21592     index = nativeMax$1(length + index, 0);
21593   }
21594   return baseFindIndex(array, baseIteratee(predicate, 3), index);
21595 }
21596
21597 /**
21598  * Iterates over elements of `collection`, returning the first element
21599  * `predicate` returns truthy for. The predicate is invoked with three
21600  * arguments: (value, index|key, collection).
21601  *
21602  * @static
21603  * @memberOf _
21604  * @since 0.1.0
21605  * @category Collection
21606  * @param {Array|Object} collection The collection to inspect.
21607  * @param {Function} [predicate=_.identity] The function invoked per iteration.
21608  * @param {number} [fromIndex=0] The index to search from.
21609  * @returns {*} Returns the matched element, else `undefined`.
21610  * @example
21611  *
21612  * var users = [
21613  *   { 'user': 'barney',  'age': 36, 'active': true },
21614  *   { 'user': 'fred',    'age': 40, 'active': false },
21615  *   { 'user': 'pebbles', 'age': 1,  'active': true }
21616  * ];
21617  *
21618  * _.find(users, function(o) { return o.age < 40; });
21619  * // => object for 'barney'
21620  *
21621  * // The `_.matches` iteratee shorthand.
21622  * _.find(users, { 'age': 1, 'active': true });
21623  * // => object for 'pebbles'
21624  *
21625  * // The `_.matchesProperty` iteratee shorthand.
21626  * _.find(users, ['active', false]);
21627  * // => object for 'fred'
21628  *
21629  * // The `_.property` iteratee shorthand.
21630  * _.find(users, 'active');
21631  * // => object for 'barney'
21632  */
21633 var find$1 = createFind(findIndex);
21634
21635 /**
21636  * The base implementation of `_.map` without support for iteratee shorthands.
21637  *
21638  * @private
21639  * @param {Array|Object} collection The collection to iterate over.
21640  * @param {Function} iteratee The function invoked per iteration.
21641  * @returns {Array} Returns the new mapped array.
21642  */
21643 function baseMap(collection, iteratee) {
21644   var index = -1,
21645       result = isArrayLike(collection) ? Array(collection.length) : [];
21646
21647   baseEach(collection, function(value, key, collection) {
21648     result[++index] = iteratee(value, key, collection);
21649   });
21650   return result;
21651 }
21652
21653 /**
21654  * Creates an array of values by running each element in `collection` thru
21655  * `iteratee`. The iteratee is invoked with three arguments:
21656  * (value, index|key, collection).
21657  *
21658  * Many lodash methods are guarded to work as iteratees for methods like
21659  * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
21660  *
21661  * The guarded methods are:
21662  * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
21663  * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
21664  * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
21665  * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
21666  *
21667  * @static
21668  * @memberOf _
21669  * @since 0.1.0
21670  * @category Collection
21671  * @param {Array|Object} collection The collection to iterate over.
21672  * @param {Function} [iteratee=_.identity] The function invoked per iteration.
21673  * @returns {Array} Returns the new mapped array.
21674  * @example
21675  *
21676  * function square(n) {
21677  *   return n * n;
21678  * }
21679  *
21680  * _.map([4, 8], square);
21681  * // => [16, 64]
21682  *
21683  * _.map({ 'a': 4, 'b': 8 }, square);
21684  * // => [16, 64] (iteration order is not guaranteed)
21685  *
21686  * var users = [
21687  *   { 'user': 'barney' },
21688  *   { 'user': 'fred' }
21689  * ];
21690  *
21691  * // The `_.property` iteratee shorthand.
21692  * _.map(users, 'user');
21693  * // => ['barney', 'fred']
21694  */
21695 function map$4(collection, iteratee) {
21696   var func = isArray(collection) ? arrayMap : baseMap;
21697   return func(collection, baseIteratee(iteratee, 3));
21698 }
21699
21700 /**
21701  * The base implementation of `_.values` and `_.valuesIn` which creates an
21702  * array of `object` property values corresponding to the property names
21703  * of `props`.
21704  *
21705  * @private
21706  * @param {Object} object The object to query.
21707  * @param {Array} props The property names to get values for.
21708  * @returns {Object} Returns the array of property values.
21709  */
21710 function baseValues(object, props) {
21711   return arrayMap(props, function(key) {
21712     return object[key];
21713   });
21714 }
21715
21716 /**
21717  * Creates an array of the own enumerable string keyed property values of `object`.
21718  *
21719  * **Note:** Non-object values are coerced to objects.
21720  *
21721  * @static
21722  * @since 0.1.0
21723  * @memberOf _
21724  * @category Object
21725  * @param {Object} object The object to query.
21726  * @returns {Array} Returns the array of property values.
21727  * @example
21728  *
21729  * function Foo() {
21730  *   this.a = 1;
21731  *   this.b = 2;
21732  * }
21733  *
21734  * Foo.prototype.c = 3;
21735  *
21736  * _.values(new Foo);
21737  * // => [1, 2] (iteration order is not guaranteed)
21738  *
21739  * _.values('hi');
21740  * // => ['h', 'i']
21741  */
21742 function values$1(object) {
21743   return object == null ? [] : baseValues(object, keys$1(object));
21744 }
21745
21746 /**
21747  * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
21748  * of key-value pairs for `object` corresponding to the property names of `props`.
21749  *
21750  * @private
21751  * @param {Object} object The object to query.
21752  * @param {Array} props The property names to get values for.
21753  * @returns {Object} Returns the key-value pairs.
21754  */
21755 function baseToPairs(object, props) {
21756   return arrayMap(props, function(key) {
21757     return [key, object[key]];
21758   });
21759 }
21760
21761 /**
21762  * Converts `set` to its value-value pairs.
21763  *
21764  * @private
21765  * @param {Object} set The set to convert.
21766  * @returns {Array} Returns the value-value pairs.
21767  */
21768 function setToPairs(set) {
21769   var index = -1,
21770       result = Array(set.size);
21771
21772   set.forEach(function(value) {
21773     result[++index] = [value, value];
21774   });
21775   return result;
21776 }
21777
21778 /** `Object#toString` result references. */
21779 var mapTag$5 = '[object Map]';
21780 var setTag$5 = '[object Set]';
21781
21782 /**
21783  * Creates a `_.toPairs` or `_.toPairsIn` function.
21784  *
21785  * @private
21786  * @param {Function} keysFunc The function to get the keys of a given object.
21787  * @returns {Function} Returns the new pairs function.
21788  */
21789 function createToPairs(keysFunc) {
21790   return function(object) {
21791     var tag = getTag$1(object);
21792     if (tag == mapTag$5) {
21793       return mapToArray(object);
21794     }
21795     if (tag == setTag$5) {
21796       return setToPairs(object);
21797     }
21798     return baseToPairs(object, keysFunc(object));
21799   };
21800 }
21801
21802 /**
21803  * Creates an array of own enumerable string keyed-value pairs for `object`
21804  * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
21805  * entries are returned.
21806  *
21807  * @static
21808  * @memberOf _
21809  * @since 4.0.0
21810  * @alias entries
21811  * @category Object
21812  * @param {Object} object The object to query.
21813  * @returns {Array} Returns the key-value pairs.
21814  * @example
21815  *
21816  * function Foo() {
21817  *   this.a = 1;
21818  *   this.b = 2;
21819  * }
21820  *
21821  * Foo.prototype.c = 3;
21822  *
21823  * _.toPairs(new Foo);
21824  * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
21825  */
21826 var toPairs = createToPairs(keys$1);
21827
21828 /**
21829  * The base implementation of `_.isNaN` without support for number objects.
21830  *
21831  * @private
21832  * @param {*} value The value to check.
21833  * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
21834  */
21835 function baseIsNaN(value) {
21836   return value !== value;
21837 }
21838
21839 /**
21840  * A specialized version of `_.indexOf` which performs strict equality
21841  * comparisons of values, i.e. `===`.
21842  *
21843  * @private
21844  * @param {Array} array The array to inspect.
21845  * @param {*} value The value to search for.
21846  * @param {number} fromIndex The index to search from.
21847  * @returns {number} Returns the index of the matched value, else `-1`.
21848  */
21849 function strictIndexOf(array, value, fromIndex) {
21850   var index = fromIndex - 1,
21851       length = array.length;
21852
21853   while (++index < length) {
21854     if (array[index] === value) {
21855       return index;
21856     }
21857   }
21858   return -1;
21859 }
21860
21861 /**
21862  * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
21863  *
21864  * @private
21865  * @param {Array} array The array to inspect.
21866  * @param {*} value The value to search for.
21867  * @param {number} fromIndex The index to search from.
21868  * @returns {number} Returns the index of the matched value, else `-1`.
21869  */
21870 function baseIndexOf(array, value, fromIndex) {
21871   return value === value
21872     ? strictIndexOf(array, value, fromIndex)
21873     : baseFindIndex(array, baseIsNaN, fromIndex);
21874 }
21875
21876 /**
21877  * A specialized version of `_.includes` for arrays without support for
21878  * specifying an index to search from.
21879  *
21880  * @private
21881  * @param {Array} [array] The array to inspect.
21882  * @param {*} target The value to search for.
21883  * @returns {boolean} Returns `true` if `target` is found, else `false`.
21884  */
21885 function arrayIncludes(array, value) {
21886   var length = array == null ? 0 : array.length;
21887   return !!length && baseIndexOf(array, value, 0) > -1;
21888 }
21889
21890 /**
21891  * This function is like `arrayIncludes` except that it accepts a comparator.
21892  *
21893  * @private
21894  * @param {Array} [array] The array to inspect.
21895  * @param {*} target The value to search for.
21896  * @param {Function} comparator The comparator invoked per element.
21897  * @returns {boolean} Returns `true` if `target` is found, else `false`.
21898  */
21899 function arrayIncludesWith(array, value, comparator) {
21900   var index = -1,
21901       length = array == null ? 0 : array.length;
21902
21903   while (++index < length) {
21904     if (comparator(value, array[index])) {
21905       return true;
21906     }
21907   }
21908   return false;
21909 }
21910
21911 /**
21912  * This method returns `undefined`.
21913  *
21914  * @static
21915  * @memberOf _
21916  * @since 2.3.0
21917  * @category Util
21918  * @example
21919  *
21920  * _.times(2, _.noop);
21921  * // => [undefined, undefined]
21922  */
21923 function noop$3() {
21924   // No operation performed.
21925 }
21926
21927 /** Used as references for various `Number` constants. */
21928 var INFINITY$3 = 1 / 0;
21929
21930 /**
21931  * Creates a set object of `values`.
21932  *
21933  * @private
21934  * @param {Array} values The values to add to the set.
21935  * @returns {Object} Returns the new set.
21936  */
21937 var createSet = !(Set$1 && (1 / setToArray(new Set$1([,-0]))[1]) == INFINITY$3) ? noop$3 : function(values) {
21938   return new Set$1(values);
21939 };
21940
21941 /** Used as the size to enable large array optimizations. */
21942 var LARGE_ARRAY_SIZE$1 = 200;
21943
21944 /**
21945  * The base implementation of `_.uniqBy` without support for iteratee shorthands.
21946  *
21947  * @private
21948  * @param {Array} array The array to inspect.
21949  * @param {Function} [iteratee] The iteratee invoked per element.
21950  * @param {Function} [comparator] The comparator invoked per element.
21951  * @returns {Array} Returns the new duplicate free array.
21952  */
21953 function baseUniq(array, iteratee, comparator) {
21954   var index = -1,
21955       includes = arrayIncludes,
21956       length = array.length,
21957       isCommon = true,
21958       result = [],
21959       seen = result;
21960
21961   if (comparator) {
21962     isCommon = false;
21963     includes = arrayIncludesWith;
21964   }
21965   else if (length >= LARGE_ARRAY_SIZE$1) {
21966     var set = iteratee ? null : createSet(array);
21967     if (set) {
21968       return setToArray(set);
21969     }
21970     isCommon = false;
21971     includes = cacheHas;
21972     seen = new SetCache;
21973   }
21974   else {
21975     seen = iteratee ? [] : result;
21976   }
21977   outer:
21978   while (++index < length) {
21979     var value = array[index],
21980         computed = iteratee ? iteratee(value) : value;
21981
21982     value = (comparator || value !== 0) ? value : 0;
21983     if (isCommon && computed === computed) {
21984       var seenIndex = seen.length;
21985       while (seenIndex--) {
21986         if (seen[seenIndex] === computed) {
21987           continue outer;
21988         }
21989       }
21990       if (iteratee) {
21991         seen.push(computed);
21992       }
21993       result.push(value);
21994     }
21995     else if (!includes(seen, computed, comparator)) {
21996       if (seen !== result) {
21997         seen.push(computed);
21998       }
21999       result.push(value);
22000     }
22001   }
22002   return result;
22003 }
22004
22005 /**
22006  * This method is like `_.isArrayLike` except that it also checks if `value`
22007  * is an object.
22008  *
22009  * @static
22010  * @memberOf _
22011  * @since 4.0.0
22012  * @category Lang
22013  * @param {*} value The value to check.
22014  * @returns {boolean} Returns `true` if `value` is an array-like object,
22015  *  else `false`.
22016  * @example
22017  *
22018  * _.isArrayLikeObject([1, 2, 3]);
22019  * // => true
22020  *
22021  * _.isArrayLikeObject(document.body.children);
22022  * // => true
22023  *
22024  * _.isArrayLikeObject('abc');
22025  * // => false
22026  *
22027  * _.isArrayLikeObject(_.noop);
22028  * // => false
22029  */
22030 function isArrayLikeObject(value) {
22031   return isObjectLike(value) && isArrayLike(value);
22032 }
22033
22034 /**
22035  * Creates an array of unique values, in order, from all given arrays using
22036  * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
22037  * for equality comparisons.
22038  *
22039  * @static
22040  * @memberOf _
22041  * @since 0.1.0
22042  * @category Array
22043  * @param {...Array} [arrays] The arrays to inspect.
22044  * @returns {Array} Returns the new array of combined values.
22045  * @example
22046  *
22047  * _.union([2], [1, 2]);
22048  * // => [2, 1]
22049  */
22050 var union = baseRest(function(arrays) {
22051   return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
22052 });
22053
22054 /** Used as the size to enable large array optimizations. */
22055 var LARGE_ARRAY_SIZE$2 = 200;
22056
22057 /**
22058  * The base implementation of methods like `_.difference` without support
22059  * for excluding multiple arrays or iteratee shorthands.
22060  *
22061  * @private
22062  * @param {Array} array The array to inspect.
22063  * @param {Array} values The values to exclude.
22064  * @param {Function} [iteratee] The iteratee invoked per element.
22065  * @param {Function} [comparator] The comparator invoked per element.
22066  * @returns {Array} Returns the new array of filtered values.
22067  */
22068 function baseDifference(array, values, iteratee, comparator) {
22069   var index = -1,
22070       includes = arrayIncludes,
22071       isCommon = true,
22072       length = array.length,
22073       result = [],
22074       valuesLength = values.length;
22075
22076   if (!length) {
22077     return result;
22078   }
22079   if (iteratee) {
22080     values = arrayMap(values, baseUnary(iteratee));
22081   }
22082   if (comparator) {
22083     includes = arrayIncludesWith;
22084     isCommon = false;
22085   }
22086   else if (values.length >= LARGE_ARRAY_SIZE$2) {
22087     includes = cacheHas;
22088     isCommon = false;
22089     values = new SetCache(values);
22090   }
22091   outer:
22092   while (++index < length) {
22093     var value = array[index],
22094         computed = iteratee == null ? value : iteratee(value);
22095
22096     value = (comparator || value !== 0) ? value : 0;
22097     if (isCommon && computed === computed) {
22098       var valuesIndex = valuesLength;
22099       while (valuesIndex--) {
22100         if (values[valuesIndex] === computed) {
22101           continue outer;
22102         }
22103       }
22104       result.push(value);
22105     }
22106     else if (!includes(values, computed, comparator)) {
22107       result.push(value);
22108     }
22109   }
22110   return result;
22111 }
22112
22113 /**
22114  * Creates an array excluding all given values using
22115  * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
22116  * for equality comparisons.
22117  *
22118  * **Note:** Unlike `_.pull`, this method returns a new array.
22119  *
22120  * @static
22121  * @memberOf _
22122  * @since 0.1.0
22123  * @category Array
22124  * @param {Array} array The array to inspect.
22125  * @param {...*} [values] The values to exclude.
22126  * @returns {Array} Returns the new array of filtered values.
22127  * @see _.difference, _.xor
22128  * @example
22129  *
22130  * _.without([2, 1, 2, 3], 1, 2);
22131  * // => [3]
22132  */
22133 var without = baseRest(function(array, values) {
22134   return isArrayLikeObject(array)
22135     ? baseDifference(array, values)
22136     : [];
22137 });
22138
22139 function osmIsInterestingTag(key) {
22140     return key !== 'attribution' &&
22141         key !== 'created_by' &&
22142         key !== 'source' &&
22143         key !== 'odbl' &&
22144         key.indexOf('tiger:') !== 0;
22145
22146 }
22147
22148
22149 var osmOneWayTags = {
22150     'aerialway': {
22151         'chair_lift': true,
22152         'mixed_lift': true,
22153         't-bar': true,
22154         'j-bar': true,
22155         'platter': true,
22156         'rope_tow': true,
22157         'magic_carpet': true,
22158         'yes': true
22159     },
22160     'highway': {
22161         'motorway': true
22162     },
22163     'junction': {
22164         'circular': true,
22165         'roundabout': true
22166     },
22167     'man_made': {
22168         'piste:halfpipe': true
22169     },
22170     'piste:type': {
22171         'downhill': true,
22172         'sled': true,
22173         'yes': true
22174     },
22175     'waterway': {
22176         'canal': true,
22177         'ditch': true,
22178         'drain': true,
22179         'river': true,
22180         'stream': true
22181     }
22182 };
22183
22184
22185 var osmPavedTags = {
22186     'surface': {
22187         'paved': true,
22188         'asphalt': true,
22189         'concrete': true,
22190         'concrete:lanes': true,
22191         'concrete:plates': true
22192     },
22193     'tracktype': {
22194         'grade1': true
22195     }
22196 };
22197
22198 var wikipedia = [
22199     [
22200         "Abkhazian",
22201         "Аҧсшәа",
22202         "ab"
22203     ],
22204     [
22205         "Achinese",
22206         "Acèh",
22207         "ace"
22208     ],
22209     [
22210         "Adyghe",
22211         "адыгабзэ",
22212         "ady"
22213     ],
22214     [
22215         "Afrikaans",
22216         "Afrikaans",
22217         "af"
22218     ],
22219     [
22220         "Akan",
22221         "Akan",
22222         "ak"
22223     ],
22224     [
22225         "Alemannisch",
22226         "Alemannisch",
22227         "als"
22228     ],
22229     [
22230         "Amharic",
22231         "አማርኛ",
22232         "am"
22233     ],
22234     [
22235         "Aragonese",
22236         "aragonés",
22237         "an"
22238     ],
22239     [
22240         "Old English",
22241         "Ænglisc",
22242         "ang"
22243     ],
22244     [
22245         "Arabic",
22246         "العربية",
22247         "ar"
22248     ],
22249     [
22250         "Aramaic",
22251         "ܐܪܡܝܐ",
22252         "arc"
22253     ],
22254     [
22255         "Egyptian Arabic",
22256         "مصرى",
22257         "arz"
22258     ],
22259     [
22260         "Assamese",
22261         "অসমীয়া",
22262         "as"
22263     ],
22264     [
22265         "Asturian",
22266         "asturianu",
22267         "ast"
22268     ],
22269     [
22270         "Avaric",
22271         "авар",
22272         "av"
22273     ],
22274     [
22275         "Aymara",
22276         "Aymar aru",
22277         "ay"
22278     ],
22279     [
22280         "Azerbaijani",
22281         "azərbaycanca",
22282         "az"
22283     ],
22284     [
22285         "تۆرکجه",
22286         "تۆرکجه",
22287         "azb"
22288     ],
22289     [
22290         "Bashkir",
22291         "башҡортса",
22292         "ba"
22293     ],
22294     [
22295         "Bavarian",
22296         "Boarisch",
22297         "bar"
22298     ],
22299     [
22300         "Samogitian",
22301         "žemaitėška",
22302         "bat-smg"
22303     ],
22304     [
22305         "Bikol Central",
22306         "Bikol Central",
22307         "bcl"
22308     ],
22309     [
22310         "Belarusian",
22311         "беларуская",
22312         "be"
22313     ],
22314     [
22315         "беларуская (тарашкевіца)‎",
22316         "беларуская (тарашкевіца)‎",
22317         "be-x-old"
22318     ],
22319     [
22320         "Bulgarian",
22321         "български",
22322         "bg"
22323     ],
22324     [
22325         "भोजपुरी",
22326         "भोजपुरी",
22327         "bh"
22328     ],
22329     [
22330         "Bislama",
22331         "Bislama",
22332         "bi"
22333     ],
22334     [
22335         "Banjar",
22336         "Bahasa Banjar",
22337         "bjn"
22338     ],
22339     [
22340         "Bambara",
22341         "bamanankan",
22342         "bm"
22343     ],
22344     [
22345         "Bangla",
22346         "বাংলা",
22347         "bn"
22348     ],
22349     [
22350         "Tibetan",
22351         "བོད་ཡིག",
22352         "bo"
22353     ],
22354     [
22355         "Bishnupriya",
22356         "বিষ্ণুপ্রিয়া মণিপুরী",
22357         "bpy"
22358     ],
22359     [
22360         "Breton",
22361         "brezhoneg",
22362         "br"
22363     ],
22364     [
22365         "Bosnian",
22366         "bosanski",
22367         "bs"
22368     ],
22369     [
22370         "Buginese",
22371         "ᨅᨔ ᨕᨘᨁᨗ",
22372         "bug"
22373     ],
22374     [
22375         "буряад",
22376         "буряад",
22377         "bxr"
22378     ],
22379     [
22380         "Catalan",
22381         "català",
22382         "ca"
22383     ],
22384     [
22385         "Chavacano de Zamboanga",
22386         "Chavacano de Zamboanga",
22387         "cbk-zam"
22388     ],
22389     [
22390         "Min Dong Chinese",
22391         "Mìng-dĕ̤ng-ngṳ̄",
22392         "cdo"
22393     ],
22394     [
22395         "Chechen",
22396         "нохчийн",
22397         "ce"
22398     ],
22399     [
22400         "Cebuano",
22401         "Cebuano",
22402         "ceb"
22403     ],
22404     [
22405         "Chamorro",
22406         "Chamoru",
22407         "ch"
22408     ],
22409     [
22410         "Cherokee",
22411         "ᏣᎳᎩ",
22412         "chr"
22413     ],
22414     [
22415         "Cheyenne",
22416         "Tsetsêhestâhese",
22417         "chy"
22418     ],
22419     [
22420         "Central Kurdish",
22421         "کوردیی ناوەندی",
22422         "ckb"
22423     ],
22424     [
22425         "Corsican",
22426         "corsu",
22427         "co"
22428     ],
22429     [
22430         "Cree",
22431         "Nēhiyawēwin / ᓀᐦᐃᔭᐍᐏᐣ",
22432         "cr"
22433     ],
22434     [
22435         "Crimean Turkish",
22436         "qırımtatarca",
22437         "crh"
22438     ],
22439     [
22440         "Czech",
22441         "čeština",
22442         "cs"
22443     ],
22444     [
22445         "Kashubian",
22446         "kaszëbsczi",
22447         "csb"
22448     ],
22449     [
22450         "Church Slavic",
22451         "словѣньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ",
22452         "cu"
22453     ],
22454     [
22455         "Chuvash",
22456         "Чӑвашла",
22457         "cv"
22458     ],
22459     [
22460         "Welsh",
22461         "Cymraeg",
22462         "cy"
22463     ],
22464     [
22465         "Danish",
22466         "dansk",
22467         "da"
22468     ],
22469     [
22470         "German",
22471         "Deutsch",
22472         "de"
22473     ],
22474     [
22475         "Zazaki",
22476         "Zazaki",
22477         "diq"
22478     ],
22479     [
22480         "Lower Sorbian",
22481         "dolnoserbski",
22482         "dsb"
22483     ],
22484     [
22485         "Divehi",
22486         "ދިވެހިބަސް",
22487         "dv"
22488     ],
22489     [
22490         "Dzongkha",
22491         "ཇོང་ཁ",
22492         "dz"
22493     ],
22494     [
22495         "Ewe",
22496         "eʋegbe",
22497         "ee"
22498     ],
22499     [
22500         "Greek",
22501         "Ελληνικά",
22502         "el"
22503     ],
22504     [
22505         "Emiliano-Romagnolo",
22506         "emiliàn e rumagnòl",
22507         "eml"
22508     ],
22509     [
22510         "English",
22511         "English",
22512         "en"
22513     ],
22514     [
22515         "Esperanto",
22516         "Esperanto",
22517         "eo"
22518     ],
22519     [
22520         "Spanish",
22521         "español",
22522         "es"
22523     ],
22524     [
22525         "Estonian",
22526         "eesti",
22527         "et"
22528     ],
22529     [
22530         "Basque",
22531         "euskara",
22532         "eu"
22533     ],
22534     [
22535         "Extremaduran",
22536         "estremeñu",
22537         "ext"
22538     ],
22539     [
22540         "Persian",
22541         "فارسی",
22542         "fa"
22543     ],
22544     [
22545         "Fulah",
22546         "Fulfulde",
22547         "ff"
22548     ],
22549     [
22550         "Finnish",
22551         "suomi",
22552         "fi"
22553     ],
22554     [
22555         "Võro",
22556         "Võro",
22557         "fiu-vro"
22558     ],
22559     [
22560         "Fijian",
22561         "Na Vosa Vakaviti",
22562         "fj"
22563     ],
22564     [
22565         "Faroese",
22566         "føroyskt",
22567         "fo"
22568     ],
22569     [
22570         "French",
22571         "français",
22572         "fr"
22573     ],
22574     [
22575         "Arpitan",
22576         "arpetan",
22577         "frp"
22578     ],
22579     [
22580         "Northern Frisian",
22581         "Nordfriisk",
22582         "frr"
22583     ],
22584     [
22585         "Friulian",
22586         "furlan",
22587         "fur"
22588     ],
22589     [
22590         "Western Frisian",
22591         "Frysk",
22592         "fy"
22593     ],
22594     [
22595         "Irish",
22596         "Gaeilge",
22597         "ga"
22598     ],
22599     [
22600         "Gagauz",
22601         "Gagauz",
22602         "gag"
22603     ],
22604     [
22605         "Gan Chinese",
22606         "贛語",
22607         "gan"
22608     ],
22609     [
22610         "Scottish Gaelic",
22611         "Gàidhlig",
22612         "gd"
22613     ],
22614     [
22615         "Galician",
22616         "galego",
22617         "gl"
22618     ],
22619     [
22620         "Gilaki",
22621         "گیلکی",
22622         "glk"
22623     ],
22624     [
22625         "Guarani",
22626         "Avañe'ẽ",
22627         "gn"
22628     ],
22629     [
22630         "Goan Konkani",
22631         "गोंयची कोंकणी / Gõychi Konknni",
22632         "gom"
22633     ],
22634     [
22635         "Gothic",
22636         "𐌲𐌿𐍄𐌹𐍃𐌺",
22637         "got"
22638     ],
22639     [
22640         "Gujarati",
22641         "ગુજરાતી",
22642         "gu"
22643     ],
22644     [
22645         "Manx",
22646         "Gaelg",
22647         "gv"
22648     ],
22649     [
22650         "Hausa",
22651         "Hausa",
22652         "ha"
22653     ],
22654     [
22655         "Hakka Chinese",
22656         "客家語/Hak-kâ-ngî",
22657         "hak"
22658     ],
22659     [
22660         "Hawaiian",
22661         "Hawaiʻi",
22662         "haw"
22663     ],
22664     [
22665         "Hebrew",
22666         "עברית",
22667         "he"
22668     ],
22669     [
22670         "Hindi",
22671         "हिन्दी",
22672         "hi"
22673     ],
22674     [
22675         "Fiji Hindi",
22676         "Fiji Hindi",
22677         "hif"
22678     ],
22679     [
22680         "Croatian",
22681         "hrvatski",
22682         "hr"
22683     ],
22684     [
22685         "Upper Sorbian",
22686         "hornjoserbsce",
22687         "hsb"
22688     ],
22689     [
22690         "Haitian Creole",
22691         "Kreyòl ayisyen",
22692         "ht"
22693     ],
22694     [
22695         "Hungarian",
22696         "magyar",
22697         "hu"
22698     ],
22699     [
22700         "Armenian",
22701         "Հայերեն",
22702         "hy"
22703     ],
22704     [
22705         "Interlingua",
22706         "interlingua",
22707         "ia"
22708     ],
22709     [
22710         "Indonesian",
22711         "Bahasa Indonesia",
22712         "id"
22713     ],
22714     [
22715         "Interlingue",
22716         "Interlingue",
22717         "ie"
22718     ],
22719     [
22720         "Igbo",
22721         "Igbo",
22722         "ig"
22723     ],
22724     [
22725         "Inupiaq",
22726         "Iñupiak",
22727         "ik"
22728     ],
22729     [
22730         "Iloko",
22731         "Ilokano",
22732         "ilo"
22733     ],
22734     [
22735         "Ido",
22736         "Ido",
22737         "io"
22738     ],
22739     [
22740         "Icelandic",
22741         "íslenska",
22742         "is"
22743     ],
22744     [
22745         "Italian",
22746         "italiano",
22747         "it"
22748     ],
22749     [
22750         "Inuktitut",
22751         "ᐃᓄᒃᑎᑐᑦ/inuktitut",
22752         "iu"
22753     ],
22754     [
22755         "Japanese",
22756         "日本語",
22757         "ja"
22758     ],
22759     [
22760         "Jamaican Creole English",
22761         "Patois",
22762         "jam"
22763     ],
22764     [
22765         "Lojban",
22766         "la .lojban.",
22767         "jbo"
22768     ],
22769     [
22770         "Javanese",
22771         "Basa Jawa",
22772         "jv"
22773     ],
22774     [
22775         "Georgian",
22776         "ქართული",
22777         "ka"
22778     ],
22779     [
22780         "Kara-Kalpak",
22781         "Qaraqalpaqsha",
22782         "kaa"
22783     ],
22784     [
22785         "Kabyle",
22786         "Taqbaylit",
22787         "kab"
22788     ],
22789     [
22790         "Kabardian",
22791         "Адыгэбзэ",
22792         "kbd"
22793     ],
22794     [
22795         "Kongo",
22796         "Kongo",
22797         "kg"
22798     ],
22799     [
22800         "Kikuyu",
22801         "Gĩkũyũ",
22802         "ki"
22803     ],
22804     [
22805         "Kazakh",
22806         "қазақша",
22807         "kk"
22808     ],
22809     [
22810         "Kalaallisut",
22811         "kalaallisut",
22812         "kl"
22813     ],
22814     [
22815         "Khmer",
22816         "ភាសាខ្មែរ",
22817         "km"
22818     ],
22819     [
22820         "Kannada",
22821         "ಕನ್ನಡ",
22822         "kn"
22823     ],
22824     [
22825         "Korean",
22826         "한국어",
22827         "ko"
22828     ],
22829     [
22830         "Komi-Permyak",
22831         "Перем Коми",
22832         "koi"
22833     ],
22834     [
22835         "Karachay-Balkar",
22836         "къарачай-малкъар",
22837         "krc"
22838     ],
22839     [
22840         "Kashmiri",
22841         "कॉशुर / کٲشُر",
22842         "ks"
22843     ],
22844     [
22845         "Colognian",
22846         "Ripoarisch",
22847         "ksh"
22848     ],
22849     [
22850         "Kurdish",
22851         "Kurdî",
22852         "ku"
22853     ],
22854     [
22855         "Komi",
22856         "коми",
22857         "kv"
22858     ],
22859     [
22860         "Cornish",
22861         "kernowek",
22862         "kw"
22863     ],
22864     [
22865         "Kyrgyz",
22866         "Кыргызча",
22867         "ky"
22868     ],
22869     [
22870         "Latin",
22871         "Latina",
22872         "la"
22873     ],
22874     [
22875         "Ladino",
22876         "Ladino",
22877         "lad"
22878     ],
22879     [
22880         "Luxembourgish",
22881         "Lëtzebuergesch",
22882         "lb"
22883     ],
22884     [
22885         "лакку",
22886         "лакку",
22887         "lbe"
22888     ],
22889     [
22890         "Lezghian",
22891         "лезги",
22892         "lez"
22893     ],
22894     [
22895         "Ganda",
22896         "Luganda",
22897         "lg"
22898     ],
22899     [
22900         "Limburgish",
22901         "Limburgs",
22902         "li"
22903     ],
22904     [
22905         "Ligurian",
22906         "Ligure",
22907         "lij"
22908     ],
22909     [
22910         "Lombard",
22911         "lumbaart",
22912         "lmo"
22913     ],
22914     [
22915         "Lingala",
22916         "lingála",
22917         "ln"
22918     ],
22919     [
22920         "Lao",
22921         "ລາວ",
22922         "lo"
22923     ],
22924     [
22925         "Northern Luri",
22926         "لۊری شومالی",
22927         "lrc"
22928     ],
22929     [
22930         "Lithuanian",
22931         "lietuvių",
22932         "lt"
22933     ],
22934     [
22935         "Latgalian",
22936         "latgaļu",
22937         "ltg"
22938     ],
22939     [
22940         "Latvian",
22941         "latviešu",
22942         "lv"
22943     ],
22944     [
22945         "Maithili",
22946         "मैथिली",
22947         "mai"
22948     ],
22949     [
22950         "Basa Banyumasan",
22951         "Basa Banyumasan",
22952         "map-bms"
22953     ],
22954     [
22955         "Moksha",
22956         "мокшень",
22957         "mdf"
22958     ],
22959     [
22960         "Malagasy",
22961         "Malagasy",
22962         "mg"
22963     ],
22964     [
22965         "Eastern Mari",
22966         "олык марий",
22967         "mhr"
22968     ],
22969     [
22970         "Maori",
22971         "Māori",
22972         "mi"
22973     ],
22974     [
22975         "Minangkabau",
22976         "Baso Minangkabau",
22977         "min"
22978     ],
22979     [
22980         "Macedonian",
22981         "македонски",
22982         "mk"
22983     ],
22984     [
22985         "Malayalam",
22986         "മലയാളം",
22987         "ml"
22988     ],
22989     [
22990         "Mongolian",
22991         "монгол",
22992         "mn"
22993     ],
22994     [
22995         "Marathi",
22996         "मराठी",
22997         "mr"
22998     ],
22999     [
23000         "Western Mari",
23001         "кырык мары",
23002         "mrj"
23003     ],
23004     [
23005         "Malay",
23006         "Bahasa Melayu",
23007         "ms"
23008     ],
23009     [
23010         "Maltese",
23011         "Malti",
23012         "mt"
23013     ],
23014     [
23015         "Mirandese",
23016         "Mirandés",
23017         "mwl"
23018     ],
23019     [
23020         "Burmese",
23021         "မြန်မာဘာသာ",
23022         "my"
23023     ],
23024     [
23025         "Erzya",
23026         "эрзянь",
23027         "myv"
23028     ],
23029     [
23030         "Mazanderani",
23031         "مازِرونی",
23032         "mzn"
23033     ],
23034     [
23035         "Nauru",
23036         "Dorerin Naoero",
23037         "na"
23038     ],
23039     [
23040         "Nāhuatl",
23041         "Nāhuatl",
23042         "nah"
23043     ],
23044     [
23045         "Neapolitan",
23046         "Napulitano",
23047         "nap"
23048     ],
23049     [
23050         "Low German",
23051         "Plattdüütsch",
23052         "nds"
23053     ],
23054     [
23055         "Low Saxon",
23056         "Nedersaksies",
23057         "nds-nl"
23058     ],
23059     [
23060         "Nepali",
23061         "नेपाली",
23062         "ne"
23063     ],
23064     [
23065         "Newari",
23066         "नेपाल भाषा",
23067         "new"
23068     ],
23069     [
23070         "Dutch",
23071         "Nederlands",
23072         "nl"
23073     ],
23074     [
23075         "Norwegian Nynorsk",
23076         "norsk nynorsk",
23077         "nn"
23078     ],
23079     [
23080         "Norwegian",
23081         "norsk bokmål",
23082         "no"
23083     ],
23084     [
23085         "Novial",
23086         "Novial",
23087         "nov"
23088     ],
23089     [
23090         "Nouormand",
23091         "Nouormand",
23092         "nrm"
23093     ],
23094     [
23095         "Northern Sotho",
23096         "Sesotho sa Leboa",
23097         "nso"
23098     ],
23099     [
23100         "Navajo",
23101         "Diné bizaad",
23102         "nv"
23103     ],
23104     [
23105         "Nyanja",
23106         "Chi-Chewa",
23107         "ny"
23108     ],
23109     [
23110         "Occitan",
23111         "occitan",
23112         "oc"
23113     ],
23114     [
23115         "Livvi-Karelian",
23116         "Livvinkarjala",
23117         "olo"
23118     ],
23119     [
23120         "Oromo",
23121         "Oromoo",
23122         "om"
23123     ],
23124     [
23125         "Odia",
23126         "ଓଡ଼ିଆ",
23127         "or"
23128     ],
23129     [
23130         "Ossetic",
23131         "Ирон",
23132         "os"
23133     ],
23134     [
23135         "Punjabi",
23136         "ਪੰਜਾਬੀ",
23137         "pa"
23138     ],
23139     [
23140         "Pangasinan",
23141         "Pangasinan",
23142         "pag"
23143     ],
23144     [
23145         "Pampanga",
23146         "Kapampangan",
23147         "pam"
23148     ],
23149     [
23150         "Papiamento",
23151         "Papiamentu",
23152         "pap"
23153     ],
23154     [
23155         "Picard",
23156         "Picard",
23157         "pcd"
23158     ],
23159     [
23160         "Pennsylvania German",
23161         "Deitsch",
23162         "pdc"
23163     ],
23164     [
23165         "Palatine German",
23166         "Pälzisch",
23167         "pfl"
23168     ],
23169     [
23170         "Pali",
23171         "पालि",
23172         "pi"
23173     ],
23174     [
23175         "Norfuk / Pitkern",
23176         "Norfuk / Pitkern",
23177         "pih"
23178     ],
23179     [
23180         "Polish",
23181         "polski",
23182         "pl"
23183     ],
23184     [
23185         "Piedmontese",
23186         "Piemontèis",
23187         "pms"
23188     ],
23189     [
23190         "Western Punjabi",
23191         "پنجابی",
23192         "pnb"
23193     ],
23194     [
23195         "Pontic",
23196         "Ποντιακά",
23197         "pnt"
23198     ],
23199     [
23200         "Pashto",
23201         "پښتو",
23202         "ps"
23203     ],
23204     [
23205         "Portuguese",
23206         "português",
23207         "pt"
23208     ],
23209     [
23210         "Quechua",
23211         "Runa Simi",
23212         "qu"
23213     ],
23214     [
23215         "Romansh",
23216         "rumantsch",
23217         "rm"
23218     ],
23219     [
23220         "Romani",
23221         "Romani",
23222         "rmy"
23223     ],
23224     [
23225         "Rundi",
23226         "Kirundi",
23227         "rn"
23228     ],
23229     [
23230         "Romanian",
23231         "română",
23232         "ro"
23233     ],
23234     [
23235         "Aromanian",
23236         "armãneashti",
23237         "roa-rup"
23238     ],
23239     [
23240         "tarandíne",
23241         "tarandíne",
23242         "roa-tara"
23243     ],
23244     [
23245         "Russian",
23246         "русский",
23247         "ru"
23248     ],
23249     [
23250         "Rusyn",
23251         "русиньскый",
23252         "rue"
23253     ],
23254     [
23255         "Kinyarwanda",
23256         "Kinyarwanda",
23257         "rw"
23258     ],
23259     [
23260         "Sanskrit",
23261         "संस्कृतम्",
23262         "sa"
23263     ],
23264     [
23265         "Sakha",
23266         "саха тыла",
23267         "sah"
23268     ],
23269     [
23270         "Sardinian",
23271         "sardu",
23272         "sc"
23273     ],
23274     [
23275         "Sicilian",
23276         "sicilianu",
23277         "scn"
23278     ],
23279     [
23280         "Scots",
23281         "Scots",
23282         "sco"
23283     ],
23284     [
23285         "Sindhi",
23286         "سنڌي",
23287         "sd"
23288     ],
23289     [
23290         "Northern Sami",
23291         "sámegiella",
23292         "se"
23293     ],
23294     [
23295         "Sango",
23296         "Sängö",
23297         "sg"
23298     ],
23299     [
23300         "Serbo-Croatian",
23301         "srpskohrvatski / српскохрватски",
23302         "sh"
23303     ],
23304     [
23305         "Sinhala",
23306         "සිංහල",
23307         "si"
23308     ],
23309     [
23310         "Simple English",
23311         "Simple English",
23312         "simple"
23313     ],
23314     [
23315         "Slovak",
23316         "slovenčina",
23317         "sk"
23318     ],
23319     [
23320         "Slovenian",
23321         "slovenščina",
23322         "sl"
23323     ],
23324     [
23325         "Samoan",
23326         "Gagana Samoa",
23327         "sm"
23328     ],
23329     [
23330         "Shona",
23331         "chiShona",
23332         "sn"
23333     ],
23334     [
23335         "Somali",
23336         "Soomaaliga",
23337         "so"
23338     ],
23339     [
23340         "Albanian",
23341         "shqip",
23342         "sq"
23343     ],
23344     [
23345         "Serbian",
23346         "српски / srpski",
23347         "sr"
23348     ],
23349     [
23350         "Sranan Tongo",
23351         "Sranantongo",
23352         "srn"
23353     ],
23354     [
23355         "Swati",
23356         "SiSwati",
23357         "ss"
23358     ],
23359     [
23360         "Southern Sotho",
23361         "Sesotho",
23362         "st"
23363     ],
23364     [
23365         "Saterland Frisian",
23366         "Seeltersk",
23367         "stq"
23368     ],
23369     [
23370         "Sundanese",
23371         "Basa Sunda",
23372         "su"
23373     ],
23374     [
23375         "Swedish",
23376         "svenska",
23377         "sv"
23378     ],
23379     [
23380         "Swahili",
23381         "Kiswahili",
23382         "sw"
23383     ],
23384     [
23385         "Silesian",
23386         "ślůnski",
23387         "szl"
23388     ],
23389     [
23390         "Tamil",
23391         "தமிழ்",
23392         "ta"
23393     ],
23394     [
23395         "Tulu",
23396         "ತುಳು",
23397         "tcy"
23398     ],
23399     [
23400         "Telugu",
23401         "తెలుగు",
23402         "te"
23403     ],
23404     [
23405         "Tetum",
23406         "tetun",
23407         "tet"
23408     ],
23409     [
23410         "Tajik",
23411         "тоҷикӣ",
23412         "tg"
23413     ],
23414     [
23415         "Thai",
23416         "ไทย",
23417         "th"
23418     ],
23419     [
23420         "Tigrinya",
23421         "ትግርኛ",
23422         "ti"
23423     ],
23424     [
23425         "Turkmen",
23426         "Türkmençe",
23427         "tk"
23428     ],
23429     [
23430         "Tagalog",
23431         "Tagalog",
23432         "tl"
23433     ],
23434     [
23435         "Tswana",
23436         "Setswana",
23437         "tn"
23438     ],
23439     [
23440         "Tongan",
23441         "lea faka-Tonga",
23442         "to"
23443     ],
23444     [
23445         "Tok Pisin",
23446         "Tok Pisin",
23447         "tpi"
23448     ],
23449     [
23450         "Turkish",
23451         "Türkçe",
23452         "tr"
23453     ],
23454     [
23455         "Tsonga",
23456         "Xitsonga",
23457         "ts"
23458     ],
23459     [
23460         "Tatar",
23461         "татарча/tatarça",
23462         "tt"
23463     ],
23464     [
23465         "Tumbuka",
23466         "chiTumbuka",
23467         "tum"
23468     ],
23469     [
23470         "Twi",
23471         "Twi",
23472         "tw"
23473     ],
23474     [
23475         "Tahitian",
23476         "reo tahiti",
23477         "ty"
23478     ],
23479     [
23480         "Tuvinian",
23481         "тыва дыл",
23482         "tyv"
23483     ],
23484     [
23485         "Udmurt",
23486         "удмурт",
23487         "udm"
23488     ],
23489     [
23490         "Uyghur",
23491         "ئۇيغۇرچە / Uyghurche",
23492         "ug"
23493     ],
23494     [
23495         "Ukrainian",
23496         "українська",
23497         "uk"
23498     ],
23499     [
23500         "Urdu",
23501         "اردو",
23502         "ur"
23503     ],
23504     [
23505         "Uzbek",
23506         "oʻzbekcha/ўзбекча",
23507         "uz"
23508     ],
23509     [
23510         "Venda",
23511         "Tshivenda",
23512         "ve"
23513     ],
23514     [
23515         "Venetian",
23516         "vèneto",
23517         "vec"
23518     ],
23519     [
23520         "Veps",
23521         "vepsän kel’",
23522         "vep"
23523     ],
23524     [
23525         "Vietnamese",
23526         "Tiếng Việt",
23527         "vi"
23528     ],
23529     [
23530         "West Flemish",
23531         "West-Vlams",
23532         "vls"
23533     ],
23534     [
23535         "Volapük",
23536         "Volapük",
23537         "vo"
23538     ],
23539     [
23540         "Walloon",
23541         "walon",
23542         "wa"
23543     ],
23544     [
23545         "Waray",
23546         "Winaray",
23547         "war"
23548     ],
23549     [
23550         "Wolof",
23551         "Wolof",
23552         "wo"
23553     ],
23554     [
23555         "Wu Chinese",
23556         "吴语",
23557         "wuu"
23558     ],
23559     [
23560         "Kalmyk",
23561         "хальмг",
23562         "xal"
23563     ],
23564     [
23565         "Xhosa",
23566         "isiXhosa",
23567         "xh"
23568     ],
23569     [
23570         "Mingrelian",
23571         "მარგალური",
23572         "xmf"
23573     ],
23574     [
23575         "Yiddish",
23576         "ייִדיש",
23577         "yi"
23578     ],
23579     [
23580         "Yoruba",
23581         "Yorùbá",
23582         "yo"
23583     ],
23584     [
23585         "Zhuang",
23586         "Vahcuengh",
23587         "za"
23588     ],
23589     [
23590         "Zeelandic",
23591         "Zeêuws",
23592         "zea"
23593     ],
23594     [
23595         "Chinese",
23596         "中文",
23597         "zh"
23598     ],
23599     [
23600         "Classical Chinese",
23601         "文言",
23602         "zh-classical"
23603     ],
23604     [
23605         "Chinese (Min Nan)",
23606         "Bân-lâm-gú",
23607         "zh-min-nan"
23608     ],
23609     [
23610         "Cantonese",
23611         "粵語",
23612         "zh-yue"
23613     ],
23614     [
23615         "Zulu",
23616         "isiZulu",
23617         "zu"
23618     ]
23619 ];
23620
23621 var wikipedia$1 = Object.freeze({
23622         default: wikipedia
23623 });
23624
23625 var require$$6 = ( wikipedia$1 && wikipedia ) || wikipedia$1;
23626
23627 var wikipedia$2 = require$$6;
23628
23629 var amenity = {"arts_centre":{"Świetlica wiejska":{"count":62},"Дом культуры":{"count":182}},"bank":{"ABANCA":{"count":83},"ABN AMRO":{"count":152},"ABSA":{"count":105},"AIB":{"count":85},"ANZ":{"count":378},"ASB Bank":{"count":51},"ATB Financial":{"count":68},"AXA":{"count":106},"Agribank":{"count":58},"Akbank":{"count":129},"Alior Bank":{"count":180},"Allahabad Bank":{"count":52},"Allied Bank":{"count":67},"Alpha Bank":{"count":329},"Andhra Bank":{"count":97},"Antonveneta":{"count":56},"Argenta":{"count":125},"Asia United Bank":{"count":57},"Askari Bank":{"count":71},"Associated Bank":{"count":55},"Axis Bank":{"count":198},"BAC":{"count":77},"BAWAG PSK":{"count":97},"BB&T":{"count":418},"BBBank":{"count":58},"BBK":{"count":122},"BBVA":{"count":1445},"BBVA Bancomer":{"count":157},"BBVA Compass":{"count":80},"BBVA Continental":{"count":74},"BBVA Francés":{"count":158},"BCA":{"count":135},"BCI":{"count":140},"BCP":{"count":226},"BCR":{"count":232},"BDO":{"count":538},"BGŻ BNP Paribas":{"count":74},"BMCE":{"count":53},"BMN":{"count":88},"BMO":{"count":339},"BMO Harris Bank":{"count":72},"BNA":{"count":70},"BNI":{"count":136},"BNL":{"count":159},"BNP Paribas":{"count":1165},"BNP Paribas Fortis":{"count":303},"BOC":{"count":95},"BPH":{"count":63},"BPI":{"count":579},"BPI Family Savings Bank":{"count":54},"BRD":{"count":276},"BRED":{"count":70},"BRI":{"count":209},"BW-Bank":{"count":95},"BZ WBK":{"count":156},"Banamex":{"count":356},"Banc Sabadell":{"count":175},"Banca Intesa":{"count":92},"Banca March":{"count":51},"Banca Popolare di Milano":{"count":99},"Banca Popolare di Novara":{"count":79},"Banca Popolare di Sondrio":{"count":105},"Banca Popolare di Verona":{"count":59},"Banca Popolare di Vicenza":{"count":119},"Banca Românească":{"count":61},"Banca Sella":{"count":56},"Banca Transilvania":{"count":167},"Banco Agrario":{"count":58},"Banco Azteca":{"count":119},"Banco BCI":{"count":74},"Banco Bradesco":{"count":226},"Banco Continental":{"count":64},"Banco Estado":{"count":153},"Banco Fassil":{"count":59},"Banco G&T Continental":{"count":84},"Banco General":{"count":53},"Banco Industrial":{"count":91},"Banco Internacional":{"count":62},"Banco Itaú":{"count":351},"Banco Nacional":{"count":143},"Banco Nación":{"count":149},"Banco Pastor":{"count":74},"Banco Pichincha":{"count":109},"Banco Popular":{"count":619},"Banco Provincia":{"count":138},"Banco Sabadell":{"count":189},"Banco Santander":{"count":112},"Banco Sol":{"count":74},"Banco de Bogotá":{"count":74},"Banco de Chile":{"count":175},"Banco de Costa Rica":{"count":123},"Banco de Desarrollo Banrural":{"count":85},"Banco de Occidente":{"count":67},"Banco de Venezuela":{"count":76},"Banco de la Nación":{"count":156},"Banco de la Nación Argentina":{"count":166},"Banco di Napoli":{"count":79},"Banco di Sardegna":{"count":79},"Banco do Brasil":{"count":1313},"Banco do Nordeste":{"count":56},"BancoEstado":{"count":121},"Bancolombia":{"count":170},"Bancomer":{"count":227},"Bancpost":{"count":77},"Banesco":{"count":209},"Bangkok Bank":{"count":69},"Bank Al Habib":{"count":52},"Bank Alfalah":{"count":63},"Bank Austria":{"count":123},"Bank BCA":{"count":71},"Bank BNI":{"count":67},"Bank BPH":{"count":56},"Bank BRI":{"count":196},"Bank Danamon":{"count":60},"Bank Mandiri":{"count":232},"Bank Mega":{"count":54},"Bank Spółdzielczy":{"count":395},"Bank Zachodni WBK":{"count":103},"Bank of Africa":{"count":59},"Bank of America":{"count":1787},"Bank of Baroda":{"count":122},"Bank of Ceylon":{"count":74},"Bank of China":{"count":152},"Bank of Commerce":{"count":69},"Bank of India":{"count":113},"Bank of Ireland":{"count":151},"Bank of Montreal":{"count":157},"Bank of New Zealand":{"count":63},"Bank of Scotland":{"count":122},"Bank of the West":{"count":173},"Bankia":{"count":613},"Bankinter":{"count":139},"Banner Bank":{"count":53},"Banorte":{"count":260},"Banque Atlantique":{"count":57},"Banque Nationale":{"count":137},"Banque Populaire":{"count":919},"Banrisul":{"count":101},"Banrural":{"count":84},"Barclays":{"count":1243},"Bcc":{"count":54},"Belfius":{"count":285},"Bendigo Bank":{"count":140},"Berliner Volksbank":{"count":73},"Bicentenario":{"count":173},"Bradesco":{"count":751},"Budapest Bank":{"count":56},"CBAO":{"count":53},"CEC Bank":{"count":121},"CGD":{"count":52},"CIB Bank":{"count":64},"CIBC":{"count":574},"CIC":{"count":742},"CIMB Bank":{"count":64},"CNEP":{"count":52},"Caisse Desjardins":{"count":69},"Caisse d'Épargne":{"count":1607},"Caixa":{"count":239},"Caixa Econômica Federal":{"count":573},"Caixa Geral de Depósitos":{"count":231},"CaixaBank":{"count":343},"Caja Círculo":{"count":68},"Caja Duero":{"count":90},"Caja España":{"count":74},"Caja Rural":{"count":216},"Caja Rural de Jaén":{"count":55},"CajaSur":{"count":73},"Cajamar":{"count":216},"Cajero Automatico Bancared":{"count":123},"Canara Bank":{"count":270},"Capital One":{"count":199},"Carige":{"count":57},"Cariparma":{"count":69},"Cassa di Risparmio del Veneto":{"count":102},"CatalunyaCaixa":{"count":107},"Central Bank of India":{"count":60},"Chase":{"count":1658},"China Bank":{"count":156},"China Bank Savings":{"count":54},"China Construction Bank":{"count":68},"Citibank":{"count":485},"Citizens Bank":{"count":248},"Clydesdale Bank":{"count":55},"Columbia Bank":{"count":79},"Comerica Bank":{"count":67},"Commerce Bank":{"count":61},"Commercial Bank":{"count":75},"Commercial Bank of Ceylon PLC":{"count":100},"Commerzbank":{"count":879},"Commonwealth Bank":{"count":376},"Corporation Bank":{"count":92},"Credem":{"count":77},"Credicoop":{"count":111},"Credit Agricole":{"count":104},"Credit Suisse":{"count":93},"Crelan":{"count":53},"Crédit Agricole":{"count":2544},"Crédit Mutuel":{"count":1129},"Crédit Mutuel de Bretagne":{"count":368},"Crédit du Nord":{"count":148},"Crédito Agrícola":{"count":87},"Cбербанк":{"count":74},"Danske Bank":{"count":157},"Davivienda":{"count":172},"De Venezuela":{"count":87},"Denizbank":{"count":58},"Desjardins":{"count":80},"Deutsche Bank":{"count":995},"Dubai Islamic Bank":{"count":71},"EastWest Bank":{"count":127},"Ecobank":{"count":197},"Erste Bank":{"count":200},"Eurobank":{"count":261},"Express Union":{"count":58},"FNB":{"count":143},"Federal Bank":{"count":88},"Fifth Third Bank":{"count":234},"Finansbank":{"count":68},"First Bank":{"count":91},"First Citizens Bank":{"count":88},"First National Bank":{"count":209},"Galicia":{"count":179},"Garanti":{"count":58},"Garanti Bankası":{"count":82},"Getin Bank":{"count":112},"Groupama":{"count":61},"HDFC Bank":{"count":219},"HNB":{"count":67},"HSBC":{"count":1748},"Halifax":{"count":367},"Halkbank":{"count":74},"Hamburger Sparkasse":{"count":159},"Handelsbanken":{"count":250},"Hong Leong Bank":{"count":51},"Hrvatska poštanska banka":{"count":54},"Huntington Bank":{"count":110},"HypoVereinsbank":{"count":408},"ICBC":{"count":158},"ICICI Bank":{"count":224},"IDBI Bank":{"count":73},"ING":{"count":654},"ING Bank Śląski":{"count":128},"IberCaja":{"count":209},"Indian Bank":{"count":98},"Indian Overseas Bank":{"count":108},"Interbank":{"count":131},"Intesa San Paolo":{"count":257},"Itaú":{"count":726},"K&H Bank":{"count":75},"KBC":{"count":273},"Kasa Stefczyka":{"count":65},"Key Bank":{"count":382},"Komerční banka":{"count":180},"Kreissparkasse":{"count":600},"Kreissparkasse Köln":{"count":69},"Kutxabank":{"count":68},"LCL":{"count":903},"La Banque Postale":{"count":124},"La Caixa":{"count":1144},"Laboral Kutxa":{"count":66},"Landbank":{"count":115},"Liberbank":{"count":164},"Lloyds Bank":{"count":612},"M&T Bank":{"count":184},"MCB":{"count":62},"MCB Bank":{"count":54},"MONETA Money Bank":{"count":92},"Macro":{"count":174},"Maybank":{"count":234},"Meezan Bank":{"count":63},"Mercantil":{"count":132},"Metro Bank":{"count":57},"Metrobank":{"count":434},"Millennium BCP":{"count":119},"Millennium Bank":{"count":386},"Monte dei Paschi di Siena":{"count":265},"Montepio":{"count":113},"NAB":{"count":205},"NSB":{"count":51},"NatWest":{"count":800},"National Bank":{"count":147},"Nationwide":{"count":337},"Nedbank":{"count":100},"Nordea":{"count":331},"Novo Banco":{"count":101},"OLB":{"count":57},"OTP":{"count":362},"Oberbank":{"count":103},"Occidental de Descuento":{"count":68},"Oldenburgische Landesbank":{"count":68},"One Network Bank":{"count":91},"Osuuspankki":{"count":89},"PBZ":{"count":65},"PKO":{"count":58},"PKO BP":{"count":561},"PNB":{"count":323},"PNC":{"count":52},"PNC Bank":{"count":639},"PSBank":{"count":108},"Patagonia":{"count":94},"Pekao SA":{"count":155},"Peoples Bank":{"count":254},"Philippine National Bank":{"count":69},"Piraeus Bank":{"count":96},"Popular":{"count":104},"Postbank":{"count":567},"Postbank Finanzcenter":{"count":65},"Provincial":{"count":135},"Public Bank":{"count":90},"Punjab National Bank":{"count":134},"RBC":{"count":487},"RBC Financial Group":{"count":59},"RBS":{"count":190},"RCBC":{"count":144},"RCBC Savings Bank":{"count":84},"Rabobank":{"count":557},"Raiffeisen Polbank":{"count":78},"Raiffeisenbank":{"count":2705},"Regions Bank":{"count":204},"Republic Bank":{"count":85},"Royal Bank":{"count":90},"Royal Bank of Canada":{"count":56},"Royal Bank of Scotland":{"count":129},"SEB":{"count":129},"SNS Bank":{"count":58},"Sabadell":{"count":97},"Sampath Bank":{"count":87},"Santander":{"count":3268},"Santander Consumer Bank":{"count":109},"Santander Río":{"count":239},"Santander Totta":{"count":201},"Sberbank":{"count":135},"Scotiabank":{"count":1144},"Security Bank":{"count":171},"Sicredi":{"count":94},"Slovenská sporiteľňa":{"count":165},"Société Générale":{"count":1136},"Sparda-Bank":{"count":277},"Sparkasse":{"count":4667},"Sparkasse Aachen":{"count":56},"Sparkasse KölnBonn":{"count":76},"Stadtsparkasse":{"count":68},"Stanbic Bank":{"count":63},"Standard Bank":{"count":165},"Standard Chartered":{"count":95},"Standard Chartered Bank":{"count":74},"State Bank of India":{"count":1013},"SunTrust":{"count":322},"Supervielle":{"count":72},"Swedbank":{"count":252},"Syndicate Bank":{"count":118},"TCF Bank":{"count":85},"TD Bank":{"count":425},"TD Canada Trust":{"count":675},"TEB":{"count":56},"TSB":{"count":259},"Takarékszövetkezet":{"count":120},"Targobank":{"count":279},"Tatra banka":{"count":70},"Türkiye İş Bankası":{"count":53},"UBS":{"count":169},"UCO Bank":{"count":51},"UCPB":{"count":122},"UOB":{"count":126},"US Bank":{"count":723},"Ulster Bank":{"count":100},"Umpqua Bank":{"count":103},"UniCredit Bank":{"count":548},"Unicaja Banco":{"count":182},"Unicredit Banca":{"count":496},"Union Bank":{"count":304},"United Bank":{"count":68},"VR-Bank":{"count":506},"Vakıfbank":{"count":85},"Veneto Banca":{"count":73},"Vijaya Bank":{"count":56},"Volks- und Raiffeisenbank":{"count":53},"Volksbank":{"count":2665},"Volksbank Mittelhessen":{"count":53},"Volksbank Raiffeisenbank":{"count":63},"VÚB":{"count":105},"Washington Federal":{"count":65},"Wells Fargo":{"count":1947},"Western Union":{"count":440},"Westpac":{"count":322},"Yorkshire Bank":{"count":95},"Yorkshire Building Society":{"count":69},"Zagrebačka banka":{"count":54},"Ziraat Bankası":{"count":172},"mBank":{"count":70},"ČSOB":{"count":211},"Česká spořitelna":{"count":243},"İş Bankası":{"count":112},"Εθνική Τράπεζα":{"count":103},"Πειραιώς":{"count":120},"Τράπεζα Πειραιώς":{"count":104},"Авангард":{"count":76},"Альфа-Банк":{"count":301},"Банк Москвы":{"count":176},"Банка ДСК":{"count":63},"Белагропромбанк":{"count":184},"Беларусбанк":{"count":570},"Белинвестбанк":{"count":78},"Бинбанк":{"count":114},"ВТБ":{"count":80},"ВТБ24":{"count":545},"Возрождение":{"count":81},"Газпромбанк":{"count":161},"Генбанк":{"count":83},"Казкоммерцбанк":{"count":74},"МДМ Банк":{"count":52},"Московский индустриальный банк":{"count":53},"Мособлбанк":{"count":54},"Народный банк":{"count":63},"ОТП Банк":{"count":54},"Открытие":{"count":92},"Ощадбанк":{"count":883},"ПУМБ":{"count":78},"Почта Банк":{"count":65},"ПриватБанк":{"count":1018},"Приватбанк":{"count":76},"Приднестровский Сбербанк":{"count":59},"Приорбанк":{"count":69},"Промсвязьбанк":{"count":133},"РНКБ":{"count":124},"Райффайзен":{"count":65},"Райффайзен Банк Аваль":{"count":125},"Райффайзенбанк":{"count":52},"Росбанк":{"count":218},"Россельхозбанк":{"count":374},"Русский стандарт":{"count":55},"Сбербанк":{"count":6921},"Совкомбанк":{"count":186},"УкрСиббанк":{"count":213},"Укрсоцбанк":{"count":57},"Уралсиб":{"count":130},"Хоум Кредит":{"count":53},"בנק הפועלים":{"count":112},"בנק לאומי":{"count":83},"بانک":{"count":219},"بانک آینده":{"count":58},"بانک اقتصاد نوین":{"count":78},"بانک انصار":{"count":99},"بانک تجارت":{"count":365},"بانک رفاه":{"count":138},"بانک رفاه کارگران":{"count":72},"بانک سپه":{"count":348},"بانک شهر":{"count":93},"بانک صادرات":{"count":492},"بانک قوامین":{"count":110},"بانک مسکن":{"count":263},"بانک ملت":{"count":428},"بانک ملی":{"count":561},"بانک ملی ایران":{"count":80},"بانک مهر اقتصاد":{"count":92},"بانک پارسیان":{"count":103},"بانک پاسارگاد":{"count":107},"بانک کشاورزی":{"count":277},"صادرات":{"count":85},"ملی":{"count":67},"پست بانک":{"count":71},"ธนาคารกรุงเทพ":{"count":121},"ธนาคารกรุงไทย":{"count":85},"ธนาคารกสิกรไทย":{"count":108},"ธนาคารออมสิน":{"count":71},"ธนาคารไทยพาณิชย์":{"count":95},"みずほ銀行":{"count":255},"りそな銀行":{"count":135},"三井住友銀行":{"count":204},"三菱東京UFJ銀行":{"count":235},"中国农业银行":{"count":198},"中国工商银行":{"count":181},"中国建设银行":{"count":158},"中国邮政储蓄银行":{"count":76},"中国银行":{"count":275},"交通银行":{"count":68},"京都中央信用金庫":{"count":53},"京都銀行":{"count":66},"农业银行":{"count":78},"北海道銀行":{"count":51},"合作金庫銀行":{"count":55},"土地銀行":{"count":54},"工商银行":{"count":160},"建设银行":{"count":89},"彰化銀行":{"count":53},"招商银行":{"count":94},"横浜銀行":{"count":92},"第一銀行":{"count":78},"華南銀行":{"count":52},"국민은행":{"count":199,"tags":{"name:en":"Gungmin Bank"}},"기업은행":{"count":53},"농협":{"count":148},"새마을금고":{"count":102},"신한은행":{"count":245,"tags":{"name:en":"Sinhan Bank"}},"우리은행":{"count":316,"tags":{"name:en":"Uri Bank"}},"하나은행":{"count":85}},"bar":{"Bar Centrale":{"count":141},"Bar Sport":{"count":90},"Beach Bar":{"count":80},"Pool Bar":{"count":54}},"bicycle_rental":{"Bicing":{"count":130},"Call a Bike":{"count":95},"Grid":{"count":51},"Mibici":{"count":116},"metropolradruhr":{"count":91}},"bureau_de_change":{"Abitab":{"count":55},"Change":{"count":51},"Travelex":{"count":75},"Western Union":{"count":189}},"cafe":{"85度C":{"count":128},"Bar Centrale":{"count":77},"Bar Kafe":{"count":253},"Barista":{"count":65},"Bistro":{"count":60},"Bonafide":{"count":63},"Cafe Coffee Day":{"count":239},"Cafe Nero":{"count":52},"Cafeteria":{"count":579},"Cafetería":{"count":61},"Caffè Nero":{"count":316},"Café Amazon":{"count":241},"Café Central":{"count":115},"Café de la Place":{"count":55},"Café des Sports":{"count":71},"Caribou Coffee":{"count":184},"Coffee Fellows":{"count":77},"Coffee House":{"count":71},"Coffee Island":{"count":51},"Coffee Time":{"count":133},"Costa":{"count":1403},"Country Style":{"count":58},"Dolce Vita":{"count":55},"Dunkin' Donuts":{"count":1662,"tags":{"cuisine":"donut"}},"Eiscafe Dolomiti":{"count":51},"Eiscafe Venezia":{"count":237},"Espresso House":{"count":122},"Havanna":{"count":81},"Internet Cafe":{"count":95},"Jamba Juice":{"count":86},"Kafe":{"count":55},"Krispy Kreme":{"count":63},"Le Pain Quotidien":{"count":59},"McCafé":{"count":72,"tags":{"amenity":"cafe","cuisine":"coffee_shop"}},"Peet's Coffee & Tea":{"count":82},"Pret A Manger":{"count":174},"Prime":{"count":51},"Second Cup":{"count":234},"Segafredo":{"count":103},"Starbucks":{"count":8463,"tags":{"cuisine":"coffee_shop"}},"Subway":{"count":114},"Tchibo":{"count":168},"The Coffee Bean & Tea Leaf":{"count":93},"The Coffee Club":{"count":81},"Tim Hortons":{"count":1945},"Traveler's Coffee":{"count":70},"Venezia":{"count":55},"Wayne's Coffee":{"count":52},"Берёзка":{"count":52},"Бистро":{"count":84},"Буфет":{"count":56},"Встреча":{"count":83},"Даблби":{"count":59},"Закусочная":{"count":101},"Кофе Хауз":{"count":119},"Кофейня":{"count":78},"Лакомка":{"count":62},"Летнее кафе":{"count":61},"Оазис":{"count":54},"Пельменная":{"count":63},"Пиццерия":{"count":60},"Рандеву":{"count":54},"Сказка":{"count":66},"Смак":{"count":62},"Старбакс":{"count":55},"Столовая":{"count":1181},"Теремок":{"count":64},"Уют":{"count":115},"Хуторок":{"count":59},"Шашлычная":{"count":153},"Шоколад":{"count":54},"Шоколадница":{"count":252},"ארומה":{"count":64},"مقهى":{"count":136},"คาเฟ่ อเมซอน":{"count":59},"エクセルシオール カフェ":{"count":61},"カフェ・ド・クリエ":{"count":80,"tags":{"name:en":"Cafe de CRIE"}},"カフェ・ベローチェ":{"count":105},"コメダ珈琲店":{"count":179},"サンマルクカフェ":{"count":156},"スターバックス":{"count":558,"tags":{"name:en":"Starbucks"}},"タリーズコーヒー":{"count":243},"ドトールコーヒーショップ":{"count":489},"星巴克":{"count":146},"스타벅스":{"count":52}},"car_rental":{"Alamo":{"count":57},"Avis":{"count":604},"Budget":{"count":218},"Enterprise":{"count":594},"Enterprise Rent-a-Car":{"count":51},"Europcar":{"count":611},"Hertz":{"count":654},"Localiza":{"count":59},"Sixt":{"count":323},"Thrifty":{"count":81},"U-Haul":{"count":94},"オリックスレンタカー":{"count":54},"トヨタレンタカー":{"count":57},"トヨタレンタリース":{"count":63},"ニッポンレンタカー":{"count":113}},"car_wash":{"Aral":{"count":88},"Autolavaggio":{"count":52},"BP":{"count":63},"Esso":{"count":55},"H-E-B Car Wash":{"count":71},"Intermarché":{"count":60},"Lavage Auto":{"count":60},"Lavazh":{"count":52},"Myjnia":{"count":54},"Myjnia bezdotykowa":{"count":93},"Myjnia samochodowa":{"count":66},"Shell":{"count":162},"Spălătorie Auto":{"count":69},"Spălătorie auto":{"count":52},"Автомийка":{"count":63}},"cinema":{"Cinema City":{"count":61},"Cinemark":{"count":87},"Cinemex":{"count":70},"Cinepolis":{"count":59},"Cineworld":{"count":64},"Odeon":{"count":81}},"clinic":{"ФАП":{"count":162}},"dentist":{"Aspen Dental":{"count":73},"Family Dentistry":{"count":51},"Vitaldent":{"count":54},"Стоматолог":{"count":72},"Стоматологія":{"count":66}},"doctors":{"Háziorvosi rendelő":{"count":54},"Инвитро":{"count":115},"ФАП":{"count":147}},"driving_school":{"Автодром":{"count":55}},"fast_food":{"A&W":{"count":614},"Ali Baba":{"count":101},"Angel's Burger":{"count":66},"Antalya":{"count":53},"Arby's":{"count":1432},"Asia Bistro":{"count":53},"Asia Wok":{"count":53},"Baskin-Robbins":{"count":262,"tags":{"amenity":"ice_cream"}},"Bistro":{"count":80},"Bob's":{"count":83},"Bojangles":{"count":89},"Booster Juice":{"count":76},"Boston Market":{"count":107},"Braum's":{"count":58},"Burger King":{"count":6601,"tags":{"cuisine":"burger"}},"Burger Machine":{"count":55},"Büfé":{"count":72},"Captain D's":{"count":56},"Carl's Jr.":{"count":593,"tags":{"cuisine":"burger"}},"Checkers":{"count":102},"Chick-fil-A":{"count":906,"tags":{"cuisine":"chicken"}},"Chicken Express":{"count":67},"Chipotle":{"count":688,"tags":{"cuisine":"mexican"}},"Chowking":{"count":250},"Church's Chicken":{"count":249},"CoCo壱番屋":{"count":218},"Cold Stone Creamery":{"count":72},"Cook Out":{"count":81},"Culver's":{"count":541},"DQ":{"count":66},"Dairy Queen":{"count":1485},"Del Taco":{"count":244},"Ditsch":{"count":55},"Domino's Pizza":{"count":2577,"tags":{"cuisine":"pizza"}},"Dunkin' Donuts":{"count":747,"tags":{"cuisine":"donut"}},"El Pollo Loco":{"count":132},"Everest":{"count":59},"Extreme Pita":{"count":58},"Fazoli's":{"count":53},"Firehouse Subs":{"count":147},"Fish & Chips":{"count":185},"Fish and Chips":{"count":55},"Five Guys":{"count":457},"Greenwich":{"count":83},"Habib's":{"count":87},"Hallo Pizza":{"count":98},"Hardee's":{"count":634,"tags":{"cuisine":"burger"}},"Harvey's":{"count":158},"Hesburger":{"count":164},"Hungry Jacks":{"count":261,"tags":{"cuisine":"burger"}},"In-N-Out Burger":{"count":211},"Istanbul":{"count":96},"Istanbul Kebab":{"count":59},"Jack in the Box":{"count":951,"tags":{"cuisine":"burger"}},"Jamba Juice":{"count":148},"Jersey Mike's Subs":{"count":88},"Jimmy John's":{"count":519,"tags":{"cuisine":"sandwich"}},"Jollibee":{"count":740},"KFC":{"count":6003,"tags":{"cuisine":"chicken"}},"KFC/Taco Bell":{"count":70},"Kebab House":{"count":74},"Kebabai":{"count":64},"Kochlöffel":{"count":78},"Kotipizza":{"count":89},"Krispy Kreme":{"count":63},"Krystal":{"count":53},"Little Caesars":{"count":567},"Little Caesars Pizza":{"count":82},"Long John Silver's":{"count":200},"Lotteria":{"count":67},"Max":{"count":54},"McDonald's":{"count":18327,"tags":{"cuisine":"burger"}},"Minute Burger":{"count":53},"Mr. Sub":{"count":153},"New York Pizza":{"count":65},"Nordsee":{"count":198},"Panda Express":{"count":593,"tags":{"cuisine":"chinese"}},"Panera Bread":{"count":120},"Papa John's":{"count":820,"tags":{"cuisine":"pizza"}},"Papa Murphy's":{"count":100},"Pinulito":{"count":58},"Pita Pit":{"count":150},"Pizza Hut":{"count":1503,"tags":{"cuisine":"pizza"}},"Pizza Hut Delivery":{"count":70},"Pizza King":{"count":56},"Pizza Nova":{"count":90},"Pizza Pizza":{"count":411},"Pollo Campero":{"count":134},"Pollo Granjero":{"count":66},"Popeye's":{"count":521,"tags":{"cuisine":"chicken"}},"Popeyes Louisiana Kitchen":{"count":51},"Qdoba":{"count":91},"Quick":{"count":434},"Quiznos":{"count":401},"Rally's":{"count":68},"Red Rooster":{"count":192},"Sbarro":{"count":65},"Schlotzsky's Deli":{"count":348},"Sibylla":{"count":74},"Sonic":{"count":1166,"tags":{"cuisine":"burger"}},"Starbucks":{"count":60,"tags":{"cuisine":"coffee_shop"}},"Steers":{"count":190},"Subway":{"count":11431},"Taco Bell":{"count":2947,"tags":{"cuisine":"mexican"}},"Taco Bueno":{"count":59},"Taco Cabana":{"count":57},"Taco Del Mar":{"count":57},"Taco John's":{"count":141},"Taco Time":{"count":171},"Telepizza":{"count":323},"Thai Express":{"count":63},"The Pizza Company":{"count":62},"Waffle House":{"count":86},"Wendy's":{"count":3036,"tags":{"cuisine":"burger"}},"Whataburger":{"count":815},"White Castle":{"count":149},"Wienerschnitzel":{"count":61},"Wimpy":{"count":168},"Zaxby's":{"count":185},"Γρηγόρης":{"count":59},"Бистро":{"count":61},"Бургер Кинг":{"count":181},"Крошка Картошка":{"count":77},"Макдоналдс":{"count":469,"tags":{"name:en":"McDonald's"}},"Робин Сдобин":{"count":131},"Русский Аппетит":{"count":129},"Сабвэй":{"count":73},"Стардог!s":{"count":66},"Теремок":{"count":155},"Шаверма":{"count":93},"Шаурма":{"count":265},"かっぱ寿司":{"count":84},"かつや":{"count":58},"くら寿司":{"count":99},"すき家":{"count":571,"tags":{"name:en":"SUKIYA"}},"なか卯":{"count":180},"ほっかほっか亭":{"count":57},"ほっともっと":{"count":168},"オリジン弁当":{"count":93},"ケンタッキーフライドチキン":{"count":334,"tags":{"cuisine":"chicken","name:en":"KFC"}},"サブウェイ":{"count":74},"スシロー":{"count":94},"マクドナルド":{"count":1261,"tags":{"cuisine":"burger","name:en":"McDonald's"}},"ミスタードーナツ":{"count":188},"モスバーガー":{"count":507,"tags":{"name:en":"MOS BURGER"}},"ロッテリア":{"count":97},"丸亀製麺":{"count":57},"吉野家":{"count":461},"幸楽苑":{"count":80},"摩斯漢堡":{"count":86},"松屋":{"count":574,"tags":{"name:en":"Matsuya"}},"肯德基":{"count":197},"麥當勞":{"count":224},"麦当劳":{"count":97},"롯데리아":{"count":83}},"fuel":{"76":{"count":603},"1-2-3":{"count":75},"7-Eleven":{"count":1013},"ABC":{"count":83},"ADNOC":{"count":76},"ANP":{"count":202},"ARAL":{"count":68},"Aegean":{"count":56},"Afriquia":{"count":134},"Agip":{"count":2348},"Agrola":{"count":99},"Alon":{"count":54},"Alpet":{"count":61},"Api":{"count":234},"Aral":{"count":1708},"Arco":{"count":585},"Asda":{"count":51},"Auchan":{"count":84},"Avanti":{"count":112},"Avia":{"count":1061},"BEBECO":{"count":77},"BFT":{"count":102},"BHPetrol":{"count":60},"BP":{"count":4069},"BR":{"count":165},"Bangchak":{"count":106},"Benzina":{"count":167},"Bharat Petroleum":{"count":230},"Bliska":{"count":141},"CAMPSA":{"count":420},"CARREFOUR":{"count":61},"CEPSA":{"count":892},"CNG":{"count":373},"Caltex":{"count":1574},"Campsa":{"count":64},"Canadian Tire":{"count":97},"Carrefour":{"count":372},"Casey's General Store":{"count":385},"Cenex":{"count":222},"Cepsa":{"count":305},"Ceypetco":{"count":70},"Chevron":{"count":1781},"Circle K":{"count":730},"Citgo":{"count":692},"Clark":{"count":56},"Co-op":{"count":52},"Coles Express":{"count":305},"Conoco":{"count":398},"Coop":{"count":71},"Copec":{"count":566},"Copetrol":{"count":119},"Cosmo":{"count":68},"Costco":{"count":82},"Costco Gas":{"count":62},"Costco Gasoline":{"count":59},"Couche-Tard":{"count":54},"Crodux":{"count":51},"Cumberland Farms":{"count":93},"Delta":{"count":157},"Diamond Shamrock":{"count":51},"Drummed Fuel":{"count":178},"E. Leclerc":{"count":136},"EKO":{"count":224},"ENEOS":{"count":1600},"ENI":{"count":92},"ERG":{"count":71},"Elan":{"count":208},"Eneos":{"count":130},"Engen":{"count":383},"Eni":{"count":681},"Erg":{"count":469},"Esso":{"count":4742},"Esso Express":{"count":176},"EuroOil":{"count":52},"Exxon":{"count":1064},"F24":{"count":67},"Firezone":{"count":66},"Flying V":{"count":175},"GALP":{"count":788},"Gazprom":{"count":68},"GetGo":{"count":54},"Goil":{"count":78},"Gulf":{"count":416},"H-E-B Fuel":{"count":51},"H-E-B Gas":{"count":155},"HEM":{"count":276},"HP":{"count":163},"HP Petrol Pump":{"count":53},"Helios":{"count":63},"Hess":{"count":195},"Hindustan Petroleum":{"count":82},"Holiday":{"count":156},"Husky":{"count":244},"IES":{"count":57},"IP":{"count":993},"Independent Fuel Station":{"count":52},"Indian Oil":{"count":416},"Indipend.":{"count":129},"Ingo":{"count":62},"Intermarché":{"count":556},"Intermarché Super":{"count":102},"Ipiranga":{"count":173},"Irving":{"count":194},"JA-SS":{"count":74},"JOMO":{"count":51},"Jet":{"count":707},"Jetti":{"count":61},"Kangaroo":{"count":115},"Kobil":{"count":87},"Kroger":{"count":59},"Kroger Fuel":{"count":68},"Kum & Go":{"count":136},"Kwik Trip":{"count":210},"LPG":{"count":349},"LPG Station":{"count":51},"LUKOIL":{"count":61},"Liberty":{"count":93},"Lotos":{"count":284},"Lotos Optima":{"count":71},"Love's":{"count":52},"Lukoil":{"count":908},"MEROIL":{"count":70},"MOL":{"count":436},"MRS":{"count":65},"Marathon":{"count":694},"Maverik":{"count":66},"Maxol":{"count":57},"Metano":{"count":248},"Migrol":{"count":71},"Minipump":{"count":140},"Mobil":{"count":1387},"Mobile":{"count":62},"Mol":{"count":64},"Morrisons":{"count":128},"Moya":{"count":62},"Murphy USA":{"count":190},"NP":{"count":63},"Neste":{"count":166},"OIL!":{"count":110},"OK":{"count":269},"OKQ8":{"count":218},"OMV":{"count":936},"Oilibya":{"count":127},"Opet":{"count":117},"Orlen":{"count":1185},"PETRONOR":{"count":182},"PSO":{"count":121},"PSO Petrol Pump":{"count":56},"PT":{"count":306},"PTT":{"count":423},"PV Oil":{"count":100},"Pacific Pride":{"count":54},"Pecsa":{"count":130},"Pemex":{"count":2023},"Pertamina":{"count":324},"Petro":{"count":54},"Petro-Canada":{"count":893},"Petrobras":{"count":487},"Petrochina":{"count":116},"Petroecuador":{"count":64},"Petrol Ofisi":{"count":237},"Petrolimex":{"count":325},"Petrom":{"count":381},"Petron":{"count":1485},"Petronas":{"count":387},"Petroperu":{"count":110},"Phillips 66":{"count":424},"Phoenix":{"count":210},"Pilot":{"count":69},"Pioneer":{"count":104},"Posto":{"count":52},"Posto Atem":{"count":68},"Posto BR":{"count":222},"Posto Ipiranga":{"count":177},"Posto Shell":{"count":104},"Primax":{"count":288},"Prio":{"count":52},"Puma":{"count":442},"Q1":{"count":53},"Q8":{"count":1467},"Q8 Easy":{"count":66},"QuikTrip":{"count":251},"REPSOL":{"count":1380},"RaceTrac":{"count":80},"Raiffeisenbank":{"count":130},"Repsol":{"count":1099},"Rompetrol":{"count":234},"Royal Farms":{"count":79},"Rubis":{"count":108},"SB Tank":{"count":62},"SPBU":{"count":203},"Safeway":{"count":74},"Sainsbury's":{"count":75},"Sam's Club":{"count":57},"Sasol":{"count":90},"Sea Oil":{"count":142},"Sheetz":{"count":304},"Shell":{"count":12317},"Shell Express":{"count":135},"Sinclair":{"count":201},"Sinopec":{"count":106},"Sinopec Fuel":{"count":116},"Slovnaft":{"count":259},"Socar":{"count":86},"Sokimex":{"count":85},"Speedway":{"count":556},"St1":{"count":141},"Star":{"count":419},"Star Oil":{"count":100},"Station Service E. Leclerc":{"count":423},"Statoil":{"count":495},"Stewart's":{"count":72},"Sunoco":{"count":853},"Super U":{"count":174},"Tamoil":{"count":959},"Tango":{"count":146},"Teboil":{"count":100},"Tela":{"count":191},"Terpel":{"count":367},"Tesco":{"count":218},"Texaco":{"count":1167},"Tinq":{"count":219},"Topaz":{"count":111},"Total":{"count":3591},"Total Access":{"count":226},"Total Erg":{"count":59},"TotalErg":{"count":267},"Turkey Hill":{"count":80},"Turmöl":{"count":80},"Ultramar":{"count":372},"United":{"count":197},"Uno":{"count":134},"Uno-X":{"count":69},"Valero":{"count":778},"Vito":{"count":91},"WOG":{"count":350},"Wawa":{"count":173},"Westfalen":{"count":94},"Woolworths Petrol":{"count":187},"Z":{"count":98},"bft":{"count":202},"eni":{"count":71},"ΕΚΟ":{"count":58},"АГЗС":{"count":1020},"АЗС":{"count":86},"Авіас":{"count":116},"БРСМ-Нафта":{"count":64},"Башнефть":{"count":272},"Белоруснефть":{"count":71},"Газовая заправка":{"count":57},"Газпромнефть":{"count":1242},"Гелиос":{"count":61},"ЕКА":{"count":78},"Заправка":{"count":63},"КазМунайГаз":{"count":150},"Лукойл":{"count":2327},"Макпетрол":{"count":108},"НК Альянс":{"count":105},"Нефтьмагистраль":{"count":66},"ОККО":{"count":316},"ОМВ":{"count":55},"Октан":{"count":53},"ПТК":{"count":104},"Петрол":{"count":124},"Пропан":{"count":83},"Роснефть":{"count":957},"Сибнефть":{"count":51},"Сургутнефтегаз":{"count":95},"ТНК":{"count":588},"Татнефтепродукт":{"count":58},"Татнефть":{"count":331},"Укрнафта":{"count":228},"דור אלון":{"count":126},"דלק":{"count":160},"סונול":{"count":159},"פז":{"count":209},"محطة وقود":{"count":221},"محطه وقود":{"count":98},"پمپ بنزین":{"count":559},"پمپ گاز":{"count":152},"บางจาก":{"count":214},"ป.ต.ท.":{"count":414},"เชลล์":{"count":90},"เอสโซ่":{"count":82},"エッソ":{"count":70},"エネオス":{"count":301},"コスモ石油":{"count":415},"ゼネラル":{"count":75},"中国石化":{"count":104},"中国石化 Sinopec":{"count":61},"中国石油":{"count":82},"中油":{"count":64},"出光":{"count":620,"tags":{"name:en":"IDEMITSU"}},"加油站":{"count":60},"台灣中油":{"count":257},"昭和シェル":{"count":274}},"hospital":{"Cruz Roja":{"count":93},"IMSS":{"count":64},"Инфекционное отделение":{"count":91},"Кожно-венерологический диспансер":{"count":57},"Районная больница":{"count":88},"Роддом":{"count":133},"Родильный дом":{"count":75},"Скорая помощь":{"count":75},"ФАП":{"count":108},"ЦРБ":{"count":122},"Центральная районная больница":{"count":144},"โรงพยาบาลส่งเสริมสุขภาพตำบล":{"count":69}},"ice_cream":{"Baskin-Robbins":{"count":69,"tags":{"amenity":"ice_cream"}},"Cold Stone Creamery":{"count":66},"Grido":{"count":163}},"kindergarten":{"Amado Nervo":{"count":64},"Anganwadi":{"count":85},"Arche Noah":{"count":67},"Benito Juarez":{"count":89},"CONAFE Preescolar":{"count":90},"Cuauhtemoc":{"count":54},"Cursos Comunitarios":{"count":74},"Educacion Inicial de CONAFE No Escolarizado":{"count":184},"Emiliano Zapata":{"count":60},"Estefania Casta�eda":{"count":53},"Evangelischer Kindergarten":{"count":320},"Federico Froebel":{"count":88},"Gabriela Mistral":{"count":129},"Jean Piaget":{"count":82},"Jose Vasconcelos":{"count":71},"Juan Escutia":{"count":82},"Katholischer Kindergarten":{"count":99},"Kindergarten Regenbogen":{"count":62},"Kindergarten St. Josef":{"count":55},"Kindergarten St. Martin":{"count":55},"Maria Montessori":{"count":93},"Miguel Hidalgo Y Costilla":{"count":57},"Ni�os Heroes":{"count":68},"PAUD":{"count":82},"Pusteblume":{"count":54},"Rosaura Zapata":{"count":68},"Sor Juana Ines De La Cruz":{"count":76},"Spatzennest":{"count":54},"Städtischer Kindergarten":{"count":103},"Villa Kunterbunt":{"count":88},"Waldkindergarten":{"count":111},"Waldorfkindergarten":{"count":71},"Óvoda":{"count":72},"Детсад":{"count":65},"Детский сад \"Солнышко\"":{"count":83},"Детский сад № 1":{"count":54},"Детский сад №1":{"count":150},"Детский сад №10":{"count":77},"Детский сад №11":{"count":81},"Детский сад №12":{"count":57},"Детский сад №13":{"count":57},"Детский сад №14":{"count":76},"Детский сад №15":{"count":72},"Детский сад №16":{"count":58},"Детский сад №17":{"count":67},"Детский сад №18":{"count":77},"Детский сад №19":{"count":62},"Детский сад №2":{"count":155},"Детский сад №22":{"count":60},"Детский сад №24":{"count":53},"Детский сад №25":{"count":56},"Детский сад №27":{"count":54},"Детский сад №29":{"count":57},"Детский сад №3":{"count":129},"Детский сад №33":{"count":55},"Детский сад №4":{"count":86},"Детский сад №5":{"count":106},"Детский сад №6":{"count":93},"Детский сад №7":{"count":98},"Детский сад №8":{"count":80},"Детский сад №9":{"count":80},"Дитячий садок":{"count":58},"Сказка":{"count":52},"Солнышко":{"count":99},"Теремок":{"count":59},"საბავშვო ბაღი":{"count":69},"中央保育所":{"count":56}},"library":{"Biblioteca Comunale":{"count":212},"Biblioteca comunale":{"count":187},"Biblioteka Publiczna":{"count":78},"Bibliothèque Municipale":{"count":299},"Bibliothèque municipale":{"count":247},"Bücherei":{"count":113},"Central Library":{"count":65},"Gemeindebücherei":{"count":150},"Gminna Biblioteka Publiczna":{"count":71},"Miejska Biblioteka Publiczna":{"count":66},"Médiathèque":{"count":287},"Městská knihovna":{"count":60},"Public Library":{"count":91},"Stadtbibliothek":{"count":232},"Stadtbücherei":{"count":289},"Городская библиотека":{"count":69},"Детская библиотека":{"count":260},"Центральная библиотека":{"count":83},"Центральная городская библиотека":{"count":61},"图书馆":{"count":65}},"pharmacy":{"36.6":{"count":57},"Adler-Apotheke":{"count":375},"Alte Apotheke":{"count":99},"Apollo Pharmacy":{"count":87},"Apotek":{"count":62},"Apotek Hjärtat":{"count":51},"Apotheke am Markt":{"count":83},"Bahnhof Apotheke":{"count":51},"Bahnhof-Apotheke":{"count":90},"Bartell Drugs":{"count":53},"Benavides":{"count":83},"Benu":{"count":61},"Boots":{"count":1348},"Botica":{"count":118},"Brunnen-Apotheke":{"count":77},"Burg-Apotheke":{"count":76},"Bären-Apotheke":{"count":111},"CVS":{"count":3228},"Camelia":{"count":54},"Catena":{"count":112},"Chemist Warehouse":{"count":82},"Clicks":{"count":123},"Cruz Azul":{"count":97},"Cruz Verde":{"count":223},"Dbam o Zdrowie":{"count":68},"Dr. Max":{"count":324},"Droga Raia":{"count":152},"Drogaria São Paulo":{"count":87},"Drogasil":{"count":157},"Duane Reade":{"count":91},"Eczane":{"count":88},"Engel-Apotheke":{"count":143},"Eurovaistinė":{"count":89},"Familiprix":{"count":70},"Farmacenter":{"count":65},"Farmacia Centrale":{"count":61},"Farmacia Comunale":{"count":196},"Farmacia Guadalajara":{"count":146},"Farmacia del Ahorro":{"count":65},"Farmacias Ahumada":{"count":182},"Farmacias Cruz Azul":{"count":134},"Farmacias Cruz Verde":{"count":162},"Farmacias Económicas":{"count":63},"Farmacias Guadalajara":{"count":107},"Farmacias SalcoBrand":{"count":140},"Farmacias Sana Sana":{"count":111},"Farmacias Similares":{"count":137},"Farmacias del Ahorro":{"count":187},"Farmacity":{"count":191},"Farmahorro":{"count":53},"Farmatodo":{"count":165},"Felicia":{"count":56},"Fybeca":{"count":52},"Generika Drugstore":{"count":52},"Gintarinė vaistinė":{"count":121},"Guardian":{"count":71},"Gyógyszertár":{"count":59},"H-E-B Pharmacy":{"count":239},"Hirsch-Apotheke":{"count":180},"Hubertus Apotheke":{"count":120},"Inkafarma":{"count":234},"Jean Coutu":{"count":132},"Kinney Drugs":{"count":74},"Kur-Apotheke":{"count":52},"Linden-Apotheke":{"count":224},"Ljekarna":{"count":77},"Lloyds Pharmacy":{"count":539},"Lékárna":{"count":52},"Löwen-Apotheke":{"count":397},"Marien-Apotheke":{"count":370},"Markt-Apotheke":{"count":207},"Mercury Drug":{"count":584},"Mifarma":{"count":195},"Mēness aptieka":{"count":64},"Neue Apotheke":{"count":129},"Pague Menos":{"count":74},"Panvel":{"count":77},"Park-Apotheke":{"count":54},"Pharmacie Centrale":{"count":218},"Pharmacie Principale":{"count":62},"Pharmacie de l'Hôtel de Ville":{"count":52},"Pharmacie de la Gare":{"count":114},"Pharmacie de la Mairie":{"count":71},"Pharmacie de la Poste":{"count":68},"Pharmacie du Centre":{"count":154},"Pharmacie du Marché":{"count":110},"Pharmacie du Parc":{"count":60},"Pharmaprix":{"count":99},"Pharmasave":{"count":129},"Punkt Apteczny":{"count":53},"Rathaus-Apotheke":{"count":181},"Rats-Apotheke":{"count":126},"Rexall":{"count":109},"Rite Aid":{"count":1481},"Rose Pharmacy":{"count":99},"Rosen-Apotheke":{"count":205},"Rowlands Pharmacy":{"count":127},"SalcoBrand":{"count":112},"Sana Sana":{"count":95},"Schloss-Apotheke":{"count":62},"Sensiblu":{"count":115},"Shoppers Drug Mart":{"count":713},"Sonnen-Apotheke":{"count":372},"South Star Drug":{"count":69},"Stadt-Apotheke":{"count":397},"Stern-Apotheke":{"count":83},"Superdrug":{"count":177},"São João":{"count":54},"The Generics Pharmacy":{"count":211},"Uniprix":{"count":63},"Walgreens":{"count":3314},"Walgreens Pharmacy":{"count":76},"Walmart Pharmacy":{"count":99},"Watsons":{"count":110},"Well Pharmacy":{"count":61},"centro naturista":{"count":123},"А5":{"count":94},"Айболит":{"count":88},"Аптека 36,6":{"count":285},"Аптека низких цен":{"count":65},"Аптека низьких цін":{"count":88},"Аптека от склада":{"count":83},"Аптека №1":{"count":92},"Аптечный пункт":{"count":285},"Арніка":{"count":124},"Бережная аптека":{"count":67},"Будь здоров":{"count":63},"Вита":{"count":140},"Горздрав":{"count":395},"Живика":{"count":105},"Здоровье":{"count":87},"Имплозия":{"count":84},"Классика":{"count":102},"Ладушка":{"count":53},"Мед-сервіс":{"count":59},"Мелодия здоровья":{"count":60},"Невис":{"count":151},"Норма":{"count":89},"Озерки":{"count":54},"Панацея":{"count":68},"Первая помощь":{"count":132},"Планета здоровья":{"count":140},"Радуга":{"count":139},"Ригла":{"count":215},"Семейная":{"count":52},"Социальная аптека":{"count":62},"Столички":{"count":83},"Фармакопейка":{"count":85},"Фармакор":{"count":106},"Фармация":{"count":187},"Фармленд":{"count":108},"Центральная аптека":{"count":57},"סופר-פארם":{"count":93},"داروخانه":{"count":264},"داروخانه شبانه روزی":{"count":54},"صيدلية":{"count":148},"くすりの福太郎":{"count":51},"さくら薬局":{"count":52},"ウエルシア":{"count":84},"カワチ薬品":{"count":52},"クリエイト":{"count":53},"サンドラッグ":{"count":130},"スギ薬局":{"count":134},"セイジョー":{"count":58},"ツルハドラッグ":{"count":185},"ドラッグてらしま (Drug Terashima)":{"count":58},"マツモトキヨシ":{"count":221},"丁丁藥局":{"count":75}},"pub":{"Black Bull":{"count":55},"Commercial Hotel":{"count":62},"Cross Keys":{"count":64},"Irish Pub":{"count":107},"Kings Arms":{"count":81},"Kings Head":{"count":65},"New Inn":{"count":100},"Prince of Wales":{"count":89},"Queens Head":{"count":55},"Red Lion":{"count":201},"Rose & Crown":{"count":63},"Rose and Crown":{"count":82},"Royal Hotel":{"count":64},"Royal Oak":{"count":172},"The Albion":{"count":51},"The Anchor":{"count":68},"The Angel":{"count":55},"The Beehive":{"count":52},"The Bell":{"count":128},"The Bell Inn":{"count":58},"The Black Horse":{"count":100},"The Bull":{"count":82},"The Castle":{"count":63},"The Chequers":{"count":74},"The Cricketers":{"count":56},"The Cross Keys":{"count":58},"The Crown":{"count":252},"The Crown Inn":{"count":88},"The Fox":{"count":76},"The George":{"count":119},"The Green Man":{"count":59},"The Greyhound":{"count":99},"The Kings Arms":{"count":65},"The Kings Head":{"count":68},"The New Inn":{"count":126},"The Plough":{"count":182},"The Plough Inn":{"count":57},"The Queens Head":{"count":61},"The Railway":{"count":112},"The Red Lion":{"count":271},"The Rising Sun":{"count":74},"The Royal Oak":{"count":223},"The Ship":{"count":92},"The Ship Inn":{"count":98},"The Star":{"count":72},"The Star Inn":{"count":53},"The Sun Inn":{"count":51},"The Swan":{"count":155},"The Swan Inn":{"count":59},"The Victoria":{"count":72},"The Wheatsheaf":{"count":126},"The White Hart":{"count":247},"The White Horse":{"count":234},"The White Lion":{"count":75},"The White Swan":{"count":55},"魚民":{"count":119},"鳥貴族":{"count":57}},"restaurant":{"Adler":{"count":228},"Adria":{"count":60},"Adyar Ananda Bhavan":{"count":60},"Akropolis":{"count":212},"Ali Baba":{"count":59},"Alte Post":{"count":68},"Applebee's":{"count":977},"Asia":{"count":78},"Athen":{"count":75},"Athos":{"count":61},"Autogrill":{"count":60},"Bahnhof":{"count":56},"Bella Italia":{"count":194},"Bella Napoli":{"count":88},"Big Boy":{"count":58},"Bistro":{"count":64},"Bob Evans":{"count":269},"Bonefish Grill":{"count":73},"Boston Market":{"count":91},"Boston Pizza":{"count":278},"Buffalo Grill":{"count":282},"Buffalo Wild Wings":{"count":454},"Bären":{"count":75},"Cafeteria":{"count":65},"California Pizza Kitchen":{"count":116},"Campanile":{"count":55},"Canteen":{"count":91},"Capri":{"count":56},"Captain D's":{"count":54},"Carluccio's":{"count":57},"Carpe Diem":{"count":60},"Carrabba's Italian Grill":{"count":62},"Casa Mia":{"count":64},"Casablanca":{"count":61},"Cheesecake Factory":{"count":52},"Chifa":{"count":86},"Chili's":{"count":698},"China Buffet":{"count":54},"China Garden":{"count":114},"China House":{"count":72},"China Town":{"count":117},"China Wok":{"count":100},"Chiquito":{"count":55},"Chuck E. Cheese's":{"count":54},"Cici's Pizza":{"count":51},"CoCo壱番屋":{"count":77},"Cold Stone Creamery":{"count":67},"Comedor":{"count":60},"Comida China":{"count":52},"Courtepaille":{"count":170},"Cracker Barrel":{"count":392},"Da Grasso":{"count":63},"Da Vinci":{"count":88},"Delphi":{"count":105},"Denny's":{"count":850},"Deutsches Haus":{"count":93},"Dionysos":{"count":75},"Dolce Vita":{"count":121},"Dorfkrug":{"count":60},"Dunkin' Donuts":{"count":94,"tags":{"cuisine":"donut"}},"East Side Mario's":{"count":53},"El Greco":{"count":112},"El Paso":{"count":60},"El Rancho":{"count":82},"Europa":{"count":61},"Famous Dave's":{"count":62},"Firehouse Subs":{"count":85},"Five Guys":{"count":91},"Flunch":{"count":179},"Frankie & Benny's":{"count":151},"Friendly's":{"count":113},"Gasthaus Krone":{"count":93},"Gasthaus zur Linde":{"count":59},"Gasthof zur Post":{"count":109},"Golden Corral":{"count":209},"Golden Dragon":{"count":62},"Great Wall":{"count":54},"Grüner Baum":{"count":122},"Gusto":{"count":74},"Hard Rock Cafe":{"count":96},"Hardee's":{"count":56,"tags":{"cuisine":"burger"}},"Harvester":{"count":75},"Hellas":{"count":66},"Hippopotamus":{"count":115},"Hirsch":{"count":83},"Hirschen":{"count":86},"Hong Kong":{"count":126},"Hooters":{"count":190},"IHOP":{"count":758},"IL Патио":{"count":51},"Jason's Deli":{"count":73},"Jimmy John's":{"count":150,"tags":{"cuisine":"sandwich"}},"Joe's Crab Shack":{"count":70},"Jägerhof":{"count":54},"Kantine":{"count":104},"Kelsey's":{"count":66},"Kirchenwirt":{"count":94},"Kreta":{"count":70},"Kreuz":{"count":85},"Krone":{"count":179},"Kudu":{"count":172},"L'Escale":{"count":66},"L'Osteria":{"count":80},"La Bodega":{"count":55},"La Boucherie":{"count":80},"La Cantina":{"count":105},"La Casa":{"count":66},"La Casona":{"count":62},"La Dolce Vita":{"count":129},"La Fontana":{"count":62},"La Gondola":{"count":60},"La Hacienda":{"count":54},"La Pataterie":{"count":116},"La Pergola":{"count":87},"La Perla":{"count":85},"La Piazza":{"count":123},"La Piazzetta":{"count":77},"La Place":{"count":55},"La Scala":{"count":62},"La Strada":{"count":74},"La Tagliatella":{"count":69},"La Tasca":{"count":56},"La Taverna":{"count":58},"La Terrasse":{"count":82},"La Terraza":{"count":56},"La Terrazza":{"count":57},"La Trattoria":{"count":91},"Lamm":{"count":69},"Linde":{"count":114},"Lindenhof":{"count":95},"Little Caesars":{"count":80},"Little Chef":{"count":62},"Little Italy":{"count":90},"Logan's Roadhouse":{"count":89},"LongHorn Steakhouse":{"count":183},"Lotus":{"count":87},"Léon de Bruxelles":{"count":63},"Löwen":{"count":141},"MK Restaurants":{"count":65},"Maharaja":{"count":52},"Mamma Mia":{"count":130},"Mandarin":{"count":90},"Mang Inasal":{"count":128},"Marco Polo":{"count":62},"Marco's Pizza":{"count":53},"McAlister's Deli":{"count":51},"Mediterraneo":{"count":55},"Mellow Mushroom":{"count":73},"Mensa":{"count":148},"Milano":{"count":77},"Mimi's Cafe":{"count":52},"Moe's Southwest Grill":{"count":79},"Mykonos":{"count":89},"Mythos":{"count":61},"Nando's":{"count":412},"Noodles & Company":{"count":106},"O'Charley's":{"count":61},"Oasis":{"count":73},"Ocean Basket":{"count":71},"Ochsen":{"count":94},"Old Chicago":{"count":54},"Olive Garden":{"count":504},"Olympia":{"count":86},"Osaka":{"count":52},"Outback Steakhouse":{"count":399},"P.F. Chang's":{"count":53},"Pancake House":{"count":79},"Panda":{"count":52},"Panera Bread":{"count":582},"Panorama":{"count":102},"Papa Murphy's":{"count":66},"Parrilla":{"count":62},"Peking":{"count":68},"Perkins":{"count":157},"Pinocchio":{"count":63},"Pizza Express":{"count":417},"Pizza Factory":{"count":59},"Pizza House":{"count":56},"Pizza Hut":{"count":2688,"tags":{"cuisine":"pizza"}},"Pizza Ranch":{"count":77},"Pizzeria Italia":{"count":65},"Pizzeria Milano":{"count":51},"Pizzeria Napoli":{"count":53},"Pizzeria Roma":{"count":86},"Pizzeria Venezia":{"count":54},"Poivre Rouge":{"count":56},"Pollo Campero":{"count":53},"Pomodoro":{"count":62},"Portofino":{"count":67},"Poseidon":{"count":145},"Prezzo":{"count":147},"Qdoba":{"count":81},"Qdoba Mexican Grill":{"count":54},"Ratskeller":{"count":161},"Red Lobster":{"count":419},"Red Robin":{"count":312},"Restaurante Universitário":{"count":53},"Rhodos":{"count":94},"Ristorante Del Arte":{"count":160},"Roma":{"count":85},"Rose":{"count":51},"Round Table Pizza":{"count":100},"Ruby Tuesday":{"count":303},"Rössle":{"count":54},"Rössli":{"count":93},"Saigon":{"count":51},"Sakura":{"count":139},"San Marco":{"count":88},"Santorini":{"count":59},"Schwarzer Adler":{"count":65},"Schützenhaus":{"count":151},"Shakey's":{"count":64},"Shalimar":{"count":53},"Shanghai":{"count":96},"Shari's":{"count":75},"Shoney's":{"count":55},"Sizzler":{"count":90},"Sonic":{"count":80,"tags":{"cuisine":"burger"}},"Sonne":{"count":121},"Sphinx":{"count":66},"Sportheim":{"count":113},"Spur":{"count":70},"Starbucks":{"count":54,"tags":{"cuisine":"coffee_shop"}},"Steak 'n Shake":{"count":86,"tags":{"cuisine":"burger"}},"Steak House":{"count":58},"Sternen":{"count":85},"Subway":{"count":1108},"Sunset Grill":{"count":55},"Sushi":{"count":88},"Sushi Bar":{"count":68},"Swiss Chalet":{"count":162},"Syrtaki":{"count":65},"TGI Friday's":{"count":364},"Taj Mahal":{"count":183},"Taste of India":{"count":68},"Taverna":{"count":69},"Telepizza":{"count":109},"Texas Roadhouse":{"count":232},"The Cheesecake Factory":{"count":52},"Tim Hortons":{"count":61},"Toby Carvery":{"count":51},"Tony Roma's":{"count":63},"Toscana":{"count":76},"Trattoria":{"count":70},"Traube":{"count":68},"Vapiano":{"count":136},"Venezia":{"count":68},"Village Inn":{"count":149},"Vips":{"count":109},"Waffle House":{"count":521},"Wagamama":{"count":111},"Waldschänke":{"count":52},"Warung":{"count":73},"Wasabi":{"count":70},"Wimpy":{"count":66},"Zaxby's":{"count":60},"Zizzi":{"count":102},"Zorbas":{"count":62},"Zum Hirschen":{"count":52},"Zum Löwen":{"count":80},"Zur Krone":{"count":96},"Zur Linde":{"count":228},"Zur Post":{"count":125},"Zur Sonne":{"count":77},"Евразия":{"count":93},"Ресторан":{"count":60},"Тануки":{"count":62},"Якитория":{"count":84},"رستوران":{"count":72},"مطعم":{"count":52},"すき家":{"count":61,"tags":{"name:en":"SUKIYA"}},"はま寿司":{"count":67},"びっくりドンキー":{"count":120},"やよい軒":{"count":71},"ガスト":{"count":512,"tags":{"name:en":"Gusto"}},"ココス":{"count":142},"サイゼリア":{"count":54},"サイゼリヤ":{"count":285},"ジョイフル":{"count":83},"ジョナサン":{"count":139},"ジョリーパスタ":{"count":75},"デニーズ":{"count":199},"バーミヤン":{"count":130},"ロイヤルホスト":{"count":108},"丸亀製麺":{"count":98},"八方雲集":{"count":145},"吉野家":{"count":61},"夢庵":{"count":67},"大戸屋":{"count":68},"大阪王将":{"count":68},"天下一品":{"count":70},"安楽亭":{"count":60},"牛角":{"count":107},"食堂":{"count":63},"餃子の王将":{"count":212},"바다횟집 (Bada Fish Restaurant)":{"count":52}},"school":{"Adolfo Lopez Mateos":{"count":137},"Agustin Ya�ez":{"count":57},"Albert-Schweitzer-Schule":{"count":81},"Amado Nervo":{"count":85},"Astrid-Lindgren-Schule":{"count":77},"Benito Juarez":{"count":294},"Brown School":{"count":54},"CEM":{"count":215},"Center School":{"count":115},"Central Elementary School":{"count":179},"Central High School":{"count":130},"Central School":{"count":215},"Colegio San José":{"count":74},"Collège Jean Moulin":{"count":68},"Collège privé Saint-Joseph":{"count":60},"Cuauhtemoc":{"count":152},"Curso Comunitario":{"count":57},"Cursos Comunitarios":{"count":116},"EPP":{"count":112},"Emiliano Zapata":{"count":286},"Fairview Elementary School":{"count":64},"Fairview School":{"count":164},"Francisco I Madero":{"count":86},"Francisco I. Madero":{"count":52},"Francisco Villa":{"count":116},"Franklin Elementary School":{"count":96},"Franklin School":{"count":126},"Garfield Elementary School":{"count":69},"Garfield School":{"count":58},"Gimnazjum nr 1":{"count":59},"Government School":{"count":60},"Gregorio Torres Quintero":{"count":53},"Groupe Scolaire":{"count":57},"Guadalupe Victoria":{"count":58},"Highland School":{"count":71},"Hillcrest Elementary School":{"count":63},"Holy Cross School":{"count":68},"Holy Family School":{"count":77},"Holy Trinity School":{"count":59},"Ignacio Allende":{"count":51},"Ignacio Zaragoza":{"count":98},"Immaculate Conception School":{"count":83},"Jackson Elementary School":{"count":53},"Jackson School":{"count":56},"Jefferson Elementary School":{"count":177},"Jefferson School":{"count":108},"Jose Clemente Orozco":{"count":59},"Jose Ma Morelos Y Pavon":{"count":120},"Jose Vasconcelos":{"count":73},"Josefa Ortiz De Dominguez":{"count":78},"Juan Escutia":{"count":121},"Justo Sierra":{"count":118},"Kumon":{"count":66},"Lazaro Cardenas":{"count":68},"Lazaro Cardenas Del Rio":{"count":153},"Leona Vicario":{"count":64},"Liberty Elementary School":{"count":56},"Liberty School":{"count":84},"Lincoln Elementary School":{"count":264},"Lincoln School":{"count":269},"Longfellow Elementary School":{"count":55},"Longfellow School":{"count":53},"Madison Elementary School":{"count":55},"Manuel Lopez Cotilla":{"count":107},"Maple Grove School":{"count":51},"McKinley Elementary School":{"count":62},"McKinley School":{"count":63},"Miguel Hidalgo":{"count":86},"Miguel Hidalgo Y Costilla":{"count":213},"Miller School":{"count":66},"Mount Pleasant School":{"count":61},"Mount Zion School":{"count":53},"Mountain View Elementary School":{"count":52},"New Hope School":{"count":51},"Nicolas Bravo":{"count":58},"Ni�os Heroes":{"count":155},"Nombre En Tramite":{"count":126},"North Elementary School":{"count":57},"Oak Grove School":{"count":148},"Pedro Moreno":{"count":69},"Pestalozzischule":{"count":84},"Pine Grove School":{"count":63},"Pleasant Hill School":{"count":110},"Pleasant Valley School":{"count":85},"Pleasant View School":{"count":61},"Primaria Comunitaria":{"count":59},"Ramon Corona":{"count":54},"Ricardo Flores Magon":{"count":91},"Riverside School":{"count":76},"Roosevelt Elementary School":{"count":112},"Roosevelt School":{"count":114},"SD":{"count":76},"SDN":{"count":290},"Sacred Heart School":{"count":206},"Saint Francis School":{"count":56},"Saint James School":{"count":83},"Saint Johns School":{"count":173},"Saint Joseph School":{"count":147},"Saint Josephs School":{"count":157},"Saint Kizito Primary School":{"count":61},"Saint Mary School":{"count":54},"Saint Marys School":{"count":256},"Saint Patricks School":{"count":80},"Saint Paul School":{"count":53},"Saint Pauls School":{"count":74},"Saint Peters School":{"count":81},"Schillerschule":{"count":61},"School Number 1":{"count":233},"School Number 2":{"count":206},"School Number 3":{"count":184},"School Number 4":{"count":126},"Smith School":{"count":60},"Sor Juana Ines De La Cruz":{"count":56},"South Elementary School":{"count":53},"Sunnyside School":{"count":60},"Szkoła Podstawowa nr 1":{"count":78},"Szkoła Podstawowa nr 2":{"count":75},"Szkoła Podstawowa nr 3":{"count":60},"Trinity School":{"count":85},"UNIDAD EDUCATIVA":{"count":106},"Union School":{"count":128},"Valentin Gomez Farias":{"count":71},"Venustiano Carranza":{"count":64},"Vicente Guerrero":{"count":159},"Volkshochschule":{"count":105},"Volksschule":{"count":366},"Washington Elementary School":{"count":192},"Washington School":{"count":213},"West Elementary School":{"count":58},"White School":{"count":51},"Wilson Elementary School":{"count":66},"Wilson School":{"count":80},"Általános iskola":{"count":105},"École Jules Ferry":{"count":51},"École Notre-Dame":{"count":61},"École Saint-Joseph":{"count":96},"École primaire Jean Jaurès":{"count":71},"École primaire Jules Ferry":{"count":82},"École primaire privée Notre-Dame":{"count":69},"École primaire privée Saint-Joseph":{"count":132},"École primaire privée Sainte-Marie":{"count":63},"École élémentaire Jules Ferry":{"count":52},"Școala Generală":{"count":51},"Școală":{"count":53},"Вечерняя школа":{"count":53},"Гимназия №1":{"count":96},"ДЮСШ":{"count":63},"Средняя школа №1":{"count":80},"Средняя школа №2":{"count":86},"Средняя школа №3":{"count":58},"Школа № 1":{"count":130},"Школа № 2":{"count":117},"Школа № 3":{"count":80},"Школа № 4":{"count":77},"Школа № 5":{"count":55},"Школа №1":{"count":576},"Школа №10":{"count":167},"Школа №11":{"count":148},"Школа №12":{"count":136},"Школа №13":{"count":129},"Школа №14":{"count":123},"Школа №15":{"count":129},"Школа №16":{"count":99},"Школа №17":{"count":117},"Школа №18":{"count":111},"Школа №19":{"count":98},"Школа №2":{"count":509},"Школа №20":{"count":100},"Школа №21":{"count":72},"Школа №22":{"count":72},"Школа №23":{"count":75},"Школа №24":{"count":78},"Школа №25":{"count":57},"Школа №26":{"count":64},"Школа №27":{"count":58},"Школа №28":{"count":53},"Школа №3":{"count":393},"Школа №31":{"count":55},"Школа №35":{"count":54},"Школа №4":{"count":281},"Школа №5":{"count":275},"Школа №6":{"count":217},"Школа №7":{"count":215},"Школа №8":{"count":188},"Школа №9":{"count":183},"مدرسة":{"count":92},"مدرسه":{"count":500},"市立南中学校":{"count":53},"市立南小学校":{"count":56},"市立東中学校":{"count":54}},"social_facility":{"Safe Haven":{"count":92},"Детский дом":{"count":70},"Социальный участковый":{"count":195}},"theatre":{"Amfiteatr":{"count":97},"Amphitheater":{"count":110},"Amphitheatre":{"count":109},"Freilichtbühne":{"count":78},"Teatro Comunale":{"count":56}}};
23630 var leisure = {"fitness_centre":{"Anytime Fitness":{"count":143},"Gold's Gym":{"count":61},"LA Fitness":{"count":126},"Planet Fitness":{"count":106},"Snap Fitness":{"count":67}},"playground":{"Çocuk Parkı":{"count":60},"놀이터":{"count":292}},"sports_centre":{"Anytime Fitness":{"count":152},"Complejo Municipal de Deportes":{"count":88},"Complexe Sportif":{"count":51},"Curves":{"count":91},"Fitness First":{"count":70},"Gold's Gym":{"count":82},"Kieser Training":{"count":90},"LA Fitness":{"count":72},"Life Time Fitness":{"count":76},"McFit":{"count":60},"Mrs. Sporty":{"count":76},"Orlik":{"count":82},"Pabellón Municipal de Deportes":{"count":109},"Palestra Comunale":{"count":81},"Planet Fitness":{"count":106},"Salle Omnisport":{"count":57},"Schützenhaus":{"count":79},"Snap Fitness":{"count":51},"Virgin Active":{"count":69},"YMCA":{"count":174},"ДЮСШ":{"count":82},"Ледовый дворец":{"count":54},"体育館":{"count":80}},"swimming_pool":{"Schwimmerbecken":{"count":57},"Yüzme Havuzu":{"count":51},"プール":{"count":56},"游泳池":{"count":55}}};
23631 var man_made = {"windmill":{"De Hoop":{"count":57}}};
23632 var shop = {"alcohol":{"Alko":{"count":170},"BC Liquor Store":{"count":66},"BWS":{"count":157},"Bargain Booze":{"count":140},"Beer Store":{"count":66},"Botilleria":{"count":121},"Dan Murphy's":{"count":61},"Gall & Gall":{"count":511},"LCBO":{"count":430},"Liquor Depot":{"count":53},"Liquor Store":{"count":72},"Liquorland":{"count":112},"Mitra":{"count":60},"Nicolas":{"count":253},"SAQ":{"count":169},"Systembolaget":{"count":271},"The Beer Store":{"count":231},"Vinmonopolet":{"count":66},"Алкомаркет":{"count":67},"Ароматный мир":{"count":196},"Бристоль":{"count":329},"Градус":{"count":52},"Живое пиво":{"count":182},"Красное & Белое":{"count":989},"Кристалл":{"count":56},"Норман":{"count":146},"Отдохни":{"count":75},"Пиво":{"count":73},"Разливное пиво":{"count":143}},"baby_goods":{"Aubert":{"count":56},"Babies R Us":{"count":80},"BabyOne":{"count":52},"西松屋":{"count":53}},"bakery":{"AILI":{"count":53},"Anker":{"count":85},"Awiteks":{"count":53},"Backshop":{"count":57},"Backwerk":{"count":161},"Baguette":{"count":72},"Bakers Delight":{"count":75},"Bakker Bart":{"count":97},"Banette":{"count":111},"Bäckerei Fuchs":{"count":62},"Bäckerei Grimminger":{"count":51},"Bäckerei Müller":{"count":68},"Bäckerei Schmidt":{"count":103},"Bäckerei Schneider":{"count":52},"Cooplands":{"count":63},"Dat Backhus":{"count":81},"Der Beck":{"count":114},"Der Mann":{"count":53},"Ditsch":{"count":70},"Dunkin' Donuts":{"count":55,"tags":{"cuisine":"donut"}},"Fornetti":{"count":113},"Goeken backen":{"count":53},"Goldilocks":{"count":124},"Greggs":{"count":613},"Hofpfisterei":{"count":134},"Ihle":{"count":108},"Julie's Bakeshop":{"count":57},"K&U":{"count":117},"K&U Bäckerei":{"count":54},"Kamps":{"count":268},"La Mie Câline":{"count":56},"Le Crobag":{"count":54},"Le Fournil":{"count":57},"Lila Bäcker":{"count":107},"Lipóti Pékség":{"count":54},"Marie Blachère":{"count":89},"Mlinar":{"count":80},"Musmanni":{"count":81},"Oebel":{"count":65},"Paul":{"count":186},"Red Ribbon":{"count":72},"Schäfer's":{"count":146},"Sehne":{"count":91},"Stadtbäckerei":{"count":60},"Steinecke":{"count":268},"Sternenbäck":{"count":89},"Ströck":{"count":62},"Wiener Feinbäcker":{"count":55},"von Allwörden":{"count":65},"Булочная":{"count":71},"Горячий хлеб":{"count":54},"Каравай":{"count":56},"Кулиничи":{"count":121},"Кулиничі":{"count":59},"Свежий хлеб":{"count":68},"Хлеб":{"count":177},"مخبز":{"count":72},"مخبزة":{"count":55},"نان لواش":{"count":54},"نانوایی":{"count":665},"نانوایی بربری":{"count":140},"نانوایی سنگک":{"count":68},"نانوایی سنگکی":{"count":52},"نانوایی لواش":{"count":63}},"beauty":{"Marionnaud":{"count":54},"Sally Beauty Supply":{"count":151},"Yves Rocher":{"count":654}},"bed":{"Dänisches Bettenlager":{"count":157},"Matratzen Concord":{"count":361},"Mattress Firm":{"count":173},"Sleepy's":{"count":52}},"beverages":{"50嵐":{"count":101},"Dursty":{"count":77},"Edeka Getränkemarkt":{"count":69},"Fristo":{"count":88},"Getränke Hoffmann":{"count":187},"Getränkeland":{"count":81},"Getränkemarkt":{"count":110},"Orterer Getränkemarkt":{"count":64},"Rewe Getränkemarkt":{"count":256},"Trinkgut":{"count":112},"茶湯會":{"count":56}},"bicycle":{"Giant":{"count":52},"Halfords":{"count":158},"Веломарка":{"count":51},"サイクルベースあさひ":{"count":87}},"bookmaker":{"Betfred":{"count":320},"Coral":{"count":466},"Ladbrokes":{"count":629},"Paddy Power":{"count":127},"William Hill":{"count":634},"ΟΠΑΠ":{"count":102}},"butcher":{"Boucherie Charcuterie":{"count":51},"Carnicería":{"count":78},"Fleischerei Richter":{"count":51},"Húsbolt":{"count":52},"Macelleria":{"count":84},"Vinzenzmurr":{"count":55},"Ариант":{"count":84},"Великолукский мясокомбинат":{"count":173},"Мясная лавка":{"count":226},"Мясницкий ряд":{"count":64},"Мясной":{"count":53},"Мясо":{"count":156},"Наша Ряба":{"count":60},"Свежее мясо":{"count":111}},"car":{"Audi":{"count":191},"BMW":{"count":216},"Chevrolet":{"count":259},"Citroën":{"count":445},"Dacia":{"count":56},"Fiat":{"count":167},"Ford":{"count":446},"Honda":{"count":348},"Hyundai":{"count":421},"Isuzu":{"count":66},"Kia":{"count":456},"Land Rover":{"count":54},"Lexus":{"count":76},"Mazda":{"count":193},"Mercedes-Benz":{"count":447},"Mitsubishi":{"count":176},"Mitsubishi Motors":{"count":60},"NISSAN":{"count":51},"Nissan":{"count":424},"Opel":{"count":218},"Peugeot":{"count":527},"Porsche":{"count":97},"Renault":{"count":701},"Seat":{"count":90},"Skoda":{"count":143},"Subaru":{"count":118},"Suzuki":{"count":178},"Toyota":{"count":597},"Volkswagen":{"count":371},"Volvo":{"count":180}},"car_parts":{"Advance Auto Parts":{"count":306},"AutoZone":{"count":759},"Brezan":{"count":95},"Halfords":{"count":95},"NAPA Auto Parts":{"count":250},"Napa Auto Parts":{"count":61},"O'Reilly Auto Parts":{"count":374},"Repco":{"count":77},"Tokić":{"count":61},"repuestos automotrices":{"count":56},"Автозапчастини":{"count":61},"Автомир":{"count":53},"イエローハット":{"count":80},"オートバックス":{"count":91},"タイヤ館":{"count":83}},"car_repair":{"A.T.U":{"count":457},"Advance Auto Parts":{"count":290},"Borracharia":{"count":56},"Bosch Car Service":{"count":65},"Carglass":{"count":234},"Citroën":{"count":108},"Euromaster":{"count":142},"Feu Vert":{"count":178},"Firestone":{"count":224},"Firestone Complete Auto Care":{"count":73},"Ford":{"count":61},"Garage Renault":{"count":84},"Gomeria":{"count":153},"Gomería":{"count":107},"Goodyear":{"count":97},"Grease Monkey":{"count":57},"Halfords":{"count":56},"Jiffy Lube":{"count":464},"Kwik Fit":{"count":249},"Lubricentro":{"count":83},"Meineke":{"count":52},"Mekonomen":{"count":59},"Midas":{"count":462},"Mr. Lube":{"count":56},"NAPA Auto Parts":{"count":82},"Norauto":{"count":257},"O'Reilly Auto Parts":{"count":227},"Pep Boys":{"count":79},"Peugeot":{"count":152},"Pit Stop":{"count":84},"Point S":{"count":59},"Renault":{"count":294},"Roady":{"count":82},"Sears Auto Center":{"count":59},"Speedy":{"count":192},"Stacja Kontroli Pojazdów":{"count":70},"Taller":{"count":63},"Toyota":{"count":63},"Valvoline":{"count":52},"Valvoline Instant Oil Change":{"count":92},"Wulkanizacja":{"count":84},"ÖAMTC":{"count":52},"Автомастерская":{"count":93},"Авторемонт":{"count":57},"Автосервис":{"count":799},"Автосервис+шиномонтаж":{"count":66},"Вулканизация":{"count":72},"Замена масла":{"count":98},"СТО":{"count":1058},"Шиномонтаж":{"count":3591},"шиномонтаж":{"count":173}},"carpet":{"Carpet Right":{"count":111},"Carpetright":{"count":53}},"charity":{"Age UK":{"count":116},"Barnardo's":{"count":56},"British Heart Foundation":{"count":189},"Cancer Research UK":{"count":129},"Goodwill":{"count":120},"Oxfam":{"count":216},"Salvation Army":{"count":63},"Scope":{"count":74},"Sue Ryder":{"count":83}},"chemist":{"7 Дней":{"count":55},"Bipa":{"count":485},"Budnikowsky":{"count":114},"CVS":{"count":58},"Etos":{"count":486},"Kruidvat":{"count":1169},"Matas":{"count":74},"Müller":{"count":350},"Rossmann":{"count":2516},"Schlecker":{"count":51},"Teta":{"count":120},"Trekpleister":{"count":185},"Walgreens":{"count":142},"Watsons":{"count":123},"dm":{"count":1877},"Бытовая химия":{"count":73},"Магнит Косметик":{"count":233},"Мила":{"count":70},"Остров чистоты":{"count":110},"Рубль Бум":{"count":68},"Улыбка радуги":{"count":110},"スギ薬局":{"count":51},"丁丁藥局":{"count":72},"屈臣氏":{"count":134},"康是美":{"count":81}},"clothes":{"AOKI":{"count":119},"AWG":{"count":95},"Ackermans":{"count":98},"Adidas":{"count":224},"Adler":{"count":83},"American Apparel":{"count":89},"American Eagle Outfitters":{"count":93},"Anthropologie":{"count":55},"Ardene":{"count":55},"Armand Thiery":{"count":89},"Banana Republic":{"count":120},"Benetton":{"count":190},"Bershka":{"count":166},"Bonita":{"count":315},"Bonobo":{"count":59},"Brooks Brothers":{"count":55},"Burberry":{"count":63},"Burlington Coat Factory":{"count":104},"Burton":{"count":94},"C&A":{"count":860},"Cache Cache":{"count":59},"Calvin Klein":{"count":78},"Calzedonia":{"count":264},"Camaïeu":{"count":167},"Caroll":{"count":75},"Carter's":{"count":64},"Cecil":{"count":119},"Celio":{"count":206},"Charles Vögele":{"count":133},"Chico's":{"count":96},"Cropp":{"count":68},"Cubus":{"count":65},"Desigual":{"count":175},"Devred":{"count":59},"Didi":{"count":72},"Diesel":{"count":77},"Dorothy Perkins":{"count":85},"Dress Barn":{"count":135},"Dressmann":{"count":67},"Eddie Bauer":{"count":54},"Edgars":{"count":117},"Engbers":{"count":64},"Ernsting's family":{"count":720},"Esprit":{"count":404},"Etam":{"count":121},"Express":{"count":56},"Fat Face":{"count":82},"Forever 21":{"count":124},"Gant":{"count":78},"Gap":{"count":258},"Gerry Weber":{"count":220},"Gina Laura":{"count":80},"Goodwill":{"count":65},"Guess":{"count":146},"Gymboree":{"count":60},"Gémo":{"count":99},"H&M":{"count":1467},"Hallhuber":{"count":63},"House":{"count":67},"Hugo Boss":{"count":109},"Humana":{"count":83},"Hunkemöller":{"count":224},"Intimissimi":{"count":173},"JBC":{"count":54},"Jack & Jones":{"count":174},"Jack Wolfskin":{"count":68},"Jeans Fritz":{"count":110},"Jennyfer":{"count":81},"Jet":{"count":68},"Jigsaw":{"count":51},"Jules":{"count":120},"Justice":{"count":81},"KappAhl":{"count":68},"KiK":{"count":1862},"Kiabi":{"count":276},"La Halle":{"count":148},"Lacoste":{"count":193},"Lane Bryant":{"count":86},"Levi's":{"count":197},"Lindex":{"count":120},"Loft":{"count":62},"Mango":{"count":339},"Marc O'Polo":{"count":82},"Mark's":{"count":76},"Marks & Spencer":{"count":53},"Marshalls":{"count":218},"Massimo Dutti":{"count":109},"Matalan":{"count":144},"Maurices":{"count":70},"Max Mara":{"count":55},"Men's Wearhouse":{"count":128},"Mexx":{"count":68},"Michael Kors":{"count":55},"Mim":{"count":57},"Monsoon":{"count":75},"Mr Price":{"count":99},"NKD":{"count":783},"New Look":{"count":280},"New Yorker":{"count":350},"NewYorker":{"count":54},"Next":{"count":313},"Nike":{"count":122},"Nordstrom Rack":{"count":57},"OVS":{"count":92},"Okaïdi":{"count":63},"Old Navy":{"count":361},"Only":{"count":94},"Orchestra":{"count":117},"Original Marines":{"count":60},"Orsay":{"count":168},"Outfit":{"count":51},"Outlet":{"count":63},"Palmers":{"count":78},"Peacocks":{"count":178},"Peek & Cloppenburg":{"count":69},"Pep":{"count":139},"Pepco":{"count":153},"Petit Bateau":{"count":67},"Pimkie":{"count":163},"Plato's Closet":{"count":53},"Primark":{"count":177},"Promod":{"count":195},"Pull & Bear":{"count":63},"Puma":{"count":65},"Reitmans":{"count":71},"Reserved":{"count":150},"River Island":{"count":125},"Ross":{"count":363},"Sela":{"count":58},"Sergent Major":{"count":77},"Shoeby":{"count":109},"Sisley":{"count":82},"Springfield":{"count":83},"Stefanel":{"count":63},"Steps":{"count":56},"Stradivarius":{"count":103},"Street One":{"count":153},"Superdry":{"count":82},"TJ Maxx":{"count":200},"TK Maxx":{"count":209},"Takko":{"count":843},"Talbots":{"count":54},"Tally Weijl":{"count":151},"Tati":{"count":64},"Terranova":{"count":63},"Tesha":{"count":76},"Tezenis":{"count":98},"The Children's Place":{"count":71},"The North Face":{"count":56},"The Sting":{"count":53},"Timberland":{"count":87},"Toko Pakaian":{"count":72},"Tom Tailor":{"count":120},"Tommy Hilfiger":{"count":206},"Topshop":{"count":62},"Triumph":{"count":132},"Truworths":{"count":72},"Ulla Popken":{"count":117},"Uniqlo":{"count":63},"United Colors of Benetton":{"count":210},"Urban Outfitters":{"count":130},"Vero Moda":{"count":222},"Victoria's Secret":{"count":143},"Vögele":{"count":191},"WE":{"count":68},"Wibra":{"count":99},"Winners":{"count":112},"Woolworths":{"count":119},"Yamamay":{"count":65},"Zara":{"count":540},"Zeeman":{"count":379},"mister*lady":{"count":59},"s.Oliver":{"count":103},"Детская одежда":{"count":59},"Женская одежда":{"count":65},"Липненски":{"count":81},"Московская ярмарка":{"count":51},"Одежда":{"count":163},"Смешные цены":{"count":86},"Спецодежда":{"count":85},"しまむら":{"count":213},"ユニクロ":{"count":201},"ワークマン":{"count":65},"洋服の青山":{"count":242},"西松屋":{"count":113}},"coffee":{"Café Amazon":{"count":212},"Nespresso":{"count":74},"Starbucks":{"count":264,"tags":{"cuisine":"coffee_shop"}},"Tchibo":{"count":197}},"computer":{"Apple Store":{"count":75},"DNS":{"count":234},"PC World":{"count":59},"ДНС":{"count":55}},"confectionery":{"Fagyizó":{"count":58},"Hussel":{"count":78},"Leonidas":{"count":84},"T. SN":{"count":77},"Thorntons":{"count":66}},"convenience":{"711":{"count":64},"777":{"count":58},"24 часа":{"count":85},"7-Eleven":{"count":11418},"8 à Huit":{"count":82},"99 Speedmart":{"count":85},"ABC":{"count":716},"AMPM":{"count":125},"Aibė":{"count":112},"Alepa":{"count":60},"Alfamart":{"count":427},"Alimentara":{"count":63},"Almacen":{"count":405},"Almacén":{"count":94},"Aral":{"count":93},"BP":{"count":273},"BP Shop":{"count":70},"Baqala":{"count":181},"Best One":{"count":57},"Best-One":{"count":63},"Biedronka":{"count":98},"Bodega":{"count":83},"Bonjour":{"count":71},"CBA":{"count":299},"COOP":{"count":470},"COOP Jednota":{"count":381},"CU":{"count":324},"Carrefour City":{"count":91},"Carrefour Express":{"count":255},"Casey's General Store":{"count":225},"Casino Shop":{"count":56},"Centra":{"count":139},"Central Convenience Store":{"count":69},"Chevron":{"count":110},"Circle K":{"count":790},"Citgo":{"count":73},"Co-Op":{"count":54},"Co-op":{"count":161},"Coles Express":{"count":217},"Coop":{"count":492},"Coop Jednota":{"count":128},"Corner Store":{"count":109},"Costcutter":{"count":435},"Couche-Tard":{"count":139},"Cumberland Farms":{"count":109},"Daisy Mart":{"count":57},"Delikatesy":{"count":148},"Delikatesy Centrum":{"count":182},"Dollar General":{"count":646},"Dollar Tree":{"count":67},"Dépanneur":{"count":53},"Esso":{"count":143},"Express":{"count":53},"Extra":{"count":86},"Exxon":{"count":51},"Family Dollar":{"count":85},"FamilyMart":{"count":919},"Food Mart":{"count":512},"Four Square":{"count":99},"Franprix":{"count":96},"Fresh":{"count":67},"Freshmarket":{"count":224},"GS25":{"count":343},"Groszek":{"count":254},"Hasty Market":{"count":87},"Holiday":{"count":67},"Hruška":{"count":89},"Indomaret":{"count":483},"Jednota":{"count":66},"Joker":{"count":56},"K-Market":{"count":104},"Kangaroo":{"count":54},"Kangaroo Express":{"count":51},"Kisbolt":{"count":94},"Konzum":{"count":229},"Kum & Go":{"count":127},"Kwik Trip":{"count":134},"Lawson":{"count":311},"Lewiatan":{"count":565},"Lifestyle Express":{"count":114},"Londis":{"count":505},"M&S Simply Food":{"count":72},"Mac's":{"count":295},"Mace":{"count":166},"Magazin":{"count":81},"Magazin Mixt":{"count":139},"Magazin Non-Stop":{"count":62},"Magazin mixt":{"count":57},"Marathon":{"count":59},"Maxikiosco":{"count":86},"Małpka Express":{"count":71},"McColl's":{"count":289},"Mercator":{"count":122},"Migrolino":{"count":63},"Mini ABC":{"count":77},"Mini Market":{"count":1312},"Mini Market Non-Stop":{"count":134},"Mini Mart":{"count":78},"Mini Stop":{"count":466},"Minimercado":{"count":77},"Mlin i pekare":{"count":63},"Mobil":{"count":82},"Nasz Sklep":{"count":92},"Nisa":{"count":70},"Nisa Local":{"count":164},"OK":{"count":107},"OK-Mart":{"count":51},"OK便利商店":{"count":96},"OK便利店 Circle K":{"count":92},"Odido":{"count":148},"On The Run":{"count":53},"On the Run":{"count":111},"One Stop":{"count":294},"Oxxo":{"count":2261},"Parduotuvė":{"count":102},"Petit Casino":{"count":297},"Plaid Pantry":{"count":69},"Potraviny":{"count":438},"Prehrana":{"count":88},"Premier":{"count":321},"Proxi":{"count":249},"Proxy":{"count":53},"Pulperia":{"count":56},"Pulpería":{"count":51},"QuikTrip":{"count":161},"Rite Aid":{"count":72},"Royal Farms":{"count":90},"Sainsbury's Local":{"count":208},"Sale":{"count":89},"Sari-sari Store":{"count":82},"Select":{"count":133},"Sheetz":{"count":137},"Shell":{"count":479},"Shell Select":{"count":71},"Shop & Go":{"count":80},"Siwa":{"count":157},"Sklep spożywczy":{"count":151},"Smíšené zboží":{"count":57},"Spar":{"count":1472},"Speedway":{"count":108},"Społem":{"count":199},"Spätkauf":{"count":60},"Statoil":{"count":62},"Stewart's":{"count":255},"Stores":{"count":70},"Stripes":{"count":63},"Studenac":{"count":113},"Sunkus":{"count":51},"Sunoco":{"count":65},"Słoneczko":{"count":61},"TESCO Lotus Express":{"count":55},"Tchibo":{"count":75},"Tesco":{"count":54},"Tesco Express":{"count":661},"Tesco Lotus Express":{"count":107},"The Co-operative Food":{"count":341},"Tom Market 89":{"count":232},"Total":{"count":172},"United Dairy Farmers":{"count":55},"Utile":{"count":63},"Valero":{"count":71},"Vegyesbolt":{"count":391},"Večerka":{"count":131},"Vival":{"count":381},"Volg":{"count":149},"Wawa":{"count":279},"Weltladen":{"count":64},"Woolworths Petrol":{"count":97},"abc":{"count":374},"ampm":{"count":152},"best-one":{"count":52},"odido":{"count":77},"Élelmiszer":{"count":59},"Élelmiszerbolt":{"count":65},"Żabka":{"count":1656},"Žabka":{"count":61},"АТБ":{"count":56},"Августина":{"count":52},"Авоська":{"count":115},"Агрокомплекс":{"count":79},"Альянс":{"count":51},"Апельсин":{"count":72},"Ассорти":{"count":118},"Белорусские продукты":{"count":58},"Берёзка":{"count":193},"Везунчик":{"count":66},"Верный":{"count":61},"Весна":{"count":101},"Ветеран":{"count":56},"Визит":{"count":99},"Виктория":{"count":164},"ВкусВилл":{"count":131},"Гастроном":{"count":383},"Гермес":{"count":68},"Гроздь":{"count":52},"Гурман":{"count":92},"Дикси":{"count":270},"Домашний":{"count":77},"Евроопт":{"count":152},"Елена":{"count":68},"Ермолино":{"count":51},"КазМунайГаз":{"count":117},"Калинка":{"count":61},"Каравай":{"count":52},"Квартал":{"count":57},"Кировский":{"count":86},"Колобок":{"count":51},"Колосок":{"count":58},"Копеечка":{"count":99},"Копейка":{"count":65},"Корзинка":{"count":54},"Крамниця":{"count":64},"Кристалл":{"count":57},"Кулинария":{"count":134},"Купец":{"count":64},"Ласточка":{"count":51},"Лидер":{"count":60},"Любимый":{"count":84},"Люкс":{"count":59},"Магазин при АЗС":{"count":54},"Магнит":{"count":1991},"Магнолия":{"count":88},"Мария-Ра":{"count":197},"Маяк":{"count":76},"Меркурий":{"count":77},"Мечта":{"count":103},"Минимаркет":{"count":424},"Мираж":{"count":56},"Монетка":{"count":165},"Надежда":{"count":115},"Ника":{"count":57},"Оазис":{"count":57},"Олимп":{"count":51},"Перекресток":{"count":157},"Подсолнух":{"count":69},"Престиж":{"count":58},"Продукти":{"count":1446},"Продуктовый":{"count":307},"Продуктовый магазин":{"count":803},"Продукты":{"count":8416},"Продукты 24":{"count":65},"Пятёрочка":{"count":1324},"Радуга":{"count":165},"Родны кут":{"count":90},"Ромашка":{"count":83},"Русь":{"count":61},"Светлана":{"count":96},"Сказка":{"count":62},"Смак":{"count":151},"Солнечный":{"count":54},"Солнышко":{"count":54},"Татьяна":{"count":68},"Теремок":{"count":105},"Тройка":{"count":62},"У Палыча":{"count":69},"Универсам":{"count":153},"Фортуна":{"count":97},"Хороший":{"count":55},"Центральный":{"count":73},"Чайка":{"count":57},"Шанс":{"count":60},"Эконом":{"count":72},"Юбилейный":{"count":56},"Юлия":{"count":58},"продукты":{"count":157},"მარკეტი":{"count":134},"მარკეტი (Market)":{"count":71},"サンクス":{"count":970,"tags":{"name:en":"sunkus"}},"サークルK":{"count":1109,"tags":{"name:en":"Circle K"}},"スリーエフ":{"count":228},"セイコーマート":{"count":449},"セブンイレブン":{"count":7859,"tags":{"name:en":"7-Eleven"}},"セブンイレブン(Seven-Eleven)":{"count":332},"セーブオン":{"count":71},"デイリーヤマザキ":{"count":421},"ファミリーマート":{"count":4457,"tags":{"name:en":"FamilyMart"}},"ポプラ":{"count":101},"ミニストップ":{"count":773,"tags":{"name:en":"MINISTOP"}},"ヤマザキショップ":{"count":106},"ローソン":{"count":4247,"tags":{"name:en":"LAWSON"}},"ローソンストア100":{"count":272},"全家":{"count":482},"全家便利商店":{"count":833},"萊爾富":{"count":405},"세븐일레븐":{"count":157}},"copyshop":{"FedEx Office":{"count":53},"FedEx Office Print and Ship Center":{"count":170}},"cosmetics":{"Douglas":{"count":58},"Lush":{"count":80},"Marionnaud":{"count":55},"Sephora":{"count":184},"The Body Shop":{"count":95},"Yves Rocher":{"count":111},"Л'Этуаль":{"count":111},"Магнит Косметик":{"count":116},"Магнит косметик":{"count":63},"Магнит-Косметик":{"count":55},"Мила":{"count":68},"Подружка":{"count":51}},"craft":{"Hobby Lobby":{"count":96},"Michaels":{"count":222}},"deli":{"ほっともっと":{"count":58}},"department_store":{"Argos":{"count":90},"Bed Bath & Beyond":{"count":72},"Big Lots":{"count":142},"Big W":{"count":120},"Canadian Tire":{"count":176},"Coppel":{"count":55},"Debenhams":{"count":118},"Dillard's":{"count":86},"Dollar General":{"count":62},"Dollar Tree":{"count":64},"El Corte Inglés":{"count":61},"Family Dollar":{"count":76},"Fred Meyer":{"count":51},"Galeria Kaufhof":{"count":60},"HEMA":{"count":248},"Harvey Norman":{"count":62},"JCPenney":{"count":365},"Karstadt":{"count":66},"Kmart":{"count":390},"Kohl's":{"count":371},"Lojas Americanas":{"count":63},"Macy's":{"count":292},"Marks & Spencer":{"count":136},"Marshalls":{"count":58},"Myer":{"count":51},"Nordstrom":{"count":54},"Sam's Club":{"count":103},"Sears":{"count":462},"Shopko":{"count":65},"Target":{"count":1104},"The Warehouse":{"count":68},"Walmart":{"count":847},"Walmart Supercenter":{"count":234},"Woolworth":{"count":153},"Магнит":{"count":88},"Универмаг":{"count":170}},"doityourself":{"Ace Hardware":{"count":300},"B&Q":{"count":229},"Bauhaus":{"count":223},"Biltema":{"count":64},"Brico":{"count":126},"Bricomarché":{"count":425},"Bricorama":{"count":117},"Bunnings Warehouse":{"count":210},"Canadian Tire":{"count":138},"Castorama":{"count":168},"Easy":{"count":53},"Gamma":{"count":133},"Globus Baumarkt":{"count":52},"Hagebaumarkt":{"count":132},"Hellweg":{"count":70},"Home Depot":{"count":1345},"Home Hardware":{"count":172},"Homebase":{"count":205},"Hornbach":{"count":134},"Hubo":{"count":107},"Karwei":{"count":77},"Lagerhaus":{"count":116},"Leroy Merlin":{"count":285},"Lowe's":{"count":1236},"Lowes":{"count":95},"Menards":{"count":132},"Mr Bricolage":{"count":112},"Mr.Bricolage":{"count":139},"OBI":{"count":501},"Point P":{"count":125},"Praktiker":{"count":54},"Praxis":{"count":61},"Rona":{"count":77},"Screwfix":{"count":80},"Sonderpreis Baumarkt":{"count":68},"Tekzen":{"count":112},"Toom Baumarkt":{"count":155},"Weldom":{"count":110},"Wickes":{"count":159},"Леруа Мерлен":{"count":54},"Мастер":{"count":59},"Сантехника":{"count":51},"Строитель":{"count":67},"Стройматериалы":{"count":506},"Хозтовары":{"count":137},"カインズホーム":{"count":51},"コメリ":{"count":137},"コーナン":{"count":77}},"dry_cleaning":{"Cleaners":{"count":103},"Pressing":{"count":58},"Диана":{"count":88},"Химчистка":{"count":73},"ホワイト急便":{"count":136}},"electronics":{"Apple Store":{"count":63},"BCC":{"count":54},"Batteries Plus Bulbs":{"count":74},"Bell":{"count":73},"Best Buy":{"count":706},"Boulanger":{"count":71},"Currys":{"count":109},"Currys PC World":{"count":70},"DNS":{"count":111},"Darty":{"count":168},"Elektra":{"count":64},"Elgiganten":{"count":67},"Euronics":{"count":247},"Expert":{"count":224},"Hartlauer":{"count":64},"Interdiscount":{"count":57},"La Curacao":{"count":69},"Maplin":{"count":114},"Media Expert":{"count":163},"Media Markt":{"count":422},"Musimundo":{"count":53},"Neonet":{"count":97},"RTV Euro AGD":{"count":68},"Radio Shack":{"count":485},"Rogers":{"count":61},"Samsung":{"count":164},"Saturn":{"count":155},"Sony":{"count":51},"The Source":{"count":91},"Unieuro":{"count":66},"М.Видео":{"count":121},"Фокстрот":{"count":76},"Эксперт":{"count":70},"Эльдорадо":{"count":313},"エディオン":{"count":74},"ケーズデンキ":{"count":136},"コジマ":{"count":53},"ヤマダ電機":{"count":162},"全國電子":{"count":72},"燦坤3C":{"count":52}},"erotic":{"Orion":{"count":85}},"fabric":{"Ткани":{"count":121}},"farm":{"Hofladen":{"count":63}},"florist":{"Blume 2000":{"count":94},"Blumen Risse":{"count":69},"Fleuriste":{"count":54},"Interflora":{"count":78},"Monceau Fleurs":{"count":69},"Virágbolt":{"count":64},"Квіти":{"count":86},"Цветочный магазин":{"count":57},"Цветы":{"count":1098}},"frame":{"rumah penduduk":{"count":316}},"funeral_directors":{"The Co-operative Funeralcare":{"count":82},"Ритуальные услуги":{"count":133}},"furniture":{"Aaron's":{"count":57},"Black Red White":{"count":79},"Bodzio":{"count":61},"But":{"count":162},"Casa":{"count":62},"Conforama":{"count":174},"DFS":{"count":52},"Dänisches Bettenlager":{"count":464},"Fly":{"count":53},"Harveys":{"count":58},"IKEA":{"count":234},"JYSK":{"count":431},"Kwantum":{"count":54},"Leen Bakker":{"count":72},"Pier 1 Imports":{"count":95},"Roller":{"count":99},"The Brick":{"count":68},"Меблі":{"count":70},"ニトリ":{"count":93}},"garden_centre":{"Dehner":{"count":59},"Gamm Vert":{"count":210},"Jardiland":{"count":124},"Point Vert":{"count":68},"Welkoop":{"count":97},"Семена":{"count":53}},"gift":{"Card Factory":{"count":116},"Hallmark":{"count":163},"Подарки":{"count":56}},"greengrocer":{"Frutería":{"count":60},"Овощи и фрукты":{"count":71}},"hairdresser":{"Berber":{"count":71},"Cost Cutters":{"count":69},"Fantastic Sams":{"count":53},"Figaro":{"count":79},"First Choice Haircutters":{"count":51},"Franck Provost":{"count":136},"Frizerie":{"count":59},"Great Clips":{"count":578},"Haarmonie":{"count":79},"Haarscharf":{"count":59},"Hair Cuttery":{"count":121},"Hairkiller":{"count":73},"Jean Louis David":{"count":90},"Jean-Louis David":{"count":59},"Klier":{"count":239},"Klipp":{"count":76},"Le Salon":{"count":55},"Marco Aldany":{"count":55},"Peluquería":{"count":165},"Salon fryzjerski":{"count":52},"Sport Clips":{"count":114},"Super Cuts":{"count":55},"Supercuts":{"count":359},"Tchip":{"count":62},"The Barber Shop":{"count":130},"Toni & Guy":{"count":77},"Top Hair":{"count":74},"Виктория":{"count":53},"Елена":{"count":53},"Локон":{"count":67},"Парикмахерская":{"count":798},"Перукарня":{"count":119},"Салон красоты":{"count":58},"Стиль":{"count":94},"Шарм":{"count":79},"حلاق":{"count":65}},"hardware":{"1000 мелочей":{"count":125},"Ferretería":{"count":295},"Harbor Freight Tools":{"count":57},"Home Hardware":{"count":94},"Lowe's":{"count":74},"Quincaillerie":{"count":105},"True Value":{"count":52},"Würth":{"count":51},"Промтовары":{"count":67},"Сантехника":{"count":87},"Стройматериалы":{"count":142},"Товары для дома":{"count":69},"Хозтовары":{"count":477}},"hearing_aids":{"Amplifon":{"count":124},"Geers":{"count":66},"Kind Hörgeräte":{"count":74},"amplifon":{"count":52}},"hifi":{"Bang & Olufsen":{"count":51}},"houseware":{"Blokker":{"count":264},"Marskramer":{"count":72},"Xenos":{"count":119}},"ice_cream":{"Мороженое":{"count":51}},"interior_decoration":{"Casa":{"count":65},"Depot":{"count":97}},"jewelry":{"585":{"count":94},"Apart":{"count":53},"Bijou Brigitte":{"count":172},"Christ":{"count":116},"Claire's":{"count":99},"Ernest Jones":{"count":53},"H Samuel":{"count":55},"James Avery Jewelry":{"count":99},"Julien d'Orcel":{"count":123},"Kay Jewelers":{"count":78},"Pandora":{"count":280},"Swarovski":{"count":240},"Адамас":{"count":60},"Золото":{"count":51}},"kiosk":{"Aral":{"count":76},"Edicola":{"count":94},"Esso":{"count":51},"KIOS":{"count":288},"Kiosko":{"count":62},"Kiosque":{"count":68},"Kolporter":{"count":88},"Lietuvos spauda":{"count":62},"Narvesen":{"count":188},"Pressbyrån":{"count":117},"Pulpería":{"count":61},"R-Kioski":{"count":352},"Relay":{"count":61},"Ruch":{"count":187},"Shell":{"count":122},"Tabak Trafik":{"count":83},"Tisak":{"count":245},"Trafik":{"count":221},"Trafika":{"count":64},"Trinkhalle":{"count":98},"Warung":{"count":73},"Белсоюзпечать":{"count":59},"Киоск":{"count":143},"Мороженое":{"count":56},"Продукты":{"count":212},"Роспечать":{"count":233},"Союзпечать":{"count":94},"მარკეტი (Market)":{"count":94}},"kitchen":{"Cuisinella":{"count":60},"Home Utensils":{"count":65}},"laundry":{"Launderette":{"count":51},"Lavandería":{"count":84},"コインランドリー":{"count":64}},"lottery":{"Loteria de la Provincia":{"count":63},"Lotería Nacional":{"count":221},"Lotería de la Provincia":{"count":349},"Lotto":{"count":192},"Lottózó":{"count":69},"ONCE":{"count":91}},"mall":{"Торговый центр":{"count":57}},"massage":{"Massage Envy":{"count":80}},"medical_supply":{"Pofam-Poznań":{"count":61}},"mobile_phone":{"3 Store":{"count":90},"AT&T":{"count":558},"Bell":{"count":140},"Bitė":{"count":66},"Boost Mobile":{"count":151},"Carphone Warehouse":{"count":357},"Claro":{"count":446},"Cricket Wireless":{"count":73},"Digicel":{"count":152},"EE":{"count":190},"MetroPCS":{"count":201},"Movistar":{"count":411},"O2":{"count":527},"Orange":{"count":730},"Personal":{"count":54},"Play":{"count":150},"Plus":{"count":122},"Rogers":{"count":52},"SFR":{"count":156},"Samsung":{"count":71},"Sprint":{"count":394},"T-Mobile":{"count":665},"TIM":{"count":67},"Telcel":{"count":52},"Tele2":{"count":186},"Telekom":{"count":148},"Telekom Shop":{"count":99},"Telenor":{"count":99},"Telus":{"count":69},"The Phone House":{"count":137},"Three":{"count":57},"Tim":{"count":51},"Télécentre":{"count":76},"Verizon":{"count":152},"Verizon Wireless":{"count":629},"Vodafone":{"count":1168},"Vodafone Shop":{"count":52},"Wind":{"count":156},"Yoigo":{"count":61},"au":{"count":136},"auショップ":{"count":340},"mobilcom debitel":{"count":63},"Алло":{"count":86},"Билайн":{"count":441},"Евросеть":{"count":1020},"Київстар":{"count":57},"МТС":{"count":1012},"Мегафон":{"count":687},"Связной":{"count":842},"Теле2":{"count":70},"ソフトバンクショップ":{"count":482},"ドコモショップ":{"count":426}},"money_lender":{"Money Mart":{"count":95}},"motorcycle":{"Harley Davidson":{"count":81},"Honda":{"count":238},"Suzuki":{"count":90},"Yamaha":{"count":235}},"music":{"HMV":{"count":81},"TSUTAYA":{"count":53}},"musical_instrument":{"Guitar Center":{"count":51}},"newsagent":{"Edicola":{"count":111},"Kolporter":{"count":56},"Maison de la Presse":{"count":132},"Relay":{"count":246},"Tabac Presse":{"count":82},"Trafika":{"count":60},"WHSmith":{"count":160},"Белсоюзпечать":{"count":52},"Витебскоблсоюзпечать":{"count":56},"Первая полоса":{"count":57},"Печать":{"count":74},"Роспечать":{"count":371},"Союзпечать":{"count":130}},"optician":{"Alain Afflelou":{"count":204},"Apollo":{"count":441},"Atol":{"count":124},"Boots Opticians":{"count":101},"Fielmann":{"count":477},"General Óptica":{"count":53},"Grand Optical":{"count":57},"Générale d'Optique":{"count":94},"Hakim Optical":{"count":73},"Hans Anders":{"count":105},"Krys":{"count":192},"Les Opticiens Mutualistes":{"count":103},"Optic 2000":{"count":281},"Optical Center":{"count":125},"Pearle":{"count":199},"Pearle Vision":{"count":52},"Specsavers":{"count":384},"Sunglass Hut":{"count":61},"Synoptik":{"count":55},"Vision Express":{"count":183},"แว่นท็อปเจริญ":{"count":97},"メガネスーパー":{"count":62},"眼鏡市場":{"count":206}},"outdoor":{"Jack Wolfskin":{"count":51},"Mountain Warehouse":{"count":74},"REI":{"count":77},"Рыболов":{"count":70}},"paint":{"Benjamin Moore":{"count":58},"Comex":{"count":68},"Jotun":{"count":51},"National Paints":{"count":53},"Sherwin Williams":{"count":323},"Sherwin-Williams Paints":{"count":59}},"pawnbroker":{"Cash Converters":{"count":83},"Lombard":{"count":55},"Palawan Pawnshop":{"count":52}},"pet":{"Das Futterhaus":{"count":158},"Fressnapf":{"count":620},"Global Pet Foods":{"count":54},"Maxi Zoo":{"count":65},"Pet Valu":{"count":112},"PetSmart":{"count":491},"Petco":{"count":377},"Pets at Home":{"count":170},"Бетховен":{"count":60},"Зоотовары":{"count":79},"Четыре лапы":{"count":56}},"second_hand":{"Goodwill":{"count":235},"Value Village":{"count":53}},"shoes":{"Adidas":{"count":51},"Aldo":{"count":74},"Bata":{"count":281},"Besson Chaussures":{"count":124},"Brantano":{"count":132},"CCC":{"count":245},"Camper":{"count":51},"Chaussea":{"count":102},"Clarks":{"count":268},"Converse":{"count":58},"Crocs":{"count":64},"DSW":{"count":52},"Deichmann":{"count":1231},"Dosenbach":{"count":58},"Ecco":{"count":185},"Famous Footwear":{"count":178},"Foot Locker":{"count":240},"Geox":{"count":151},"Kari":{"count":66},"La Halle aux Chaussures":{"count":158},"Mephisto":{"count":57},"Minelli":{"count":55},"New Balance":{"count":52},"Payless":{"count":56},"Payless Shoe Source":{"count":316},"Payless ShoeSource":{"count":133},"Quick Schuh":{"count":116},"Rack Room Shoes":{"count":51},"Reno":{"count":233},"Rieker":{"count":83},"Salamander":{"count":103},"San Marina":{"count":54},"Scapino":{"count":67},"Shoe Carnival":{"count":66},"Shoe Zone":{"count":161},"Siemes Schuhcenter":{"count":69},"Skechers":{"count":83},"Tamaris":{"count":99},"Timberland":{"count":51},"vanHaren":{"count":98},"Éram":{"count":88},"Ремонт обуви":{"count":71},"ЦентрОбувь":{"count":76},"Юничел":{"count":73},"東京靴流通センター":{"count":81}},"sports":{"Adidas":{"count":132},"Aktiesport":{"count":61},"Big 5 Sporting Goods":{"count":93},"Decathlon":{"count":409},"Dick's Sporting Goods":{"count":222},"Hervis":{"count":66},"Intersport":{"count":737},"JD Sports":{"count":58},"Nike":{"count":95},"Sport 2000":{"count":209},"Sports Authority":{"count":108},"Sports Direct":{"count":217},"Спортмастер":{"count":208},"Спорттовары":{"count":68}},"stationery":{"Bureau Vallée":{"count":64},"Libro":{"count":73},"McPaper":{"count":158},"Office Depot":{"count":378},"Office Max":{"count":169},"Officeworks":{"count":73},"Pagro":{"count":64},"Paperchase":{"count":54},"Ryman":{"count":85},"Staples":{"count":671},"Канцтовары":{"count":140}},"supermarket":{"7-Eleven":{"count":60},"A&O":{"count":67},"A101":{"count":388},"AD Delhaize":{"count":80},"ADEG":{"count":85},"Ahorramás":{"count":66},"Albert":{"count":245},"Albert Heijn":{"count":766},"Albertsons":{"count":316},"Aldi":{"count":6323},"Aldi Nord":{"count":356},"Aldi Süd":{"count":916},"Alfamart":{"count":109},"Alimerka":{"count":96},"Alnatura":{"count":97},"Asda":{"count":474},"Atac":{"count":53},"Atacadão":{"count":80},"Auchan":{"count":229},"BM":{"count":52},"Biedronka":{"count":2348},"Big C":{"count":53},"Billa":{"count":1592},"Bim":{"count":678},"Biocoop":{"count":159},"Bodega Aurrera":{"count":264},"Budgens":{"count":77},"Bulk Barn":{"count":54},"Bunnpris":{"count":69},"CBA":{"count":236},"CONAD":{"count":67},"COOP":{"count":255},"COOP Jednota":{"count":177},"CRAI":{"count":66},"CU":{"count":64},"Caprabo":{"count":144},"Cargills Food City":{"count":79},"Carrefour":{"count":2544},"Carrefour City":{"count":349},"Carrefour Contact":{"count":270},"Carrefour Express":{"count":921},"Centra":{"count":63},"Centre Commercial E. Leclerc":{"count":385},"Checkers":{"count":140},"Chedraui":{"count":80},"Co-Op":{"count":62},"Co-op":{"count":352},"Co-operative":{"count":51},"Coles":{"count":583},"Colmado":{"count":103},"Colruyt":{"count":212},"Combi":{"count":127},"Comercial Mexicana":{"count":59},"Conad":{"count":560},"Conad City":{"count":95},"Condis":{"count":126},"Consum":{"count":236},"Continente":{"count":111},"Coop":{"count":1665},"Coop Extra":{"count":88},"Coop Jednota":{"count":101},"Coop Konsum":{"count":96},"Costco":{"count":295},"Costcutter":{"count":93},"Coto":{"count":65},"Countdown":{"count":135},"Coviran":{"count":124},"Covirán":{"count":51},"Crai":{"count":119},"Cub Foods":{"count":57},"Dagli'Brugsen":{"count":135},"Deen":{"count":55},"Delhaize":{"count":228},"Delikatesy Centrum":{"count":209},"Denner":{"count":412},"Despar":{"count":209},"Despensa Familiar":{"count":81},"Dia":{"count":1329},"Dia %":{"count":181},"Dia Market":{"count":60},"Dino":{"count":298},"Dirk van den Broek":{"count":66},"Disco":{"count":74},"Diska":{"count":68},"Dollar General":{"count":106},"Dollar Tree":{"count":52},"Dunnes Stores":{"count":72},"E-Center":{"count":66},"E. Leclerc":{"count":186},"E. Leclerc Drive":{"count":97},"EKO":{"count":78},"EMTÉ":{"count":74},"Edeka":{"count":2231},"Ekom":{"count":64},"Ekono":{"count":68},"El Árbol":{"count":86},"Eroski":{"count":351},"Esselunga":{"count":106},"EuroSpin":{"count":81},"Eurospar":{"count":340},"Eurospin":{"count":328},"Extra":{"count":149},"Famiglia Cooperativa":{"count":89},"Famila":{"count":167},"Family Dollar":{"count":72},"Fareway":{"count":51},"Farmfoods":{"count":141},"Feneberg":{"count":64},"Food Basics":{"count":116},"Food Lion":{"count":425},"Foodland":{"count":192},"Foodworks":{"count":90},"Franprix":{"count":401},"Fred Meyer":{"count":70},"Freshmarket":{"count":86},"Froiz":{"count":97},"Føtex":{"count":74},"G20":{"count":71},"GS25":{"count":72},"Gadis":{"count":126},"Game":{"count":59},"Giant":{"count":276},"Giant Eagle":{"count":134},"Grand Frais":{"count":70},"Grocery Outlet":{"count":128},"Géant Casino":{"count":75},"H-E-B":{"count":274},"HIT":{"count":64},"Hannaford":{"count":95},"Harris Teeter":{"count":158},"Hemköp":{"count":87},"Heron Foods":{"count":55},"Hofer":{"count":484},"Hoogvliet":{"count":66},"Hruška":{"count":54},"Hy-Vee":{"count":121},"ICA":{"count":255},"ICA Kvantum":{"count":51},"IDEA":{"count":52},"IGA":{"count":568},"Iceland":{"count":538},"Indomaret":{"count":124},"Intermarché":{"count":1477},"Intermarché Contact":{"count":122},"Intermarché Super":{"count":261},"Interspar":{"count":117},"Irma":{"count":69},"Jewel-Osco":{"count":72},"Jumbo":{"count":476},"K+K":{"count":119},"Kaufland":{"count":1172},"King Soopers":{"count":99},"Kiwi":{"count":178},"Konsum":{"count":144},"Konzum":{"count":370},"Kroger":{"count":627},"Kvickly":{"count":60},"La Vie Claire":{"count":65},"Landi":{"count":54},"Leader Price":{"count":502},"Leclerc Drive":{"count":120},"Lewiatan":{"count":255},"Lider":{"count":78},"Lidl":{"count":8927},"Londis":{"count":52},"Lupa":{"count":79},"M&S Simply Food":{"count":52},"MPREIS":{"count":187},"Makro":{"count":226},"Markant":{"count":98},"Market Basket":{"count":57},"Marktkauf":{"count":117},"Match":{"count":139},"Maxi":{"count":198},"Maxi Dia":{"count":52},"Maxima":{"count":111},"Maxima X":{"count":158},"Maxima XX":{"count":69},"Mega Image":{"count":97},"Mego":{"count":52},"Meijer":{"count":129},"Meny":{"count":105},"Mercado Municipal":{"count":52},"Mercado de Abastos":{"count":57},"Mercadona":{"count":1228},"Mercator":{"count":155},"Merkur":{"count":132},"Metro":{"count":395},"Migros":{"count":641},"Mila":{"count":90},"Mini Market":{"count":81},"Minipreço":{"count":213},"Mix Markt":{"count":60},"Monoprix":{"count":283},"More":{"count":61},"Morrisons":{"count":443},"NORMA":{"count":144},"NP":{"count":251},"Nah & Frisch":{"count":107},"Nahkauf":{"count":324},"Netto":{"count":4429},"Netto Marken-Discount":{"count":706},"New World":{"count":89},"No Frills":{"count":177},"Norfa XL":{"count":66},"Norma":{"count":1162},"Oxxo":{"count":278},"PENNY":{"count":89},"PLUS":{"count":92},"POLOmarket":{"count":172},"Palí":{"count":69},"Pam":{"count":77},"Penny":{"count":2819},"Penny Markt":{"count":77},"Petit Casino":{"count":146},"Pick n Pay":{"count":268},"Piggly Wiggly":{"count":103},"Pingo Doce":{"count":308},"Piotr i Paweł":{"count":112},"Plaza Vea":{"count":68},"Plodine":{"count":67},"Poiesz":{"count":53},"Price Chopper":{"count":132},"Prix":{"count":53},"Profi":{"count":203},"Proxi":{"count":75},"Proxy Delhaize":{"count":63},"Publix":{"count":645},"Punto Simply":{"count":54},"Puregold":{"count":75},"Pão de Açúcar":{"count":76},"QFC":{"count":54},"REMA 1000":{"count":89},"Ralphs":{"count":81},"Real":{"count":210},"Real Canadian Superstore":{"count":69},"Reliance Fresh":{"count":95},"Rema 1000":{"count":394},"Rewe":{"count":2808},"Rewe City":{"count":78},"Rimi":{"count":115},"S-Market":{"count":110},"Safeway":{"count":619},"Sainsbury's":{"count":595},"Sainsbury's Local":{"count":248},"Sam's Club":{"count":303},"Santa Isabel":{"count":174},"Save-A-Lot":{"count":100,"tags":{"shop":"supermarket"}},"ShopRite":{"count":53},"Shoprite":{"count":337},"Sigma":{"count":107},"Simply Market":{"count":541},"Sky":{"count":113},"Smith's":{"count":56},"Sobeys":{"count":186},"Soriana":{"count":194},"Spar":{"count":3381},"Społem":{"count":120},"Sprouts Farmers Market":{"count":71},"Stokrotka":{"count":227},"Stop & Shop":{"count":147},"Super C":{"count":57},"Super U":{"count":654},"SuperBrugsen":{"count":183},"SuperValu":{"count":80},"Superama":{"count":51},"Supersol":{"count":51},"Superspar":{"count":54},"Tegut":{"count":118},"Tengelmann":{"count":155},"Tesco":{"count":1373},"Tesco Express":{"count":566},"Tesco Extra":{"count":200},"Tesco Lotus":{"count":95},"Tesco Metro":{"count":153},"The Co-operative":{"count":79},"The Co-operative Food":{"count":1261},"Tommy":{"count":56},"Tottus":{"count":82},"Trader Joe's":{"count":345},"Treff 3000":{"count":134},"U Express":{"count":129},"Unimarc":{"count":256},"Unimarkt":{"count":104},"Utile":{"count":68},"Vea":{"count":67},"Vival":{"count":80},"Volg":{"count":231},"Waitrose":{"count":301},"Walmart":{"count":1164},"Walmart Neighborhood Market":{"count":171},"Walmart Supercenter":{"count":688},"Wasgau":{"count":51},"Wegmans":{"count":89},"Wellcome":{"count":51},"Whole Foods Market":{"count":379,"tags":{"shop":"supermarket"}},"Willys":{"count":89},"WinCo Foods":{"count":53},"Winn Dixie":{"count":168},"Woolworths":{"count":816},"denn's Biomarkt":{"count":147},"fakta":{"count":296},"real":{"count":58},"tegut":{"count":89},"Şok":{"count":271},"Żabka":{"count":88},"ΑΒ Βασιλόπουλος":{"count":82},"Γαλαξίας":{"count":54},"Μασούτης":{"count":85},"Σκλαβενίτης":{"count":92},"АТБ":{"count":618},"Абсолют":{"count":51},"Авоська":{"count":60},"Азбука Вкуса":{"count":66},"Атак":{"count":85},"Ашан":{"count":80},"Верный":{"count":226},"Виктория":{"count":74},"Вопак":{"count":59},"Гастроном":{"count":54},"Гроздь":{"count":63},"Десяточка":{"count":52},"Дикси":{"count":1670},"Евроопт":{"count":201},"Карусель":{"count":68},"Квартал":{"count":77},"Кировский":{"count":54},"Командор":{"count":75},"Красный Яр":{"count":58},"Лента":{"count":165},"Магнит":{"count":4289},"Магнолия":{"count":121},"Мария-Ра":{"count":159},"Монетка":{"count":363},"Народная 7Я семьЯ":{"count":199},"Перекресток":{"count":501},"Покупочка":{"count":73},"Полушка":{"count":213},"Пятёрочка":{"count":3622},"Радеж":{"count":64},"Рукавичка":{"count":78},"Светофор":{"count":73},"Седьмой континент":{"count":69},"Семейный":{"count":52},"Семья":{"count":85},"Супермаркет":{"count":65},"Сільпо":{"count":203},"Таврія‑В":{"count":66},"Универсам":{"count":77},"Фора":{"count":162},"Фуршет":{"count":86},"Хүнсний дэлгүүр":{"count":63},"Эдельвейс":{"count":55},"хүнсний дэлгүүр":{"count":73},"بقالة":{"count":74},"سوپر مارکت":{"count":75},"سوپرمارکت":{"count":79},"いなげや":{"count":66},"まいばすけっと":{"count":162},"イオン":{"count":95},"イトーヨーカドー":{"count":67},"カスミ":{"count":56},"マックスバリュ":{"count":143},"マルエツ":{"count":99},"ライフ":{"count":125},"全聯":{"count":74},"全聯福利中心":{"count":241},"惠康 Wellcome":{"count":57},"業務スーパー":{"count":176},"美廉社":{"count":74},"西友":{"count":137}},"tailor":{"Atelier de couture":{"count":63}},"ticket":{"Boutique Grandes Lignes":{"count":60},"Guichet Transilien":{"count":243},"Касса":{"count":61},"Проездные билеты":{"count":65}},"tobacco":{"Dohánybolt":{"count":109},"Estanco":{"count":134},"Nemzeti Dohánybolt":{"count":926},"Tabacos":{"count":62},"Табакерка":{"count":73}},"toys":{"Dráčik":{"count":63},"Intertoys":{"count":242},"King Jouet":{"count":102},"La Grande Récré":{"count":112},"Maxi Toys":{"count":63},"Toys R Us":{"count":410,"tags":{"shop":"toys"}},"Детский мир":{"count":186},"Игрушки":{"count":95}},"travel_agency":{"D-reizen":{"count":64},"DER Reisebüro":{"count":52},"First Reisebüro":{"count":57},"Flight Centre":{"count":159},"Reiseland":{"count":52},"TUI":{"count":262},"The Co-operative Travel":{"count":58},"Thomas Cook":{"count":298},"Thomson":{"count":144}},"tyres":{"Borracharia":{"count":98},"Bridgestone":{"count":65},"Discount Tire":{"count":94},"Euromaster":{"count":76},"Firestone":{"count":57},"Gomeria":{"count":71},"Les Schwab Tire Center":{"count":59},"Vianor":{"count":52},"Вулканизация":{"count":113},"Шиномонтаж":{"count":419}},"variety_store":{"Action":{"count":147},"Bazar":{"count":56},"Big Bazar":{"count":60},"Big Lots":{"count":65},"Dollar General":{"count":345},"Dollar Tree":{"count":753},"Dollarama":{"count":404},"EuroShop":{"count":59},"Family Dollar":{"count":590},"Fix Price":{"count":97},"Fix price":{"count":127},"FixPrice":{"count":62},"GiFi":{"count":229},"Home Bargains":{"count":68},"Mäc-Geiz":{"count":59},"NOZ":{"count":82},"Poundland":{"count":197},"Poundworld":{"count":70},"Tedi":{"count":611},"ダイソー":{"count":226}},"video":{"Blockbuster":{"count":75},"Family Video":{"count":113},"TSUTAYA":{"count":122},"World of Video":{"count":53},"ゲオ":{"count":81}},"video_games":{"EB Games":{"count":101},"Game":{"count":76},"GameStop":{"count":676},"Micromania":{"count":83}}};
23633 var tourism = {"alpine_hut":{"КОШ":{"count":105}},"apartment":{"Двухкомнатная квартира на сутки":{"count":52}},"attraction":{"Arch":{"count":51},"Kursächsische Postmeilensäule":{"count":54},"Maibaum":{"count":52},"Moab trail":{"count":55},"Moai":{"count":702},"OWŚ":{"count":102},"Sommerrodelbahn":{"count":54},"path contiunes":{"count":75},"white blaze":{"count":53},"Кладбище еврейское":{"count":89},"Колесо обозрения":{"count":69},"Приусадебный парк":{"count":69},"Усадьба":{"count":53},"Хозяйственный двор":{"count":72},"Часовня":{"count":64},"дольмен":{"count":86}},"camp_site":{"Camping Municipal":{"count":198},"Camping municipal":{"count":80}},"guest_house":{"Casa":{"count":61},"Home":{"count":68},"OW \"Bielanka\"":{"count":54}},"hostel":{"Albergue de Peregrinos":{"count":67},"Hospedaje":{"count":70},"Hostal":{"count":124}},"hotel":{"B&B Hôtel":{"count":104},"B&b Hôtel":{"count":78},"Best Western":{"count":242},"Campanile":{"count":145},"Central Hotel":{"count":51},"City Hotel":{"count":74},"Comfort Inn":{"count":283},"Comfort Inn & Suites":{"count":67},"Comfort Suites":{"count":148},"Country Inn & Suites":{"count":83},"Courtyard by Marriott":{"count":155},"Crowne Plaza":{"count":85},"Days Inn":{"count":245},"Econo Lodge":{"count":70},"Embassy Suites":{"count":68},"Extended Stay America":{"count":102},"Fairfield Inn":{"count":60},"Fairfield Inn & Suites":{"count":67},"Formule 1":{"count":74},"Grand Hotel":{"count":90},"Hampton Inn":{"count":376},"Hampton Inn & Suites":{"count":96},"Hilton Garden Inn":{"count":183},"Holiday Inn":{"count":411},"Holiday Inn Express":{"count":479},"Holiday Inn Express & Suites":{"count":72},"Homewood Suites":{"count":61},"Hotel Central":{"count":92},"Hotel Europa":{"count":91},"Hotel Ibis":{"count":67},"Hotel Krone":{"count":58},"Hotel Panorama":{"count":61},"Hotel Plaza":{"count":62},"Hotel Post":{"count":60},"Hotel Royal":{"count":62},"Hotel Victoria":{"count":71},"Hotel zur Post":{"count":60},"Hôtel Ibis":{"count":70},"Hôtel de France":{"count":61},"Ibis":{"count":215},"Ibis Budget":{"count":188},"Ibis Styles":{"count":53},"Krone":{"count":68},"Kyriad":{"count":65},"La Quinta":{"count":54},"Marriott":{"count":57},"Mercure":{"count":109},"Motel 6":{"count":83},"Novotel":{"count":180},"Palace Hotel":{"count":54},"Park Hotel":{"count":88},"Parkhotel":{"count":64},"Premier Inn":{"count":400},"Première Classe":{"count":62},"Quality Inn":{"count":178},"Quality Inn & Suites":{"count":80},"Ramada":{"count":97},"Residence Inn":{"count":89},"Royal Hotel":{"count":94},"Sheraton":{"count":56},"Sleep Inn":{"count":68},"Staybridge Suites":{"count":54},"Super 8":{"count":229},"Travelodge":{"count":284},"Гостиница":{"count":166},"Уют":{"count":58},"東横イン":{"count":57}},"motel":{"Best Western":{"count":59},"Budget Inn":{"count":76},"Comfort Inn":{"count":131},"Days Inn":{"count":103},"Econo Lodge":{"count":117},"Motel 6":{"count":214},"Quality Inn":{"count":113},"Rodeway Inn":{"count":102},"Super 8":{"count":173},"Travelodge":{"count":68}},"museum":{"Heimatmuseum":{"count":336},"Stadtmuseum":{"count":86},"Tájház":{"count":93},"Краеведческий музей":{"count":247},"Музей":{"count":99}}};
23634 var dataSuggestions = {
23635         amenity: amenity,
23636         leisure: leisure,
23637         man_made: man_made,
23638         shop: shop,
23639         tourism: tourism
23640 };
23641
23642 var dataAddressFormats = [{"format":[["housenumber","street"],["city","postcode"]]},{"countryCodes":["gb"],"format":[["housename"],["housenumber","street"],["city","postcode"]]},{"countryCodes":["ie"],"format":[["housename"],["housenumber","street"],["city"],["postcode"]]},{"countryCodes":["at","ch","de","si"],"format":[["street","housenumber"],["postcode","city"]]},{"countryCodes":["ad","ba","be","cz","dk","es","fi","gr","hr","is","it","li","nl","no","pt","se","sk","sm","va"],"format":[["street","housenumber","unit"],["postcode","city"]]},{"countryCodes":["pl"],"format":[["street","housenumber"],["postcode"],["place","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":["au","ca"],"format":[["housenumber","street","unit"],["city","province","postcode"]]},{"countryCodes":["us"],"format":[["housenumber","street","unit"],["city","state","postcode"]]},{"countryCodes":["tw"],"format":[["postcode","city","district"],["place","street"],["housenumber","floor","unit"]]},{"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"]]},{"countryCodes":["ua"],"format":[["housenumber","postcode"],["street"]]},{"countryCodes":["cn"],"format":[["postcode","province"],["city","district"],["street","housenumber"]]}];
23643
23644 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"}}];
23645
23646 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"];
23647
23648 var dataLocales = {"af":{"rtl":false},"ar":{"rtl":true},"ar-AA":{"rtl":true},"ast":{"rtl":false},"be":{"rtl":false},"bg":{"rtl":false},"bg-BG":{"rtl":false},"bn":{"rtl":false},"bs":{"rtl":false},"ca":{"rtl":false},"cs":{"rtl":false},"cy":{"rtl":false},"da":{"rtl":false},"de":{"rtl":false},"dv":{"rtl":true},"el":{"rtl":false},"en-GB":{"rtl":false},"eo":{"rtl":false},"es":{"rtl":false},"et":{"rtl":false},"eu":{"rtl":false},"fa":{"rtl":true},"fi":{"rtl":false},"fr":{"rtl":false},"gan":{"rtl":false},"gl":{"rtl":false},"gu":{"rtl":false},"he":{"rtl":true},"hi":{"rtl":false},"hr":{"rtl":false},"hu":{"rtl":false},"hy":{"rtl":false},"ia":{"rtl":false},"id":{"rtl":false},"is":{"rtl":false},"it":{"rtl":false},"ja":{"rtl":false},"jv":{"rtl":false},"km":{"rtl":false},"kn":{"rtl":false},"ko":{"rtl":false},"ku":{"rtl":true},"lij":{"rtl":false},"lt":{"rtl":false},"lv":{"rtl":false},"mg":{"rtl":false},"mk":{"rtl":false},"ml":{"rtl":false},"mn":{"rtl":false},"ms":{"rtl":false},"ne":{"rtl":false},"nl":{"rtl":false},"nn":{"rtl":false},"no":{"rtl":false},"nv":{"rtl":false},"pl":{"rtl":false},"pt":{"rtl":false},"pt-BR":{"rtl":false},"rm":{"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},"ur":{"rtl":true},"vi":{"rtl":false},"yue":{"rtl":false},"zh":{"rtl":false},"zh-CN":{"rtl":false},"zh-HK":{"rtl":false},"zh-TW":{"rtl":false}};
23649
23650 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","cn":"+86 10 12345678","tw":"+886 1 2345 6789","tr":"+90 312 123 4567","ua":"+380 44 123 4567","at":"+43 1 123 45 67","ci":"+225 20 12 34 56","bj":"+229 20 12 34 56"};
23651
23652 var dataShortcuts = [{"tab":"browsing","text":"shortcuts.browsing.title","columns":[{"rows":[{"section":"navigation","text":"shortcuts.browsing.navigation.title"},{"shortcuts":["↓","↑","←","→"],"text":"shortcuts.browsing.navigation.pan","separator":","},{"modifiers":["⌘"],"shortcuts":["↓","↑","←","→"],"text":"shortcuts.browsing.navigation.pan_more","separator":","},{"shortcuts":["+","-"],"text":"shortcuts.browsing.navigation.zoom","separator":","},{"modifiers":["⌘"],"shortcuts":["+","-"],"text":"shortcuts.browsing.navigation.zoom_more","separator":","},{"section":"help","text":"shortcuts.browsing.help.title"},{"shortcuts":["help.key"],"text":"shortcuts.browsing.help.help"},{"shortcuts":["shortcuts.toggle.key"],"text":"shortcuts.browsing.help.keyboard"},{"section":"display_options","text":"shortcuts.browsing.display_options.title"},{"shortcuts":["background.key"],"text":"shortcuts.browsing.display_options.background"},{"modifiers":["⌘"],"shortcuts":["background.key"],"text":"shortcuts.browsing.display_options.background_switch"},{"shortcuts":["map_data.key"],"text":"shortcuts.browsing.display_options.map_data"},{"modifiers":["⌃","⌘"],"shortcuts":["F","F11"],"text":"shortcuts.browsing.display_options.fullscreen"},{"shortcuts":["area_fill.wireframe.key"],"text":"shortcuts.browsing.display_options.wireframe"},{"shortcuts":["background.minimap.key"],"text":"shortcuts.browsing.display_options.minimap"}]},{"rows":[{"section":"selecting","text":"shortcuts.browsing.selecting.title"},{"shortcuts":["Left-click"],"text":"shortcuts.browsing.selecting.select_one"},{"modifiers":["⇧"],"shortcuts":["Left-click"],"text":"shortcuts.browsing.selecting.select_multi"},{"modifiers":["⇧"],"shortcuts":["Left-click"],"gesture":"shortcuts.gesture.drag","text":"shortcuts.browsing.selecting.lasso"},{"modifiers":["⌘"],"shortcuts":["F"],"text":"shortcuts.browsing.selecting.search"},{"section":"with_selected","text":"shortcuts.browsing.with_selected.title"},{"shortcuts":["Right-click","shortcuts.key.space"],"text":"shortcuts.browsing.with_selected.edit_menu"},{"shortcuts":[],"text":""},{"section":"vertex_selected","text":"shortcuts.browsing.vertex_selected.title"},{"shortcuts":["[","↖"],"text":"shortcuts.browsing.vertex_selected.previous"},{"shortcuts":["]","↘"],"text":"shortcuts.browsing.vertex_selected.next"},{"shortcuts":["{","⇞"],"text":"shortcuts.browsing.vertex_selected.first"},{"shortcuts":["}","⇟"],"text":"shortcuts.browsing.vertex_selected.last"},{"shortcuts":["\\","shortcuts.key.pause"],"text":"shortcuts.browsing.vertex_selected.change_parent"}]}]},{"tab":"editing","text":"shortcuts.editing.title","columns":[{"rows":[{"section":"drawing","text":"shortcuts.editing.drawing.title"},{"shortcuts":["1"],"text":"shortcuts.editing.drawing.add_point"},{"shortcuts":["2"],"text":"shortcuts.editing.drawing.add_line"},{"shortcuts":["3"],"text":"shortcuts.editing.drawing.add_area"},{"shortcuts":["Left-click","shortcuts.key.space"],"text":"shortcuts.editing.drawing.place_point"},{"shortcuts":["⌥"],"text":"shortcuts.editing.drawing.disable_snap"},{"shortcuts":["↵","⎋"],"text":"shortcuts.editing.drawing.stop_line"},{"section":"commands","text":"shortcuts.editing.commands.title"},{"modifiers":["⌘"],"shortcuts":["C"],"text":"shortcuts.editing.commands.copy"},{"modifiers":["⌘"],"shortcuts":["V"],"text":"shortcuts.editing.commands.paste"},{"modifiers":["⌘"],"shortcuts":["Z"],"text":"shortcuts.editing.commands.undo"},{"modifiers":["⌘","⇧"],"shortcuts":["Z"],"text":"shortcuts.editing.commands.redo"},{"modifiers":["⌘"],"shortcuts":["S"],"text":"shortcuts.editing.commands.save"}]},{"rows":[{"section":"operations","text":"shortcuts.editing.operations.title"},{"shortcuts":["operations.continue.key"],"text":"shortcuts.editing.operations.continue_line"},{"shortcuts":["operations.merge.key"],"text":"shortcuts.editing.operations.merge"},{"shortcuts":["operations.disconnect.key"],"text":"shortcuts.editing.operations.disconnect"},{"shortcuts":["operations.split.key"],"text":"shortcuts.editing.operations.split"},{"shortcuts":["operations.reverse.key"],"text":"shortcuts.editing.operations.reverse"},{"shortcuts":["operations.move.key"],"text":"shortcuts.editing.operations.move"},{"shortcuts":["operations.rotate.key"],"text":"shortcuts.editing.operations.rotate"},{"shortcuts":["operations.orthogonalize.key"],"text":"shortcuts.editing.operations.orthogonalize"},{"shortcuts":["operations.circularize.key"],"text":"shortcuts.editing.operations.circularize"},{"shortcuts":["operations.reflect.key.long"],"text":"shortcuts.editing.operations.reflect_long"},{"shortcuts":["operations.reflect.key.short"],"text":"shortcuts.editing.operations.reflect_short"},{"modifiers":["⌘"],"shortcuts":["⌫"],"text":"shortcuts.editing.operations.delete"}]}]},{"tab":"tools","text":"shortcuts.tools.title","columns":[{"rows":[{"section":"info","text":"shortcuts.tools.info.title"},{"modifiers":["⌘"],"shortcuts":["info_panels.key"],"text":"shortcuts.tools.info.all"},{"modifiers":["⌘","⇧"],"shortcuts":["info_panels.background.key"],"text":"shortcuts.tools.info.background"},{"modifiers":["⌘","⇧"],"shortcuts":["info_panels.history.key"],"text":"shortcuts.tools.info.history"},{"modifiers":["⌘","⇧"],"shortcuts":["info_panels.location.key"],"text":"shortcuts.tools.info.location"},{"modifiers":["⌘","⇧"],"shortcuts":["info_panels.measurement.key"],"text":"shortcuts.tools.info.measurement"}]}]}];
23653
23654 var type$2 = "FeatureCollection";
23655 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]]]}}];
23656 var dataImperial = {
23657         type: type$2,
23658         features: features
23659 };
23660
23661 var type$3 = "FeatureCollection";
23662 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]]]}}];
23663 var dataDriveLeft = {
23664         type: type$3,
23665         features: features$1
23666 };
23667
23668 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."},"drag_node":{"connected_to_hidden":"This can't be edited because it is connected to a hidden feature."}},"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."},"too_large":{"single":"This feature can't be deleted because not enough of it is currently visible.","multiple":"These features can't be deleted because not enough of them are currently visible."},"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 their endpoints 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":{"long":"Reflect Long","short":"Reflect Short"},"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 a feature across its long axis.","multiple":"Reflected multiple features across their long axis."},"short":{"single":"Reflected a 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","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.","request_review":"I would like someone to review my edits.","save":"Upload","cancel":"Cancel","changes":"{count} Changes","download_changes":"Download osmChange file","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":"https://www.openstreetmap.org/copyright"},"contributors":{"list":"Edits by {users}","truncated_list":"Edits by {users} and {count} others"},"info_panels":{"key":"I","background":{"key":"B","title":"Background","zoom":"Zoom","vintage":"Vintage","source":"Source","description":"Description","resolution":"Resolution","accuracy":"Accuracy","unknown":"Unknown","show_tiles":"Show Tiles","hide_tiles":"Hide Tiles","show_vintage":"Show Vintage","hide_vintage":"Hide Vintage"},"history":{"key":"H","title":"History","selected":"{n} selected","version":"Version","last_edit":"Last Edit","edited_by":"Edited By","changeset":"Changeset","unknown":"Unknown","link_text":"History on openstreetmap.org"},"location":{"key":"L","title":"Location","unknown_location":"Unknown Location"},"measurement":{"key":"M","title":"Measurement","selected":"{n} selected","geometry":"Geometry","closed_line":"closed line","closed_area":"closed area","center":"Center","perimeter":"Perimeter","length":"Length","area":"Area","centroid":"Centroid","location":"Location","metric":"Metric","imperial":"Imperial","node_count":"Number of nodes"}},"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","reverser":"Change Direction"},"radio":{"structure":{"type":"Type","default":"Default","layer":"Layer"}},"add":"Add","none":"None","node":"Node","way":"Way","relation":"Relation","location":"Location","add_fields":"Add field:"},"background":{"title":"Background","description":"Background settings","key":"B","backgrounds":"Backgrounds","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:\n   - {zoom} or {z}, {x}, {y} for Z/X/Y tile scheme\n   - {-y} or {ty} for flipped TMS-style Y coordinates\n   - {u} for quadtile scheme\n   - {switch:a,b,c} for DNS server multiplexing\n\nExample:\n{example}","overlays":"Overlays","imagery_source_faq":"Imagery Info / Report a Problem","reset":"reset","display_options":"Display Options","brightness":"Brightness","contrast":"Contrast","saturation":"Saturation","sharpness":"Sharpness","minimap":{"description":"Show Minimap","tooltip":"Show a zoomed out map to help locate the area currently displayed.","key":"/"},"fix_misalignment":"Adjust imagery offset","offset":"Drag anywhere in the gray area below to adjust the imagery offset, or enter the offset values in meters."},"map_data":{"title":"Map Data","description":"Map Data","key":"F","data_layers":"Data Layers","layers":{"osm":{"tooltip":"Map data from OpenStreetMap","title":"OpenStreetMap data"}},"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.","osmhidden":"These features have been automatically hidden because the OpenStreetMap layer is hidden."},"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.","key":"W"},"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 my changes","reset":"Discard my changes"},"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...","conflict_progress":"Checking for conflicts: {num} of {total}","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 osmChange file","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":"OK","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"},"version":{"whats_new":"What's new in iD {version}"},"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 or building entrances.","old_multipolygon":"Multipolygon tags on outer way","old_multipolygon_tooltip":"This style of multipolygon is deprecated. Please assign the tags to the parent multipolygon instead of the outer way.","untagged_point":"Untagged point","untagged_point_tooltip":"Select a feature type that describes what this point is.","untagged_line":"Untagged line","untagged_line_tooltip":"Select a feature type that describes what this line is.","untagged_area":"Untagged area","untagged_area_tooltip":"Select a feature type that describes what this area is.","untagged_relation":"Untagged relation","untagged_relation_tooltip":"Select a feature type that describes what this relation is.","many_deletions":"You're deleting {n} features: {p} nodes, {l} lines, {a} areas, {r} relations. 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","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"},"openstreetcam_images":{"tooltip":"Street-level photos from OpenStreetCam","title":"Photo Overlay (OpenStreetCam)"},"openstreetcam":{"view_on_openstreetcam":"View this image on OpenStreetCam"},"help":{"title":"Help","key":"H","help":{"title":"Help","welcome":"Welcome to the iD editor for [OpenStreetMap](https://www.openstreetmap.org/). With this editor you can update OpenStreetMap right from your web browser.","open_data_h":"Open Data","open_data":"Edits that you make on this map will be visible to everyone who uses OpenStreetMap. Your edits can be based on personal knowledge, on-the-ground surveying, or imagery collected from aerial or street level photos. Copying from commercial sources, like Google Maps, [is strictly forbidden](https://www.openstreetmap.org/copyright).","before_start_h":"Before you start","before_start":"You should be familiar with OpenStreetMap and this editor before you start editing. iD contains a walkthrough to teach you the basics of editing OpenStreetMap. Click \"Start the Walkthrough\" on this screen to take the tutorial - it takes only about 15 minutes.","open_source_h":"Open Source","open_source":"The iD editor is a collaborative open source project, and you are using version {version} now. The source code is available [on GitHub](https://github.com/openstreetmap/iD).","open_source_help":"You can help iD by [translating](https://github.com/openstreetmap/iD/blob/master/CONTRIBUTING.md#translating) or [reporting bugs](https://github.com/openstreetmap/iD/issues)."},"overview":{"title":"Overview","navigation_h":"Navigation","navigation_drag":"You can drag the map by pressing and holding down the {leftclick} left mouse button and moving the mouse around. You can also use the `↓`, `↑`, `←`, `→` arrow keys on your keyboard.","navigation_zoom":"You can zoom in or out by scrolling with the mouse wheel or trackpad, or by clicking the {plus} / {minus} buttons along the side of the map. You can also use the `+`, `-` keys on your keyboard.","features_h":"Map Features","features":"We use the word *features* to describe things that appear on the map, such as roads, buildings, or points of interest. Anything in the real world can be mapped as a feature on OpenStreetMap. Map features are represented on the map using *points*, *lines*, or *areas*.","nodes_ways":"In OpenStreetmap, points are sometimes called *nodes*, and lines and areas are sometimes called *ways*."},"editing":{"title":"Editing & Saving","select_h":"Select","select_left_click":"{leftclick} Left-click on a feature to select it. This will highlight it with a pulsing glow, and the sidebar will display details about that feature, such as its name or address.","select_right_click":"{rightclick} Right-click on a feature to display the editing menu, which shows the commands that are available, such as rotating, moving, and deleting.","multiselect_h":"Multiselect","multiselect_shift_click":"`{shift}`+{leftclick} left-click to select several features together.  This makes it easier to move or delete multiple items.","multiselect_lasso":"Another way to select multiple features is to hold down the `{shift}` key, then press and hold down the {leftclick} left mouse button and drag the mouse to draw a selection lasso. All of the points inside the lasso area will be selected.","undo_redo_h":"Undo & Redo","undo_redo":"Your edits are stored locally in your browser until you choose to save them to the OpenStreetMap server. You can undo edits by clicking the {undo} **Undo** button, and redo them by clicking the {redo} **Redo** button.","save_h":"Save","save":"Click {save} **Save** to finish your edits and send them to OpenStreetMap. You should remember to save your work frequently!","save_validation":"On the save screen, you'll have a chance to review what you've done. iD will also perform some basic checks for missing data and may offer helpful suggestions and warnings if something doesn't seem right.","upload_h":"Upload","upload":"Before uploading your changes you must enter a [changeset comment](https://wiki.openstreetmap.org/wiki/Good_changeset_comments). Then click **Upload** to send your changes to OpenStreetMap, where they will be merged into the map and publicly visible to everyone.","backups_h":"Automatic Backups","backups":"If you can't finish your edits in one sitting, for example if your computer crashes or you close the browser tab, your edits are still saved in your browser's storage. You can come back later (on the same browser and computer), and iD will offer to restore your work.","keyboard_h":"Keyboard Shortcuts","keyboard":"You can view a list of keyboard shortcuts by pressing the `?` key."},"feature_editor":{"title":"Feature Editor","intro":"The *feature editor* appears alongside the map, and allows you to see and edit all of the information for the selected feature.","definitions":"The top section displays the feature's type. The middle section contains *fields* showing the feature's attributes, such as its name or address.","type_h":"Feature Type","type":"You can click on the feature type to change the feature to a different type. Everything that exists in the real world can be added to OpenStreetMap, so there are thousands of feature types to choose from.","type_picker":"The type picker displays the most common feature types, such as parks, hospitals, restaurants, roads, and buildings. You can search for anything by typing what you're looking for in the search box. You can also click the {inspect} **Info** icon next to the feature type to learn more about it.","fields_h":"Fields","fields_all_fields":"The \"All fields\" section contains all of the feature's details that you may edit. In OpenStreetMap, all of the fields are optional, and it's OK to leave a field blank if you are unsure.","fields_example":"Each feature type will display different fields. For example, a road may display fields for its surface and speed limit, but a restaurant may display fields for the type of food it serves and the hours it is open.","fields_add_field":"You can also click the \"Add field\" dropdown to add more fields, such as a description, Wikipedia link, wheelchair access, and more.","tags_h":"Tags","tags_all_tags":"Below the fields section, you can expand the \"All tags\" section to edit any of the OpenStreetMap *tags* for the selected feature. Each tag consists of a *key* and *value*, data elements that define all of the features stored in OpenStreetMap.","tags_resources":"Editing a feature's tags requires intermediate knowledge about OpenStreetMap. You should consult resources like the [OpenStreetMap Wiki](https://wiki.openstreetmap.org/wiki/Main_Page) or [Taginfo](https://taginfo.openstreetmap.org/) to learn more about accepted OpenStreetMap tagging practices."},"points":{"title":"Points","intro":"*Points* can be used to represent features such as shops, restaurants, and monuments. They mark a specific location, and describe what's there.","add_point_h":"Adding Points","add_point":"To add a point, click the {point} **Point** button on the toolbar above the map, or press the shortcut key `1`. This will change the mouse cursor to a cross symbol.","add_point_finish":"To place the new point on the map, position the mouse cursor where the point should go, then {leftclick} left-click or press `Space`.","move_point_h":"Moving Points","move_point":"To move a point, place the mouse cursor over the point, then press and hold the {leftclick} left mouse button while dragging the point to its new location.","delete_point_h":"Deleting Points","delete_point":"It's OK to delete features that don't exist in the real world. Deleting a feature from OpenStreetMap removes it from the map that everyone uses, so you should make sure a feature is really gone before you delete it.","delete_point_command":"To delete a point, {rightclick} right-click on the point to select it and show the edit menu, then use the {delete} **Delete** command."},"lines":{"title":"Lines","intro":"*Lines* are used to represent features such as roads, railroads, and rivers. Lines should be drawn down the center of the feature that they represent.","add_line_h":"Adding Lines","add_line":"To add a line, click the {line} **Line** button on the toolbar above the map, or press the shortcut key `2`. This will change the mouse cursor to a cross symbol.","add_line_draw":"Next, position the mouse cursor where the line should begin and {leftclick} left-click or press `Space` to begin placing nodes along the line. Continue placing more nodes by clicking or pressing `Space`. While drawing, you can zoom in or drag the map in order to add more detail.","add_line_finish":"To finish a line, press `{return}` or click again on the last node.","modify_line_h":"Modifying Lines","modify_line_dragnode":"Often you'll see lines that aren't shaped correctly, for example a road that does not match up with the background imagery. To adjust the shape of a line, first {leftclick} left-click to select it. All nodes of the line will be drawn as small circles. You can then drag the nodes to better locations.","modify_line_addnode":"You can also create new nodes along a line either by {leftclick}**x2** double-clicking on the line or by dragging the small triangles at the midpoints between nodes.","connect_line_h":"Connecting Lines","connect_line":"Having roads connected properly is important for the map and essential for providing driving directions.","connect_line_display":"The connections between roads are drawn with gray circles. The endpoints of a line are drawn with larger white circles if they don't connect to anything.","connect_line_drag":"To connect a line to another feature, drag one of the line's nodes onto the other feature until both features snap together. Tip: You can hold down the `{alt}` key to prevent nodes from connecting to other features.","connect_line_tag":"If you know that the connection has traffic lights or crosswalks, you can add them by selecting the connecting node and using the feature editor to select the correct feature's type.","disconnect_line_h":"Disconnecting Lines","disconnect_line_command":"To disconnect a road from another feature, {rightclick} right-click the connecting node and select the {disconnect} **Disconnect** command from the editing menu.","move_line_h":"Moving Lines","move_line_command":"To move an entire line, {rightclick} right-click the line and select the {move} **Move** command from the editing menu. Then move the mouse, and {leftclick} left-click to place the line in a new location.","move_line_connected":"Lines that are connected to other features will stay connected as you move the line to a new location. iD may prevent you from moving a line across another connected line.","delete_line_h":"Deleting Lines","delete_line":"If a line is entirely incorrect, for example a road that doesn't exist in the real world, it's OK to delete it. Be careful when deleting features: the background imagery you are using might be outdated, and a road that looks wrong could simply be newly built.","delete_line_command":"To delete a line, {rightclick} right-click on the line to select it and show the edit menu, then use the {delete} **Delete** command."},"areas":{"title":"Areas","intro":"*Areas* are used to show the boundaries of features like lakes, buildings, and residential areas. Areas should be traced around the edge of the feature that they represent, for example, around the base of a building.","point_or_area_h":"Points or Areas?","point_or_area":"Many features can be represented as points or areas. You should map buildings and property outlines as areas whenever possible. Place points inside a building area to represent businesses, amenities, and other features located inside the building.","add_area_h":"Adding Areas","add_area_command":"To add an area, click the {area} **Area** button on the toolbar above the map, or press the shortcut key `3`. This will change the mouse cursor to a cross symbol.","add_area_draw":"Next, position the mouse cursor at one of the corners of the feature and {leftclick} left-click or press `Space` to begin placing nodes around the outer edge of the area. Continue placing more nodes by clicking or pressing `Space`. While drawing, you can zoom in or drag the map in order to add more detail.","add_area_finish":"To finish an area, press `{return}` or click again on either the first or last node.","square_area_h":"Square Corners","square_area_command":"Many area features like buildings have square corners. To square the corners of an area, {rightclick} right-click the edge of the area and select the {orthogonalize} **Square** command from the editing menu.","modify_area_h":"Modifying Areas","modify_area_dragnode":"Often you'll see areas that aren't shaped correctly, for example a building that does not match up with the background imagery. To adjust the shape of an area, first {leftclick} left-click to select it. All nodes of the area will be drawn as small circles. You can then drag the nodes to better locations.","modify_area_addnode":"You can also create new nodes along an area either by {leftclick}**x2** double-clicking on the edge of the area or by dragging the small triangles at the midpoints between nodes.","delete_area_h":"Deleting Areas","delete_area":"If an area is entirely incorrect, for example a building that doesn't exist in the real world, it's OK to delete it. Be cautious when deleting features - the background imagery you are using might be outdated, and a building that looks wrong could simply be newly built.","delete_area_command":"To delete an area, {rightclick} right-click on the area to select it and show the edit menu, then use the {delete} **Delete** command."},"relations":{"title":"Relations","intro":"A *relation* is a special type of feature in OpenStreetMap that groups together other features. The features that belong to a relation are called *members*, and each member can have a *role* in the relation.","edit_relation_h":"Editing Relations","edit_relation":"At the bottom of the feature editor, you can expand the \"All relations\" section to see if the selected feature is a member of any relations. You can then click on the relation to select and edit it.","edit_relation_add":"To add a feature to a relation, select the feature, then click the {plus} add button in the \"All relations\" section of the feature editor. You can choose from a list of nearby relations, or choose the \"New relation...\" option.","edit_relation_delete":"You can also click the {delete} **Delete** button to remove the selected feature from the relation. If you remove all of the members from a relation, the relation will be deleted automatically.","maintain_relation_h":"Maintaining Relations","maintain_relation":"For the most part, iD will maintain relations automatically as you edit. You should take care when replacing features that might be members of relations. For example if you delete a section of road and draw a new section of road to replace it, you should add the new section to the same relations (routes, turn restrictions, etc.) as the original.","relation_types_h":"Relation Types","multipolygon_h":"Multipolygons","multipolygon":"A *multipolygon* relation is a group of one or more *outer* features and one or more inner features. The outer features define the outer edges of the multipolygon, and the inner features define sub-areas or holes cut out from the inside of the multipolygon.","multipolygon_create":"To create a multipolygon, for example a building with a hole in it, draw the outer edge as an area and the inner edge as a line or different kind of area. Then `{shift}`+{leftclick} left-click to select both features, {rightclick} right-click to show the edit menu, and select the {merge} **Merge** command.","multipolygon_merge":"Merging several lines or areas will create a new multipolygon relation with all selected areas as members. iD will choose the inner and outer roles automatically, based on which features are contained inside other features.","turn_restriction_h":"Turn restrictions","turn_restriction":"A *turn restriction* relation is a group of several road segments in an intersection. Turn restrictions consist of a *from* road, *via* node or roads, and a *to* road.","turn_restriction_field":"To edit turn restrictions, select a junction node where two or more roads meet. The feature editor will display a special \"Turn Restrictions\" field containing a model of the intersection.","turn_restriction_editing":"In the \"Turn Restrictions\" field, click to select a \"from\" road, and see whether turns are allowed or restricted to any of the \"to\" roads. You can click on the turn icons to toggle them between allowed and restricted. iD will create relations automatically and set the from, via, and to roles based on your choices.","route_h":"Routes","route":"A *route* relation is a group of one or more line features that together form a route network, like a bus route, train route, or highway route.","route_add":"To add a feature to a route relation, select the feature and scroll down to the \"All relations\" section of the feature editor, then click the {plus} add button to add this feature to a nearby existing relation or a new relation.","boundary_h":"Boundaries","boundary":"A *boundary* relation is a group of one or more line features that together form an administrative boundary.","boundary_add":"To add a feature to a boundary relation, select the feature and scroll down to the \"All relations\" section of the feature editor, then click the {plus} add button to add this feature to a nearby existing relation or a new relation."},"imagery":{"title":"Background Imagery","intro":"The background imagery that appears beneath the map data is an important resource for mapping. This imagery can be aerial photos collected from satellites, airplanes, and drones, or it can be scanned historical maps or other freely available source data.","sources_h":"Imagery Sources","choosing":"To see which imagery sources are available for editing, click the {layers} **Background settings** button on the side of the map.","sources":"By default, a [Bing Maps](https://www.bing.com/maps/) satellite layer is chosen as the background image. Depending on where you are editing, other imagery sources will be available. Some may be newer or have higher resolution, so it is always useful to check and see which layer is the best one to use as a mapping reference.","offsets_h":"Adjusting Imagery Offset","offset":"Imagery is sometimes offset slightly from accurate map data. If you see a lot of roads or buildings shifted from the background imagery, it may be the imagery that's incorrect, so don't move them all to match the background. Instead, you can adjust the background so that it matches the existing data by expanding the \"Adjust Imagery Offset\" section at the bottom of the Background Settings pane.","offset_change":"Click on the small triangles to adjust the imagery offset in small steps, or hold the left mouse button and drag within the gray square to slide the imagery into alignment."},"streetlevel":{"title":"Street Level Photos","intro":"Street level photos are useful for mapping traffic signs, businesses, and other details that you can't see from satellite and aerial images. The iD editor supports street level photos from [Mapillary](https://www.mapillary.com) and [OpenStreetCam](https://www.openstreetcam.org).","using_h":"Using Street Level Photos","using":"To use street level photos for mapping, click the {data} **Map data** panel on the side of the map to enable or disable the available photo layers.","photos":"When enabled, the photo layer displays a line along the sequence of photos. At higher zoom levels, a circle marks at each photo location, and at even higher zoom levels, a cone indicates the direction the camera was facing when the photo was taken.","viewer":"When you click on one of the photo locations, a photo viewer appears in the bottom corner of the map. The photo viewer contains controls to step forward and backward in the image sequence. It also shows the username of the person who captured the image, the date it was captured, and a link to view the image on the original site."},"gps":{"title":"GPS Traces","intro":"Collected GPS traces are a valuable source of data for OpenStreetMap. This editor supports *.gpx*, *.geojson*, and *.kml* files on your local computer. You can collect GPS traces with a smartphone, sports watch, or other GPS device.","survey":"For information on how to perform a GPS survey, read [Mapping with a smartphone, GPS, or paper](http://learnosm.org/en/mobile-mapping/).","using_h":"Using GPS Traces","using":"To use a GPS trace for mapping, drag and drop the data file onto the map editor. If it's recognized, it will be drawn on the map as a bright purple line. Click the {data} **Map data** panel on the side of the map to enable, disable, or zoom to your GPS data.","tracing":"The GPS track isn't sent to OpenStreetMap - the best way to use it is to draw on the map, using it as a guide for the new features that you add.","upload":"You can also [upload your GPS data to OpenStreetMap](https://www.openstreetmap.org/trace/create) for other users to use."}},"intro":{"done":"done","ok":"OK","graph":{"block_number":"<value for addr:block_number>","city":"Three Rivers","county":"<value for addr:county>","district":"<value for addr:district>","hamlet":"<value for addr:hamlet>","neighbourhood":"<value for addr:neighbourhood>","postcode":"49093","province":"<value for addr:province>","quarter":"<value for addr:quarter>","state":"MI","subdistrict":"<value for addr:subdistrict>","suburb":"<value for addr:suburb>","countrycode":"us","name":{"1st-avenue":"1st Avenue","2nd-avenue":"2nd Avenue","4th-avenue":"4th Avenue","5th-avenue":"5th Avenue","6th-avenue":"6th Avenue","6th-street":"6th Street","7th-avenue":"7th Avenue","8th-avenue":"8th Avenue","9th-avenue":"9th Avenue","10th-avenue":"10th Avenue","11th-avenue":"11th Avenue","12th-avenue":"12th Avenue","access-point-employment":"Access Point Employment","adams-street":"Adams Street","andrews-elementary-school":"Andrews Elementary School","andrews-street":"Andrews Street","armitage-street":"Armitage Street","barrows-school":"Barrows School","battle-street":"Battle Street","bennett-street":"Bennett Street","bowman-park":"Bowman Park","collins-drive":"Collins Drive","conrail-railroad":"Conrail Railroad","conservation-park":"Conservation Park","constantine-street":"Constantine Street","cushman-street":"Cushman Street","dollar-tree":"Dollar Tree","douglas-avenue":"Douglas Avenue","east-street":"East Street","elm-street":"Elm Street","flower-street":"Flower Street","foster-street":"Foster Street","french-street":"French Street","garden-street":"Garden Street","gem-pawnbroker":"Gem Pawnbroker","golden-finch-framing":"Golden Finch Framing","grant-avenue":"Grant Avenue","hoffman-pond":"Hoffman Pond","hoffman-street":"Hoffman Street","hook-avenue":"Hook Avenue","jefferson-street":"Jefferson Street","kelsey-street":"Kelsey Street","lafayette-park":"LaFayette Park","las-coffee-cafe":"L.A.'s Coffee Cafe","lincoln-avenue":"Lincoln Avenue","lowrys-books":"Lowry's Books","lynns-garage":"Lynn's Garage","main-street-barbell":"Main Street Barbell","main-street-cafe":"Main Street Cafe","main-street-fitness":"Main Street Fitness","main-street":"Main Street","maple-street":"Maple Street","marina-park":"Marina Park","market-street":"Market Street","memory-isle-park":"Memory Isle Park","memory-isle":"Memory Isle","michigan-avenue":"Michigan Avenue","middle-street":"Middle Street","millard-street":"Millard Street","moore-street":"Moore Street","morris-avenue":"Morris Avenue","mural-mall":"Mural Mall","paisanos-bar-and-grill":"Paisano's Bar and Grill","paisley-emporium":"Paisley Emporium","paparazzi-tattoo":"Paparazzi Tattoo","pealer-street":"Pealer Street","pine-street":"Pine Street","pizza-hut":"Pizza Hut","portage-avenue":"Portage Avenue","portage-river":"Portage River","preferred-insurance-services":"Preferred Insurance Services","railroad-drive":"Railroad Drive","river-city-appliance":"River City Appliance","river-drive":"River Drive","river-road":"River Road","river-street":"River Street","riverside-cemetery":"Riverside Cemetery","riverwalk-trail":"Riverwalk Trail","riviera-theatre":"Riviera Theatre","rocky-river":"Rocky River","saint-joseph-river":"Saint Joseph River","scidmore-park-petting-zoo":"Scidmore Park Petting Zoo","scidmore-park":"Scidmore Park","scouter-park":"Scouter Park","sherwin-williams":"Sherwin-Williams","south-street":"South Street","southern-michigan-bank":"Southern Michigan Bank","spring-street":"Spring Street","sturgeon-river-road":"Sturgeon River Road","three-rivers-city-hall":"Three Rivers City Hall","three-rivers-elementary-school":"Three Rivers Elementary School","three-rivers-fire-department":"Three Rivers Fire Department","three-rivers-high-school":"Three Rivers High School","three-rivers-middle-school":"Three Rivers Middle School","three-rivers-municipal-airport":"Three Rivers Municipal Airport","three-rivers-post-office":"Three Rivers Post Office","three-rivers-public-library":"Three Rivers Public Library","three-rivers":"Three Rivers","unique-jewelry":"Unique Jewelry","walnut-street":"Walnut Street","washington-street":"Washington Street","water-street":"Water Street","west-street":"West Street","wheeler-street":"Wheeler Street","william-towing":"William Towing","willow-drive":"Willow Drive","wood-street":"Wood Street","world-fare":"World Fare"}},"welcome":{"title":"Welcome","welcome":"Welcome! This walkthrough will teach you the basics of editing on OpenStreetMap.","practice":"All of the data in this walkthrough is just for practicing, and any edits that you make in the walkthrough will not be saved.","words":"This walkthrough will introduce some new words and concepts. When we introduce a new word, we'll use *italics*.","mouse":"You can use any input device to edit the map, but this walkthrough assumes you have a mouse with left and right buttons. **If you want to attach a mouse, do so now, then click OK.**","leftclick":"When this tutorial asks you to click or double-click, we mean with the left button. On a trackpad it might be a single-click or single-finger tap. **Left-click {num} times.**","rightclick":"Sometimes we'll also ask you to right-click. This might be the same as control-click, or two-finger tap on a trackpad. Your keyboard might even have a 'menu' key that works like right-click. **Right-click {num} times.**","chapters":"So far, so good! You can use the buttons below to skip chapters at any time or to restart a chapter if you get stuck. Let's begin! **Click '{next}' to continue.**"},"navigation":{"title":"Navigation","drag":"The main map area shows OpenStreetMap data on top of a background.{br}You can drag the map by pressing and holding the left mouse button while moving the mouse around. You can also use the arrow keys on your keyboard. **Drag the map!**","zoom":"You can zoom in or out by scrolling with the mouse wheel or trackpad, or by clicking the {plus} / {minus} buttons. **Zoom the map!**","features":"We use the word *features* to describe the things that appear on the map. Anything in the real world can be mapped as a feature on OpenStreetMap.","points_lines_areas":"Map features are represented using *points, lines, or areas.*","nodes_ways":"In OpenStreetMap, points are sometimes called *nodes*, and lines and areas are sometimes called *ways*.","click_townhall":"All features on the map can be selected by clicking on them. **Click on the point to select it.**","selected_townhall":"Great! The point is now selected. Selected features are drawn with a pulsing glow.","editor_townhall":"When a feature is selected, the *feature editor* is displayed alongside the map.","preset_townhall":"The top part of the feature editor shows the feature's type. This point is a {preset}.","fields_townhall":"The middle part of the feature editor contains *fields* showing the feature's attributes, such as its name and address.","close_townhall":"**Close the feature editor by hitting escape or pressing the {button} button in the upper corner.**","search_street":"You can also search for features in the current view, or worldwide. **Search for '{name}'.**","choose_street":"**Choose {name} from the list to select it.**","selected_street":"Great! {name} is now selected.","editor_street":"The fields shown for a street are different than the fields that were shown for the town hall.{br}For this selected street, the feature editor shows fields like '{field1}' and '{field2}'. **Close the feature editor by hitting escape or pressing the {button} button.**","play":"Try moving the map and clicking on some other features to see what kinds of things can be added to OpenStreetMap. **When you are ready to continue to the next chapter, click '{next}'.**"},"points":{"title":"Points","add_point":"*Points* can be used to represent features such as shops, restaurants, and monuments.{br}They mark a specific location, and describe what's there. **Click the {button} Point button to add a new point.**","place_point":"To place the new point on the map, position your mouse cursor where the point should go, then left-click or press the spacebar. **Move the mouse pointer over this building, then left-click or press the spacebar.**","search_cafe":"There are many different features that can be represented by points. The point you just added is a cafe. **Search for '{preset}'.**","choose_cafe":"**Choose {preset} from the list.**","feature_editor":"The point is now marked as a cafe. Using the feature editor, we can add more information about the cafe.","add_name":"In OpenStreetMap, all of the fields are optional, and it's OK to leave a field blank if you are unsure.{br}Let's pretend that you have local knowledge of this cafe, and you know its name. **Add a name for the cafe.**","add_close":"The feature editor will remember all of your changes automatically. **When you are finished adding the name, hit escape, enter, or 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 cafe you just created.**","update":"Let's fill in some more details for this cafe. You can change its name, add a cuisine, or add an address. **Change the cafe details.**","update_close":"**When you are finished updating the cafe, hit escape, enter, or click the {button} button to close the feature editor.**","rightclick":"You can right-click on any feature to see the *edit menu*, which shows a list of editing operations that can be performed. **Right-click to select the point you created and show the edit menu.**","delete":"It's OK to delete features that don't exist in the real world.{br}Deleting a feature from OpenStreetMap removes it from the map that everyone uses, so you should make sure a feature is really gone before you delete it. **Click on the {button} button to delete the point.**","undo":"You can always undo any changes up until you save your edits to OpenStreetMap. **Click on the {button} button to undo the delete and get the point back.**","play":"Now that you know how to create and edit points, try creating a few more points for practice! **When you are ready to continue to the next chapter, click '{next}'.**"},"areas":{"title":"Areas","add_playground":"*Areas* are used to show the boundaries of features like lakes, buildings, and residential areas.{br}They can 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.**","start_playground":"Let's add this playground to the map by drawing an area. Areas are drawn by placing *nodes* along the outer edge of the feature. **Click or press spacebar to place a starting node on one of the corners of the playground.**","continue_playground":"Continue drawing the area by placing more nodes along the playground's edge. It is OK to connect the area to the existing walking paths.{br}Tip: You can hold down the '{alt}' key to prevent nodes from connecting to other features. **Continue drawing an area for the playground.**","finish_playground":"Finish the area by pressing enter, or clicking again on either the first or last node. **Finish drawing an area for the playground.**","search_playground":"**Search for '{preset}'.**","choose_playground":"**Choose {preset} from the list.**","add_field":"This playground doesn't have an official name, so we won't add anything in the Name field.{br}Instead let's add some additional details about the playground to the Description field. **Open the Add Field list.**","choose_field":"**Choose {field} from the list.**","retry_add_field":"You didn't select the {field} field. Let's try again.","describe_playground":"**Add a description, then click the {button} button to close the feature editor.**","play":"Good job! Try drawing a few more areas, and see what other kinds of area features you can add to OpenStreetMap. **When you are ready to continue to the next chapter, click '{next}'.**"},"lines":{"title":"Lines","add_line":"*Lines* are used to represent features such as roads, railroads, and rivers. **Click the {button} Line button to add a new line.**","start_line":"Here is a road that is missing. Let's add it!{br}In OpenStreetMap, lines should be drawn down the center of the road. You can drag and zoom the map while drawing if necessary. **Start a new line by clicking at the top end of this missing road.**","intersect":"Click or press spacebar to add more nodes to the line.{br}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.**","retry_intersect":"The road needs to intersect {name}. Let's try again!","continue_line":"Continue drawing the line for the new road. Remember that you can drag and zoom the map if needed.{br}When you are finished drawing, click on the last node again. **Finish drawing the road.**","choose_category_road":"**Select {category} from the list.**","choose_preset_residential":"There are many different types of roads, but this one is a residential road. **Choose the {preset} type.**","retry_preset_residential":"You didn't select the {preset} type. **Click here to choose again.**","name_road":"**Give this road a name, then hit escape, enter, or click the {button} button to close the feature editor.**","did_name_road":"Looks good! Next we will learn how to update the shape of a line.","update_line":"Sometimes you will need to change the shape of an existing line. Here is a road that doesn't look quite right.","add_node":"We can add some nodes to this line to improve its shape. One way to add a node is to double-click the line where you want to add a node. **Double-click on the line to create a new node.**","start_drag_endpoint":"When a line is selected, you can drag any of its nodes by clicking and holding down the left mouse button while you drag. **Drag the endpoint to the place where these roads should intersect.**","finish_drag_endpoint":"This spot looks good. **Release the left mouse button to finish dragging.**","start_drag_midpoint":"Small triangles are drawn at the *midpoints* between nodes. Another way to create a new node is to drag a midpoint to a new location. **Drag the midpoint triangle to create a new node along the curve of the road.**","continue_drag_midpoint":"This line is looking much better! Continue to adjust this line by double-clicking or dragging midpoints until the curve matches the road shape. **When you're happy with how the line looks, click OK.**","delete_lines":"It's OK to delete lines for roads that don't exist in the real world.{br}Here's an example where the city planned a {street} but never built it. We can improve this part of the map by deleting the extra lines.","rightclick_intersection":"The last real street is {street1}, so we will *split* {street2} at this intersection and remove everything above it. **Right click on the intersection node.**","split_intersection":"**Click on the {button} button to split {street}.**","retry_split":"You didn't click the Split button. Try again.","did_split_multi":"Good job! {street1} is now split into two pieces. The top part can be removed. **Click the top part of {street2} to select it.**","did_split_single":"**Click the top part of {street2} to select it.**","multi_select":"{selected} is now selected. Let's also select {other1}. You can shift-click to select multiple things. **Shift-click on {other2}.**","multi_rightclick":"Good! Both lines to delete are now selected. **Right-click on one of the lines to show the edit menu.**","multi_delete":"**Click on the {button} button to delete the extra lines.**","retry_delete":"You didn't click the Delete button. Try again.","play":"Great! Use the skills that you've learned in this chapter to practice editing some more lines. **When you are ready to continue to the next chapter, click '{next}'.**"},"buildings":{"title":"Buildings","add_building":"OpenStreetMap is the world's largest database of buildings.{br}You can help improve this database by tracing buildings that aren't already mapped. **Click the {button} Area button to add a new area.**","start_building":"Let's add this house to the map by tracing its outline.{br}Buildings should be traced around their footprint as accurately as possible. **Click or press spacebar to place a starting node on one of the corners of the building.**","continue_building":"Continue adding more nodes to trace the outline of the building. Remember that you can zoom in if you want to add more details.{br}Finish the building by pressing enter, or clicking again on either the first or last node. **Finish tracing the building.**","retry_building":"It looks like you had some trouble placing the nodes at the building corners. Try again!","choose_category_building":"**Choose {category} from the list.**","choose_preset_house":"There are many different types of buildings, but this one is clearly a house.{br}If you're not sure of the type, it's OK to just choose the generic Building type. **Choose the {preset} type.**","close":"**Hit escape or click the {button} button to close the feature editor.**","rightclick_building":"**Right-click to select the building you created and show the edit menu.**","square_building":"The house that you just added will look even better with perfectly square corners. **Click on the {button} button to square the building shape.**","retry_square":"You didn't click the Square button. Try again.","done_square":"See how the corners of the building moved into place? Let's learn another useful trick.","add_tank":"Next we'll trace this circular storage tank. **Click the {button} Area button to add a new area.**","start_tank":"Don't worry, you won't need to draw a perfect circle. Just draw an area inside the tank that touches its edge. **Click or press spacebar to place a starting node on the edge of the tank.**","continue_tank":"Add a few more nodes around the edge. The circle will be created outside the nodes that you draw.{br}Finish the area by pressing enter, or clicking again on either the first or last node. **Finish tracing the tank.**","search_tank":"**Search for '{preset}'.**","choose_tank":"**Choose {preset} from the list.**","rightclick_tank":"**Right-click to select the storage tank you created and show the edit menu.**","circle_tank":"**Click on the {button} button to make the tank a circle.**","retry_circle":"You didn't click the Circularize button. Try again.","play":"Great Job! Practice tracing a few more buildings, and try some of the other commands on the edit menu. **When you are ready to continue to the next chapter, click '{next}'.**"},"startediting":{"title":"Start Editing","help":"You're now ready to edit OpenStreetMap!{br}You can replay this walkthrough anytime or view more documentation by clicking the {button} Help button or pressing the '{key}' key.","shortcuts":"You can view a list of commands along with their keyboard shortcuts by pressing the '{key}' key.","save":"Don't forget to regularly save your changes!","start":"Start mapping!"}},"shortcuts":{"title":"Keyboard shortcuts","tooltip":"Show the keyboard shortcuts screen.","toggle":{"key":"?"},"key":{"alt":"Alt","backspace":"Backspace","cmd":"Cmd","ctrl":"Ctrl","delete":"Delete","del":"Del","end":"End","enter":"Enter","esc":"Esc","home":"Home","option":"Option","pause":"Pause","pgdn":"PgDn","pgup":"PgUp","return":"Return","shift":"Shift","space":"Space"},"gesture":{"drag":"drag"},"or":"-or-","browsing":{"title":"Browsing","navigation":{"title":"Navigation","pan":"Pan map","pan_more":"Pan map by one screenful","zoom":"Zoom in / Zoom out","zoom_more":"Zoom in / Zoom out by a lot"},"help":{"title":"Help","help":"Show help/documentation","keyboard":"Show keyboard shortcuts"},"display_options":{"title":"Display options","background":"Show background options","background_switch":"Switch back to last background","map_data":"Show map data options","fullscreen":"Enter full screen mode","wireframe":"Toggle wireframe mode","minimap":"Toggle minimap"},"selecting":{"title":"Selecting features","select_one":"Select a single feature","select_multi":"Select multiple features","lasso":"Draw a selection lasso around features","search":"Find features matching search text"},"with_selected":{"title":"With feature selected","edit_menu":"Toggle edit menu"},"vertex_selected":{"title":"With node selected","previous":"Jump to previous node","next":"Jump to next node","first":"Jump to first node","last":"Jump to last node","change_parent":"Switch parent way"}},"editing":{"title":"Editing","drawing":{"title":"Drawing","add_point":"'Add point' mode","add_line":"'Add line' mode","add_area":"'Add area' mode","place_point":"Place a point","disable_snap":"Hold to disable point snapping","stop_line":"Finish drawing a line or area"},"operations":{"title":"Operations","continue_line":"Continue a line at the selected node","merge":"Combine (merge) selected features","disconnect":"Disconnect features at the selected node","split":"Split a line into two at the selected node","reverse":"Reverse a line","move":"Move selected features","rotate":"Rotate selected features","orthogonalize":"Straighten line / Square area corners","circularize":"Circularize a closed line or area","reflect_long":"Reflect features across the longer axis","reflect_short":"Reflect features across the shorter axis","delete":"Delete selected features"},"commands":{"title":"Commands","copy":"Copy selected features","paste":"Paste copied features","undo":"Undo last action","redo":"Redo last action","save":"Save changes"}},"tools":{"title":"Tools","info":{"title":"Information","all":"Toggle all information panels","background":"Toggle background panel","history":"Toggle history panel","location":"Toggle location panel","measurement":"Toggle measurement panel"}}},"units":{"feet":"{quantity} ft","miles":"{quantity} mi","square_feet":"{quantity} sq ft","square_miles":"{quantity} sq mi","acres":"{quantity} ac","meters":"{quantity} m","kilometers":"{quantity} km","square_meters":"{quantity} m²","square_kilometers":"{quantity} km²","hectares":"{quantity} ha","area_pair":"{area1} ({area2})","arcdegrees":"{quantity}°","arcminutes":"{quantity}′","arcseconds":"{quantity}″","north":"N","south":"S","east":"E","west":"W","coordinate":"{coordinate}{direction}","coordinate_pair":"{latitude}, {longitude}"},"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":{"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","unit":"Unit"}},"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"},"agrarian":{"label":"Products"},"amenity":{"label":"Type"},"animal_boarding":{"label":"For Animals"},"animal_breeding":{"label":"For Animals"},"animal_shelter":{"label":"For Animals"},"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"},"boules":{"label":"Type"},"boundary":{"label":"Type"},"brand":{"label":"Brand"},"brewery":{"label":"Draft Beers"},"bridge":{"label":"Type","placeholder":"Default"},"building_area":{"label":"Building"},"building":{"label":"Building"},"bunker_type":{"label":"Type"},"cables":{"label":"Cables","placeholder":"1, 2, 3..."},"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..."},"castle_type":{"label":"Type"},"clothes":{"label":"Clothes"},"club":{"label":"Type"},"collection_times":{"label":"Collection Times"},"comment":{"label":"Changeset Comment","placeholder":"Brief description of your contributions (required)"},"communication_multi":{"label":"Communication Types"},"construction":{"label":"Type"},"contact/webcam":{"label":"Webcam URL","placeholder":"http://example.com/"},"content":{"label":"Content"},"country":{"label":"Country"},"covered":{"label":"Covered"},"craft":{"label":"Type"},"crane/type":{"label":"Crane Type","options":{"portal_crane":"Portal Crane","floor-mounted_crane":"Floor-mounted Crane","travel_lift":"Travel Lift"}},"crop":{"label":"Crops"},"crossing":{"label":"Type"},"cuisine":{"label":"Cuisines"},"currency_multi":{"label":"Currency Types"},"cutting":{"label":"Type","placeholder":"Default"},"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"},"devices":{"label":"Devices","placeholder":"1, 2, 3..."},"diaper":{"label":"Diaper Changing Available"},"direction_cardinal":{"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"}},"direction_clock":{"label":"Direction","options":{"clockwise":"Clockwise","anticlockwise":"Counterclockwise"}},"direction_vertex":{"label":"Direction","options":{"forward":"Forward","backward":"Backward","both":"Both / All"}},"direction":{"label":"Direction (Degrees Clockwise)","placeholder":"45, 90, 180, 270"},"display":{"label":"Display"},"dock":{"label":"Type"},"drive_through":{"label":"Drive-Through"},"duration":{"label":"Duration","placeholder":"00:00"},"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"},"embankment":{"label":"Type","placeholder":"Default"},"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"}},"fitness_station":{"label":"Equipment Type"},"fixme":{"label":"Fix Me"},"ford":{"label":"Type","placeholder":"Default"},"frequency":{"label":"Operating Frequency"},"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/output/electricity":{"label":"Power Output","placeholder":"50 MW, 100 MW, 200 MW..."},"generator/source":{"label":"Source"},"generator/type":{"label":"Type"},"government":{"label":"Type"},"grape_variety":{"label":"Grape Varieties"},"handicap":{"label":"Handicap","placeholder":"1-18"},"handrail":{"label":"Handrail"},"hashtags":{"label":"Suggested Hashtags","placeholder":"#example"},"healthcare":{"label":"Type"},"healthcare/speciality":{"label":"Specialties"},"height":{"label":"Height (Meters)"},"highway":{"label":"Type"},"historic":{"label":"Type"},"historic/civilization":{"label":"Historic Civilization"},"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"},"inscription":{"label":"Inscription"},"intermittent":{"label":"Intermittent"},"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"},"label":{"label":"Label"},"lamp_type":{"label":"Type"},"landuse":{"label":"Type"},"lanes":{"label":"Lanes","placeholder":"1, 2, 3..."},"layer":{"label":"Layer","placeholder":"0"},"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"},"manhole":{"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"},"maxweight":{"label":"Max Weight"},"memorial":{"label":"Type"},"monitoring_multi":{"label":"Monitoring"},"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","reversible":"Reversible","alternating":"Alternating"}},"oneway":{"label":"One Way","options":{"undefined":"Assumed to be No","yes":"Yes","no":"No","reversible":"Reversible","alternating":"Alternating"}},"opening_hours":{"label":"Hours"},"operator":{"label":"Operator"},"outdoor_seating":{"label":"Outdoor Seating"},"par":{"label":"Par","placeholder":"3, 4, 5..."},"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"},"phases":{"label":"Phases","placeholder":"1, 2, 3..."},"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"},"plant/output/electricity":{"label":"Power Output","placeholder":"500 MW, 1000 MW, 2000 MW..."},"playground/baby":{"label":"Baby Seat"},"playground/max_age":{"label":"Maximum Age"},"playground/min_age":{"label":"Minimum Age"},"population":{"label":"Population"},"power_supply":{"label":"Power Supply"},"power":{"label":"Type"},"produce":{"label":"Produce"},"product":{"label":"Products"},"railway":{"label":"Type"},"railway/position":{"label":"Milestone Position","placeholder":"Distance to one decimal (123.4)"},"railway/signal/direction":{"label":"Direction","options":{"forward":"Forward","backward":"Backward","both":"Both / All"}},"rating":{"label":"Power Rating"},"recycling_accepts":{"label":"Accepts"},"ref_aeroway_gate":{"label":"Gate Number"},"ref_golf_hole":{"label":"Hole Number","placeholder":"1-18"},"ref_highway_junction":{"label":"Junction Number"},"ref_platform":{"label":"Platform Number"},"ref_road_number":{"label":"Road Number"},"ref_route":{"label":"Route Number"},"ref_runway":{"label":"Runway Number","placeholder":"e.g. 01L/19R"},"ref_stop_position":{"label":"Stop Number"},"ref_taxiway":{"label":"Taxiway Name","placeholder":"e.g. A5"},"ref":{"label":"Reference Code"},"ref/isil":{"label":"ISIL Code"},"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_times":{"label":"Service Times"},"service":{"label":"Type"},"service/bicycle":{"label":"Services"},"service/vehicle":{"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":"Sources"},"sport_ice":{"label":"Sports"},"sport_racing_motor":{"label":"Sports"},"sport_racing_nonmotor":{"label":"Sports"},"sport":{"label":"Sports"},"stars":{"label":"Stars"},"start_date":{"label":"Start Date"},"step_count":{"label":"Number of Steps"},"stop":{"label":"Stop Type","options":{"all":"All Ways","minor":"Minor Road"}},"structure_waterway":{"label":"Structure","placeholder":"Unknown","options":{"tunnel":"Tunnel"}},"structure":{"label":"Structure","placeholder":"Unknown","options":{"bridge":"Bridge","tunnel":"Tunnel","embankment":"Embankment","cutting":"Cutting","ford":"Ford"}},"studio":{"label":"Type"},"substance":{"label":"Substance"},"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"},"switch":{"label":"Type","options":{"mechanical":"Mechanical","circuit_breaker":"Circuit Breaker","disconnector":"Disconnector","earthing":"Earthing"}},"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"},"tomb":{"label":"Type"},"tourism_attraction":{"label":"Tourism"},"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"}},"trade":{"label":"Type"},"traffic_calming":{"label":"Type"},"traffic_signals":{"label":"Type"},"traffic_signals/direction":{"label":"Direction","options":{"forward":"Forward","backward":"Backward","both":"Both / All"}},"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"}},"transformer":{"label":"Type","options":{"distribution":"Distribution","generator":"Generator","converter":"Converter","traction":"Traction","auto":"Autotransformer","phase_angle_regulator":"Phase Angle Regulator","auxiliary":"Auxiliary","yes":"Unknown"}},"trees":{"label":"Trees"},"tunnel":{"label":"Type","placeholder":"Default"},"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)"}},"volcano/status":{"label":"Volcano Status","options":{"active":"Active","dormant":"Dormant","extinct":"Extinct"}},"volcano/type":{"label":"Volcano Type","options":{"stratovolcano":"Stratovolcano","shield":"Shield","scoria":"Scoria"}},"voltage":{"label":"Voltage"},"voltage/primary":{"label":"Primary Voltage"},"voltage/secondary":{"label":"Secondary Voltage"},"voltage/tertiary":{"label":"Tertiary Voltage"},"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"},"windings":{"label":"Windings","placeholder":"1, 2, 3..."},"windings/configuration":{"label":"Windings Configuration","options":{"star":"Star / Wye","delta":"Delta","open-delta":"Open Delta","zigzag":"Zig Zag","open":"Open","scott":"Scott","leblanc":"Leblanc"}}},"presets":{"aerialway":{"name":"Aerialway","terms":"ski lift,funifor,funitel"},"aeroway":{"name":"Aeroway","terms":""},"amenity":{"name":"Amenity","terms":""},"circular":{"name":"Traffic Circle","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/station":{"name":"Aerialway Station","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/t-bar":{"name":"T-bar Lift","terms":"tbar"},"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/bus_station":{"name":"Bus Station / Terminal","terms":""},"amenity/coworking_space":{"name":"Coworking Space","terms":""},"amenity/ferry_terminal":{"name":"Ferry Station / Terminal","terms":""},"amenity/nursing_home":{"name":"Nursing Home","terms":""},"amenity/register_office":{"name":"Register Office","terms":""},"amenity/scrapyard":{"name":"Scrap Yard","terms":""},"amenity/swimming_pool":{"name":"Swimming Pool","terms":""},"amenity/animal_boarding":{"name":"Animal Boarding Facility","terms":"boarding,cat,cattery,dog,horse,kennel,kitten,pet,pet boarding,pet care,pet hotel,puppy,reptile"},"amenity/animal_breeding":{"name":"Animal Breeding Facility","terms":"breeding,bull,cat,cow,dog,horse,husbandry,kitten,livestock,pet breeding,puppy,reptile"},"amenity/animal_shelter":{"name":"Animal Shelter","terms":"adoption,aspca,cat,dog,horse,kitten,pet care,pet rescue,puppy,raptor,reptile,rescue,spca"},"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/cafe":{"name":"Cafe","terms":"bistro,coffee,tea"},"amenity/car_pooling":{"name":"Car Pooling","terms":""},"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/clinic/abortion":{"name":"Abortion Clinic","terms":""},"amenity/clinic/fertility":{"name":"Fertility Clinic","terms":"egg,fertility,reproductive,sperm,ovulation"},"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*,physician"},"amenity/dojo":{"name":"Dojo / Martial Arts Academy","terms":"martial arts,dojang"},"amenity/drinking_water":{"name":"Drinking Water","terms":"fountain,potable"},"amenity/driving_school":{"name":"Driving School","terms":""},"amenity/embassy":{"name":"Embassy","terms":""},"amenity/fast_food":{"name":"Fast Food","terms":"restaurant,takeaway"},"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/love_hotel":{"name":"Love Hotel","terms":""},"amenity/marketplace":{"name":"Marketplace","terms":""},"amenity/motorcycle_parking":{"name":"Motorcycle Parking","terms":""},"amenity/music_school":{"name":"Music School","terms":"school of music"},"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/pavilion":{"name":"Pavilion","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/hindu":{"name":"Hindu Temple","terms":"kovil,devasthana,mandir,kshetram,alayam,shrine,temple"},"amenity/place_of_worship/jewish":{"name":"Synagogue","terms":"jewish"},"amenity/place_of_worship/muslim":{"name":"Mosque","terms":"muslim"},"amenity/place_of_worship/shinto":{"name":"Shinto Shrine","terms":"kami,torii"},"amenity/place_of_worship/sikh":{"name":"Sikh Temple","terms":"gurudwara,temple"},"amenity/place_of_worship/taoist":{"name":"Taoist Temple","terms":"daoist,monastery,temple"},"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 Container","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/shower":{"name":"Shower","terms":"rain closet"},"amenity/smoking_area":{"name":"Smoking Area","terms":""},"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,care home,assisted 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,assisted living"},"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":{"name":"Vending Machine","terms":""},"amenity/vending_machine/news_papers":{"name":"Newspaper Vending Machine","terms":"newspaper"},"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/feminine_hygiene":{"name":"Feminine Hygiene Vending Machine","terms":"condom,tampon,pad,woman,women,menstrual hygiene products,personal care"},"amenity/vending_machine/newspapers":{"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/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/waste/dog_excrement":{"name":"Dog Excrement Bin","terms":"bin,garbage,rubbish,litter,trash,poo,dog"},"amenity/water_point":{"name":"RV Drinking Water","terms":""},"amenity/watering_place":{"name":"Animal Watering Place","terms":""},"area":{"name":"Area","terms":""},"area/highway":{"name":"Road Surface","terms":""},"attraction/amusement_ride":{"name":"Amusement Ride","terms":"theme park,carnival ride"},"attraction/animal":{"name":"Animal","terms":"zoo,theme park,animal park,lion,tiger,bear"},"attraction/big_wheel":{"name":"Big Wheel","terms":"ferris wheel,theme park,amusement ride"},"attraction/bumper_car":{"name":"Bumper Car","terms":"theme park,dodgem cars,autoscooter"},"attraction/bungee_jumping":{"name":"Bungee Jumping","terms":"theme park,bungy jumping,jumping platform"},"attraction/carousel":{"name":"Carousel","terms":"theme park,roundabout,merry-go-round,galloper,jumper,horseabout,flying horses"},"attraction/dark_ride":{"name":"Dark Ride","terms":"theme park,ghost train"},"attraction/drop_tower":{"name":"Drop Tower","terms":"theme park,amusement ride,gondola,tower,big drop"},"attraction/pirate_ship":{"name":"Pirate Ship","terms":"theme park,carnival ride,amusement ride"},"attraction/river_rafting":{"name":"River Rafting","terms":"theme park,aquatic park,water park,rafting simulator,river rafting ride,river rapids ride"},"attraction/roller_coaster":{"name":"Roller Coaster","terms":"theme park,amusement ride"},"attraction/train":{"name":"Tourist Train","terms":"theme park,rackless train,road train,Tschu-Tschu train,dotto train,park train"},"attraction/water_slide":{"name":"Water Slide","terms":"theme park,aquatic park,water park,flumes,water chutes,hydroslides"},"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/kerb":{"name":"Kerb","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/boathouse":{"name":"Boathouse","terms":""},"building/bungalow":{"name":"Bungalow","terms":"home,detached"},"building/cabin":{"name":"Cabin","terms":""},"building/cathedral":{"name":"Cathedral Building","terms":""},"building/chapel":{"name":"Chapel Building","terms":""},"building/church":{"name":"Church Building","terms":""},"building/civic":{"name":"Civic 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/farm":{"name":"Farm Building","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/mosque":{"name":"Mosque Building","terms":""},"building/public":{"name":"Public Building","terms":""},"building/residential":{"name":"Residential Building","terms":""},"building/retail":{"name":"Retail Building","terms":""},"building/roof":{"name":"Roof","terms":""},"building/ruins":{"name":"Building Ruins","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/service":{"name":"Service Building","terms":""},"building/shed":{"name":"Shed","terms":""},"building/stable":{"name":"Stable","terms":""},"building/stadium":{"name":"Stadium Building","terms":""},"building/static_caravan":{"name":"Static Mobile Home","terms":""},"building/temple":{"name":"Temple Building","terms":""},"building/terrace":{"name":"Row Houses","terms":"home,terrace,brownstone,family,residence,dwelling"},"building/transportation":{"name":"Transportation Building","terms":""},"building/university":{"name":"University Building","terms":"college"},"building/warehouse":{"name":"Warehouse","terms":""},"camp_site/camp_pitch":{"name":"Camp Pitch","terms":"tent,rv"},"club":{"name":"Club","terms":"social"},"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":"alcohol,beer,beverage,bier,booze,cider"},"craft/carpenter":{"name":"Carpenter","terms":"woodworker"},"craft/carpet_layer":{"name":"Carpet Layer","terms":""},"craft/caterer":{"name":"Caterer","terms":""},"craft/chimney_sweeper":{"name":"Chimney Sweeper","terms":""},"craft/clockmaker":{"name":"Clockmaker","terms":""},"craft/confectionery":{"name":"Candy Maker","terms":"sweet,candy"},"craft/distillery":{"name":"Distillery","terms":"alcohol,beverage,bourbon,booze,brandy,gin,hooch,liquor,mezcal,moonshine,rum,scotch,spirits,still,tequila,vodka,whiskey,whisky"},"craft/dressmaker":{"name":"Dressmaker","terms":"seamstress"},"craft/electrician":{"name":"Electrician","terms":"power,wire"},"craft/electronics_repair":{"name":"Electronics Repair Shop","terms":""},"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/sculptor":{"name":"Sculptor","terms":""},"craft/shoemaker":{"name":"Shoemaker","terms":"cobbler"},"craft/stonemason":{"name":"Stonemason","terms":"masonry"},"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/life_ring":{"name":"Life Ring","terms":"life buoy,kisby ring,kisbie ring,perry buoy"},"emergency/phone":{"name":"Emergency Phone","terms":""},"emergency/water_tank":{"name":"Emergency Water Tank","terms":"water tank,cistern,reservoir"},"entrance":{"name":"Entrance/Exit","terms":""},"footway/crossing-raised":{"name":"Raised Street Crossing","terms":"flat top,hump,speed,slow"},"footway/crossing":{"name":"Street Crossing","terms":""},"footway/crosswalk-raised":{"name":"Raised Pedestrian Crosswalk","terms":"zebra crossing,flat top,hump,speed,slow"},"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":{"name":"Healthcare Facility","terms":"clinic,doctor,disease,health,institution,sick,surgery,wellness"},"healthcare/alternative":{"name":"Alternative Medicine","terms":"acupuncture,anthroposophical,applied kinesiology,aromatherapy,ayurveda,herbalism,homeopathy,hydrotherapy,hypnosis,naturopathy,osteopathy,reflexology,reiki,shiatsu,traditional,tuina,unani"},"healthcare/alternative/chiropractic":{"name":"Chiropractor","terms":"back,pain,spine"},"healthcare/audiologist":{"name":"Audiologist","terms":"ear,hearing,sound"},"healthcare/birthing_center":{"name":"Birthing Center","terms":"baby,childbirth,delivery,labour,labor,pregnancy"},"healthcare/blood_donation":{"name":"Blood Donor Center","terms":"blood bank,blood donation,blood transfusion,apheresis,plasmapheresis,plateletpheresis,stem cell donation"},"healthcare/hospice":{"name":"Hospice","terms":"terminal,illness"},"healthcare/midwife":{"name":"Midwife","terms":"baby,childbirth,delivery,labour,labor,pregnancy"},"healthcare/occupational_therapist":{"name":"Occupational Therapist","terms":"therapist,therapy"},"healthcare/optometrist":{"name":"Optometrist","terms":"eye,glasses,lasik,lenses,vision"},"healthcare/physiotherapist":{"name":"Physiotherapist","terms":"physical,therapist,therapy"},"healthcare/podiatrist":{"name":"Podiatrist","terms":"foot,feet,nails"},"healthcare/psychotherapist":{"name":"Psychotherapist","terms":"anxiety,counselor,depression,mental health,mind,suicide,therapist,therapy"},"healthcare/rehabilitation":{"name":"Rehabilitation Facility","terms":"rehab,therapist,therapy"},"healthcare/speech_therapist":{"name":"Speech Therapist","terms":"speech,therapist,therapy,voice"},"highway/bus_stop":{"name":"Bus Stop / Platform","terms":""},"highway/bridleway":{"name":"Bridle Path","terms":"bridleway,equestrian,horse"},"highway/bus_guideway":{"name":"Bus Guideway","terms":""},"highway/corridor":{"name":"Indoor Corridor","terms":"gallery,hall,hallway,indoor,passage,passageway"},"highway/crossing-raised":{"name":"Raised Street Crossing","terms":"flat top,hump,speed,slow"},"highway/crossing":{"name":"Street Crossing","terms":""},"highway/crosswalk-raised":{"name":"Raised Pedestrian Crosswalk","terms":"zebra crossing,flat top,hump,speed,slow"},"highway/crosswalk":{"name":"Pedestrian Crosswalk","terms":"zebra crossing"},"highway/cycleway":{"name":"Cycle Path","terms":"bike"},"highway/elevator":{"name":"Elevator","terms":"lift"},"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_area":{"name":"Pedestrian Area","terms":"center,centre,plaza,quad,square,walkway"},"highway/pedestrian_line":{"name":"Pedestrian Street","terms":"center,centre,plaza,quad,square,walkway"},"highway/primary_link":{"name":"Primary Link","terms":"ramp,on ramp,off ramp"},"highway/primary":{"name":"Primary Road","terms":""},"highway/raceway":{"name":"Racetrack (Motorsport)","terms":"auto*,formula one,kart,motocross,nascar,race*,track"},"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/speed_camera":{"name":"Speed Camera","terms":""},"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/tomb":{"name":"Tomb","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/brownfield":{"name":"Brownfield","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":"Garage Landuse","terms":""},"landuse/grass":{"name":"Grass","terms":""},"landuse/greenfield":{"name":"Greenfield","terms":""},"landuse/greenhouse_horticulture":{"name":"Greenhouse Horticulture","terms":"flower,greenhouse,horticulture,grow,vivero"},"landuse/harbour":{"name":"Harbor","terms":"boat"},"landuse/industrial":{"name":"Industrial Area","terms":""},"landuse/industrial/scrap_yard":{"name":"Scrap Yard","terms":"car,junk,metal,salvage,scrap,u-pull-it,vehicle,wreck,yard"},"landuse/industrial/slaughterhouse":{"name":"Slaughterhouse","terms":"abattoir,beef,butchery,calf,chicken,cow,killing house,meat,pig,pork,poultry,shambles,stockyard"},"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/railway":{"name":"Railway Corridor","terms":"rail,train,track"},"landuse/recreation_ground":{"name":"Recreation Ground","terms":"playing fields"},"landuse/religious":{"name":"Religious Area","terms":""},"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":"bowling center"},"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":"exercise,fitness,gym,trim trail"},"leisure/fitness_station/balance_beam":{"name":"Exercise Balance Beam","terms":"balance,exercise,fitness,gym,trim trail"},"leisure/fitness_station/box":{"name":"Exercise Box","terms":"box,exercise,fitness,gym,jump,trim trail"},"leisure/fitness_station/horizontal_bar":{"name":"Exercise Horizontal Bar","terms":"bar,chinup,chin up,exercise,fitness,gym,pullup,pull up,trim trail"},"leisure/fitness_station/horizontal_ladder":{"name":"Exercise Monkey Bars","terms":"bar,chinup,chin up,exercise,fitness,gym,ladder,monkey bars,pullup,pull up,trim trail"},"leisure/fitness_station/hyperextension":{"name":"Hyperextension Station","terms":"back,exercise,extension,fitness,gym,roman chair,trim trail"},"leisure/fitness_station/parallel_bars":{"name":"Parallel Bars","terms":"bar,dip,exercise,fitness,gym,trim trail"},"leisure/fitness_station/push-up":{"name":"Push-Up Station","terms":"bar,exercise,fitness,gym,pushup,push up,trim trail"},"leisure/fitness_station/rings":{"name":"Exercise Rings","terms":"exercise,fitness,gym,muscle up,pullup,pull up,trim trail"},"leisure/fitness_station/sign":{"name":"Exercise Instruction Sign","terms":"exercise,fitness,gym,trim trail"},"leisure/fitness_station/sit-up":{"name":"Sit-Up Station","terms":"crunch,exercise,fitness,gym,situp,sit up,trim trail"},"leisure/fitness_station/stairs":{"name":"Exercise Stairs","terms":"exercise,fitness,gym,steps,trim trail"},"leisure/garden":{"name":"Garden","terms":""},"leisure/golf_course":{"name":"Golf Course","terms":"links"},"leisure/hackerspace":{"name":"Hackerspace","terms":"makerspace,hackspace,hacklab"},"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/beachvolleyball":{"name":"Beach Volleyball Court","terms":"volleyball"},"leisure/pitch/boules":{"name":"Boules/Bocce Court","terms":"bocce,lyonnaise,pétanque"},"leisure/pitch/bowls":{"name":"Bowling Green","terms":""},"leisure/pitch/cricket":{"name":"Cricket Field","terms":""},"leisure/pitch/equestrian":{"name":"Riding Arena","terms":"dressage,equestrian,horse,horseback,riding"},"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":"football"},"leisure/pitch/table_tennis":{"name":"Ping Pong Table","terms":"table tennis,ping pong"},"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":"Racetrack (Running)","terms":"race*,running,sprint,track"},"leisure/sauna":{"name":"Sauna","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":"cycle,dog,greyhound,horse,race*,track"},"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/crane":{"name":"Crane","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":"Mast","terms":"antenna,broadcast tower,cell phone tower,cell tower,communication mast,communication tower,guyed tower,mobile phone tower,radio mast,radio tower,television tower,transmission mast,transmission tower,tv tower"},"man_made/monitoring_station":{"name":"Monitoring Station","terms":"weather,earthquake,seismology,air,gps"},"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,jetty"},"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":"trig point,triangulation pillar,trigonometrical station"},"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/watermill":{"name":"Watermill","terms":"water,wheel,mill"},"man_made/windmill":{"name":"Windmill","terms":"wind,wheel,mill"},"man_made/works":{"name":"Factory","terms":"assembly,build,brewery,car,plant,plastic,processing,manufacture,refinery"},"manhole":{"name":"Manhole","terms":"cover,hole,sewer,sewage,telecom"},"manhole/drain":{"name":"Storm Drain","terms":"cover,drain,hole,rain,sewer,sewage,storm"},"manhole/telecom":{"name":"Telecom Manhole","terms":"cover,phone,hole,telecom,telephone,bt"},"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":"bog,marsh,reedbed,swamp,tidalflat"},"natural/wood":{"name":"Wood","terms":"tree"},"noexit/yes":{"name":"No Exit","terms":"no exit,road end,dead end"},"office":{"name":"Office","terms":""},"office/administrative":{"name":"Administrative Office","terms":""},"office/physician":{"name":"Physician","terms":""},"office/travel_agent":{"name":"Travel Agency","terms":""},"office/accountant":{"name":"Accountant Office","terms":""},"office/adoption_agency":{"name":"Adoption Agency","terms":""},"office/advertising_agency":{"name":"Advertising Agency","terms":"ad,ad agency,advert agency,advertising,marketing"},"office/architect":{"name":"Architect Office","terms":""},"office/association":{"name":"Nonprofit Organization Office","terms":"association,non-profit,nonprofit,organization,society"},"office/charity":{"name":"Charity Office","terms":"charitable organization"},"office/company":{"name":"Corporate 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/energy_supplier":{"name":"Energy Supplier Office","terms":"electricity,energy company,energy utility,gas utility"},"office/estate_agent":{"name":"Real Estate Office","terms":""},"office/financial":{"name":"Financial Office","terms":""},"office/forestry":{"name":"Forestry Office","terms":"forest,ranger"},"office/foundation":{"name":"Foundation Office","terms":""},"office/government":{"name":"Government Office","terms":""},"office/government/register_office":{"name":"Register Office","terms":"clerk,marriage,death,birth,certificate"},"office/government/tax":{"name":"Tax and Revenue Office","terms":"fiscal authorities,revenue office,tax office"},"office/guide":{"name":"Tour Guide Office","terms":"dive guide,mountain guide,tour guide"},"office/insurance":{"name":"Insurance Office","terms":""},"office/it":{"name":"Information Technology Office","terms":"computer,information,software,technology"},"office/lawyer":{"name":"Law Office","terms":""},"office/lawyer/notary":{"name":"Notary Office","terms":""},"office/moving_company":{"name":"Moving Company Office","terms":"relocation"},"office/newspaper":{"name":"Newspaper Office","terms":""},"office/ngo":{"name":"NGO Office","terms":"ngo,non government,non-government,organization,organisation"},"office/notary":{"name":"Notary Office","terms":"clerk,deeds,estate,signature,wills"},"office/political_party":{"name":"Political Party","terms":""},"office/private_investigator":{"name":"Private Investigator Office","terms":"PI,private eye,private detective"},"office/quango":{"name":"Quasi-NGO Office","terms":"ngo,non government,non-government,organization,organisation,quasi autonomous,quasi-autonomous"},"office/research":{"name":"Research Office","terms":""},"office/surveyor":{"name":"Surveyor Office","terms":""},"office/tax_advisor":{"name":"Tax Advisor Office","terms":"tax,tax consultant"},"office/telecommunication":{"name":"Telecom Office","terms":"communication,internet,phone,voice"},"office/therapist":{"name":"Therapist Office","terms":"therapy"},"office/water_utility":{"name":"Water Utility Office","terms":"water board,utility"},"piste":{"name":"Piste/Ski Trail","terms":"ski,sled,sleigh,snowboard,nordic,downhill,snowmobile"},"place/farm":{"name":"Farm","terms":""},"place/city":{"name":"City","terms":""},"place/hamlet":{"name":"Hamlet","terms":""},"place/island":{"name":"Island","terms":"archipelago,atoll,bar,cay,isle,islet,key,reef"},"place/islet":{"name":"Islet","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/plot":{"name":"Plot","terms":"tract,land,lot,parcel"},"place/quarter":{"name":"Sub-Borough / Quarter","terms":"boro,borough,quarter"},"place/square":{"name":"Square","terms":""},"place/suburb":{"name":"Borough / Suburb","terms":"boro,borough,quarter"},"place/town":{"name":"Town","terms":""},"place/village":{"name":"Village","terms":""},"playground/balance_beam":{"name":"Play Balance Beam","terms":""},"playground/basket_spinner":{"name":"Basket Spinner","terms":"basket rotator"},"playground/basket_swing":{"name":"Basket Swing","terms":""},"playground/climbing_frame":{"name":"Climbing Frame","terms":""},"playground/cushion":{"name":"Bouncy Cushion","terms":""},"playground/horizontal_bar":{"name":"Play Horizontal Bar","terms":"high bar"},"playground/rocker":{"name":"Spring Rider","terms":"spring rocker,springy rocker"},"playground/roundabout":{"name":"Play Roundabout","terms":"merry-go-round"},"playground/sandpit":{"name":"Sandpit","terms":""},"playground/seesaw":{"name":"Seesaw","terms":""},"playground/slide":{"name":"Slide","terms":""},"playground/structure":{"name":"Play Structure","terms":""},"playground/swing":{"name":"Swing","terms":""},"playground/zipwire":{"name":"Zip Wire","terms":""},"point":{"name":"Point","terms":""},"power/sub_station":{"name":"Substation","terms":""},"power/generator":{"name":"Power Generator","terms":"hydro,solar,turbine,wind"},"power/generator/source_nuclear":{"name":"Nuclear Reactor","terms":"fission,generator,nuclear,nuke,reactor"},"power/generator/source_wind":{"name":"Wind Turbine","terms":"generator,turbine,windmill,wind"},"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/switch":{"name":"Power Switch","terms":""},"power/tower":{"name":"High-Voltage Tower","terms":""},"power/transformer":{"name":"Transformer","terms":""},"public_transport/linear_platform_aerialway":{"name":"Aerialway Stop / Platform","terms":"aerialway,cable car,platform,public transit,public transportation,transit,transportation"},"public_transport/linear_platform_bus":{"name":"Bus Stop / Platform","terms":"bus,platform,public transit,public transportation,transit,transportation"},"public_transport/linear_platform_ferry":{"name":"Ferry Stop / Platform","terms":"boat,dock,ferry,pier,platform,public transit,public transportation,transit,transportation"},"public_transport/linear_platform_light_rail":{"name":"Light Rail Stop / Platform","terms":"electric,light rail,platform,public transit,public transportation,rail,track,tram,trolley,transit,transportation"},"public_transport/linear_platform_monorail":{"name":"Monorail Stop / Platform","terms":"monorail,platform,public transit,public transportation,rail,transit,transportation"},"public_transport/linear_platform_subway":{"name":"Subway Stop / Platform","terms":"metro,platform,public transit,public transportation,rail,subway,track,transit,transportation,underground"},"public_transport/linear_platform_train":{"name":"Train Stop / Platform","terms":"platform,public transit,public transportation,rail,track,train,transit,transportation"},"public_transport/linear_platform_tram":{"name":"Tram Stop / Platform","terms":"electric,light rail,platform,public transit,public transportation,rail,streetcar,track,tram,trolley,transit,transportation"},"public_transport/linear_platform_trolleybus":{"name":"Trolleybus Stop / Platform","terms":"bus,electric,platform,public transit,public transportation,streetcar,trackless,tram,trolley,transit,transportation"},"public_transport/linear_platform":{"name":"Transit Stop / Platform","terms":"platform,public transit,public transportation,transit,transportation"},"public_transport/platform_aerialway":{"name":"Aerialway Stop / Platform","terms":"aerialway,cable car,platform,public transit,public transportation,transit,transportation"},"public_transport/platform_bus":{"name":"Bus Stop / Platform","terms":"bus,platform,public transit,public transportation,transit,transportation"},"public_transport/platform_ferry":{"name":"Ferry Stop / Platform","terms":"boat,dock,ferry,pier,platform,public transit,public transportation,transit,transportation"},"public_transport/platform_light_rail":{"name":"Light Rail Stop / Platform","terms":"electric,light rail,platform,public transit,public transportation,rail,track,tram,trolley,transit,transportation"},"public_transport/platform_monorail":{"name":"Monorail Stop / Platform","terms":"monorail,platform,public transit,public transportation,rail,transit,transportation"},"public_transport/platform_subway":{"name":"Subway Stop / Platform","terms":"metro,platform,public transit,public transportation,rail,subway,track,transit,transportation,underground"},"public_transport/platform_train":{"name":"Train Stop / Platform","terms":"platform,public transit,public transportation,rail,track,train,transit,transportation"},"public_transport/platform_tram":{"name":"Tram Stop / Platform","terms":"electric,light rail,platform,public transit,public transportation,rail,streetcar,track,tram,trolley,transit,transportation"},"public_transport/platform_trolleybus":{"name":"Trolleybus Stop / Platform","terms":"bus,electric,platform,public transit,public transportation,streetcar,trackless,tram,trolley,transit,transportation"},"public_transport/platform":{"name":"Transit Stop / Platform","terms":"platform,public transit,public transportation,transit,transportation"},"public_transport/station_aerialway":{"name":"Aerialway Station","terms":"aerialway,cable car,public transit,public transportation,station,terminal,transit,transportation"},"public_transport/station_bus":{"name":"Bus Station / Terminal","terms":"bus,public transit,public transportation,station,terminal,transit,transportation"},"public_transport/station_ferry":{"name":"Ferry Station / Terminal","terms":"boat,dock,ferry,pier,public transit,public transportation,station,terminal,transit,transportation"},"public_transport/station_light_rail":{"name":"Light Rail Station","terms":"electric,light rail,public transit,public transportation,rail,station,terminal,track,tram,trolley,transit,transportation"},"public_transport/station_monorail":{"name":"Monorail Station","terms":"monorail,public transit,public transportation,rail,station,terminal,transit,transportation"},"public_transport/station_subway":{"name":"Subway Station","terms":"metro,public transit,public transportation,rail,station,subway,terminal,track,transit,transportation,underground"},"public_transport/station_train_halt":{"name":"Train Station (Halt / Request)","terms":"halt,public transit,public transportation,rail,station,track,train,transit,transportation,whistle stop"},"public_transport/station_train":{"name":"Train Station","terms":"public transit,public transportation,rail,station,terminal,track,train,transit,transportation"},"public_transport/station_tram":{"name":"Tram Station","terms":"electric,light rail,public transit,public transportation,rail,station,streetcar,terminal,track,tram,trolley,transit,transportation"},"public_transport/station_trolleybus":{"name":"Trolleybus Station / Terminal","terms":"bus,electric,public transit,public transportation,station,streetcar,terminal,trackless,tram,trolley,transit,transportation"},"public_transport/station":{"name":"Transit Station","terms":"public transit,public transportation,station,terminal,transit,transportation"},"public_transport/stop_area":{"name":"Transit Stop Area","terms":""},"public_transport/stop_position_aerialway":{"name":"Aerialway Stopping Location","terms":"aerialway,cable car,public transit,public transportation,transit,transportation"},"public_transport/stop_position_bus":{"name":"Bus Stopping Location","terms":"bus,public transit,public transportation,transit,transportation"},"public_transport/stop_position_ferry":{"name":"Ferry Stopping Location","terms":"boat,dock,ferry,pier,public transit,public transportation,transit,transportation"},"public_transport/stop_position_light_rail":{"name":"Light Rail Stopping Location","terms":"electric,light rail,public transit,public transportation,rail,track,tram,trolley,transit,transportation"},"public_transport/stop_position_monorail":{"name":"Monorail Stopping Location","terms":"monorail,public transit,public transportation,rail,transit,transportation"},"public_transport/stop_position_subway":{"name":"Subway Stopping Location","terms":"metro,public transit,public transportation,rail,subway,track,transit,transportation,underground"},"public_transport/stop_position_train":{"name":"Train Stopping Location","terms":"public transit,public transportation,rail,track,train,transit,transportation"},"public_transport/stop_position_tram":{"name":"Tram Stopping Location","terms":"electric,light rail,public transit,public transportation,rail,streetcar,track,tram,trolley,transit,transportation"},"public_transport/stop_position_trolleybus":{"name":"Trolleybus Stopping Location","terms":"bus,electric,public transit,public transportation,streetcar,trackless,tram,trolley,transit,transportation"},"public_transport/stop_position":{"name":"Transit Stopping Location","terms":"public transit,public transportation,transit,transportation"},"railway/halt":{"name":"Train Station (Halt / Request)","terms":"break,interrupt,rest,wait,interruption"},"railway/platform":{"name":"Train Stop / Platform","terms":""},"railway/station":{"name":"Train Station","terms":"train station,station"},"railway/tram_stop":{"name":"Tram Stopping Position","terms":"light rail,streetcar,tram,trolley"},"railway/abandoned":{"name":"Abandoned Railway","terms":""},"railway/buffer_stop":{"name":"Buffer Stop","terms":"stop,halt,buffer"},"railway/crossing":{"name":"Railway Crossing (Path)","terms":"crossing,pedestrian crossing,railroad crossing,level crossing,grade crossing,path through railroad,train crossing"},"railway/derail":{"name":"Railway Derailer","terms":"derailer"},"railway/disused":{"name":"Disused Railway","terms":""},"railway/funicular":{"name":"Funicular","terms":"venicular,cliff railway,cable car,cable railway,funicular railway"},"railway/level_crossing":{"name":"Railway Crossing (Road)","terms":"crossing,railroad crossing,level crossing,grade crossing,road through railroad,train crossing"},"railway/light_rail":{"name":"Light Rail","terms":"light rail,streetcar,trolley"},"railway/milestone":{"name":"Railway Milestone","terms":"milestone,marker"},"railway/miniature":{"name":"Miniature Railway","terms":"rideable miniature railway,narrow gauge railway,minimum gauge railway"},"railway/monorail":{"name":"Monorail","terms":""},"railway/narrow_gauge":{"name":"Narrow Gauge Rail","terms":"narrow gauge railway,narrow gauge railroad"},"railway/rail":{"name":"Rail","terms":""},"railway/signal":{"name":"Railway Signal","terms":"signal,lights"},"railway/subway_entrance":{"name":"Subway Entrance","terms":"metro,transit"},"railway/subway":{"name":"Subway","terms":"metro,transit"},"railway/switch":{"name":"Railway Switch","terms":"switch,points"},"railway/train_wash":{"name":"Train Wash","terms":"wash,clean"},"railway/tram":{"name":"Tram","terms":"light rail,streetcar,tram,trolley"},"relation":{"name":"Relation","terms":""},"route/ferry":{"name":"Ferry Route","terms":""},"shop":{"name":"Shop","terms":""},"shop/fishmonger":{"name":"Fishmonger","terms":""},"shop/furnace":{"name":"Furnace Store","terms":"oven,stove"},"shop/vacant":{"name":"Vacant Shop","terms":""},"shop/agrarian":{"name":"Agriculture Shop","terms":"agricultural inputs,agricultural machines,seeds,pesticides,fertilizer,agricultural tools"},"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/appliance":{"name":"Appliance Store","terms":"air conditioner,appliance,dishwasher,dryer,freezer,fridge,grill,kitchen,oven,refrigerator,stove,washer,washing machine"},"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":"sweet"},"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,blueray,camera,computer,dvd,home theater,radio,speaker,tv,video"},"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/furniture":{"name":"Furniture Store","terms":"chair,sofa,table"},"shop/garden_centre":{"name":"Garden Center","terms":"landscape,mulch,shrub,tree"},"shop/gas":{"name":"Bottled Gas Shop","terms":"cng,lpg,natural gas,propane,refill,tank"},"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":"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/perfumery":{"name":"Perfume Store","terms":""},"shop/pet":{"name":"Pet Store","terms":"animal,cat,dog,fish,kitten,puppy,reptile"},"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/tiles":{"name":"Tile Shop","terms":""},"shop/tobacco":{"name":"Tobacco Shop","terms":""},"shop/toys":{"name":"Toy Store","terms":""},"shop/trade":{"name":"Trade Shop","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":"climbing hut"},"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":"Holiday Cottage","terms":"holiday,holiday cottage,holiday home,vacation,vacation home"},"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":"signpost"},"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/wilderness_hut":{"name":"Wilderness Hut","terms":"wilderness hut,backcountry hut,bothy"},"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":"Speed Table","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/light_rail":{"name":"Light Rail Route","terms":""},"type/route/pipeline":{"name":"Pipeline Route","terms":""},"type/route/piste":{"name":"Piste/Ski Route","terms":""},"type/route/power":{"name":"Power Route","terms":""},"type/route/road":{"name":"Road Route","terms":""},"type/route/subway":{"name":"Subway Route","terms":""},"type/route/train":{"name":"Train Route","terms":""},"type/route/tram":{"name":"Tram Route","terms":""},"type/site":{"name":"Site","terms":""},"type/waterway":{"name":"Waterway","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_intermittent":{"name":"Intermittent Stream","terms":"arroyo,beck,branch,brook,burn,course,creek,drift,flood,flow,gully,run,runnel,rush,spate,spritz,tributary,wadi,wash,watercourse"},"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":""}}},"imagery":{"Bing":{"description":"Satellite and aerial imagery.","name":"Bing aerial imagery"},"DigitalGlobe-Premium":{"attribution":{"text":"Terms & Feedback"},"description":"Premium DigitalGlobe satellite imagery.","name":"DigitalGlobe Premium Imagery"},"DigitalGlobe-Premium-vintage":{"attribution":{"text":"Terms & Feedback"},"description":"Imagery boundaries and capture dates. Labels appear at zoom level 14 and higher.","name":"DigitalGlobe Premium Imagery Vintage"},"DigitalGlobe-Standard":{"attribution":{"text":"Terms & Feedback"},"description":"Standard DigitalGlobe satellite imagery.","name":"DigitalGlobe Standard Imagery"},"DigitalGlobe-Standard-vintage":{"attribution":{"text":"Terms & Feedback"},"description":"Imagery boundaries and capture dates. Labels appear at zoom level 14 and higher.","name":"DigitalGlobe Standard Imagery Vintage"},"EsriWorldImagery":{"attribution":{"text":"Terms & Feedback"},"description":"Esri world imagery.","name":"Esri World Imagery"},"EsriWorldImageryClarity":{"attribution":{"text":"Terms & Feedback"},"description":"Esri archive imagery that may be clearer and more accurate than the default layer.","name":"Esri World Imagery (Clarity) Beta"},"MAPNIK":{"attribution":{"text":"© OpenStreetMap contributors, CC-BY-SA"},"description":"The default OpenStreetMap layer.","name":"OpenStreetMap (Standard)"},"Mapbox":{"attribution":{"text":"Terms & Feedback"},"description":"Satellite and aerial imagery.","name":"Mapbox Satellite"},"OSM_Inspector-Addresses":{"attribution":{"text":"© Geofabrik GmbH, OpenStreetMap contributors, CC-BY-SA"},"name":"OSM Inspector: Addresses"},"OSM_Inspector-Geometry":{"attribution":{"text":"© Geofabrik GmbH, OpenStreetMap contributors, CC-BY-SA"},"name":"OSM Inspector: Geometry"},"OSM_Inspector-Highways":{"attribution":{"text":"© Geofabrik GmbH, OpenStreetMap contributors, CC-BY-SA"},"name":"OSM Inspector: Highways"},"OSM_Inspector-Multipolygon":{"attribution":{"text":"© Geofabrik GmbH, OpenStreetMap contributors, CC-BY-SA"},"name":"OSM Inspector: Area"},"OSM_Inspector-Places":{"attribution":{"text":"© Geofabrik GmbH, OpenStreetMap contributors, CC-BY-SA"},"name":"OSM Inspector: Places"},"OSM_Inspector-Routing":{"attribution":{"text":"© Geofabrik GmbH, OpenStreetMap contributors, CC-BY-SA"},"name":"OSM Inspector: Routing"},"OSM_Inspector-Tagging":{"attribution":{"text":"© Geofabrik GmbH, OpenStreetMap contributors, CC-BY-SA"},"name":"OSM Inspector: Tagging"},"US-TIGER-Roads-2012":{"name":"TIGER Roads 2012"},"US-TIGER-Roads-2014":{"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","name":"TIGER Roads 2014"},"US-TIGER-Roads-2017":{"description":"Yellow = Public domain map data from the US Census. Red = Data not found in OpenStreetMap","name":"TIGER Roads 2017"},"Waymarked_Trails-Cycling":{"attribution":{"text":"© waymarkedtrails.org, OpenStreetMap contributors, CC by-SA 3.0"},"name":"Waymarked Trails: Cycling"},"Waymarked_Trails-Hiking":{"attribution":{"text":"© waymarkedtrails.org, OpenStreetMap contributors, CC by-SA 3.0"},"name":"Waymarked Trails: Hiking"},"Waymarked_Trails-MTB":{"attribution":{"text":"© waymarkedtrails.org, OpenStreetMap contributors, CC by-SA 3.0"},"name":"Waymarked Trails: MTB"},"Waymarked_Trails-Skating":{"attribution":{"text":"© waymarkedtrails.org, OpenStreetMap contributors, CC by-SA 3.0"},"name":"Waymarked Trails: Skating"},"Waymarked_Trails-Winter_Sports":{"attribution":{"text":"© waymarkedtrails.org, OpenStreetMap contributors, CC by-SA 3.0"},"name":"Waymarked Trails: Winter Sports"},"basemap.at":{"attribution":{"text":"basemap.at"},"description":"Basemap of Austria, based on goverment data.","name":"basemap.at"},"basemap.at-orthofoto":{"attribution":{"text":"basemap.at"},"description":"Orthofoto layer provided by basemap.at. \"Successor\" of geoimage.at imagery.","name":"basemap.at Orthofoto"},"hike_n_bike":{"attribution":{"text":"© OpenStreetMap contributors"},"name":"Hike & Bike"},"mapbox_locator_overlay":{"attribution":{"text":"Terms & Feedback"},"description":"Shows major features to help orient you.","name":"Locator Overlay"},"openpt_map":{"attribution":{"text":"© OpenStreetMap contributors, CC-BY-SA"},"name":"OpenPT Map (overlay)"},"osm-gps":{"attribution":{"text":"© OpenStreetMap contributors"},"description":"Public GPS traces uploaded to OpenStreetMap.","name":"OpenStreetMap GPS traces"},"osm-mapnik-black_and_white":{"attribution":{"text":"© OpenStreetMap contributors, CC-BY-SA"},"name":"OpenStreetMap (Standard Black & White)"},"osm-mapnik-german_style":{"attribution":{"text":"© OpenStreetMap contributors, CC-BY-SA"},"name":"OpenStreetMap (German Style)"},"qa_no_address":{"attribution":{"text":"Simon Poole, Data ©OpenStreetMap contributors"},"name":"QA No Address"},"skobbler":{"attribution":{"text":"© Tiles: skobbler Map data: OpenStreetMap contributors"},"name":"skobbler"},"stamen-terrain-background":{"attribution":{"text":"Map tiles by Stamen Design, under CC BY 3.0"},"name":"Stamen Terrain"},"tf-cycle":{"attribution":{"text":"Maps © Thunderforest, Data © OpenStreetMap contributors"},"name":"Thunderforest OpenCycleMap"},"tf-landscape":{"attribution":{"text":"Maps © Thunderforest, Data © OpenStreetMap contributors"},"name":"Thunderforest Landscape"}}};
23669
23670 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}","endDate":"2013-06-01T00:00:00.000Z","startDate":"2013-05-01T00:00:00.000Z","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]]],"description":"Public domain aerial imagery taken in May/June 2013 from San Juan County, WA. Resolution is 9 inch."},{"id":"sjcgis.org-Aerials_2016_WM","name":"2016 aerial imagery for San Juan County WA","type":"tms","template":"http://sjcgis.org/arcgis/rest/services/Basemaps/Aerials_2016_WM/MapServer/tile/{zoom}/{y}/{x}","endDate":"2016-07-01T00:00:00.000Z","startDate":"2016-05-01T00:00:00.000Z","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,"description":"Public domain aerial imagery taken in May, June, and July from San Juan County, WA. Resolution is 6 inch countywide."},{"id":"OS7","name":"7th Series (OS7)","type":"tms","template":"http://ooc.openstreetmap.org/os7/{zoom}/{x}/{y}.jpg","polygon":[[[-3.046968,54.839473],[-3.058641,55.2415704],[-4.0446639,55.2329572],[-4.0707564,55.6365416],[-4.6190429,55.6253005],[-4.6492553,56.0283381],[-4.4896102,56.0321747],[-4.5239425,56.4367031],[-3.8675094,56.4458128],[-3.8417602,56.049435],[-3.445909,56.0498185],[-3.4349227,55.6442923],[-2.7949691,55.6504917],[-2.8080153,56.0574872],[-3.2066131,56.0532696],[-3.2141662,56.4568175],[-3.7380767,56.4507463],[-3.7418532,56.8617541],[-5.0766921,56.8317131],[-5.0365233,56.4294897],[-5.1601195,56.4249331],[-5.1299071,56.0179772],[-5.9260726,55.994559],[-5.8551764,55.2333487],[-5.2280974,55.2513559],[-5.2102447,55.027647],[-4.659555,55.0418131],[-4.6454787,54.8163344],[-3.046968,54.839473]],[[-1.7483497,57.7642809],[-1.7406468,57.3599979],[-2.5802193,57.3553698],[-2.5743689,57.0452643],[-2.0840782,57.0479899],[-2.0765057,56.6427564],[-2.734497,56.6390587],[-2.737815,56.8171751],[-3.2388513,56.8143725],[-3.2489563,57.351683],[-3.7562947,57.3488858],[-3.7621877,57.6586785],[-4.7658688,57.6447324],[-4.810078,58.2698422],[-5.2511001,58.2654711],[-5.2737594,58.6676722],[-3.5581778,58.6988712],[-3.566072,58.9316035],[-3.3765578,58.9344382],[-3.3858372,59.2017095],[-3.187134,59.2021481],[-3.1874677,59.2417623],[-3.0675673,59.2420266],[-3.0785537,59.4213467],[-2.3713088,59.4276337],[-2.3685622,59.0221982],[-2.678926,59.0207845],[-2.6734328,58.8393493],[-2.8656936,58.8365068],[-2.8602004,58.5353109],[-3.0346084,58.5331604],[-3.0195022,58.1315879],[-3.6155983,58.1198177],[-3.6127639,57.9775439],[-3.7109154,57.9756153],[-3.699316,57.7536442],[-1.7483497,57.7642809]],[[-7.0749164,56.7631857],[-7.7347099,56.7356573],[-7.7911007,57.1399384],[-7.7066243,57.1434261],[-7.7629881,57.5431114],[-7.6021787,57.5496778],[-7.6213373,57.6845215],[-7.724988,57.6803049],[-7.7301746,57.7167278],[-7.6026437,57.7219106],[-7.5996413,57.7008338],[-7.4863439,57.7054402],[-7.49528,57.7681282],[-7.3749316,57.7730121],[-7.3933722,57.9020139],[-7.2359063,57.9083804],[-7.2432312,57.9594843],[-7.1391571,57.9636854],[-7.1450794,58.0049464],[-7.2374247,58.001223],[-7.2329687,57.9701789],[-7.3113276,57.9670164],[-7.3153794,57.9952475],[-7.2490415,57.9979228],[-7.2808211,58.218564],[-7.0735459,58.2268701],[-7.0827038,58.2901845],[-6.807432,58.3011927],[-6.8276802,58.4407359],[-6.5030498,58.4536624],[-6.5153194,58.5379206],[-6.1647379,58.5518417],[-6.1063084,58.1489361],[-6.3346892,58.139764],[-6.2775862,57.7414459],[-6.9613783,57.7136632],[-6.9333168,57.5161471],[-7.100168,57.5093277],[-7.0521806,57.169002],[-7.1311072,57.1657457],[-7.0749164,56.7631857]],[[0.4107642,50.8208689],[0.9810233,50.8061178],[0.9943731,51.0117337],[1.4506241,50.9999804],[1.4771216,51.4055151],[0.8961869,51.4203486],[0.882435,51.2103932],[0.5050041,51.2200721],[0.5227271,51.4904202],[-0.6339669,51.5106322],[-0.6367135,51.4456291],[-1.0995126,51.4524759],[-1.1148479,51.0481357],[-0.5298744,51.0394048],[-0.5275085,51.10203],[0.4280611,51.0877836],[0.4107642,50.8208689]],[[-5.3945661,51.9618998],[-4.7958112,51.9805124],[-4.7887332,51.8940308],[-4.2026458,51.9122773],[-4.2294099,52.2382823],[-3.6551984,52.2560218],[-3.6222764,51.8548323],[-4.2134157,51.836405],[-4.1855134,51.4934202],[-4.776615,51.4748465],[-4.7847576,51.5752482],[-5.0879928,51.5657379],[-5.0942224,51.6424172],[-5.3678001,51.6338498],[-5.3945661,51.9618998]],[[-1.2389016,54.0353696],[-0.6277871,54.0281103],[-0.6200376,54.2525704],[-0.5726819,54.2520109],[-0.5586479,54.6554165],[-1.17998,54.6626853],[-1.1878192,54.4378771],[-1.2322093,54.4383992],[-1.2389016,54.0353696]],[[-2.6722741,50.9767709],[-2.0996118,50.9802295],[-2.1057212,51.3794917],[-1.5887659,51.3825866],[-1.594992,51.7858908],[-2.1756313,51.7889106],[-2.1715392,51.3839176],[-2.6784576,51.3808828],[-2.6722741,50.9767709]],[[-2.6015496,53.2715461],[-3.2297251,53.2685042],[-3.2352183,53.6723131],[-2.6070428,53.6753262],[-2.6015496,53.2715461]],[[-0.0394177,51.7727994],[-0.6156335,51.7757705],[-0.6046472,52.5841377],[-0.0284314,52.5812201],[-0.0394177,51.7727994]],[[-2.9152892,54.0352257],[-3.5322877,54.0286638],[-3.5448438,54.4339736],[-2.9278454,54.4404713],[-2.9152892,54.0352257]],[[-6.3058305,57.1968949],[-6.3538957,57.6001458],[-5.6911121,57.6229455],[-5.643047,57.2199469],[-6.3058305,57.1968949]],[[1.171145,52.5723589],[1.1986505,52.9759408],[1.7978754,52.9610616],[1.7703699,52.5573411],[1.171145,52.5723589]],[[-2.4022508,55.5631737],[-2.4008775,55.9656986],[-1.7608445,55.965011],[-1.7622178,55.562479],[-2.4022508,55.5631737]],[[-6.3257432,56.3853727],[-7.0196021,56.3574652],[-7.0731605,56.7638392],[-6.3793015,56.7914485],[-6.3257432,56.3853727]],[[-2.422577,54.4430983],[-2.4257397,54.841885],[-1.7993058,54.8435404],[-1.7961431,54.4447701],[-2.422577,54.4430983]],[[-3.0270123,51.3793548],[-3.6058877,51.370168],[-3.6223672,51.7730401],[-3.0434918,51.7821458],[-3.0270123,51.3793548]],[[-3.0537915,52.1897924],[-3.0661511,52.5937352],[-2.4836401,52.600342],[-2.4712805,52.1964599],[-3.0537915,52.1897924]],[[-5.676726,51.7042466],[-5.6788616,51.731006],[-5.4635982,51.7375973],[-5.4614627,51.7108418],[-5.676726,51.7042466]],[[-5.8442675,59.1088192],[-5.8469031,59.1357806],[-5.7955763,59.1371015],[-5.7929408,59.1101412],[-5.8442675,59.1088192]],[[-8.648442,57.7786066],[-8.6659651,57.87717],[-8.4664946,57.8872093],[-8.4489714,57.7886733],[-8.648442,57.7786066]],[[-4.5271098,59.0153156],[-4.5285904,59.0331938],[-4.4762337,59.034342],[-4.4747531,59.0164644],[-4.5271098,59.0153156]],[[-7.6806151,58.2583811],[-7.6865455,58.2938023],[-7.5344535,58.3008387],[-7.5285231,58.2654246],[-7.6806151,58.2583811]],[[-6.1910235,59.080087],[-6.1954619,59.1158563],[-6.125424,59.1181472],[-6.1209857,59.0823803],[-6.1910235,59.080087]],[[-4.4266879,59.0711219],[-4.4280472,59.0886998],[-4.3762055,59.089758],[-4.3748462,59.0721806],[-4.4266879,59.0711219]]]},{"id":"AGRI-black_and_white-2.5m","name":"AGRI black-and-white 2.5m","type":"tms","template":"https://{switch:a,b,c}.agri.openstreetmap.org/layer/au_ga_agri/{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","endDate":"2010-07-20T00:00:00.000Z","startDate":"2013-07-19T00:00:00.000Z","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","icon":"https://www.geoportail.lu/static/img/lion.png"},{"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","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","description":"Basemap of Austria, based on goverment data.","icon":"https://www.basemap.at/images/logo_basemap.jpg"},{"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","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,"description":"Orthofoto layer provided by basemap.at. \"Successor\" of geoimage.at imagery.","icon":"https://www.basemap.at/images/logo_basemap.jpg"},{"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 © AGIV","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAABm0lEQVQ4y6WTPUgCYRjHf5oFJVfRUZKVHYFBoBAUFLZE0FBD0NQHRENESzS019LSFNHWx1DQEhGRg0JFREM11FJuLWem4GB5HULdwdkgHprn5LO97/O8v+fj/7y2bDabpQKzFx5S6ntlgE81xvHtclHAbuSNloNT5q/uywP021cAvO4hAPYu5/hI5e6GWpsBCEfjxNSMNUALPvJ7eA3AQPcML3KIzbNhlvdEWmu+6RCcAISiCWtA3fosPztBfrYvAGgX/QCIggdR8DDe6Qbg5E0uAdjyKhhykq+uBeySi9qVCfSAB61HRBQ8RFJpRs6vALiZHMUnNpYO0Ujn+jPkJJnVfbTBNeqfFQB8YqP56H8VJqBKcuHcWsQuuXIOyUX1sN8MnPJKlnOwWS2SIScx0hkcvV3mXUzN0HcSAuBoNMBYZxsADittVXcT/XcPKE/PltqHowkTYLcMkOMoml52+wr9jnIZAJZ8XjYGe0vaUDSdsBxnulsqrUDRdMLReNHg8tYhOAs2M2HdQiSVBqChprpI7/9q5JPYKv3OfxL1n52ATYYBAAAAAElFTkSuQmCC"},{"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 © AGIV","best":true,"icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAABm0lEQVQ4y6WTPUgCYRjHf5oFJVfRUZKVHYFBoBAUFLZE0FBD0NQHRENESzS019LSFNHWx1DQEhGRg0JFREM11FJuLWem4GB5HULdwdkgHprn5LO97/O8v+fj/7y2bDabpQKzFx5S6ntlgE81xvHtclHAbuSNloNT5q/uywP021cAvO4hAPYu5/hI5e6GWpsBCEfjxNSMNUALPvJ7eA3AQPcML3KIzbNhlvdEWmu+6RCcAISiCWtA3fosPztBfrYvAGgX/QCIggdR8DDe6Qbg5E0uAdjyKhhykq+uBeySi9qVCfSAB61HRBQ8RFJpRs6vALiZHMUnNpYO0Ujn+jPkJJnVfbTBNeqfFQB8YqP56H8VJqBKcuHcWsQuuXIOyUX1sN8MnPJKlnOwWS2SIScx0hkcvV3mXUzN0HcSAuBoNMBYZxsADittVXcT/XcPKE/PltqHowkTYLcMkOMoml52+wr9jnIZAJZ8XjYGe0vaUDSdsBxnulsqrUDRdMLReNHg8tYhOAs2M2HdQiSVBqChprpI7/9q5JPYKv3OfxL1n52ATYYBAAAAAElFTkSuQmCC"},{"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/","scaleExtent":[0,22],"default":true,"description":"Satellite and aerial imagery.","icon":"data:image/png;base64,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"},{"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","endDate":"2013-06-01T00:00:00.000Z","startDate":"2009-01-01T00:00:00.000Z","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","icon":"https://www.geoportail.lu/static/img/lion.png"},{"id":"osm-cambodia_laos_thailand_vietnam-bilingual","name":"Cambodia, Laos, Thailand, Vietnam, Malaysia, Myanmar bilingual","type":"tms","template":"http://{switch:a,b,c,d}.tile.osm-tools.org/osm/{zoom}/{x}/{y}.png","scaleExtent":[0,20],"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":"https://{switch:a,b,c}.coct.aerial.openstreetmap.org.za/layer/za_coct_aerial_2013/{zoom}/{x}/{y}.jpg","endDate":"2015-01-01T00:00:00.000Z","startDate":"2013-01-01T00:00:00.000Z","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","description":"OpenStreetMap use only. City of Cape Town Aerial ortho-photography of the municipal area. 12cm ground sample distance"},{"id":"South_Africa-CapeTown-Aerial","name":"City of Cape Town 2015 Aerial","type":"tms","template":"https://{switch:a,b,c}.coct.aerial.openstreetmap.org.za/layer/za_coct_aerial_2015/{zoom}/{x}/{y}.jpg","endDate":"2016-01-01T00:00:00.000Z","startDate":"2015-01-01T00:00:00.000Z","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,"description":"OpenStreetMap use only. City of Cape Town Aerial ortho-photography of the municipal area. 8cm ground sample distance"},{"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":"https://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 orthophoto 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","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","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."},{"id":"DigitalGlobe-Premium","name":"DigitalGlobe Premium Imagery","type":"tms","template":"https://{switch:a,b,c,d}.tiles.mapbox.com/v4/digitalglobe.316c9a2e/{zoom}/{x}/{y}.png?access_token=pk.eyJ1IjoiZGlnaXRhbGdsb2JlIiwiYSI6ImNqOGRmNXltOTBucm0yd3BtY3E5czl6NmYifQ.qJJsPgCjyzMCm3YG3YWQBQ","scaleExtent":[0,22],"terms_url":"https://wiki.openstreetmap.org/wiki/DigitalGlobe","terms_text":"Terms & Feedback","default":true,"description":"Premium DigitalGlobe satellite imagery.","icon":"data:image/png;base64,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"},{"id":"DigitalGlobe-Premium-vintage","name":"DigitalGlobe Premium Imagery Vintage","type":"tms","template":"https://{switch:a,b,c,d}.tiles.mapbox.com/v4/digitalglobe.2850d66c/{zoom}/{x}/{y}.png?access_token=pk.eyJ1IjoiZGlnaXRhbGdsb2JlIiwiYSI6ImNqOTBkcmZjNzJ5ZnozNHF6NnVkOGd6ODYifQ.grAnqgpCjOaeq-ozqt4QNw","scaleExtent":[0,22],"terms_url":"https://wiki.openstreetmap.org/wiki/DigitalGlobe","terms_text":"Terms & Feedback","description":"Imagery boundaries and capture dates. Labels appear at zoom level 14 and higher.","icon":"data:image/png;base64,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","overlay":true},{"id":"DigitalGlobe-Standard","name":"DigitalGlobe Standard Imagery","type":"tms","template":"https://{switch:a,b,c,d}.tiles.mapbox.com/v4/digitalglobe.0a8e44ba/{zoom}/{x}/{y}.png?access_token=pk.eyJ1IjoiZGlnaXRhbGdsb2JlIiwiYSI6ImNqOGRmNW9qZjBudmgzMnA1a294OGRtNm8ifQ.06mo-nDisy4KmqjYxEVwQw","scaleExtent":[0,22],"terms_url":"https://wiki.openstreetmap.org/wiki/DigitalGlobe","terms_text":"Terms & Feedback","default":true,"description":"Standard DigitalGlobe satellite imagery.","icon":"data:image/png;base64,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"},{"id":"DigitalGlobe-Standard-vintage","name":"DigitalGlobe Standard Imagery Vintage","type":"tms","template":"https://{switch:a,b,c,d}.tiles.mapbox.com/v4/digitalglobe.1412531a/{zoom}/{x}/{y}.png?access_token=pk.eyJ1IjoiZGlnaXRhbGdsb2JlIiwiYSI6ImNqOTBlYWJ1ZDAza2YyeG14NWVodTA4OWUifQ.wVc8ZOuPuYVw39lhS2j3_g","scaleExtent":[0,22],"terms_url":"https://wiki.openstreetmap.org/wiki/DigitalGlobe","terms_text":"Terms & Feedback","description":"Imagery boundaries and capture dates. Labels appear at zoom level 14 and higher.","icon":"data:image/png;base64,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","overlay":true},{"id":"EsriWorldImagery","name":"Esri World Imagery","type":"tms","template":"https://{switch:services,server}.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{zoom}/{y}/{x}","scaleExtent":[0,22],"terms_url":"https://wiki.openstreetmap.org/wiki/Esri","terms_text":"Terms & Feedback","default":true,"description":"Esri world imagery.","icon":"data:image/png;base64,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"},{"id":"EsriWorldImageryClarity","name":"Esri World Imagery (Clarity) Beta","type":"tms","template":"https://clarity.maptiles.arcgis.com/arcgis/rest/services/World_Imagery/MapServer/tile/{zoom}/{y}/{x}","scaleExtent":[0,22],"terms_url":"https://wiki.openstreetmap.org/wiki/Esri","terms_text":"Terms & Feedback","default":true,"description":"Esri archive imagery that may be clearer and more accurate than the default layer.","icon":"data:image/png;base64,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"},{"id":"maaamet.ee-orto","name":"Estonia Ortho (Maaamet)","type":"tms","template":"http://tiles.maaamet.ee/tm/tms/1.0.0/foto@GMC/{zoom}/{x}/{-y}.png","scaleExtent":[14,18],"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 orthophoto 2000","type":"tms","template":"http://e.tile.openstreetmap.hu/ortofoto2000/{zoom}/{x}/{y}.jpg","endDate":"2000-01-01T00:00:00.000Z","startDate":"2000-01-01T00:00:00.000Z","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 orthophoto 2005","type":"tms","template":"http://e.tile.openstreetmap.hu/ortofoto2005/{zoom}/{x}/{y}.jpg","endDate":"2005-01-01T00:00:00.000Z","startDate":"2005-01-01T00:00:00.000Z","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","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","description":"French address registry or Base Adresses Nationale"},{"id":"FR-Cadastre","name":"FR-Cadastre","type":"tms","template":"http://tms.cadastre.openstreetmap.fr/*/tout/{zoom}/{x}/{y}.png","scaleExtent":[12,22],"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_Cadastre_Fran%C3%A7ais/Conditions_d%27utilisation","terms_text":"cadastre-dgi-fr source : Direction Générale des Impôts - Cadastre. Mise à jour : 2015","description":"French land registry","icon":"https://svn.openstreetmap.org/applications/editors/josm/plugins/cadastre-fr/images/cadastre_small.png"},{"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.","icon":"http://www.freemap.sk/index.php?c=core.download&filename=/JOSM/freemap.png"},{"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.","icon":"http://www.freemap.sk/index.php?c=core.download&filename=/JOSM/freemap.png"},{"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.","icon":"http://www.freemap.sk/index.php?c=core.download&filename=/JOSM/freemap.png"},{"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.","icon":"http://www.freemap.sk/index.php?c=core.download&filename=/JOSM/freemap.png"},{"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,"icon":"http://i.imgur.com/aFlvMpM.png"},{"id":"Hampshire-Aerial-FCIR","name":"Hampshire Aerial FCIR","type":"tms","template":"https://{switch:a,b,c}.hampshire.aerial.openstreetmap.org.uk/layer/gb_hampshire_aerial_fcir/{zoom}/{x}/{y}.png","endDate":"2013-01-01T00:00:00.000Z","startDate":"2013-01-01T00:00:00.000Z","scaleExtent":[8,20],"polygon":[[[-1.315673,50.77809],[-1.491387,50.73027],[-1.57113,50.69041],[-1.680953,50.71748],[-1.693378,50.73484],[-1.695277,50.74065],[-1.686891,50.74999],[-1.710684,50.74812],[-1.719504,50.75261],[-1.746001,50.74452],[-1.748452,50.75675],[-1.742869,50.76397],[-1.751012,50.77577],[-1.78525,50.76177],[-1.799108,50.77236],[-1.822565,50.77225],[-1.826778,50.78077],[-1.822497,50.79933],[-1.807317,50.80074],[-1.81566,50.80752],[-1.808894,50.81358],[-1.805787,50.83249],[-1.798157,50.83535],[-1.806491,50.84414],[-1.809882,50.86189],[-1.813783,50.85591],[-1.830516,50.85261],[-1.852711,50.85651],[-1.85655,50.86684],[-1.849205,50.87802],[-1.85082,50.89178],[-1.84077,50.90051],[-1.826931,50.89939],[-1.820062,50.90492],[-1.821513,50.91691],[-1.816889,50.92412],[-1.841137,50.92886],[-1.874458,50.91441],[-1.911294,50.9439],[-1.923386,50.95917],[-1.95751,50.97575],[-1.959101,50.99152],[-1.949071,50.98649],[-1.928787,51.00055],[-1.887094,51.0026],[-1.87393,51.0097],[-1.871695,50.99083],[-1.854331,51.00786],[-1.835675,51.01238],[-1.815019,50.9899],[-1.800312,50.99457],[-1.751838,50.98133],[-1.719271,50.98047],[-1.691416,50.95943],[-1.66829,50.95041],[-1.652596,50.95029],[-1.635362,50.96269],[-1.623972,50.95903],[-1.608898,50.97686],[-1.621721,50.98099],[-1.631149,50.99984],[-1.609836,51.01225],[-1.601734,51.01042],[-1.607874,51.01582],[-1.605696,51.02271],[-1.635423,51.03176],[-1.638583,51.04126],[-1.631067,51.07819],[-1.640253,51.09201],[-1.630602,51.10359],[-1.634078,51.11099],[-1.630674,51.11652],[-1.641093,51.12237],[-1.665249,51.12546],[-1.657236,51.15539],[-1.674737,51.177],[-1.67213,51.18708],[-1.696792,51.20233],[-1.69247,51.21617],[-1.652877,51.22301],[-1.635643,51.22019],[-1.623947,51.24136],[-1.614024,51.24467],[-1.607408,51.25513],[-1.577168,51.25863],[-1.544434,51.24826],[-1.538396,51.25085],[-1.534359,51.25919],[-1.543446,51.25957],[-1.540068,51.27602],[-1.545961,51.28095],[-1.535908,51.28978],[-1.525949,51.28975],[-1.530933,51.29948],[-1.530081,51.3111],[-1.536275,51.31596],[-1.529857,51.34057],[-1.515522,51.34219],[-1.494983,51.33228],[-1.435991,51.33861],[-1.447589,51.3464],[-1.446305,51.35699],[-1.430556,51.35941],[-1.416077,51.37517],[-1.348989,51.37045],[-1.314724,51.37627],[-1.275549,51.3707],[-1.251156,51.37511],[-1.241179,51.36938],[-1.222093,51.37271],[-1.176023,51.36102],[-1.143212,51.36028],[-1.118753,51.36156],[-1.120961,51.36859],[-1.116785,51.3767],[-1.083632,51.38712],[-1.047537,51.36122],[-0.990405,51.36619],[-0.972636,51.36297],[-0.92376,51.36937],[-0.876809,51.3555],[-0.86549,51.35947],[-0.82728,51.35574],[-0.811219,51.34418],[-0.783225,51.34084],[-0.763252,51.32721],[-0.760048,51.32013],[-0.741834,51.31112],[-0.728423,51.28238],[-0.726306,51.25653],[-0.737128,51.23126],[-0.748978,51.2277],[-0.777122,51.23901],[-0.801926,51.23628],[-0.806106,51.24056],[-0.824914,51.23137],[-0.827009,51.22315],[-0.844932,51.20998],[-0.822682,51.18268],[-0.830416,51.15022],[-0.819518,51.15047],[-0.805037,51.15847],[-0.793819,51.15491],[-0.788794,51.14141],[-0.77846,51.13664],[-0.778131,51.13063],[-0.766544,51.11946],[-0.743652,51.11491],[-0.747146,51.10131],[-0.754112,51.10116],[-0.751217,51.09547],[-0.75506,51.08987],[-0.750757,51.0852],[-0.778501,51.07715],[-0.786448,51.06467],[-0.799544,51.06078],[-0.826446,51.05881],[-0.836458,51.0664],[-0.845193,51.06052],[-0.849904,51.0436],[-0.894853,51.01978],[-0.890651,51.00194],[-0.904614,50.99327],[-0.914614,50.97806],[-0.912784,50.9708],[-0.932457,50.94278],[-0.921188,50.9232],[-0.93793,50.91615],[-0.951325,50.89178],[-0.923681,50.86513],[-0.929757,50.85365],[-0.929033,50.84245],[-0.943419,50.82191],[-0.929902,50.78445],[-0.932748,50.77435],[-0.953469,50.73682],[-1.315673,50.77809]]]},{"id":"Hampshire-Aerial-RGB","name":"Hampshire Aerial RGB","type":"tms","template":"https://{switch:a,b,c}.hampshire.aerial.openstreetmap.org.uk/layer/gb_hampshire_aerial_rgb/{zoom}/{x}/{y}.png","endDate":"2013-01-01T00:00:00.000Z","startDate":"2013-01-01T00:00:00.000Z","scaleExtent":[8,20],"polygon":[[[-1.315673,50.77809],[-1.491387,50.73027],[-1.57113,50.69041],[-1.680953,50.71748],[-1.693378,50.73484],[-1.695277,50.74065],[-1.686891,50.74999],[-1.710684,50.74812],[-1.719504,50.75261],[-1.746001,50.74452],[-1.748452,50.75675],[-1.742869,50.76397],[-1.751012,50.77577],[-1.78525,50.76177],[-1.799108,50.77236],[-1.822565,50.77225],[-1.826778,50.78077],[-1.822497,50.79933],[-1.807317,50.80074],[-1.81566,50.80752],[-1.808894,50.81358],[-1.805787,50.83249],[-1.798157,50.83535],[-1.806491,50.84414],[-1.809882,50.86189],[-1.813783,50.85591],[-1.830516,50.85261],[-1.852711,50.85651],[-1.85655,50.86684],[-1.849205,50.87802],[-1.85082,50.89178],[-1.84077,50.90051],[-1.826931,50.89939],[-1.820062,50.90492],[-1.821513,50.91691],[-1.816889,50.92412],[-1.841137,50.92886],[-1.874458,50.91441],[-1.911294,50.9439],[-1.923386,50.95917],[-1.95751,50.97575],[-1.959101,50.99152],[-1.949071,50.98649],[-1.928787,51.00055],[-1.887094,51.0026],[-1.87393,51.0097],[-1.871695,50.99083],[-1.854331,51.00786],[-1.835675,51.01238],[-1.815019,50.9899],[-1.800312,50.99457],[-1.751838,50.98133],[-1.719271,50.98047],[-1.691416,50.95943],[-1.66829,50.95041],[-1.652596,50.95029],[-1.635362,50.96269],[-1.623972,50.95903],[-1.608898,50.97686],[-1.621721,50.98099],[-1.631149,50.99984],[-1.609836,51.01225],[-1.601734,51.01042],[-1.607874,51.01582],[-1.605696,51.02271],[-1.635423,51.03176],[-1.638583,51.04126],[-1.631067,51.07819],[-1.640253,51.09201],[-1.630602,51.10359],[-1.634078,51.11099],[-1.630674,51.11652],[-1.641093,51.12237],[-1.665249,51.12546],[-1.657236,51.15539],[-1.674737,51.177],[-1.67213,51.18708],[-1.696792,51.20233],[-1.69247,51.21617],[-1.652877,51.22301],[-1.635643,51.22019],[-1.623947,51.24136],[-1.614024,51.24467],[-1.607408,51.25513],[-1.577168,51.25863],[-1.544434,51.24826],[-1.538396,51.25085],[-1.534359,51.25919],[-1.543446,51.25957],[-1.540068,51.27602],[-1.545961,51.28095],[-1.535908,51.28978],[-1.525949,51.28975],[-1.530933,51.29948],[-1.530081,51.3111],[-1.536275,51.31596],[-1.529857,51.34057],[-1.515522,51.34219],[-1.494983,51.33228],[-1.435991,51.33861],[-1.447589,51.3464],[-1.446305,51.35699],[-1.430556,51.35941],[-1.416077,51.37517],[-1.348989,51.37045],[-1.314724,51.37627],[-1.275549,51.3707],[-1.251156,51.37511],[-1.241179,51.36938],[-1.222093,51.37271],[-1.176023,51.36102],[-1.143212,51.36028],[-1.118753,51.36156],[-1.120961,51.36859],[-1.116785,51.3767],[-1.083632,51.38712],[-1.047537,51.36122],[-0.990405,51.36619],[-0.972636,51.36297],[-0.92376,51.36937],[-0.876809,51.3555],[-0.86549,51.35947],[-0.82728,51.35574],[-0.811219,51.34418],[-0.783225,51.34084],[-0.763252,51.32721],[-0.760048,51.32013],[-0.741834,51.31112],[-0.728423,51.28238],[-0.726306,51.25653],[-0.737128,51.23126],[-0.748978,51.2277],[-0.777122,51.23901],[-0.801926,51.23628],[-0.806106,51.24056],[-0.824914,51.23137],[-0.827009,51.22315],[-0.844932,51.20998],[-0.822682,51.18268],[-0.830416,51.15022],[-0.819518,51.15047],[-0.805037,51.15847],[-0.793819,51.15491],[-0.788794,51.14141],[-0.77846,51.13664],[-0.778131,51.13063],[-0.766544,51.11946],[-0.743652,51.11491],[-0.747146,51.10131],[-0.754112,51.10116],[-0.751217,51.09547],[-0.75506,51.08987],[-0.750757,51.0852],[-0.778501,51.07715],[-0.786448,51.06467],[-0.799544,51.06078],[-0.826446,51.05881],[-0.836458,51.0664],[-0.845193,51.06052],[-0.849904,51.0436],[-0.894853,51.01978],[-0.890651,51.00194],[-0.904614,50.99327],[-0.914614,50.97806],[-0.912784,50.9708],[-0.932457,50.94278],[-0.921188,50.9232],[-0.93793,50.91615],[-0.951325,50.89178],[-0.923681,50.86513],[-0.929757,50.85365],[-0.929033,50.84245],[-0.943419,50.82191],[-0.929902,50.78445],[-0.932748,50.77435],[-0.953469,50.73682],[-1.315673,50.77809]]]},{"id":"IBGE_DF_Addresses","name":"IBGE Distrito Federal","type":"tms","template":"https://{switch:a,b,c,d}.tiles.mapbox.com/styles/v1/wille/cirnnxni1000jg8nfppc8g7pm/tiles/256/{zoom}/{x}/{y}?access_token=pk.eyJ1Ijoid2lsbGUiLCJhIjoicFNVWk5VWSJ9.hluCd0YGvYHNlFi_utWe2g","scaleExtent":[0,20],"polygon":[[[-48.2444,-16.0508],[-48.2444,-15.5005],[-47.5695,-15.5005],[-47.5695,-16.0508],[-48.2444,-16.0508]]],"description":"Addresses data from IBGE","overlay":true},{"id":"IBGE_Setores_Rurais","name":"IBGE Mapa de Setores Rurais","type":"tms","template":"https://{switch:a,b,c,d}.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":"https://{switch:a,b,c,d}.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: Adams Bridge","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R119_N09_20160327T050917&z={zoom}&x={x}&y={-y}","endDate":"2016-03-27T00:00:00.000Z","startDate":"2016-03-27T00:00:00.000Z","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","description":"Supplementing incomplete coverage in other sources (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC80700162014211LGN00","name":"imagico.de: Alaska Range","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC80700162014211LGN00&z={zoom}&x={x}&y={-y}","endDate":"2014-07-31T00:00:00.000Z","startDate":"2014-07-31T00:00:00.000Z","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","description":"Recent summer image of the Alaska Range for mapping natural features (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-aral2","name":"imagico.de: Aral Sea (high water level)","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=aral2&z={zoom}&x={x}&y={-y}","endDate":"2016-03-03T00:00:00.000Z","startDate":"2016-03-03T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[58.049,43.2623],[58.049,46.7189],[58.1014,46.8645],[61.5524,46.8629],[61.5524,46.3896],[61.4675,45.3416],[60.6317,43.2623],[58.049,43.2623]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Water and wetland extents, dams etc. - some remaining winter ice in the north (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-aral1","name":"imagico.de: Aral Sea (low water level)","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=aral1&z={zoom}&x={x}&y={-y}","endDate":"2016-09-09T00:00:00.000Z","startDate":"2016-09-09T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[58.049,43.2623],[58.049,46.7334],[58.096,46.8645],[61.5524,46.8629],[61.5524,46.3896],[61.4685,45.3544],[60.6267,43.2623],[58.049,43.2623]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Water and wetland extents, dams etc. (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R067_S40_20170417T140051","name":"imagico.de: Bahía Blanca (high tide)","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R067_S40_20170417T140051&z={zoom}&x={x}&y={-y}","endDate":"2017-04-17T00:00:00.000Z","startDate":"2017-04-17T00:00:00.000Z","scaleExtent":[0,14],"polygon":[[[-62.9988,-40.7327],[-62.9988,-37.9476],[-61.7505,-37.9474],[-61.7501,-40.7322],[-62.9988,-40.7327]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Tidal flats and islands at the coast (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R067_S40_20170127T140051","name":"imagico.de: Bahía Blanca (low tide)","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R067_S40_20170127T140051&z={zoom}&x={x}&y={-y}","endDate":"2017-01-27T00:00:00.000Z","startDate":"2017-01-27T00:00:00.000Z","scaleExtent":[0,14],"polygon":[[[-62.9988,-40.7327],[-62.9988,-37.9476],[-61.7505,-37.9474],[-61.7501,-40.7322],[-62.9988,-40.7327]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Tidal flats and islands at the coast (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC81190582014075LGN00","name":"imagico.de: Bakun Reservoir","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81190582014075LGN00&z={zoom}&x={x}&y={-y}","endDate":"2014-03-16T00:00:00.000Z","startDate":"2014-03-16T00:00:00.000Z","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","description":"Missing in older pre-2011 images (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC81250592016107LGN00","name":"imagico.de: Batam","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81250592016107LGN00&z={zoom}&x={x}&y={-y}","endDate":"2016-01-01T00:00:00.000Z","startDate":"2014-01-01T00:00:00.000Z","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","description":"Missing Islands in OSM (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC80770232017156LGN00","name":"imagico.de: Bogoslof Island","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC80770232017156LGN00&z={zoom}&x={x}&y={-y}","endDate":"2017-06-05T00:00:00.000Z","startDate":"2017-06-05T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[-168.2544,53.8749],[-168.2544,54.0213],[-167.8591,54.0213],[-167.8591,53.8749],[-168.2544,53.8749]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Recent image from after the eruption (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC81800982013291LGN00","name":"imagico.de: Bouvet Island","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81800982013291LGN00&z={zoom}&x={x}&y={-y}","endDate":"2013-10-18T00:00:00.000Z","startDate":"2013-10-18T00:00:00.000Z","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,"description":"For more accurate coastline and glacier mapping (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R017_S67_20170223T022551","name":"imagico.de: Bunger Hills","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R017_S67_20170223T022551&z={zoom}&x={x}&y={-y}","endDate":"2017-02-23T00:00:00.000Z","startDate":"2017-02-23T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[96.1197,-67.6542],[96.1201,-67.1899],[98.7331,-65.044],[105.1028,-65.044],[105.1028,-65.7224],[103.3017,-67.6542],[96.1197,-67.6542]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Largest ice free area at the East Antarctic coast - shows considerable amounts of non-permanent ice. (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R065_N47_20160929T102022","name":"imagico.de: Central 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}","endDate":"2016-09-29T00:00:00.000Z","startDate":"2016-09-29T00:00:00.000Z","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","description":"Up-to-date image for glacier mapping - beware of some fresh snow at higher altitudes (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC82050982015344LGN00","name":"imagico.de: Clerke Rocks","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC82050982015344LGN00&z={zoom}&x={x}&y={-y}","endDate":"2015-12-10T00:00:00.000Z","startDate":"2015-12-10T00:00:00.000Z","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","description":"Missing in other image sources (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R086_N60_20160831T213532","name":"imagico.de: Cook Inlet","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R086_N60_20160831T213532&z={zoom}&x={x}&y={-y}","endDate":"2016-08-31T00:00:00.000Z","startDate":"2016-08-31T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[-154.5102,59.4577],[-154.5097,60.6888],[-153.5403,62.1718],[-148.0423,62.1718],[-148.0445,61.5342],[-149.7291,59.4584],[-154.5102,59.4577]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Tidal flats and glaciers in surrounding mountains (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-EO1A0040712016264110KF","name":"imagico.de: Coropuna","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=EO1A0040712016264110KF&z={zoom}&x={x}&y={-y}","endDate":"2016-09-21T00:00:00.000Z","startDate":"2016-09-21T00:00:00.000Z","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","description":"Up-to-date image for glacier mapping (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R022_N06_20151221T103009","name":"imagico.de: Cotonou","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R022_N06_20151221T103009&z={zoom}&x={x}&y={-y}","endDate":"2015-12-21T00:00:00.000Z","startDate":"2015-12-21T00:00:00.000Z","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","description":"Patchy and partly cloudy coverage in usual sources (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R040_N01_20160311T164128","name":"imagico.de: 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}","endDate":"2016-03-11T00:00:00.000Z","startDate":"2016-03-11T00:00:00.000Z","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","description":"Recent image, only old and poor images in other sources currently (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC80360072014245LGN00","name":"imagico.de: Eastern Devon Island coast","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC80360072014245LGN00&z={zoom}&x={x}&y={-y}","endDate":"2014-09-02T00:00:00.000Z","startDate":"2014-09-02T00:00:00.000Z","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","description":"Coastline mostly mapped meanwhile (false color IR)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC82160152013239LGN00","name":"imagico.de: Eastern Iceland","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC82160152013239LGN00&z={zoom}&x={x}&y={-y}","endDate":"2013-08-27T00:00:00.000Z","startDate":"2013-08-27T00:00:00.000Z","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","description":"Missing islets and inaccurate coast (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-AST_L1T_00302052007154424_20150518041444_91492","name":"imagico.de: El Altar","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=AST_L1T_00302052007154424_20150518041444_91492&z={zoom}&x={x}&y={-y}","endDate":"2012-02-05T00:00:00.000Z","startDate":"2012-02-05T00:00:00.000Z","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","description":"2007 ASTER image offering better glacier coverage than common sources (true color with estimated blue)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R009_S61_20160109","name":"imagico.de: 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}","endDate":"2016-01-09T00:00:00.000Z","startDate":"2016-01-09T00:00:00.000Z","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","description":"Fairly clear up-to-date image for updating glacier edges (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-enderby","name":"imagico.de: Enderby Land and Kemp Coast","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=enderby&z={zoom}&x={x}&y={-y}","endDate":"2017-03-27T00:00:00.000Z","startDate":"2017-01-25T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[45.4547,-68.5091],[45.4547,-67.5724],[49.7155,-65.7176],[59.2693,-65.7176],[67.3735,-67.3449],[67.3735,-68.2581],[67.088,-68.5091],[45.4547,-68.5091]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Sentinel-2 images of Enderby Land and Kemp Coast (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC82100502015347LGN00","name":"imagico.de: Fogo, Cape Verde","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC82100502015347LGN00&z={zoom}&x={x}&y={-y}","endDate":"2015-12-13T00:00:00.000Z","startDate":"2015-12-13T00:00:00.000Z","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","description":"Image from after the 2014/2015 eruption (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-greenland","name":"imagico.de: Greenland mosaic","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=greenland&z={zoom}&x={x}&y={-y}","endDate":"2015-01-01T00:00:00.000Z","startDate":"2013-01-01T00:00:00.000Z","scaleExtent":[0,12],"polygon":[[[-43.9774,59.7171],[-44.545,59.7302],[-44.9203,59.7672],[-45.3587,59.8218],[-45.763,59.8848],[-46.0859,59.9827],[-46.3381,60.119],[-46.577,60.2652],[-46.8114,60.4418],[-47.2635,60.5314],[-47.6937,60.5549],[-48.1457,60.6192],[-48.5771,60.7015],[-48.8689,60.8506],[-49.0578,61.0555],[-49.396,61.2957],[-49.7601,61.4934],[-50.2064,61.7324],[-50.4699,61.9539],[-50.8647,62.1596],[-51.0631,62.3869],[-51.2121,62.6001],[-51.3005,62.8389],[-51.4238,62.9979],[-51.6767,63.1944],[-51.9465,63.4079],[-52.0253,63.6377],[-52.2255,63.8378],[-52.3658,64.0705],[-52.4829,64.3792],[-52.4988,64.6788],[-52.789,64.9063],[-53.2046,65.1321],[-53.6649,65.4753],[-53.9977,65.8019],[-54.1348,66.1568],[-54.1441,66.5235],[-54.2285,66.8319],[-54.4519,67.303],[-54.5141,67.7648],[-54.604,68.2021],[-54.568,68.5698],[-54.598,68.8347],[-54.7606,69.1207],[-55.0028,69.4125],[-55.2735,69.6187],[-55.3808,69.8283],[-55.3945,70.0838],[-55.3094,70.2573],[-55.4307,70.479],[-55.5501,70.6707],[-55.7654,70.861],[-56.2489,71.2343],[-56.5018,71.5429],[-56.5867,71.9015],[-56.5189,72.2355],[-56.5085,72.5258],[-56.8923,72.8144],[-57.4027,73.1054],[-57.8066,73.4566],[-58.1461,73.7696],[-58.3554,74.0972],[-58.5125,74.3783],[-58.7336,74.6328],[-59.3551,74.8869],[-60.1412,75.102],[-61.0067,75.2763],[-61.911,75.3886],[-62.4706,75.5595],[-62.9776,75.7454],[-64.1463,75.779],[-65.4481,75.7235],[-66.7068,75.6792],[-67.8379,75.6525],[-69.0456,75.6195],[-70.055,75.5344],[-71.0898,75.4705],[-72.1119,75.4476],[-74.2311,76.4102],[-74.5601,76.5328],[-74.5601,82.6959],[-14.4462,82.6959],[-14.3994,82.5997],[-13.5339,82.4379],[-12.0312,82.3426],[-10.7796,82.3196],[-10.7796,80.1902],[-11.2123,80.069],[-11.136,79.8103],[-10.7796,79.5176],[-10.7796,79.0441],[-11.2626,78.7128],[-12.2579,78.3558],[-13.2398,78.1272],[-13.7649,77.9279],[-14.1169,77.6779],[-14.7129,77.5278],[-15.5507,77.3655],[-16.0936,77.0771],[-16.0586,76.5548],[-15.838,75.9611],[-15.6879,75.4726],[-16.253,75.058],[-17.0427,74.6425],[-18.3155,74.2702],[-19.4463,73.9378],[-19.8329,73.632],[-20.2938,73.3524],[-20.7831,73.0446],[-21.01,72.6766],[-20.8774,72.2926],[-20.7672,71.8726],[-20.7765,71.4304],[-20.9411,70.9802],[-21.219,70.6126],[-21.5326,70.3001],[-21.8039,70.0911],[-22.166,69.8947],[-22.4831,69.7539],[-22.9027,69.6585],[-23.3545,69.544],[-23.9177,69.4036],[-24.1794,69.3088],[-24.6745,69.1084],[-25.1222,68.9555],[-25.6659,68.7995],[-26.0994,68.583],[-26.6316,68.4043],[-27.7638,68.2813],[-28.4575,68.0023],[-29.353,67.8135],[-30.6456,67.4911],[-31.7673,67.0005],[-32.9783,66.2596],[-33.9313,66.0156],[-34.8956,65.7403],[-35.5914,65.5208],[-36.1483,65.372],[-36.7532,65.2559],[-37.1858,65.1349],[-37.6032,64.9727],[-38.0624,64.4901],[-38.5304,64.1244],[-39.0545,63.7213],[-39.3131,63.4405],[-39.5739,62.7506],[-39.9532,62.2739],[-40.2757,61.8547],[-40.714,61.3365],[-41.2091,60.8495],[-41.821,60.5526],[-42.4368,60.3264],[-42.8643,60.0299],[-43.1131,59.9147],[-43.3282,59.83],[-43.5459,59.7695],[-43.797,59.7284],[-43.9774,59.7171]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Landsat mosaic of Greenland (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R047_S54_20160411T044330","name":"imagico.de: Heard Island coast","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R047_S54_20160411T044330&z={zoom}&x={x}&y={-y}","endDate":"2016-04-12T00:00:00.000Z","startDate":"2016-04-12T00:00:00.000Z","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","description":"Recent image of Heard island with interior mostly cloud covered but mostly well visible coast (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC82280982013259LGN00","name":"imagico.de: Isla Londonderry","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC82280982013259LGN00&z={zoom}&x={x}&y={-y}","endDate":"2013-09-16T00:00:00.000Z","startDate":"2013-09-16T00:00:00.000Z","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","description":"A lot of very coarse coastlines could be improved here, much snow cover though so no use for glacier mapping (false color IR)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-dms_kangerlussuaq_20151008","name":"imagico.de: Kangerlussuaq Autumn","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=dms_kangerlussuaq_20151008&z={zoom}&x={x}&y={-y}","endDate":"2015-10-08T00:00:00.000Z","startDate":"2015-10-08T00:00:00.000Z","scaleExtent":[0,17],"polygon":[[[-50.6992,66.9888],[-50.721,67.0017],[-50.7341,67.0125],[-50.7396,67.0193],[-50.7396,67.0212],[-50.7158,67.0265],[-50.7017,67.0265],[-50.6829,67.0176],[-50.6686,67.0077],[-50.6638,66.998],[-50.6642,66.9946],[-50.6891,66.9888],[-50.6992,66.9888]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Icebridge DMS image of the airport and settlement - alignment might be poor","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-dms_kangerlussuaq_20160518","name":"imagico.de: Kangerlussuaq Spring","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=dms_kangerlussuaq_20160518&z={zoom}&x={x}&y={-y}","endDate":"2016-05-18T00:00:00.000Z","startDate":"2016-05-18T00:00:00.000Z","scaleExtent":[0,18],"polygon":[[[-50.7519,66.9996],[-50.7555,67.0023],[-50.7555,67.0033],[-50.6395,67.0297],[-50.6162,67.0339],[-50.6097,67.0281],[-50.6331,67.022],[-50.7323,66.9996],[-50.7519,66.9996]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Icebridge DMS image of the airport and roads - alignment might be poor","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R021_N44_20160807T083013","name":"imagico.de: Kerch Strait","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R021_N44_20160807T083013&z={zoom}&x={x}&y={-y}","endDate":"2016-08-07T00:00:00.000Z","startDate":"2016-08-07T00:00:00.000Z","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","description":"State of bridge construction in August 2016 (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-ls_polar2","name":"imagico.de: Landsat off-nadir July 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=ls_polar2&z={zoom}&x={x}&y={-y}","endDate":"2016-07-17T00:00:00.000Z","startDate":"2016-07-17T00:00:00.000Z","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","description":"Latest images north of the regular Landsat limit (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-larsen_2018","name":"imagico.de: Larsen C ice shelf after calving","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=larsen_2018&z={zoom}&x={x}&y={-y}","endDate":"2018-01-06T00:00:00.000Z","startDate":"2018-01-06T00:00:00.000Z","scaleExtent":[0,12],"polygon":[[[-62.7282,-68.9652],[-64.0489,-68.7318],[-64.0486,-68.5373],[-60.8845,-65.9399],[-59.9187,-65.9389],[-59.1088,-66.0775],[-59.1088,-68.8359],[-59.2544,-68.9652],[-62.7282,-68.9652]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"For updating the ice edge after the 2017 iceberg calving (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-AST_L1T_00311162013112731_20150618142416_109190","name":"imagico.de: 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}","endDate":"2013-11-16T00:00:00.000Z","startDate":"2013-11-16T00:00:00.000Z","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","description":"Missing in other image sources (true color with estimated blue)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC81991002015286LGN00","name":"imagico.de: Leskov Island Landsat","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81991002015286LGN00&z={zoom}&x={x}&y={-y}","endDate":"2015-10-13T00:00:00.000Z","startDate":"2015-10-13T00:00:00.000Z","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","description":"Missing in other image sources (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-ls_polar","name":"imagico.de: May 2013 off-nadir Landsat","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=ls_polar&z={zoom}&x={x}&y={-y}","endDate":"2013-05-17T00:00:00.000Z","startDate":"2013-05-17T00:00:00.000Z","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","description":"First available image north of the regular Landsat limit, mostly with seasonal snow cover so difficult to interpret (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R042_S78_20170214T202521","name":"imagico.de: McMurdo Sound and Dry Valleys ","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R042_S78_20170214T202521&z={zoom}&x={x}&y={-y}","endDate":"2017-02-14T00:00:00.000Z","startDate":"2017-02-14T00:00:00.000Z","scaleExtent":[0,12],"polygon":[[[162.9125,-78.4514],[162.6595,-78.4257],[159.2712,-77.6013],[159.2712,-77.4108],[164.157,-76.477],[169.7813,-76.4764],[169.7813,-78.4514],[162.9125,-78.4514]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Up-to-date late season image - not ice minimum, be careful with distinguishing sea ice from ice shelves. (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R092_S02_20160613T075613","name":"imagico.de: Mount Kenya 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R092_S02_20160613T075613&z={zoom}&x={x}&y={-y}","endDate":"2016-06-13T00:00:00.000Z","startDate":"2016-06-13T00:00:00.000Z","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","description":"Up-to-date image for glacier mapping (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R092_S05_20160802T075556","name":"imagico.de: Mount Kilimanjaro 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R092_S05_20160802T075556&z={zoom}&x={x}&y={-y}","endDate":"2016-08-02T00:00:00.000Z","startDate":"2016-08-02T00:00:00.000Z","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","description":"Up-to-date image for glacier mapping (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC80940622015159LGN00","name":"imagico.de: New Ireland","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC80940622015159LGN00&z={zoom}&x={x}&y={-y}","endDate":"2015-06-08T00:00:00.000Z","startDate":"2015-06-08T00:00:00.000Z","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","description":"Many missing islands in OSM (mostly mapped meanwhile) (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-northsea_s2_2016","name":"imagico.de: North Sea Coast 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=northsea_s2_2016&z={zoom}&x={x}&y={-y}","endDate":"2016-09-25T00:00:00.000Z","startDate":"2016-09-25T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[5.1562,52.8755],[5.1615,53.0325],[6.4155,55.7379],[9.8813,55.7459],[9.8813,53.2428],[9.6846,52.8877],[5.1562,52.8755]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Up-to-date low tide imagery of the coast for updating mapping of tidalflats and shoals (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-northsea_s2_2017","name":"imagico.de: North Sea Coast 2017","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=northsea_s2_2017&z={zoom}&x={x}&y={-y}","endDate":"2017-06-02T00:00:00.000Z","startDate":"2017-06-02T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[5.1713,53.0918],[6.477,55.8973],[9.8813,55.8973],[9.8813,53.2761],[9.7789,53.0918],[5.1713,53.0918]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Up-to-date low tide imagery of the coast for updating mapping of tidalflats and shoals (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-ural_s2_2016","name":"imagico.de: 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}","endDate":"2016-08-12T00:00:00.000Z","startDate":"2016-08-12T00:00:00.000Z","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","description":"Up-to-date late summer imagery with few clouds - caution: not all visible snow is glaciers (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-ndvina","name":"imagico.de: Northern Dvina delta at low tide","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=ndvina&z={zoom}&x={x}&y={-y}","endDate":"2015-09-13T00:00:00.000Z","startDate":"2015-09-13T00:00:00.000Z","scaleExtent":[0,12],"polygon":[[[37.7291,64.1971],[37.7291,65.1161],[37.8592,65.2705],[41.3223,65.2705],[41.3223,64.3142],[41.2114,64.1973],[37.7291,64.1971]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Beaches, tidal flats and other costal forms (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-nellesmere_ast","name":"imagico.de: Northern Ellesmere Island","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=nellesmere_ast&z={zoom}&x={x}&y={-y}","endDate":"2012-07-09T00:00:00.000Z","startDate":"2012-07-09T00:00:00.000Z","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","description":"Assembled from July 2012 ASTER imagery (true color with estimated blue)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-nellesmere_ast_2016","name":"imagico.de: 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}","endDate":"2012-07-15T00:00:00.000Z","startDate":"2012-07-08T00:00:00.000Z","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","description":"Assembled from July 2016 ASTER imagery (true color with estimated blue)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC81960222015233LGN00vis","name":"imagico.de: Northern German west coast tidalflats","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81960222015233LGN00vis&z={zoom}&x={x}&y={-y}","endDate":"2015-08-21T00:00:00.000Z","startDate":"2015-08-21T00:00:00.000Z","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","description":"Up-to-date low tide imagery of the coast for updating mapping of tidalflats and shoals (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC81960222015233LGN00ir","name":"imagico.de: Northern German west coast tidalflats (infrared)","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81960222015233LGN00ir&z={zoom}&x={x}&y={-y}","endDate":"2015-08-21T00:00:00.000Z","startDate":"2015-08-21T00:00:00.000Z","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","description":"Up-to-date low tide imagery of the coast for updating mapping of tidalflats and shoals (false color IR)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-ngreenland_ast","name":"imagico.de: Northern Greenland ASTER","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=ngreenland_ast&z={zoom}&x={x}&y={-y}","endDate":"2012-08-13T00:00:00.000Z","startDate":"2005-06-21T00:00:00.000Z","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","description":"Assembled from mostly 2012 ASTER imagery, some 2005 images mainly in the northeast (true color with estimated blue)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-EO1A1350972013086110KF","name":"imagico.de: Northwest Heard Island","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=EO1A1350972013086110KF&z={zoom}&x={x}&y={-y}","endDate":"2013-03-13T00:00:00.000Z","startDate":"2013-03-13T00:00:00.000Z","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","description":"Glaciers of Northwest Heard Island (mapped meanwhile) (false color IR)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R111_N09_20160604T154554","name":"imagico.de: Panama Canal","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R111_N09_20160604T154554&z={zoom}&x={x}&y={-y}","endDate":"2016-06-07T00:00:00.000Z","startDate":"2016-06-07T00:00:00.000Z","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","description":"Images of the new locks (but partly cloudy) (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-EO1A0120532016364110KF","name":"imagico.de: Panama Canal - Pacific side","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=EO1A0120532016364110KF&z={zoom}&x={x}&y={-y}","endDate":"2016-12-30T00:00:00.000Z","startDate":"2016-12-30T00:00:00.000Z","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","description":"New locks with less clouds than in the Sentinel-2 image - make sure to check image alignment (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R078_N68_20160930T081002","name":"imagico.de: Pechora Sea Coast","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R078_N68_20160930T081002&z={zoom}&x={x}&y={-y}","endDate":"2016-09-30T00:00:00.000Z","startDate":"2016-09-30T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[53.1802,67.5344],[53.1821,68.414],[54.2107,69.3367],[55.3584,70.2786],[59.004,70.2786],[60.6947,69.977],[61.9837,69.7161],[61.9823,68.9395],[59.9153,67.5344],[53.1802,67.5344]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Sentinel-2 image of the Pechora Sea coast in autumn 2016 (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC81511242016033LGN00","name":"imagico.de: Pensacola Mountains","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81511242016033LGN00&z={zoom}&x={x}&y={-y}","endDate":"2016-02-02T00:00:00.000Z","startDate":"2016-02-02T00:00:00.000Z","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","description":"Outside regular Landsat coverage and therefore not in LIMA and Bing/Mapbox (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R136_N41_20150831T093006","name":"imagico.de: Prokletije Mountains","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R136_N41_20150831T093006&z={zoom}&x={x}&y={-y}","endDate":"2015-08-31T00:00:00.000Z","startDate":"2015-08-31T00:00:00.000Z","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","description":"Late summer imagery where usual sources are severely limited by clouds and snow (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-DMS_1142622_03746_20110415_17533956","name":"imagico.de: Qasigiannguit","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=DMS_1142622_03746_20110415_17533956&z={zoom}&x={x}&y={-y}","endDate":"2011-04-15T00:00:00.000Z","startDate":"2011-04-15T00:00:00.000Z","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","description":"Icebridge DMS image of the settlement - alignment might be poor","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC81510432015030LGN00","name":"imagico.de: Rann of Kutch","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81510432015030LGN00&z={zoom}&x={x}&y={-y}","endDate":"2015-01-01T00:00:00.000Z","startDate":"2015-01-01T00:00:00.000Z","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","description":"Land/water distinction difficult to properly map based on Bing/Mapbox images (false color IR)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R093_N41_20150828T092005","name":"imagico.de: 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}","endDate":"2015-08-28T00:00:00.000Z","startDate":"2015-08-28T00:00:00.000Z","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","description":"Late summer imagery where usual sources are severely limited by clouds and snow (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC81730602015040LGN00","name":"imagico.de: Rwenzori Mountains","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81730602015040LGN00&z={zoom}&x={x}&y={-y}","endDate":"2015-02-09T00:00:00.000Z","startDate":"2015-02-09T00:00:00.000Z","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","description":"Recent image of most of the remaining Rwenzori Mountains glaciers (false color IR)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R078_N01_20160702T082522","name":"imagico.de: Rwenzori Mountains 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R078_N01_20160702T082522&z={zoom}&x={x}&y={-y}","endDate":"2016-07-02T00:00:00.000Z","startDate":"2016-07-02T00:00:00.000Z","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","description":"Up-to-date image for glacier mapping (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC80611072014036LGN00","name":"imagico.de: Scott Island","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC80611072014036LGN00&z={zoom}&x={x}&y={-y}","endDate":"2014-02-05T00:00:00.000Z","startDate":"2014-02-05T00:00:00.000Z","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","description":"Missing in other image sources (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC82100972015347LGN00","name":"imagico.de: Shag Rocks","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC82100972015347LGN00&z={zoom}&x={x}&y={-y}","endDate":"2015-12-13T00:00:00.000Z","startDate":"2015-12-13T00:00:00.000Z","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","description":"Missing in other image sources (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC81130622013270LGN00","name":"imagico.de: Southeastern Sulawesi","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81130622013270LGN00&z={zoom}&x={x}&y={-y}","endDate":"2013-09-27T00:00:00.000Z","startDate":"2013-09-27T00:00:00.000Z","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","description":"Missing islands and coarse coastline due to cloud cover in Bing, lakes could also use additional detail (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC80281222016035LGN00","name":"imagico.de: Southern Transantarctic Mountains","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC80281222016035LGN00&z={zoom}&x={x}&y={-y}","endDate":"2016-02-04T00:00:00.000Z","startDate":"2016-02-04T00:00:00.000Z","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","description":"Outside regular Landsat coverage and therefore not in LIMA and Bing/Mapbox (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC81030632015286LGN00","name":"imagico.de: Sudirman Range 2015","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81030632015286LGN00&z={zoom}&x={x}&y={-y}","endDate":"2015-10-13T00:00:00.000Z","startDate":"2015-10-13T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[136.4226,-4.2853],[136.4226,-3.6447],[137.7971,-3.6447],[137.7971,-4.2853],[136.4226,-4.2853]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Older image of the Sudirman Range with no fresh snow showing glacier extent (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R088_S05_20160812T011732","name":"imagico.de: Sudirman Range 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R088_S05_20160812T011732&z={zoom}&x={x}&y={-y}","endDate":"2016-08-12T00:00:00.000Z","startDate":"2016-08-12T00:00:00.000Z","scaleExtent":[0,14],"polygon":[[[136.8044,-4.2585],[136.8044,-3.7836],[137.7701,-3.7836],[137.7701,-4.2585],[136.8044,-4.2585]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Cloud free image of the Sudirman Range but with fresh snow (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-s2sval","name":"imagico.de: Svalbard mosaic","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=s2sval&z={zoom}&x={x}&y={-y}","endDate":"2016-01-01T00:00:00.000Z","startDate":"2016-01-01T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[16.6108,76.4137],[16.4731,76.4268],[16.3788,76.4589],[14.4124,77.1324],[14.0784,77.2536],[10.9875,78.4054],[10.631,78.5605],[10.2314,78.8392],[10.3952,79.6074],[10.516,79.7731],[10.9632,79.8707],[20.2294,80.849],[20.4702,80.8493],[25.1752,80.6817],[33.4391,80.3438],[33.7809,80.3016],[34.0395,80.239],[33.977,80.1527],[25.5722,76.5917],[25.2739,76.481],[25.1416,76.4327],[24.937,76.4176],[16.6108,76.4137]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Sentinel-2 mosaic of Svalbard (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-DMS_1142636_160xx_20110507_1822xxxx","name":"imagico.de: 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}","endDate":"2011-05-07T00:00:00.000Z","startDate":"2011-05-07T00:00:00.000Z","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","description":"Icebridge DMS image - alignment might be poor","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-dms_thule2_2015.09.25","name":"imagico.de: 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}","endDate":"2015-09-25T00:00:00.000Z","startDate":"2015-09-25T00:00:00.000Z","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","description":"Icebridge DMS aerial images from Thule Airbase - alignment might be poor","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-dms_thule_2015.10.06","name":"imagico.de: 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}","endDate":"2015-10-06T00:00:00.000Z","startDate":"2015-10-06T00:00:00.000Z","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","description":"Icebridge DMS aerial images from Thule Airbase - alignment might be poor","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-dms_thule_2015.09.25","name":"imagico.de: 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}","endDate":"2015-09-25T00:00:00.000Z","startDate":"2015-09-25T00:00:00.000Z","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","description":"Icebridge DMS aerial images from Thule Airbase - alignment might be poor","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R094_N79_20160812T105622","name":"imagico.de: 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}","endDate":"2016-08-12T00:00:00.000Z","startDate":"2016-08-12T00:00:00.000Z","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","description":"Up-to-date late summer imagery with few clouds (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC80910682014358LGN00","name":"imagico.de: Vanatinai","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC80910682014358LGN00&z={zoom}&x={x}&y={-y}","endDate":"2014-12-24T00:00:00.000Z","startDate":"2014-12-24T00:00:00.000Z","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","description":"Coarse coastline due to cloud cover in Bing/Mapbox (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC82330892016031LGN00","name":"imagico.de: Volcán Calbuco","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC82330892016031LGN00&z={zoom}&x={x}&y={-y}","endDate":"2016-01-31T00:00:00.000Z","startDate":"2016-01-31T00:00:00.000Z","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","description":"Image from after the 2015 eruption (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R089_N52_20160623T024048","name":"imagico.de: Vostochny Cosmodrome","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R089_N52_20160623T024048&z={zoom}&x={x}&y={-y}","endDate":"2016-06-23T00:00:00.000Z","startDate":"2016-06-23T00:00:00.000Z","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","description":"Recent image showing newest features (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-walps_autumn_2017","name":"imagico.de: Western Alps autumn colors 2017","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=walps_autumn_2017&z={zoom}&x={x}&y={-y}","endDate":"2017-10-17T00:00:00.000Z","startDate":"2017-10-17T00:00:00.000Z","scaleExtent":[0,13],"polygon":[[[4.6412,43.2493],[4.3118,43.2653],[4.3118,44.2167],[5.2562,46.965],[5.9151,48.7177],[7.3866,48.7467],[10.088,48.7467],[10.088,48.7032],[7.7819,43.2813],[7.76,43.2653],[7.3646,43.2493],[4.6412,43.2493]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","description":"Autumn colors in the Alps, Jura and southwestern Germany  (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-LC81490352013282LGN00","name":"imagico.de: Western Karakoram","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81490352013282LGN00&z={zoom}&x={x}&y={-y}","endDate":"2013-10-09T00:00:00.000Z","startDate":"2013-10-09T00:00:00.000Z","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","description":"Represents approximately minimum snow cover so can be well used for glacier mapping (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"osmim-imagicode-S2A_R039_S15_20160510T145731","name":"imagico.de: 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}","endDate":"2016-05-10T00:00:00.000Z","startDate":"2016-05-10T00:00:00.000Z","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","description":"Poor and outdated imagery in other sources (true color)","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAADWElEQVQ4y13TS2gcdQDH8e/szGQ372Tz2irGpoS0KSapoqjRQ4knD0WweLRCCXiQXuJFMR6EYMVC0IsPyKVFsJpWbQ0KQmL14KPWirGmZjdmk+w7mX1kZ2d2dv7/mfFUsX5Pv8Pv+lH4X6/NvTPc239gOlXyp7ZzlaEg8EGYyVaZWY7dc+/CuTde+fu/f+XOeP3iLT2bTMxN9NVm1PZhbfKBGC/OXsDzHJr1EEf6ilSMLZFrxObHJk/OfvDqCQmgArz3TUJfXZm/3K53nZ4YPRw69czjXPrqR+LJHJ4rUFXA3qG33Va3cpknU2vxY1pz9yWzlPZVgL6xobNGXp7u6T9Geq/O+U+usHRtE6du0aJncSyXtnCOcqVC0ZTIhnM44itNhpFeVs5+kRxe//OP22VDar4ncRwHz85TKtY40H2D4n6KwNMRgUPIC9ES0mj2NNwK4rfE2qhWyBnT1YrUQkqA3hwmpIYw63law4JcaR/hR9GVAh2tOmEUHunpwKkJVm10VdOntbptP+VJiaIoKIDv7zPQbVDxJIPRPkRkh8CN0KFrjHdGiXW3kkuXSRYEakid0qQrDkrhEgQ+tZpNtVTmoQdNrGgB6XjUpEJzSxvCgnhOZ+RQFKtcZV8IpO8NhXxfIoWLY9tUS0XePxXHMNrY3BxkOx+lXVX54dc+VjdaiHabXPg6RcMSWFULT3poEGxJ0eit1Wq06w4FMURPl8NObo9MvgnTaOGF402M399DrDNEPJHnl99rZIoWvudvaeGwtux53sOPjffy9pn7CHdKnn5WJ/5XnudnrjF2tJ/F61mGBiIc7fe4mXT5ds0lu1tE8f1lbSDWu5DZyb98fMLVwp0dgINv5Bjpcfj50yloUsAo8Ob8T/iVBociLrtlC9+tCwgW1O8++7A09dxLbUvfrzzRpV7nSCyK0qRDOEwjlUYr7iH2DPx6hXevpLi5YXNjfRsCcQ4aiwrAlxuB/tHCx5fTyaUTg/1pJke6eHR0GF9AKZtnv1BlYSWFWYBEepdyuXwV5EmQ8l9Mn9929asXF+c21xMz5b1NreHewvNcHAc0qRGpQyqfFZZZnQc5C1LepfFOZ946P5xJbkybRmbKzm8f3C3b2GZlyzYLy9WqteD5jbs4/wOHuM2qT5aWEQAAAABJRU5ErkJggg=="},{"id":"IPR-orotofoto-last-tms","name":"IPR ortofoto LAST (tmsproxy)","type":"tms","template":"http://osm-{switch:a,b,c}.zby.cz/tiles_ipr_last.php/{zoom}/{x}/{y}.jpg","scaleExtent":[1,18],"polygon":[[[14.81231552124,49.93089301941],[14.18754582291,49.87687266984],[14.12025456314,50.19881542327],[14.74502426147,50.25247461226],[14.81231552124,49.93089301941]]]},{"id":"IPR-orotofoto-vege-tms","name":"IPR ortofoto Low-Vegetation (tmsproxy)","type":"tms","template":"http://osm-{switch:a,b,c}.zby.cz/tiles_ipr_vege.php/{zoom}/{x}/{y}.jpg","scaleExtent":[1,20],"polygon":[[[14.30454236984,49.99538124382],[14.3160436821,49.94205148763],[14.3499983888,49.94508261663],[14.35383872175,49.92726356386],[14.42385321818,49.93351545169],[14.4200902288,49.95097343212],[14.48865449494,49.95709281879],[14.48479036398,49.9750111737],[14.55385989188,49.98117257481],[14.55011770159,49.99851689993],[14.58455395868,50.0015874108],[14.58829614897,49.98424419323],[14.69168128485,49.99346468175],[14.67633637226,50.06452744171],[14.71278864961,50.06777324036],[14.70115373952,50.12158114828],[14.66470146217,50.11833899243],[14.6610031918,50.13543086714],[14.62755290441,50.13245658485],[14.61965341283,50.16894659259],[14.58542741996,50.16590546732],[14.58162921725,50.18344165464],[14.40776267983,50.167995553],[14.41156088254,50.15045369625],[14.37764851321,50.14743927281],[14.37379555571,50.16523508727],[14.33892816423,50.16213672855],[14.34278112173,50.14433976066],[14.27367931007,50.13819641038],[14.27749028245,50.12058459573],[14.20879964298,50.11447476994],[14.21288816219,50.09557069695],[14.24656290855,50.09856724424],[14.25417384067,50.06335893014],[14.21987061144,50.0603042129],[14.22369648177,50.04259477081],[14.257999711,50.04565061557],[14.26952647673,49.99225864496],[14.30454236984,49.99538124382]]]},{"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","icon":"http://nls.tileserver.com/nls70-nq8.png"},{"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":"https://wiki.openstreetmap.org/wiki/WikiProject_Ireland#Trinity_College_Dublin","terms_text":"Glucksman Map Library, Trinity College Dublin","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAB3RJTUUH3gQOFR0YB1KT3QAAAAlwSFlzAAAewQAAHsEBw2lUUwAAAARnQU1BAACxjwv8YQUAAAS/SURBVHjandN7TFNXHAfwzrn/lm3ZHy7LYrJkybK5zMw9fCEoPjbeChoHTtBVRF7l1ZZSaG8flCtvsFVpoZZHC5Y6jDM+UScDaxF5lIfSAaMIlVKBS8EZN4d+d9voZpbMFX/JN7nnnvM7n5xzcxmM5wrPlX1yFmP2adgmXKHc78bsU+j9ZRT3HzzE+D0n7tjuYdo5h38X47/q+UWD1nE0tw/gktEC66gdN/tG0Dc4hnEHhdG7DujOdqGHxi4ae2AZti8ccJXZYoOxawRPnjzGwcpmzM8//ntOe86MickZTEw7ka+99nJAZ/8YWjqs7ufc6ibM/fbQ/fzHo0eoOduJ8UkKljt2nLhk9hj4/Wlm6VA9A2NUa/ew6wNQE1OzVGvPEGUZvkvZHVNUo2mA6ugfpvoGrNT8/Dz1tMfd/yJgKZ13h6zjzFbzvbwO8wDZaR4kzeZbZG/fIHnTbCOvdzrI9h472dnVT97oociO23NkW+9M3pDVsc/V69rjRYA7Su11/dvbfkRJvDeOcMORuj8CpelLkJO6BVs4vQhj3QD5fTQS2PXYndQAblw2yrUt9c/6/xeoqzulK+VEoCTtawgSM5HCr0Nsmg48ngJhYiukonNIybeg8MQEFIZBFBWIoa4z1XoMaOrbtbHci2BtW4RachnOlO/GZW0SjuZEY2eWGYVEFfYJ+kDo/4ThdDPExadQcbxb5zmgb6/xYZlAxPtDmByFS2U+EHM5yBOyEZZ8HkzeZaQmyxFZROGkgUQIMQSNvkPrMXBM31YdFqNDJK8ZHE4FYgSt2Jl0GpKUGAhFjTiQ2QJDgRBGdSTIvEJ8IXDSQJvngEbfWrWacGJDzn1sJ34FkSqFQbgWTcUrcLWIATlnBzYSE8hOOIBQzk9YK56jgRs1CzlBVXD6bcijCYSwTYjhXUFD7nrUlHyFc6pPUCL4BpskUwhn6iGPSMYG3igN3KxeCKDZyulGddReBKV3YbNkGidkIWhQLMeFiuUoE3ths8iOfXFnoQ5nwTt9xHVFVZ5f0XGjxks0A++sIWyNqYM0TYp6qS9+UHxOn+BjqMQfwF8wgg2x5+ErccCboKA5bloAUGc8tk40i2CmGuGhgQhjX0MZwUY5uRJVuX6QcpPhm2TErlBfBLAa4S2epYHrlZ5fke4K6SVyIjRejz1REfhO2Ab2wavgZJ8EU9gEUek1MDMvIIa5DUFpzVhHzECtbRR4DJRrDP5f8h04ILwAmTQLAkEWCgsLIJVIIcwS4uhRBSQSCfi8FGzP6sbKjLsoV+tWewwolUfe+pR1y7GD1YDd4cGIi4uFgM/HulWr4LdpI5ITE5EQH49dOwMRmtmND/ebLMoy+WueA2VyBmO9opSTcx6HimWQHypGBicF+6MjwdzzLSQEH6UlBSjKFyNS1AnGMm6Csuwww2NApVK6hkv2JMptmTkGiPNqEcc+jFiuGsy0SrD4lciQ1kJW3ICAqJIWeu1ilUq1EEDlHr/6vr/XxozBuQD6jw6UUXRm6DgRQCeQfIA1iaZ+BuP191xrXwpw1RtL16zwSfi5PVg2hZAcyp0gqQOr9548TU+/82zdywGvLH429eZnO8rPBNMbB4ps+MhPpvyna9ELgb8ASvKZeuq+E9sAAAAASUVORK5CYII="},{"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","icon":"http://nls.tileserver.com/nls70-nq8.png"},{"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","endDate":"2011-01-01T00:00:00.000Z","startDate":"2011-01-01T00:00:00.000Z","scaleExtent":[14,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 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","endDate":"2014-01-01T00:00:00.000Z","startDate":"2014-01-01T00:00:00.000Z","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"},{"id":"Aargau-AGIS-2016","name":"Kanton Aargau 25cm (AGIS 2016)","type":"tms","template":"http://mapproxy.osm.ch:8080/tiles/AGIS2016/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","endDate":"2016-01-01T00:00:00.000Z","startDate":"2016-01-01T00:00:00.000Z","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 OF2016","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":"KTBASELSTADT2017","name":"Kanton Basel-Stadt 2017","type":"tms","template":"http://mapproxy.osm.ch:8080/tiles/KTBASELSTADT2017/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","scaleExtent":[8,21],"polygon":[[[7.6713752,47.5952248],[7.6799583,47.6007811],[7.6845073,47.6018228],[7.6943779,47.601707],[7.6939487,47.5966718],[7.6870823,47.5935462],[7.6788425,47.5871208],[7.685709,47.585384],[7.6890564,47.5761205],[7.6941204,47.573399],[7.6924038,47.5669132],[7.6847005,47.5617009],[7.6642513,47.5616429],[7.6487159,47.5568934],[7.6303482,47.558689],[7.6235675,47.5566617],[7.6278591,47.5514483],[7.6273763,47.5365801],[7.6183319,47.5366163],[7.6133537,47.5326179],[7.5996208,47.5191137],[7.5850296,47.5191717],[7.5840854,47.5263589],[7.5771331,47.5316327],[7.581253,47.5398612],[7.5718975,47.5414835],[7.553873,47.5414835],[7.5537872,47.5512166],[7.5565338,47.5582836],[7.5537014,47.5603108],[7.5537872,47.5747308],[7.5643444,47.5812157],[7.5793647,47.579884],[7.583313,47.5901889],[7.5856304,47.5923306],[7.5920677,47.5923885],[7.598505,47.5907098],[7.609148,47.5864261],[7.6092338,47.5810999],[7.6191043,47.580463],[7.6368713,47.593141],[7.6378154,47.595572],[7.6416778,47.5988711],[7.6452827,47.6002602],[7.664938,47.5961798],[7.6713752,47.5952248]]],"terms_text":"Kanton Basel-Stadt OF 2017","best":true},{"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,"icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAIVBMVEX///+LKCbMAABycnL+/v7v7+9sbGz39/fz8/Pw8PD8/Pz60siYAAAAAWJLR0QAiAUdSAAAAAd0SU1FB+AIGAsXN84mS+sAAAA4SURBVAjXY2AUBAMBBkYlMCCXwcwABgZYGCwGIJo5AMQGAjYgLgYxLICY05iBwRisjsvY2IGBAQAGpQmjMKkg/wAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNi0wOC0yNFQxMToyMzo1NS0wNDowMLEFqzIAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTYtMDgtMjRUMTE6MjM6NTUtMDQ6MDDAWBOOAAAAAElFTkSuQmCC"},{"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":"kartverket-topo4","name":"Kartverket N50 topo","type":"tms","template":"http://opencache{switch:,2,3}.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=topo4&zoom={zoom}&x={x}&y={y}","scaleExtent":[3,15],"polygon":[[[31.904253,70.4368136],[28.4765186,71.3289643],[23.6865015,71.2514263],[16.8090601,70.0730823],[11.1620655,67.5253903],[9.975542,64.811576],[4.2187061,62.1449966],[4.3725367,59.1871966],[6.1743055,57.8915032],[7.932118,57.7393554],[10.777577,58.8649103],[11.7224012,58.762509],[12.722157,60.1141506],[13.0517469,61.3493518],[12.5243921,63.6169922],[14.2382593,63.9856094],[15.1171656,65.9016624],[18.6987085,68.3749083],[20.0610132,68.2612583],[21.0058375,68.7841518],[25.2465601,68.3506025],[26.9384546,69.8472011],[28.7621851,69.6112133],[28.5864039,68.8556004],[31.069314,69.5191547],[31.904253,70.4368136]]],"terms_url":"https://wiki.openstreetmap.org/wiki/No:Kartverket_import","terms_text":"© Kartverket","description":"Topographic map N50, equivalent to Norway 1:50.000 paper map series.","icon":"https://www.kartverket.no/Content/Images/logo-graphic-512.png"},{"id":"kelowna_2012","name":"Kelowna 2012","type":"tms","template":"http://{switch:a,b,c,d}.tile.paulnorman.ca/kelowna2012/{zoom}/{x}/{y}.png","endDate":"2012-05-14T00:00:00.000Z","startDate":"2012-05-13T00:00:00.000Z","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]]],"description":"High quality aerial imagery taken for the City of Kelowna"},{"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","endDate":"2013-09-03T00:00:00.000Z","startDate":"2013-09-03T00:00:00.000Z","scaleExtent":[5,14],"polygon":[[[-60.8550011,6.1765004],[-60.4762612,7.9188291],[-62.161689,8.2778675],[-62.5322549,6.5375488],[-60.8550011,6.1765004]]],"description":"Recent Landsat imagery"},{"id":"lu.geoportail.opendata.ortholatest","name":"Latest available ortho geoportail.lu","type":"tms","template":"http://{switch:wmts1,wmts2}.geoportail.lu/opendata/wmts/ortho_latest/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,"icon":"https://www.geoportail.lu/static/img/lion.png"},{"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","endDate":"2013-09-12T00:00:00.000Z","startDate":"2013-09-12T00:00:00.000Z","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]]],"description":"Recent lower-resolution landsat imagery for southwest British Columbia"},{"id":"LINZ_NZ_Aerial_Imagery","name":"LINZ NZ Aerial Imagery","type":"tms","template":"https://tiles-a.data-cdn.linz.govt.nz/services;key=3197c6d0e5cb494a95d58dc2de3216c2/tiles/v4/set=2/EPSG:3857/{zoom}/{x}/{y}.png","scaleExtent":[0,21],"polygon":[[[167.2503662109375,-47.21956811231548],[167.244873046875,-47.28016067076474],[167.5030517578125,-47.37975438400816],[168.2501220703125,-47.15610477504402],[168.7445068359375,-46.79629898997744],[169.3267822265625,-46.75491661928188],[169.78271484375,-46.604167162931844],[170.4254150390625,-46.11132565729794],[170.804443359375,-45.95114968669139],[170.9527587890625,-45.440862671781744],[171.309814453125,-44.91035917458493],[171.40869140625,-44.39061697878681],[172.562255859375,-43.92954993561458],[172.90283203125,-43.96909818325171],[173.1610107421875,-43.90976594390799],[173.2598876953125,-43.69567969789881],[172.9742431640625,-43.53660274231031],[172.760009765625,-43.37710501700071],[173.1500244140625,-43.17714134663171],[173.704833984375,-42.63395872267314],[174.36401367187497,-41.78360106648077],[174.320068359375,-41.409775832009544],[174.84741210937497,-41.52914198872309],[175.0726318359375,-41.70572851523751],[175.506591796875,-41.672911819602085],[176.2261962890625,-41.10832999732831],[176.8304443359375,-40.42604212826493],[177.17102050781247,-39.67337039176559],[177.0391845703125,-39.39375459224347],[177.4456787109375,-39.18117526158747],[177.60498046875,-39.3300485529424],[177.978515625,-39.368279149160124],[178.3355712890625,-38.65977773071253],[178.7091064453125,-37.74465712069938],[178.626708984375,-37.54457732085582],[178.3135986328125,-37.43125050179357],[177.6214599609375,-37.37888785004525],[177.0391845703125,-37.39634613318924],[176.561279296875,-37.37015718405751],[176.3360595703125,-37.05956083025124],[176.0064697265625,-36.29741818650809],[175.6768798828125,-36.05354012833974],[174.671630859375,-35.1782983520012],[173.1939697265625,-34.28445325435288],[172.6776123046875,-34.234512362369856],[172.386474609375,-34.40237742424137],[172.4798583984375,-34.71903991764788],[172.9852294921875,-35.32184842037683],[173.56201171875,-36.142310873529986],[174.30908203125,-37.077093191754415],[174.5562744140625,-38.052416771864834],[174.4793701171875,-38.655488159952995],[174.3255615234375,-38.865374851611634],[173.7982177734375,-38.95940879245421],[173.60595703125,-39.232253141714885],[173.6993408203125,-39.56335316582929],[174.5892333984375,-39.95606977009003],[174.9847412109375,-40.216635475391215],[174.9847412109375,-40.49291502689579],[174.7210693359375,-40.805493843894155],[174.1497802734375,-40.65147128144056],[173.2818603515625,-40.43440488077009],[172.5897216796875,-40.350730565917885],[172.0843505859375,-40.534676780615406],[171.7657470703125,-40.826280356677124],[171.57348632812497,-41.3974150664646],[171.2823486328125,-41.652392884268124],[170.8758544921875,-42.53284428171312],[170.35400390625,-42.87193842444846],[168.277587890625,-43.92954993561458],[167.6239013671875,-44.47691085722324],[166.55273437499997,-45.38687734827038],[166.27258300781247,-45.916765867649],[166.4813232421875,-46.22545288226937],[167.6788330078125,-46.471916320870406],[167.2503662109375,-47.21956811231548]]],"terms_url":"http://www.linz.govt.nz/data/licensing-and-using-data/attributing-elevation-or-aerial-imagery-data","terms_text":"Sourced from LINZ CC-BY 3.0","best":true},{"id":"LINZ_NZ_Topo50_Gridless_Maps","name":"LINZ NZ Topo50 Gridless Maps","type":"tms","template":"https://tiles-a.data-cdn.linz.govt.nz/services;key=3197c6d0e5cb494a95d58dc2de3216c2/tiles/v4/layer=2343/EPSG:3857/{zoom}/{x}/{y}.png","scaleExtent":[0,21],"polygon":[[[167.2503662109375,-47.21956811231548],[167.244873046875,-47.28016067076474],[167.5030517578125,-47.37975438400816],[168.2501220703125,-47.15610477504402],[168.7445068359375,-46.79629898997744],[169.3267822265625,-46.75491661928188],[169.78271484375,-46.604167162931844],[170.4254150390625,-46.11132565729794],[170.804443359375,-45.95114968669139],[170.9527587890625,-45.440862671781744],[171.309814453125,-44.91035917458493],[171.40869140625,-44.39061697878681],[172.562255859375,-43.92954993561458],[172.90283203125,-43.96909818325171],[173.1610107421875,-43.90976594390799],[173.2598876953125,-43.69567969789881],[172.9742431640625,-43.53660274231031],[172.760009765625,-43.37710501700071],[173.1500244140625,-43.17714134663171],[173.704833984375,-42.63395872267314],[174.36401367187497,-41.78360106648077],[174.320068359375,-41.409775832009544],[174.84741210937497,-41.52914198872309],[175.0726318359375,-41.70572851523751],[175.506591796875,-41.672911819602085],[176.2261962890625,-41.10832999732831],[176.8304443359375,-40.42604212826493],[177.17102050781247,-39.67337039176559],[177.0391845703125,-39.39375459224347],[177.4456787109375,-39.18117526158747],[177.60498046875,-39.3300485529424],[177.978515625,-39.368279149160124],[178.3355712890625,-38.65977773071253],[178.7091064453125,-37.74465712069938],[178.626708984375,-37.54457732085582],[178.3135986328125,-37.43125050179357],[177.6214599609375,-37.37888785004525],[177.0391845703125,-37.39634613318924],[176.561279296875,-37.37015718405751],[176.3360595703125,-37.05956083025124],[176.0064697265625,-36.29741818650809],[175.6768798828125,-36.05354012833974],[174.671630859375,-35.1782983520012],[173.1939697265625,-34.28445325435288],[172.6776123046875,-34.234512362369856],[172.386474609375,-34.40237742424137],[172.4798583984375,-34.71903991764788],[172.9852294921875,-35.32184842037683],[173.56201171875,-36.142310873529986],[174.30908203125,-37.077093191754415],[174.5562744140625,-38.052416771864834],[174.4793701171875,-38.655488159952995],[174.3255615234375,-38.865374851611634],[173.7982177734375,-38.95940879245421],[173.60595703125,-39.232253141714885],[173.6993408203125,-39.56335316582929],[174.5892333984375,-39.95606977009003],[174.9847412109375,-40.216635475391215],[174.9847412109375,-40.49291502689579],[174.7210693359375,-40.805493843894155],[174.1497802734375,-40.65147128144056],[173.2818603515625,-40.43440488077009],[172.5897216796875,-40.350730565917885],[172.0843505859375,-40.534676780615406],[171.7657470703125,-40.826280356677124],[171.57348632812497,-41.3974150664646],[171.2823486328125,-41.652392884268124],[170.8758544921875,-42.53284428171312],[170.35400390625,-42.87193842444846],[168.277587890625,-43.92954993561458],[167.6239013671875,-44.47691085722324],[166.55273437499997,-45.38687734827038],[166.27258300781247,-45.916765867649],[166.4813232421875,-46.22545288226937],[167.6788330078125,-46.471916320870406],[167.2503662109375,-47.21956811231548]]],"terms_url":"https://data.linz.govt.nz/layer/2343-nz-mainland-topo50-gridless-maps/","terms_text":"Sourced from the LINZ Data Service and licensed by LINZ for re-use under the Creative Commons Attribution 3.0 New Zealand licence."},{"id":"ORT10LT","name":"Lithuania - NŽT ORT10LT","type":"tms","template":"http://ort10lt.openmap.lt/g16/{zoom}/{x}/{y}.jpeg","endDate":"2016-01-01T00:00:00.000Z","startDate":"2010-01-01T00:00:00.000Z","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":"https://{switch:a,b,c,d}.tiles.mapbox.com/v4/openstreetmap.map-inh76ba2/{zoom}/{x}/{y}.png?access_token=pk.eyJ1Ijoib3BlbnN0cmVldG1hcCIsImEiOiJncjlmd0t3In0.DmZsIeOW-3x-C5eX-wAqTw","scaleExtent":[0,16],"overzoom":false,"terms_url":"http://www.mapbox.com/about/maps/","terms_text":"Terms & Feedback","default":true,"description":"Shows major features to help orient you.","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 2017"},{"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 2017","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 2017"},{"id":"Mapbox","name":"Mapbox Satellite","type":"tms","template":"https://{switch:a,b,c,d}.tiles.mapbox.com/styles/v1/openstreetmap/cj8gojt0i1eau2rnn7q4mdgu7/tiles/256/{zoom}/{x}/{y}?access_token=pk.eyJ1Ijoib3BlbnN0cmVldG1hcCIsImEiOiJhNVlHd29ZIn0.ti6wATGDWOmCnCYen-Ip7Q","scaleExtent":[0,22],"terms_url":"http://www.mapbox.com/about/maps/","terms_text":"Terms & Feedback","default":true,"description":"Satellite and aerial imagery.","icon":"data:image/png;base64,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"},{"id":"geodata.md.gov-MD_SixInchImagery","name":"MD Latest 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","endDate":"2016-01-01T00:00:00.000Z","startDate":"2013-01-01T00:00:00.000Z","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","description":"Six Inch resolution aerial imagery for the State of Maryland"},{"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","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","description":"Maryland State Highway Administration road features and additional Maryland focused landmarks"},{"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","endDate":"2015-05-03T00:00:00.000Z","startDate":"2015-03-29T00:00:00.000Z","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],[-73.890266,40.998039],[-73.933406,40.882078],[-73.933407,40.882077],[-73.933408,40.882076],[-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.466251,39.750764],[-75.466251,39.750765],[-75.46625,39.750767],[-75.466249,39.750768],[-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)","description":"Digital orthophotography of New Jersey, Near Infrared, 1 foot resolution"},{"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","endDate":"2015-05-03T00:00:00.000Z","startDate":"2015-03-29T00:00:00.000Z","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],[-73.890266,40.998039],[-73.933406,40.882078],[-73.933407,40.882077],[-73.933408,40.882076],[-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.466251,39.750764],[-75.466251,39.750765],[-75.46625,39.750767],[-75.466249,39.750768],[-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)","description":"Digital orthophotography of New Jersey, Natural Color, 1 foot resolution"},{"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","icon":"http://nls.tileserver.com/nls70-nq8.png"},{"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","icon":"http://nls.tileserver.com/nls70-nq8.png"},{"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","icon":"http://nls.tileserver.com/nls70-nq8.png"},{"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","icon":"http://nls.tileserver.com/nls70-nq8.png"},{"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","icon":"http://nls.tileserver.com/nls70-nq8.png"},{"id":"NLSC-EMAP5","name":"NLSC General Map with Contour line","type":"tms","template":"http://wmts.nlsc.gov.tw/wmts/EMAP5_OPENDATA/default/EPSG:3857/{zoom}/{y}/{x}","startDate":"2015-01-01T00:00:00.000Z","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":"© National Land Surveying and Mapping Center, Taiwan OGDL 1.0","description":"The emap from Taiwan National Land Surveying and Mapping Center","icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABHNCSVQICAgIfAhkiAAAAxJJREFUOI3tlF9oW2UYxn9f4nKW2ixfjJGYMnuctRUZ5mhEpjdJEEaHtmsZaKHq0qt6ZdtZL3Zhk3ilIKS9Ui806UStE7Edjln8kwzEwaB6IshsmJIqK1ttZ7Qlzel2eryQhqZrsDC8EHyuvu993+/53j+8D/yPfxtip4GqH1X1owLkdHI3RSwbkbFu1yAPdx4t3hpSS6YLAM05i/vCqcmzZwpj9T6pIZYOZNArNADhsQj3RVNjtyS1DcKtiHlPIb96PTn67nJiq8++cRgJicTpQ7Yz0oHc7cQZeakzPbTyqr9iKXUr0lfbqOx7LHJgbXrux5/X9M0+G0C8SySeeWTPQPSLxu4jn1vd4tE7m4euDNclrCEvt6E+25/e6H+VuKen57vEe1b8I29b8cKyo6j6Uece6I/VK387jC70crgjMFBDPDEx8aA5aOPkG+f7FhcX9YhGZLIUBSD7VAtSsZOKNpGKNgFU710tbiJ7G0lFm9DucCL2R7uCXjTpQFZbMV6wMu+EbWnpQOIJVKcvFTuDIR+az4nmc1Zt6h4HuV9XGHjIx1D2EvrCKtLnUgE+Pig+kQ6kDeDFc9YQwJdP2rLuBlfzRjklw7yh7JJh0vfZL6Tb70IqdqRSnT/5JfQTBcZfDom4HaBiUjn5k/Xh0VYRe85ztZ11QX53K4ZQyPxwFcO0yP+2Ste9bi6XrxPbfxuvnV9g6uIfPK/dTskwURbOFfPTM2PSIeTT99Bzw4KMhERi5ICIl667OOHuYNzdQV5p/ccBxi89kUmm5vveDou06kLddvNSibasbvZGXvj9fYJGgbldAaYaI+SVVoq7ApxtCNXEH7ZyhL8+Nho00YJeoT3+6Xp0W2KtBU07NpzNlHulem2ecHmGzpUcmlGg+dp83aynitbkK99ayfwSel2tiLUTo3M4lSn3ys12ub5MsFL4O4GGWZq/fyszfvrPsfwSNZtnpw70i+jMfjPdf//MfXf7UYtrASqWQkUoeNzLtHumS0buzePJD4zjV1a5vPX9jmRT9aNGNCKbZXMn0vnfwl+e9BTflqrxKAAAAABJRU5ErkJggg=="},{"id":"IBGE_Salvador_Streets","name":"Nomes de Ruas IBGE Salvador-BA","type":"tms","template":"https://api.mapbox.com/styles/v1/wille/cj8lp78dn62wl2rquim47qo0g/tiles/256/{zoom}/{x}/{y}?access_token=pk.eyJ1Ijoid2lsbGUiLCJhIjoicFNVWk5VWSJ9.hluCd0YGvYHNlFi_utWe2g","scaleExtent":[0,20],"polygon":[[[-38.489742279052734,-12.811131765117107],[-38.54484558105469,-13.013924052026558],[-38.47755432128906,-13.034662471471638],[-38.33473205566406,-12.946846814654444],[-38.30005645751953,-12.906692193510644],[-38.33953857421875,-12.904349641337422],[-38.35481643676758,-12.830213284310222],[-38.38090896606445,-12.821844374997415],[-38.40717315673828,-12.867535227819912],[-38.46536636352539,-12.815985972925704],[-38.489742279052734,-12.811131765117107]]],"description":"Streets geometry and names of Salvador, Bahia. Source: Faces de Logradouro - IBGE.","overlay":true},{"id":"MAPNIK","name":"OpenStreetMap (Standard)","type":"tms","template":"https://{switch:a,b,c}.tile.openstreetmap.org/{zoom}/{x}/{y}.png","scaleExtent":[0,19],"terms_url":"https://www.openstreetmap.org/","terms_text":"© OpenStreetMap contributors, CC-BY-SA","default":true,"description":"The default OpenStreetMap layer.","icon":"data:image/png;base64,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"},{"id":"OpenStreetMap-turistautak","name":"OpenStreetMap (turistautak)","type":"tms","template":"http://{switch:h,i,j}.tile.openstreetmap.hu/turistautak/{zoom}/{x}/{y}.png","scaleExtent":[0,18],"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":"https://www.openstreetmap.org/","terms_text":"© OpenStreetMap contributors"},{"id":"osm-gps","name":"OpenStreetMap GPS traces","type":"tms","template":"https://{switch:a,b,c}.gps-tile.openstreetmap.org/lines/{zoom}/{x}/{y}.png","scaleExtent":[0,20],"terms_url":"https://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;'>&larr;</span> <span style='color: #96f;'>&darr;</span> <span style='color: #6e0;'>&uarr;</span> <span style='color: #f63;'>&rarr;</span> </span></span> © <a href='https://www.openstreetmap.org/copyright'>OpenStreetMap contributors</a>.","description":"Public GPS traces uploaded to OpenStreetMap.","icon":"data:image/png;base64,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","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","endDate":"2010-07-02T00:00:00.000Z","startDate":"2010-06-24T00:00:00.000Z","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","icon":"https://www.geoportail.lu/static/img/lion.png"},{"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","endDate":"2013-07-20T00:00:00.000Z","startDate":"2013-07-19T00:00:00.000Z","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","icon":"https://www.geoportail.lu/static/img/lion.png"},{"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","endDate":"2016-08-16T00:00:00.000Z","startDate":"2013-08-30T00:00:00.000Z","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","icon":"https://www.geoportail.lu/static/img/lion.png"},{"id":"lu.geoportail.opendata.ortho2017","name":"Ortho 2017 geoportail.lu","type":"tms","template":"https://{switch:wmts3,wmts4}.geoportail.lu/opendata/wmts/ortho_2017/GLOBAL_WEBMERCATOR_4_V3/{zoom}/{x}/{y}.jpeg","endDate":"2017-06-22T00:00:00.000Z","startDate":"2017-06-14T00:00:00.000Z","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","icon":"https://www.geoportail.lu/static/img/lion.png"},{"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":"https://{switch:a,b,c}.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 (Philippines 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":"Actueel_ortho25_WMTS","name":"PDOK Luchtfoto Beeldmateriaal 25cm","type":"tms","template":"https://geodata.nationaalgeoregister.nl/luchtfoto/rgb/wmts?FORMAT=image/jpeg&SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=2016_ortho25&STYLE=&FORMAT=image/jpeg&tileMatrixSet=OGC:1.0:GoogleMapsCompatible&tileMatrix={zoom}&tileRow={y}&tileCol={x}","scaleExtent":[0,18],"polygon":[[[3.1437689,51.3598403],[3.1575018,51.2411346],[3.3387762,51.1154412],[3.9128119,51.0585083],[4.6571356,51.2806657],[4.8933416,51.2634825],[5.1789862,51.1257851],[5.3849798,51.1309561],[5.5442816,51.056782],[5.4206854,50.8595581],[5.4673773,50.7032633],[5.6568914,50.6192567],[6.1485296,50.6214349],[6.3023382,50.8578243],[6.2995916,50.9543819],[6.2638861,51.0183545],[6.3723761,51.0925902],[6.4012152,51.2011393],[6.3737494,51.2510206],[6.4451605,51.3158713],[6.4204413,51.5496009],[6.343537,51.6792182],[6.796723,51.7642909],[7.046662,51.9102418],[7.0713812,52.0455856],[7.2718817,52.1704147],[7.3075872,52.3855111],[7.2059637,52.5319494],[7.282868,52.614576],[7.2993475,52.7785318],[7.4421698,52.9782705],[7.43393,53.2831352],[7.0439154,53.5515877],[6.7829901,53.6363531],[6.2391668,53.5401639],[5.6871039,53.5124077],[5.173493,53.4388477],[4.8164373,53.2338445],[4.6516424,53.0658312],[4.5417791,52.4859784],[4.3220526,52.1956753],[4.08104,52.0136897],[4.0219885,52.0162253],[3.9368445,51.9637937],[3.9519507,51.8807927],[3.844834,51.8494157],[3.6237341,51.7075226],[3.6553198,51.6606936],[3.6333471,51.6274583],[3.5468298,51.622343],[3.3957678,51.5609145],[3.3820349,51.5173524],[3.4987646,51.4326715],[3.3298498,51.3855587],[3.1437689,51.3598403]]],"terms_url":"http://www.nationaalgeoregister.nl/geonetwork/srv/dut/catalog.search#/search?facet.q=license%2FCC-BY&isChild=%27false%27&resultType=details&any_OR_title_OR_keyword=luchtfoto&fast=index&_content_type=json&from=1&to=20&sortBy=relevance","terms_text":"Kadaster / Beeldmateriaal.nl, CC BY 4.0","best":true,"description":"Landsdekkende dataset 25cm resolutie kleuren luchtfotos van de meest recente jaargang.","icon":"data:image/png;base64,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"},{"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":"Geodatastyrelsen_Denmark","name":"SDFE aerial imagery","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,"icon":"data:image/png;base64,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"},{"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":"Soskut_Pusztazamor_Tarnok_Diosd_orto_2017","name":"Sóskút, Pusztazámor, Tárnok, Diósd ortophoto 2017","type":"tms","template":"http://adam.openstreetmap.hu/mapproxy/tiles/1.0.0/Soskut-Tarnok-Pusztazamor-Diosd/mercator/{zoom}/{x}/{y}.png","startDate":"2017-03-01T00:00:00.000Z","polygon":[[[18.79273330201,47.37078533804],[18.791936169,47.37048036201],[18.79139114593,47.37063268281],[18.7901097,47.3717614],[18.7891647,47.3734529],[18.78721506824,47.37566027041],[18.7860339,47.37764910001],[18.7849824,47.3790513],[18.783695,47.3803226],[18.782665,47.3819499],[18.781399,47.3836789],[18.7793426,47.3871257],[18.776657,47.3893959],[18.764716,47.396699],[18.7616966,47.3996569],[18.7563102,47.4032821],[18.7583737,47.4065272],[18.75879657883,47.40776342073],[18.76199554897,47.41217224817],[18.7630394973,47.41315137445],[18.7659298,47.4147108],[18.7704058,47.4176575],[18.77247285488,47.41808545272],[18.7724806,47.4202978],[18.8086021,47.4404108],[18.8174212,47.435389],[18.8209188,47.4357228],[18.8280427,47.4375516],[18.8302099,47.4352584],[18.8358533,47.4375371],[18.8404882,47.4334586],[18.847655,47.4357228],[18.8510024,47.4328054],[18.8689996,47.4396086],[18.87361350924,47.43597176329],[18.87499181607,47.43342149293],[18.87386045593,47.43248349864],[18.8760377,47.4279677],[18.8605023,47.4230028],[18.8662101,47.4179794],[18.8724328,47.4108645],[18.8662959,47.4077278],[18.8696433,47.4047072],[18.86776892261,47.40207457802],[18.86509430105,47.40052438512],[18.87081279074,47.3983820654],[18.86772375423,47.39699336542],[18.86992005424,47.39655168559],[18.87648610191,47.39477958954],[18.87748924808,47.39494663392],[18.87866942005,47.39462343887],[18.88358322696,47.3899604942],[18.88290731029,47.3896699544],[18.88538567142,47.38530440107],[18.87747851924,47.38339390377],[18.88181296901,47.37604910406],[18.87914148883,47.37392756692],[18.88638345317,47.36922645965],[18.88205973224,47.36772957402],[18.87973157482,47.36640704749],[18.8746997507,47.36252284243],[18.87282220439,47.36136733615],[18.87027947025,47.36062605465],[18.86687842922,47.3585329683],[18.86234013156,47.35637438604],[18.85566679554,47.35199153827],[18.84873596744,47.34728120653],[18.83192388134,47.3384118486],[18.82497159557,47.34257772442],[18.81619540767,47.34925116493],[18.8107880743,47.35356882392],[18.80823461132,47.35599644336],[18.80645362453,47.35854023611],[18.80707589702,47.359019909],[18.80634633617,47.36021180457],[18.80465118007,47.36175250772],[18.80381433086,47.36335130305],[18.80054616504,47.36544732015],[18.79988097721,47.36617355102],[18.79416204336,47.36974865444],[18.79273330201,47.37078533804]],[[18.91871480064,47.4093812629],[18.91826418952,47.40997664498],[18.9206674488,47.41155945729],[18.92509845809,47.41372304121],[18.93473295288,47.41916790937],[18.94063381271,47.42241278301],[18.94981769638,47.41937843296],[18.95154503898,47.41749820965],[18.95689872818,47.41922598493],[18.95770339088,47.41877589767],[18.95755318717,47.41435467478],[18.9621129425,47.40506817222],[18.96266011314,47.40117592194],[18.96316436843,47.39903360927],[18.95446328239,47.3967314338],[18.95275739746,47.39526437993],[18.95201710777,47.39362297422],[18.95119098739,47.39356487042],[18.94692091064,47.39798783856],[18.94410995559,47.3984526281],[18.94161013679,47.39868502134],[18.93735078887,47.39633199249],[18.93617061691,47.39682584676],[18.93122462348,47.39999947627],[18.93120316581,47.40023186269],[18.92923978881,47.40204734624],[18.92561344223,47.40604845111],[18.92465857582,47.40635342305],[18.92293123321,47.40925782918],[18.91871480064,47.4093812629]]],"terms_url":"http://fototerkep.hu/","terms_text":"Fototerkep.hu","best":true},{"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","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-Orthofoto-2014-2015","name":"South Tyrol Orthofoto 2014/2015","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_2015_EPSG3857&STYLE=default&TILEMATRIXSET=GoogleMapsCompatible&TILEMATRIX=GoogleMapsCompatible%3A{zoom}&TILEROW={y}&TILECOL={x}&FORMAT=image%2Fjpeg","endDate":"2015-11-01T00:00:00.000Z","startDate":"2014-07-01T00:00:00.000Z","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 4.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","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","description":"Topographical basemap of South Tyrol"},{"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","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":"https://{switch:a,b,c}.surrey.aerial.openstreetmap.org.uk/layer/gb_surrey_aerial/{zoom}/{x}/{y}.png","endDate":"2009-01-01T00:00:00.000Z","startDate":"2007-01-01T00:00:00.000Z","scaleExtent":[8,21],"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 orthophoto 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","best":true},{"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}","startDate":"2012-01-01T00:00:00.000Z","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":"US-TIGER-Roads-2017","name":"TIGER Roads 2017","type":"tms","template":"https://{switch:a,b,c,d}.tiles.mapbox.com/styles/v1/openstreetmapus/cj8dftc3q1ecn2tnx9qhwyj0c/tiles/256/{zoom}/{x}/{y}?access_token=pk.eyJ1Ijoib3BlbnN0cmVldG1hcHVzIiwiYSI6ImNpcnF4Ym43dDBoOXZmYW04bWhlNWdrY2EifQ.4SFexuTUuKkZeerO3dgtmw","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.1572,68.722],[-164.8554,67.0255],[-168.0022,66.0018],[-169.0087,66.0015],[-169.0075,64.9988],[-172.5143,63.8767],[-173.8197,59.7401],[-178.0001,52.2446],[-177.9993,51.2554],[-171.4689,51.8215],[-162.4025,53.9567],[-159.0076,55.0025],[-158.0191,55.0028],[-151.9963,55.9992],[-151.5003,57.9988],[-151.5013,58.992],[-138.516,58.9953],[-138.515,57.9986],[-133.9948,54.0032],[-130.0044,54.0043],[-130.0071,57.0001],[-131.9759,56.9995],[-135.123,59.7566],[-138.0072,59.9918],[-139.1716,60.4127],[-140.9874,61.0119],[-140.9684,69.9535],[-156.1769,71.5633],[-160.4136,70.7398],[-163.0218,69.9707],[-164.9717,68.9947],[-167.1572,68.722]],[[-68.2,17.8],[-64.32,17.38],[-64.64,18.36],[-65.33,18.57],[-67.9,18.67],[-68.2,17.8]],[[146.2,15.4],[145.7,15.6],[144.2,13.2],[144.8,12.9],[146.2,15.4]],[[179.99,52.2],[172,53.5],[172,52.5],[179.99,51],[179.99,52.2]]],"description":"Yellow = Public domain map data from the US Census. Red = Data not found in OpenStreetMap","icon":"data:image/png;base64,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","overlay":true},{"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","endDate":"2010-07-20T00:00:00.000Z","startDate":"2013-07-19T00:00:00.000Z","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","icon":"https://www.geoportail.lu/static/img/lion.png"},{"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}","endDate":"2011-01-01T00:00:00.000Z","startDate":"2008-01-01T00:00:00.000Z","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":"https://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}","endDate":"2013-01-01T00:00:00.000Z","startDate":"2013-01-01T00:00:00.000Z","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":"https://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":"https://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":"UrbISOrtho2017","name":"UrbIS-Ortho 2017","type":"tms","template":"http://whoots.mapwarper.net/tms/{zoom}/{x}/{y}/Urbis:Ortho2017/https://geoservices-urbis.irisnet.be/geoserver/ows","endDate":"2018-01-01T00:00:00.000Z","startDate":"2017-01-01T00:00:00.000Z","polygon":[[[4.3797288,50.7638205],[4.3891701,50.7637662],[4.430283,50.7751656],[4.4350037,50.7750028],[4.464272,50.7864537],[4.4816956,50.7913372],[4.4823823,50.7961658],[4.459208,50.8062556],[4.4594655,50.8166144],[4.4797215,50.8203559],[4.4695935,50.8353735],[4.4689927,50.8457258],[4.4623837,50.8539626],[4.4496808,50.8559133],[4.4459901,50.8599226],[4.4253049,50.8661526],[4.431828,50.8762815],[4.4400677,50.8784478],[4.4310555,50.8901441],[4.4359479,50.8950167],[4.4295964,50.9010255],[4.4165501,50.9075748],[4.4154343,50.9134197],[4.3957791,50.914069],[4.3846211,50.9109303],[4.3811879,50.9031907],[4.3726048,50.9003218],[4.3621335,50.9032989],[4.3485722,50.9034072],[4.3402467,50.9041108],[4.328917,50.902487],[4.3164716,50.8960453],[4.3063435,50.8927429],[4.2900357,50.8898192],[4.2914948,50.8849461],[4.2955289,50.8826176],[4.2956147,50.8809389],[4.2827401,50.8722735],[4.2769894,50.8671277],[4.2780194,50.8591099],[4.2804227,50.8572136],[4.2809376,50.8421489],[4.2719254,50.8403603],[4.2546735,50.8369455],[4.2510686,50.83288],[4.2522702,50.8269708],[4.2434296,50.82182],[4.2440305,50.8154755],[4.2551884,50.8150959],[4.2580209,50.8093472],[4.2721829,50.8101065],[4.2757878,50.8069607],[4.2854008,50.8050623],[4.2890057,50.8069065],[4.298018,50.8059302],[4.3028245,50.7970881],[4.3145833,50.7945382],[4.3162141,50.7862367],[4.3295178,50.7738087],[4.3420491,50.7716375],[4.3452248,50.7733745],[4.3785271,50.7681092],[4.3797288,50.7638205]]],"terms_text":"Realized by means of Brussels UrbIS®© - Distribution & Copyright CIRB","best":true,"icon":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAAsSAAALEgHS3X78AAACnUlEQVQoz11SXUiTYRh93ndz06YMNWcpRmWRSpgO+0EUDYwQ6sZ+oAyti8y6yCyKxOimILqQsLKbukmHSpFFLYlMqSkUmi3/pjZ/Zmv+Tec2bU237z1dfFHSc/HcPOc5HM45DAAREREgGOM217BpzDjs7PEHfNGa2PT47KxN+RFqrYDgjBMRE0JijBMRAKOlzmgxhChDN0cla1ThM0uTE65vsRFxRRkXk3TpMiMBkEQQQFPvw0LDnoYvVStBNwAhBIApj+X6m5OlT/dbnX0AJCHxkbl+zhTWub6XA4ZDqcd3JJTl1to7HV7G2E3TxOU2zaWcKm1YZKO5RlaliNknBma6Bqe7V6SVc5mVrmVFxSvLu1G3bSlwy2jVaXE6IzE0JLzV+jxJlxYTvp5X5j3Qx2ePzPcn6VJVysiUaHXX+d2zy8HqlrE8/bq3xXoiStalr1Fpxl1DRMQ547s27NWGRikVKtmuju9e34pEYcrhWV/f7E8iUinDQrjaH/AREQfAmSJGEzc6P0Qkvbd5ymt7DqfEmEr0Tre/4PFXInK4R7z+hXjtRiIi2aKPtpbi+qxue6vHj5ou+8KvAIBPP7yG3mkAd9sry18ULPrdAAgQAIJS4EZLacXrwqVlDwBJiKAkJCEB+Gz/UNyQ1TxY/8dWIiYgFFx5JPXM7JLjWe8jIgKBM3DGXT5no7lmy9rteVsLiIjJGXPGBcQ2XdqBlKJWa1PHeLOCcRAEhKH7zuKy+4T+QohCDQhGjLBqJBGsNl0teZI3OGMG0GiuKarPNI0aZTEyhq0qHxhjXv/C7bYyASkjIddoqctPOnY07ezf5hHRvwcikg+TXtv9jmsOjy0n8eCpnVeIESMiecnE/6kC0D/Vea+90h/wARAQqwG/AaEjsUbwLtXdAAAAAElFTkSuQmCC"},{"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]]],"icon":"data:image/png;base64,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"},{"id":"USGS-Scanned_Topographic","name":"USGS Topographic Maps","type":"tms","template":"https://caltopo.s3.amazonaws.com/topo/{zoom}/{x}/{y}.png","scaleExtent":[0,16],"polygon":[[[-55.9959409871,52.00107125754],[-112.02896100663,52.00107125754],[-112.03994733476,56.01308253302],[-120.0049439862,56.00592357111],[-120.01711631014,60.01202439709],[-132.00196823895,60.00239237126],[-132.01208445818,63.00193292546],[-133.96882922149,63.00050478005],[-133.97240257168,63.9922484722],[-141.04429430438,63.98726254018],[-141.06879354491,69.92045693283],[-156.24893170976,71.51583202984],[-160.44570905351,70.83527373985],[-167.08145124101,68.42906280103],[-164.08218366288,67.03913532024],[-169.01504499101,65.68268604273],[-166.57608014726,64.50777504773],[-161.82998639726,64.0500622981],[-165.08193952226,63.26030016403],[-168.02627545976,59.7862264253],[-162.53311139726,59.73089435789],[-162.35733014726,58.55904663221],[-157.83096295976,58.31752983705],[-158.00674420976,57.52404350658],[-168.22402936601,53.51022153947],[-166.55410749101,53.14277307072],[-158.77578717851,54.88541314654],[-158.68240338944,55.7496444805],[-156.55105573319,56.00847621073],[-156.15554792069,56.7746616888],[-154.70535260819,56.14336689443],[-152.07412702226,57.37034511851],[-151.62918073319,58.22653323066],[-152.00820905351,58.98055685754],[-145.98770124101,60.24740887373],[-140.38467389726,59.48634241018],[-136.53945905351,57.80610084736],[-133.79287702226,54.83482554482],[-133.33145124101,53.14277307072],[-131.46377545976,51.69838238021],[-128.52493268632,51.74602265442],[-129.79385358476,50.90159054062],[-124.56436139726,47.49785657441],[-124.03701764726,45.48627362525],[-124.69619733476,42.90428451679],[-124.49844342851,40.3414647251],[-122.80654889726,37.53929308709],[-119.99404889726,33.37084692374],[-117.24746686601,32.54119524801],[-111.13906842851,31.19770451575],[-106.70059186601,31.23528720858],[-103.20693952226,28.64618215851],[-101.84463483476,29.81580068657],[-99.20791608476,26.28743998885],[-96.79092389726,25.75431753335],[-96.92275983476,27.96911213371],[-93.47305280351,29.68226300815],[-88.94668561601,28.87732407469],[-88.61709577226,30.17736083469],[-86.20010358476,30.3671253082],[-84.96963483476,29.43379356715],[-84.09072858476,30.06332630046],[-82.97012311601,28.95425748047],[-82.97012311601,27.26823750278],[-81.25625592851,25.07956298739],[-82.09121686601,24.5610471236],[-80.06973249101,24.76073298597],[-79.85000592851,27.11188091684],[-81.27822858476,30.70777424386],[-78.99307233476,33.20554049136],[-75.03799420976,35.59830000028],[-75.85098249101,37.2425160052],[-73.74160749101,40.4585957587],[-69.89639264726,41.60224497127],[-70.68740827226,43.17628724449],[-66.93008405351,44.69516042167],[-66.53457624101,43.08006996122],[-64.20547467851,43.35229243812],[-59.50332624101,45.73220792131],[-59.51431256913,46.24761804024],[-60.00320417069,46.25901313529],[-59.99221784257,47.24505773341],[-59.00894147538,47.23759898478],[-58.99795514726,47.50266941922],[-56.51504499101,47.50266941922],[-56.52603131913,46.74770404019],[-53.99917585038,46.74770404019],[-53.97720319413,46.48358117386],[-52.49404889726,46.46354265729],[-52.50503522538,48.75360583388],[-52.99667340898,48.75451123442],[-53.01315290116,49.99551104004],[-55.00167829179,50.00610367548],[-55.03738385819,53.74720613495],[-56.00418073319,53.73421061801],[-55.9959409871,52.00107125754]],[[-59.50126630448,43.7495431608],[-60.50239545487,43.7495431608],[-60.50239545487,43.99999882251],[-59.99839765214,43.99999882251],[-59.99839765214,44.2494016836],[-59.50126630448,44.2494016836],[-59.50126630448,43.7495431608]],[[-155.95024091386,20.49523373356],[-157.3267518687,20.49153389084],[-157.32902509355,21.23181053727],[-155.95251413871,21.23549220541],[-155.95024091386,20.49523373356]],[[-157.64488202714,21.24845058596],[-158.28534362719,21.24673774522],[-158.28689557694,21.7499618541],[-157.6464339769,21.75166877943],[-157.64488202714,21.24845058596]],[[-156.12602216386,20.32469602374],[-154.7461696274,20.3284088686],[-154.74174482011,18.87578125335],[-156.12159735656,18.87203473488],[-156.12602216386,20.32469602374]],[[-159.29077130937,22.24504086823],[-159.2892966564,21.76857042389],[-160.28916841131,21.76590592196],[-160.29064306428,22.24238530626],[-159.29077130937,22.24504086823]]],"terms_url":"https://caltopo.com/","terms_text":"© Caltopo","icon":"data:image/png;base64,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"},{"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}","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,"description":"Public domain street and address data from the San Juan County, WA. Updated at least quarterly."},{"id":"Vejmidte_Denmark","name":"Vejmidte","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":"https://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","icon":"https://www.wien.gv.at/layout-a/logo/wappen-klein.gif"},{"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","icon":"https://www.wien.gv.at/layout-a/logo/wappen-klein.gif"},{"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","icon":"https://www.wien.gv.at/layout-a/logo/wappen-klein.gif"}];
23671
23672 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"},"circular":{"geometry":["vertex","line"],"fields":["name"],"tags":{"junction":"circular"},"name":"Traffic Circle","searchable":false},"highway":{"fields":["name","highway"],"geometry":["point","vertex","line","area"],"tags":{"highway":"*"},"searchable":false,"name":"Highway"},"place":{"fields":["name","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"],"fields":["name"],"tags":{"junction":"roundabout"},"name":"Roundabout","searchable":false},"waterway":{"fields":["name","waterway"],"geometry":["point","vertex","line","area"],"tags":{"waterway":"*"},"searchable":false,"name":"Waterway"},"address":{"fields":["address"],"geometry":["point","vertex","area"],"tags":{"addr:*":"*"},"addTags":{},"removeTags":{},"reference":{"key":"addr"},"name":"Address","matchScore":0.15},"advertising/billboard":{"fields":["direction","lit"],"geometry":["point","vertex","line"],"tags":{"advertising":"billboard"},"name":"Billboard"},"aerialway/station":{"icon":"aerialway","geometry":["point","vertex","area"],"fields":["aerialway/access","aerialway/summer/access","elevation","building_area"],"tags":{"aerialway":"station"},"name":"Aerialway Station","searchable":false},"aerialway/cable_car":{"geometry":["line"],"terms":["tramway","ropeway"],"fields":["name","aerialway/occupancy","aerialway/capacity","aerialway/duration","aerialway/heating"],"tags":{"aerialway":"cable_car"},"name":"Cable Car"},"aerialway/chair_lift":{"geometry":["line"],"fields":["name","aerialway/occupancy","aerialway/capacity","aerialway/duration","aerialway/bubble","aerialway/heating"],"tags":{"aerialway":"chair_lift"},"name":"Chair Lift"},"aerialway/drag_lift":{"geometry":["line"],"fields":["name","aerialway/capacity","aerialway/duration"],"tags":{"aerialway":"drag_lift"},"name":"Drag Lift"},"aerialway/gondola":{"geometry":["line"],"fields":["name","aerialway/occupancy","aerialway/capacity","aerialway/duration","aerialway/bubble","aerialway/heating"],"tags":{"aerialway":"gondola"},"name":"Gondola"},"aerialway/goods":{"geometry":["line"],"fields":["name","aerialway/capacity","aerialway/duration"],"tags":{"aerialway":"goods"},"name":"Goods Aerialway"},"aerialway/magic_carpet":{"geometry":["line"],"fields":["name","aerialway/capacity","aerialway/duration","aerialway/heating"],"tags":{"aerialway":"magic_carpet"},"name":"Magic Carpet Lift"},"aerialway/mixed_lift":{"geometry":["line"],"fields":["name","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":["name","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":["name","aerialway/capacity","aerialway/duration"],"tags":{"aerialway":"rope_tow"},"name":"Rope Tow Lift"},"aerialway/t-bar":{"geometry":["line"],"fields":["name","aerialway/capacity","aerialway/duration"],"terms":["tbar"],"tags":{"aerialway":"t-bar"},"name":"T-bar Lift"},"aeroway/aerodrome":{"icon":"airport","geometry":["point","area"],"fields":["name","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_aeroway_gate"],"tags":{"aeroway":"gate"},"name":"Airport Gate"},"aeroway/hangar":{"geometry":["area"],"fields":["name","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_runway","surface","length","width"],"tags":{"aeroway":"runway"},"name":"Runway"},"aeroway/taxiway":{"geometry":["line"],"fields":["ref_taxiway","surface"],"tags":{"aeroway":"taxiway"},"name":"Taxiway"},"aeroway/terminal":{"icon":"airport","geometry":["point","area"],"terms":["airport","aerodrome"],"fields":["name","operator","building_area"],"tags":{"aeroway":"terminal"},"name":"Airport Terminal"},"amenity/bus_station":{"icon":"bus","fields":["name","building_area","operator","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"amenity":"bus_station"},"name":"Bus Station / Terminal","searchable":false},"amenity/coworking_space":{"icon":"commercial","fields":["name","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/ferry_terminal":{"icon":"ferry","fields":["name","network","operator","address","building_area"],"geometry":["point","vertex","area"],"terms":[],"tags":{"amenity":"ferry_terminal"},"name":"Ferry Station / Terminal","searchable":false},"amenity/nursing_home":{"icon":"wheelchair","fields":["name","operator","address","building_area","social_facility","social_facility_for","opening_hours","wheelchair"],"geometry":["point","area"],"tags":{"amenity":"nursing_home"},"reference":{"key":"social_facility","value":"nursing_home"},"name":"Nursing Home","searchable":false},"amenity/register_office":{"icon":"town-hall","fields":["name","address","building_area","opening_hours","operator"],"geometry":["point","area"],"tags":{"amenity":"register_office"},"reference":{"key":"government","value":"register_office"},"name":"Register Office","searchable":false},"amenity/scrapyard":{"icon":"car","fields":["name","operator","address","opening_hours"],"geometry":["point","area"],"tags":{"amenity":"scrapyard"},"reference":{"key":"industrial","value":"scrap_yard"},"name":"Scrap Yard","searchable":false},"amenity/swimming_pool":{"icon":"swimming","geometry":["point","vertex","area"],"tags":{"amenity":"swimming_pool"},"reference":{"key":"leisure","value":"swimming_pool"},"name":"Swimming Pool","searchable":false},"amenity/animal_boarding":{"icon":"veterinary","fields":["name","operator","address","building_area","opening_hours","animal_boarding"],"geometry":["point","area"],"terms":["boarding","cat","cattery","dog","horse","kennel","kitten","pet","pet boarding","pet care","pet hotel","puppy","reptile"],"tags":{"amenity":"animal_boarding"},"name":"Animal Boarding Facility"},"amenity/animal_breeding":{"icon":"veterinary","fields":["name","operator","address","building_area","opening_hours","animal_breeding"],"geometry":["point","area"],"terms":["breeding","bull","cat","cow","dog","horse","husbandry","kitten","livestock","pet breeding","puppy","reptile"],"tags":{"amenity":"animal_breeding"},"name":"Animal Breeding Facility"},"amenity/animal_shelter":{"icon":"veterinary","fields":["name","operator","address","building_area","opening_hours","animal_shelter"],"geometry":["point","area"],"terms":["adoption","aspca","cat","dog","horse","kitten","pet care","pet rescue","puppy","raptor","reptile","rescue","spca"],"tags":{"amenity":"animal_shelter"},"name":"Animal Shelter"},"amenity/arts_centre":{"icon":"theatre","fields":["name","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":["name","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":["name","operator","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"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":{"icon":"poi-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","payment_multi"],"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"],"terms":["bike","repair","chain","pump"],"tags":{"amenity":"bicycle_repair_station"},"name":"Bicycle Repair Tool Stand"},"amenity/biergarten":{"icon":"beer","fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"geometry":["point","area"],"tags":{"amenity":"biergarten"},"terms":["beer","bier","booze"],"name":"Beer Garden"},"amenity/boat_rental":{"fields":["name","operator","payment_multi"],"geometry":["point","area"],"tags":{"amenity":"boat_rental"},"name":"Boat Rental"},"amenity/bureau_de_change":{"icon":"bank","fields":["name","operator","currency_multi"],"geometry":["point","vertex"],"terms":["bureau de change","money changer"],"tags":{"amenity":"bureau_de_change"},"name":"Currency Exchange"},"amenity/cafe":{"icon":"cafe","fields":["name","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_pooling":{"icon":"car","fields":["name","operator","capacity"],"geometry":["point","area"],"tags":{"amenity":"car_pooling"},"name":"Car Pooling"},"amenity/car_rental":{"icon":"car","fields":["name","operator","payment_multi"],"geometry":["point","area"],"tags":{"amenity":"car_rental"},"name":"Car Rental"},"amenity/car_sharing":{"icon":"car","fields":["name","operator","capacity","payment_multi"],"geometry":["point","area"],"tags":{"amenity":"car_sharing"},"name":"Car Sharing"},"amenity/car_wash":{"icon":"car","fields":["address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"amenity":"car_wash"},"name":"Car Wash"},"amenity/casino":{"icon":"poi-dice","fields":["name","operator","address","building_area","opening_hours","payment_multi","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"],"tags":{"amenity":"charging_station"},"terms":["EV","Electric Vehicle","Supercharger"],"name":"Charging Station"},"amenity/childcare":{"icon":"school","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["daycare","orphanage","playgroup"],"tags":{"amenity":"childcare"},"name":"Nursery/Childcare"},"amenity/cinema":{"icon":"cinema","fields":["name","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["drive-in","film","flick","movie","theater","picture","show","screen"],"tags":{"amenity":"cinema"},"name":"Cinema"},"amenity/clinic":{"icon":"hospital","fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["medical","urgentcare"],"tags":{"amenity":"clinic"},"addTags":{"amenity":"clinic","healthcare":"clinic"},"removeTags":{"amenity":"clinic","healthcare":"clinic"},"reference":{"key":"amenity","value":"clinic"},"name":"Clinic"},"amenity/clinic/abortion":{"icon":"hospital","fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"geometry":["point","area"],"terms":[],"tags":{"amenity":"clinic","healthcare":"clinic","healthcare:speciality":"abortion"},"reference":{"key":"amenity","value":"clinic"},"name":"Abortion Clinic"},"amenity/clinic/fertility":{"icon":"hospital","fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["egg","fertility","reproductive","sperm","ovulation"],"tags":{"amenity":"clinic","healthcare":"clinic","healthcare:speciality":"fertility"},"reference":{"key":"amenity","value":"clinic"},"name":"Fertility Clinic"},"amenity/clock":{"icon":"poi-clock","fields":["name","support","display","visibility","date"],"geometry":["point","vertex"],"tags":{"amenity":"clock"},"name":"Clock"},"amenity/college":{"icon":"college","fields":["name","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":["name","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":["name","operator","address","building_area"],"geometry":["point","area"],"tags":{"amenity":"courthouse"},"name":"Courthouse"},"amenity/crematorium":{"icon":"cemetery","fields":["name","website","phone","opening_hours","wheelchair"],"geometry":["area","point"],"tags":{"amenity":"crematorium"},"terms":["cemetery","funeral"],"name":"Crematorium"},"amenity/dentist":{"icon":"dentist","fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["tooth","teeth"],"tags":{"amenity":"dentist"},"addTags":{"amenity":"dentist","healthcare":"dentist"},"removeTags":{"amenity":"dentist","healthcare":"dentist"},"reference":{"key":"amenity","value":"dentist"},"name":"Dentist"},"amenity/doctors":{"icon":"hospital","fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["medic*","physician"],"tags":{"amenity":"doctors"},"addTags":{"amenity":"doctors","healthcare":"doctor"},"removeTags":{"amenity":"doctors","healthcare":"doctor"},"reference":{"key":"amenity","value":"doctors"},"name":"Doctor"},"amenity/dojo":{"icon":"pitch","fields":["name","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/driving_school":{"icon":"car","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"amenity":"driving_school"},"name":"Driving School"},"amenity/embassy":{"icon":"embassy","fields":["name","country","address","building_area"],"geometry":["point","area"],"tags":{"amenity":"embassy"},"name":"Embassy"},"amenity/fast_food":{"icon":"fast-food","fields":["name","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/fire_station":{"icon":"fire-station","fields":["name","operator","address","building_area"],"geometry":["point","area"],"terms":[],"tags":{"amenity":"fire_station"},"name":"Fire Station"},"amenity/food_court":{"icon":"restaurant","fields":["name","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":{"icon":"poi-fountain","geometry":["point","area"],"tags":{"amenity":"fountain"},"name":"Fountain"},"amenity/fuel":{"icon":"fuel","fields":["name","operator","address","fuel_multi","opening_hours","payment_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":["name","operator","healthcare/speciality","address","emergency"],"geometry":["point","area"],"terms":["clinic","doctor","emergency room","health","infirmary","institution","sanatorium","sanitarium","sick","surgery","ward"],"tags":{"amenity":"hospital"},"addTags":{"amenity":"hospital","healthcare":"hospital"},"removeTags":{"amenity":"hospital","healthcare":"hospital"},"reference":{"key":"amenity","value":"hospital"},"name":"Hospital Grounds"},"amenity/hunting_stand":{"icon":"poi-binoculars","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":["name","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":{"icon":"poi-mast","fields":["name","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":["name","operator","address"],"geometry":["point","area"],"terms":["kindergarden","pre-school"],"tags":{"amenity":"kindergarten"},"name":"Preschool/Kindergarten Grounds"},"amenity/library":{"icon":"library","fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid","ref/isil"],"geometry":["point","area"],"terms":["book"],"tags":{"amenity":"library"},"name":"Library"},"amenity/love_hotel":{"icon":"heart","fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"amenity":"love_hotel"},"name":"Love Hotel"},"amenity/marketplace":{"icon":"shop","fields":["name","operator","address","building","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/music_school":{"icon":"school","fields":["name","operator","address"],"geometry":["point","area"],"terms":["school of music"],"tags":{"amenity":"music_school"},"name":"Music School"},"amenity/nightclub":{"icon":"bar","fields":["name","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"},"matchScore":0.95,"name":"Parking Space"},"amenity/parking":{"icon":"parking","fields":["operator","parking","capacity","fee","access_simple","supervised","park_ride","surface","maxstay"],"geometry":["point","vertex","area"],"tags":{"amenity":"parking"},"terms":[],"name":"Car Parking"},"amenity/pavilion":{"icon":"shelter","fields":["bin","bench"],"geometry":["point","vertex","area"],"tags":{"amenity":"shelter","shelter_type":"pavilion"},"name":"Pavilion"},"amenity/pharmacy":{"icon":"pharmacy","fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"amenity":"pharmacy"},"addTags":{"amenity":"pharmacy","healthcare":"pharmacy"},"removeTags":{"amenity":"pharmacy","healthcare":"pharmacy"},"reference":{"key":"amenity","value":"pharmacy"},"terms":["drug*","med*","prescription"],"name":"Pharmacy"},"amenity/place_of_worship":{"icon":"place-of-worship","fields":["name","religion","denomination","address","building_area","service_times"],"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":["name","denomination","building_area","address","service_times"],"geometry":["point","area"],"terms":["stupa","vihara","monastery","temple","pagoda","zendo","dojo"],"tags":{"amenity":"place_of_worship","religion":"buddhist"},"reference":{"key":"amenity","value":"place_of_worship"},"name":"Buddhist Temple"},"amenity/place_of_worship/christian":{"icon":"religious-christian","fields":["name","denomination","building_area","address","service_times"],"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"},"reference":{"key":"amenity","value":"place_of_worship"},"name":"Church"},"amenity/place_of_worship/hindu":{"icon":"poi-hinduist","fields":["name","denomination","building_area","address","service_times"],"geometry":["point","area"],"terms":["kovil","devasthana","mandir","kshetram","alayam","shrine","temple"],"tags":{"amenity":"place_of_worship","religion":"hindu"},"reference":{"key":"amenity","value":"place_of_worship"},"name":"Hindu Temple"},"amenity/place_of_worship/jewish":{"icon":"religious-jewish","fields":["name","denomination","building_area","address","service_times"],"geometry":["point","area"],"terms":["jewish"],"tags":{"amenity":"place_of_worship","religion":"jewish"},"reference":{"key":"amenity","value":"place_of_worship"},"name":"Synagogue"},"amenity/place_of_worship/muslim":{"icon":"religious-muslim","fields":["name","denomination","building_area","address","service_times"],"geometry":["point","area"],"terms":["muslim"],"tags":{"amenity":"place_of_worship","religion":"muslim"},"reference":{"key":"amenity","value":"place_of_worship"},"name":"Mosque"},"amenity/place_of_worship/shinto":{"icon":"poi-shintoist","fields":["name","denomination","building_area","address","service_times"],"geometry":["point","area"],"terms":["kami","torii"],"tags":{"amenity":"place_of_worship","religion":"shinto"},"reference":{"key":"amenity","value":"place_of_worship"},"name":"Shinto Shrine"},"amenity/place_of_worship/sikh":{"icon":"poi-sikhist","fields":["name","denomination","building_area","address","service_times"],"geometry":["point","area"],"terms":["gurudwara","temple"],"tags":{"amenity":"place_of_worship","religion":"sikh"},"reference":{"key":"amenity","value":"place_of_worship"},"name":"Sikh Temple"},"amenity/place_of_worship/taoist":{"icon":"poi-taoist","fields":["name","denomination","building_area","address","service_times"],"geometry":["point","area"],"terms":["daoist","monastery","temple"],"tags":{"amenity":"place_of_worship","religion":"taoist"},"reference":{"key":"amenity","value":"place_of_worship"},"name":"Taoist Temple"},"amenity/planetarium":{"icon":"museum","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["museum","astronomy","observatory"],"tags":{"amenity":"planetarium"},"name":"Planetarium"},"amenity/police":{"icon":"police","fields":["name","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":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["letter","mail"],"tags":{"amenity":"post_office"},"name":"Post Office"},"amenity/prison":{"icon":"prison","fields":["name","operator","address"],"geometry":["point","area"],"terms":["cell","jail"],"tags":{"amenity":"prison"},"name":"Prison Grounds"},"amenity/pub":{"icon":"beer","fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"geometry":["point","area"],"tags":{"amenity":"pub"},"terms":["alcohol","drink","dive","beer","bier","booze"],"name":"Pub"},"amenity/public_bath":{"icon":"water","fields":["name","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":["name","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":"recycling","fields":["name","operator","address","building","opening_hours","recycling_accepts"],"geometry":["point","area"],"terms":["bottle","can","dump","glass","garbage","rubbish","scrap","trash"],"tags":{"amenity":"recycling","recycling_type":"centre"},"reference":{"key":"recycling_type","value":"*"},"name":"Recycling Center"},"amenity/recycling":{"icon":"recycling","fields":["recycling_accepts","collection_times"],"geometry":["point","area"],"terms":["bin","can","bottle","glass","garbage","rubbish","scrap","trash"],"tags":{"amenity":"recycling"},"addTags":{"amenity":"recycling","recycling_type":"container"},"removeTags":{"amenity":"recycling","recycling_type":"container"},"reference":{"key":"amenity","value":"recycling"},"name":"Recycling Container"},"amenity/restaurant":{"icon":"restaurant","fields":["name","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":{"icon":"poi-storage-tank","fields":["operator","access_simple","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":["name","operator","address","religion","denomination"],"geometry":["point","area"],"terms":["academy","elementary school","middle school","high school"],"tags":{"amenity":"school"},"name":"School Grounds"},"amenity/shelter":{"icon":"shelter","fields":["name","shelter_type","bin"],"geometry":["point","vertex","area"],"terms":["lean-to","gazebo","picnic"],"tags":{"amenity":"shelter"},"name":"Shelter"},"amenity/shower":{"icon":"poi-shower","fields":["operator","opening_hours","fee","supervised","building_area"],"geometry":["point","vertex","area"],"terms":["rain closet"],"tags":{"amenity":"shower"},"name":"Shower"},"amenity/smoking_area":{"fields":["name","shelter","bin","bench","opening_hours"],"geometry":["point","vertex","area"],"terms":[],"tags":{"amenity":"smoking_area"},"name":"Smoking Area"},"amenity/social_facility":{"icon":"poi-social-facility","fields":["name","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":{"icon":"poi-social-facility","fields":["name","operator","address","building_area","social_facility","social_facility_for","opening_hours"],"geometry":["point","area"],"terms":[],"tags":{"amenity":"social_facility","social_facility":"food_bank"},"reference":{"key":"social_facility","value":"food_bank"},"name":"Food Bank"},"amenity/social_facility/group_home":{"icon":"wheelchair","fields":["name","operator","address","building_area","social_facility","social_facility_for","opening_hours","wheelchair"],"geometry":["point","area"],"terms":["old","senior","living","care home","assisted living"],"tags":{"amenity":"social_facility","social_facility":"group_home","social_facility:for":"senior"},"reference":{"key":"social_facility","value":"group_home"},"name":"Elderly Group Home"},"amenity/social_facility/homeless_shelter":{"icon":"poi-social-facility","fields":["name","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"},"reference":{"key":"social_facility","value":"shelter"},"name":"Homeless Shelter"},"amenity/social_facility/nursing_home":{"icon":"wheelchair","fields":["name","operator","address","building_area","social_facility","social_facility_for","opening_hours","wheelchair"],"geometry":["point","area"],"terms":["elderly","living","nursing","old","senior","assisted living"],"tags":{"amenity":"social_facility","social_facility":"nursing_home","social_facility:for":"senior"},"reference":{"key":"social_facility","value":"nursing_home"},"name":"Nursing Home"},"amenity/studio":{"icon":"karaoke","fields":["name","studio","address","building_area"],"geometry":["point","area"],"terms":["recording","radio","television"],"tags":{"amenity":"studio"},"name":"Studio"},"amenity/taxi":{"icon":"car","fields":["name","operator","capacity"],"geometry":["point","vertex","area"],"terms":["cab"],"tags":{"amenity":"taxi"},"name":"Taxi Stand"},"amenity/telephone":{"icon":"telephone","fields":["operator","phone","fee","payment_multi","covered","indoor"],"geometry":["point","vertex"],"tags":{"amenity":"telephone"},"terms":["phone"],"name":"Telephone"},"amenity/theatre":{"icon":"theatre","fields":["name","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_simple","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":["name","operator","address","building_area"],"geometry":["point","area"],"terms":["village","city","government","courthouse","municipal"],"tags":{"amenity":"townhall"},"name":"Town Hall"},"amenity/university":{"icon":"college","fields":["name","operator","address","internet_access","internet_access/ssid"],"geometry":["point","area"],"terms":["college"],"tags":{"amenity":"university"},"name":"University Grounds"},"amenity/vending_machine":{"icon":"poi-vending-machine","fields":["vending","operator","payment_multi","currency_multi"],"geometry":["point"],"terms":[],"tags":{"amenity":"vending_machine"},"name":"Vending Machine"},"amenity/vending_machine/news_papers":{"icon":"poi-vending-machine","fields":["operator","fee","payment_multi","currency_multi"],"geometry":["point"],"terms":["newspaper"],"tags":{"amenity":"vending_machine","vending":"news_papers"},"reference":{"key":"vending","value":"newspapers"},"name":"Newspaper Vending Machine","searchable":false},"amenity/vending_machine/cigarettes":{"icon":"poi-vending-machine","fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["cigarette"],"tags":{"amenity":"vending_machine","vending":"cigarettes"},"reference":{"key":"vending","value":"cigarettes"},"name":"Cigarette Vending Machine"},"amenity/vending_machine/condoms":{"icon":"poi-vending-machine","fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["condom"],"tags":{"amenity":"vending_machine","vending":"condoms"},"reference":{"key":"vending","value":"condoms"},"name":"Condom Vending Machine"},"amenity/vending_machine/drinks":{"icon":"poi-vending-machine","fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["drink","soda","beverage","juice","pop"],"tags":{"amenity":"vending_machine","vending":"drinks"},"reference":{"key":"vending","value":"drinks"},"name":"Drink Vending Machine"},"amenity/vending_machine/excrement_bags":{"icon":"poi-vending-machine","fields":["operator","fee","payment_multi","currency_multi"],"geometry":["point"],"terms":["excrement bags","poop","dog","animal"],"tags":{"amenity":"vending_machine","vending":"excrement_bags"},"reference":{"key":"vending","value":"excrement_bags"},"name":"Excrement Bag Vending Machine"},"amenity/vending_machine/feminine_hygiene":{"icon":"poi-vending-machine","fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["condom","tampon","pad","woman","women","menstrual hygiene products","personal care"],"tags":{"amenity":"vending_machine","vending":"feminine_hygiene"},"reference":{"key":"vending","value":"feminine_hygiene"},"name":"Feminine Hygiene Vending Machine"},"amenity/vending_machine/newspapers":{"icon":"poi-vending-machine","fields":["operator","fee","payment_multi","currency_multi"],"geometry":["point"],"terms":["newspaper"],"tags":{"amenity":"vending_machine","vending":"newspapers"},"reference":{"key":"vending","value":"newspapers"},"name":"Newspaper Vending Machine"},"amenity/vending_machine/parcel_pickup_dropoff":{"icon":"poi-vending-machine","fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["parcel","mail","pickup"],"tags":{"amenity":"vending_machine","vending":"parcel_pickup;parcel_mail_in"},"reference":{"key":"vending","value":"parcel_pickup;parcel_mail_in"},"name":"Parcel Pickup/Dropoff Vending Machine"},"amenity/vending_machine/parking_tickets":{"icon":"poi-vending-machine","fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["parking","ticket"],"tags":{"amenity":"vending_machine","vending":"parking_tickets"},"reference":{"key":"vending","value":"parking_tickets"},"matchScore":0.94,"name":"Parking Ticket Vending Machine"},"amenity/vending_machine/public_transport_tickets":{"icon":"poi-vending-machine","fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["bus","train","ferry","rail","ticket","transportation"],"tags":{"amenity":"vending_machine","vending":"public_transport_tickets"},"reference":{"key":"vending","value":"public_transport_tickets"},"name":"Transit Ticket Vending Machine"},"amenity/vending_machine/sweets":{"icon":"poi-vending-machine","fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["candy","gum","chip","pretzel","cookie","cracker"],"tags":{"amenity":"vending_machine","vending":"sweets"},"reference":{"key":"vending","value":"sweets"},"name":"Snack Vending Machine"},"amenity/veterinary":{"icon":"veterinary","fields":["name","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"],"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":["name","operator","address","opening_hours"],"geometry":["point","area"],"terms":["dump","garbage","recycling","rubbish","scrap","trash"],"tags":{"amenity":"waste_transfer_station"},"name":"Waste Transfer Station"},"amenity/waste/dog_excrement":{"icon":"waste-basket","fields":["collection_times"],"geometry":["point","vertex","area"],"tags":{"amenity":"waste_basket","waste":"dog_excrement"},"reference":{"key":"waste","value":"dog_excrement"},"terms":["bin","garbage","rubbish","litter","trash","poo","dog"],"name":"Dog Excrement Bin"},"amenity/water_point":{"icon":"drinking-water","geometry":["area","vertex","point"],"tags":{"amenity":"water_point"},"name":"RV Drinking Water"},"amenity/watering_place":{"icon":"drinking-water","geometry":["area","vertex","point"],"tags":{"amenity":"watering_place"},"name":"Animal Watering Place"},"area":{"fields":["name"],"geometry":["area"],"tags":{"area":"yes"},"name":"Area","matchScore":0.1},"area/highway":{"fields":["name","area/highway"],"geometry":["area"],"tags":{"area:highway":"*"},"name":"Road Surface"},"attraction/amusement_ride":{"icon":"amusement-park","fields":["name","operator","opening_hours"],"geometry":["point","area"],"terms":["theme park","carnival ride"],"tags":{"attraction":"amusement_ride"},"name":"Amusement Ride"},"attraction/animal":{"icon":"zoo","fields":["name","operator"],"geometry":["point","area"],"terms":["zoo","theme park","animal park","lion","tiger","bear"],"tags":{"attraction":"animal"},"name":"Animal"},"attraction/big_wheel":{"icon":"amusement-park","fields":["name","operator","height","opening_hours"],"geometry":["point"],"terms":["ferris wheel","theme park","amusement ride"],"tags":{"attraction":"big_wheel"},"name":"Big Wheel"},"attraction/bumper_car":{"icon":"car","fields":["name","operator","opening_hours"],"geometry":["point","area"],"terms":["theme park","dodgem cars","autoscooter"],"tags":{"attraction":"bumper_car"},"name":"Bumper Car"},"attraction/bungee_jumping":{"icon":"pitch","fields":["name","operator","height","opening_hours"],"geometry":["point","area"],"terms":["theme park","bungy jumping","jumping platform"],"tags":{"attraction":"bungee_jumping"},"name":"Bungee Jumping"},"attraction/carousel":{"icon":"horse-riding","fields":["name","operator","opening_hours"],"geometry":["point","area"],"terms":["theme park","roundabout","merry-go-round","galloper","jumper","horseabout","flying horses"],"tags":{"attraction":"carousel"},"name":"Carousel"},"attraction/dark_ride":{"icon":"rail-metro","fields":["name","operator","opening_hours"],"geometry":["point","line","area"],"terms":["theme park","ghost train"],"tags":{"attraction":"dark_ride"},"name":"Dark Ride"},"attraction/drop_tower":{"icon":"poi-tower","fields":["name","operator","height","opening_hours"],"geometry":["point","area"],"terms":["theme park","amusement ride","gondola","tower","big drop"],"tags":{"attraction":"drop_tower"},"name":"Drop Tower"},"attraction/pirate_ship":{"icon":"amusement-park","fields":["name","operator","opening_hours"],"geometry":["point"],"terms":["theme park","carnival ride","amusement ride"],"tags":{"attraction":"pirate_ship"},"name":"Pirate Ship"},"attraction/river_rafting":{"icon":"ferry","fields":["name","operator","opening_hours"],"geometry":["point","line"],"terms":["theme park","aquatic park","water park","rafting simulator","river rafting ride","river rapids ride"],"tags":{"attraction":"river_rafting"},"name":"River Rafting"},"attraction/roller_coaster":{"icon":"amusement-park","fields":["name","operator","opening_hours"],"geometry":["point","area"],"terms":["theme park","amusement ride"],"tags":{"attraction":"roller_coaster"},"name":"Roller Coaster"},"attraction/train":{"icon":"rail","fields":["name","operator","fee","opening_hours"],"geometry":["point","line"],"terms":["theme park","rackless train","road train","Tschu-Tschu train","dotto train","park train"],"tags":{"attraction":"train"},"name":"Tourist Train"},"attraction/water_slide":{"icon":"swimming","fields":["name","operator","opening_hours"],"geometry":["line","area"],"terms":["theme park","aquatic park","water park","flumes","water chutes","hydroslides"],"tags":{"attraction":"water_slide"},"name":"Water Slide"},"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/kerb":{"icon":"wheelchair","fields":["kerb","tactile_paving"],"geometry":["vertex","line"],"tags":{"barrier":"kerb"},"name":"Kerb"},"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":["name","admin_level"]},"building":{"icon":"home","fields":["name","building","levels","address"],"geometry":["point","area"],"tags":{"building":"*"},"matchScore":0.6,"terms":[],"name":"Building"},"building/bunker":{"fields":["name","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":["name","address","levels"],"geometry":["point","vertex","area"],"tags":{"building":"train_station"},"matchScore":0.5,"name":"Train Station","searchable":false},"building/apartments":{"icon":"building","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"apartments"},"matchScore":0.5,"name":"Apartments"},"building/barn":{"icon":"farm","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"barn"},"matchScore":0.5,"name":"Barn"},"building/boathouse":{"icon":"harbor","fields":["name","levels","address"],"geometry":["area"],"tags":{"building":"boathouse"},"matchScore":0.5,"terms":[],"name":"Boathouse"},"building/bungalow":{"icon":"home","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"bungalow"},"terms":["home","detached"],"matchScore":0.5,"name":"Bungalow"},"building/cabin":{"icon":"home","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"cabin"},"matchScore":0.5,"name":"Cabin"},"building/cathedral":{"icon":"place-of-worship","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"cathedral"},"matchScore":0.5,"name":"Cathedral Building"},"building/chapel":{"icon":"place-of-worship","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"chapel"},"matchScore":0.5,"name":"Chapel Building"},"building/church":{"icon":"place-of-worship","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"church"},"matchScore":0.5,"name":"Church Building"},"building/civic":{"icon":"building","fields":["name","address","levels","smoking"],"geometry":["area"],"tags":{"building":"civic"},"matchScore":0.5,"name":"Civic Building"},"building/college":{"icon":"building","fields":["name","address","levels"],"geometry":["area"],"terms":["university"],"tags":{"building":"college"},"matchScore":0.5,"name":"College Building"},"building/commercial":{"icon":"suitcase","fields":["name","address","levels","smoking"],"geometry":["area"],"tags":{"building":"commercial"},"matchScore":0.5,"name":"Commercial Building"},"building/construction":{"icon":"building","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"construction"},"matchScore":0.5,"name":"Building Under Construction"},"building/detached":{"icon":"home","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"detached"},"terms":["home","single","family","residence","dwelling"],"matchScore":0.5,"name":"Detached House"},"building/dormitory":{"icon":"building","fields":["name","address","levels","smoking"],"geometry":["area"],"tags":{"building":"dormitory"},"matchScore":0.5,"name":"Dormitory"},"building/farm":{"icon":"farm","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"farm"},"matchScore":0.5,"name":"Farm Building"},"building/garage":{"icon":"warehouse","fields":["name","capacity"],"geometry":["area"],"tags":{"building":"garage"},"matchScore":0.5,"name":"Garage"},"building/garages":{"icon":"warehouse","fields":["name","capacity"],"geometry":["area"],"tags":{"building":"garages"},"matchScore":0.5,"name":"Garages"},"building/greenhouse":{"icon":"garden-center","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"greenhouse"},"matchScore":0.5,"name":"Greenhouse"},"building/hospital":{"icon":"building","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"hospital"},"matchScore":0.5,"name":"Hospital Building"},"building/hotel":{"icon":"building","fields":["name","address","levels","smoking"],"geometry":["area"],"tags":{"building":"hotel"},"matchScore":0.5,"name":"Hotel Building"},"building/house":{"icon":"home","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"house"},"terms":["home","family","residence","dwelling"],"matchScore":0.5,"name":"House"},"building/hut":{"geometry":["area"],"fields":["name"],"tags":{"building":"hut"},"matchScore":0.5,"name":"Hut"},"building/industrial":{"icon":"industry","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"industrial"},"matchScore":0.5,"name":"Industrial Building"},"building/kindergarten":{"icon":"building","fields":["name","address","levels"],"geometry":["area"],"terms":["kindergarden","pre-school"],"tags":{"building":"kindergarten"},"matchScore":0.5,"name":"Preschool/Kindergarten Building"},"building/mosque":{"icon":"place-of-worship","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"mosque"},"matchScore":0.5,"name":"Mosque Building"},"building/public":{"icon":"building","fields":["name","address","levels","smoking"],"geometry":["area"],"tags":{"building":"public"},"matchScore":0.5,"name":"Public Building"},"building/residential":{"icon":"residential-community","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"residential"},"matchScore":0.5,"name":"Residential Building"},"building/retail":{"icon":"commercial","fields":["name","address","levels","smoking"],"geometry":["area"],"tags":{"building":"retail"},"matchScore":0.5,"name":"Retail Building"},"building/roof":{"icon":"shelter","fields":["name","address"],"geometry":["area"],"tags":{"building":"roof"},"matchScore":0.5,"name":"Roof"},"building/ruins":{"icon":"poi-ruins","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"ruins"},"matchScore":0.5,"name":"Building Ruins"},"building/school":{"icon":"building","fields":["name","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":["name","address","levels"],"geometry":["area"],"tags":{"building":"semidetached_house"},"terms":["home","double","duplex","twin","family","residence","dwelling"],"matchScore":0.5,"name":"Semi-Detached House"},"building/service":{"icon":"home","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"service"},"matchScore":0.5,"name":"Service Building"},"building/shed":{"icon":"home","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"shed"},"matchScore":0.5,"name":"Shed"},"building/stable":{"icon":"horse-riding","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"stable"},"matchScore":0.5,"name":"Stable"},"building/stadium":{"icon":"stadium","fields":["name","address","levels","smoking"],"geometry":["area"],"tags":{"building":"stadium"},"matchScore":0.5,"name":"Stadium Building"},"building/static_caravan":{"icon":"home","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"static_caravan"},"matchScore":0.5,"name":"Static Mobile Home"},"building/temple":{"icon":"place-of-worship","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"temple"},"matchScore":0.5,"name":"Temple Building"},"building/terrace":{"icon":"building","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"terrace"},"terms":["home","terrace","brownstone","family","residence","dwelling"],"matchScore":0.5,"name":"Row Houses"},"building/transportation":{"icon":"building","fields":["name","address","levels","smoking"],"geometry":["area"],"tags":{"building":"transportation"},"matchScore":0.5,"name":"Transportation Building"},"building/university":{"icon":"building","fields":["name","address","levels"],"geometry":["area"],"terms":["college"],"tags":{"building":"university"},"matchScore":0.5,"name":"University Building"},"building/warehouse":{"icon":"warehouse","fields":["name","address","levels"],"geometry":["area"],"tags":{"building":"warehouse"},"matchScore":0.5,"name":"Warehouse"},"camp_site/camp_pitch":{"icon":"campsite","fields":["name","ref"],"geometry":["point","area"],"terms":["tent","rv"],"tags":{"camp_site":"camp_pitch"},"name":"Camp Pitch"},"club":{"icon":"heart","fields":["name","club","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"club":"*"},"terms":["social"],"name":"Club"},"craft":{"icon":"poi-tool","fields":["name","craft","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"*"},"terms":[],"name":"Craft"},"craft/jeweler":{"icon":"marker-stroked","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"jeweler"},"reference":{"key":"shop","value":"jewelry"},"name":"Jeweler","searchable":false},"craft/locksmith":{"icon":"marker-stroked","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"locksmith"},"reference":{"key":"shop","value":"locksmith"},"name":"Locksmith","searchable":false},"craft/optician":{"icon":"marker-stroked","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"optician"},"reference":{"key":"shop","value":"optician"},"name":"Optician","searchable":false},"craft/tailor":{"icon":"clothing-store","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["clothes","suit"],"tags":{"craft":"tailor"},"reference":{"key":"shop","value":"tailor"},"name":"Tailor","searchable":false},"craft/basket_maker":{"icon":"art-gallery","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"basket_maker"},"name":"Basket Maker"},"craft/beekeeper":{"icon":"farm","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"beekeeper"},"name":"Beekeeper"},"craft/blacksmith":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"blacksmith"},"name":"Blacksmith"},"craft/boatbuilder":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"boatbuilder"},"name":"Boat Builder"},"craft/bookbinder":{"icon":"library","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["book repair"],"tags":{"craft":"bookbinder"},"name":"Bookbinder"},"craft/brewery":{"icon":"poi-storage-tank","fields":["name","operator","address","building_area","opening_hours","product"],"geometry":["point","area"],"terms":["alcohol","beer","beverage","bier","booze","cider"],"tags":{"craft":"brewery"},"name":"Brewery"},"craft/carpenter":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["woodworker"],"tags":{"craft":"carpenter"},"name":"Carpenter"},"craft/carpet_layer":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"carpet_layer"},"name":"Carpet Layer"},"craft/caterer":{"icon":"restaurant","fields":["name","cuisine","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"caterer"},"name":"Caterer"},"craft/chimney_sweeper":{"icon":"poi-chimney","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"chimney_sweeper"},"name":"Chimney Sweeper"},"craft/clockmaker":{"icon":"poi-clock","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"clockmaker"},"name":"Clockmaker"},"craft/confectionery":{"icon":"bakery","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["sweet","candy"],"tags":{"craft":"confectionery"},"name":"Candy Maker"},"craft/distillery":{"icon":"poi-storage-tank","fields":["name","operator","address","building_area","opening_hours","product"],"geometry":["point","area"],"terms":["alcohol","beverage","bourbon","booze","brandy","gin","hooch","liquor","mezcal","moonshine","rum","scotch","spirits","still","tequila","vodka","whiskey","whisky"],"tags":{"craft":"distillery"},"name":"Distillery"},"craft/dressmaker":{"icon":"clothing-store","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["seamstress"],"tags":{"craft":"dressmaker"},"name":"Dressmaker"},"craft/electrician":{"icon":"poi-power","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["power","wire"],"tags":{"craft":"electrician"},"name":"Electrician"},"craft/electronics_repair":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"electronics_repair"},"name":"Electronics Repair Shop"},"craft/gardener":{"icon":"garden","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["landscaper","grounds keeper"],"tags":{"craft":"gardener"},"name":"Gardener"},"craft/glaziery":{"icon":"fire-station","fields":["name","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":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"handicraft"},"name":"Handicraft"},"craft/hvac":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["heat*","vent*","air conditioning"],"tags":{"craft":"hvac"},"name":"HVAC"},"craft/insulator":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"insulation"},"name":"Insulator"},"craft/key_cutter":{"icon":"marker-stroked","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"key_cutter"},"name":"Key Cutter"},"craft/metal_construction":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"metal_construction"},"name":"Metal Construction"},"craft/painter":{"icon":"art-gallery","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"painter"},"name":"Painter"},"craft/photographer":{"icon":"attraction","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"photographer"},"name":"Photographer"},"craft/photographic_laboratory":{"icon":"attraction","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["film"],"tags":{"craft":"photographic_laboratory"},"name":"Photographic Laboratory"},"craft/plasterer":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"plasterer"},"name":"Plasterer"},"craft/plumber":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["pipe"],"tags":{"craft":"plumber"},"name":"Plumber"},"craft/pottery":{"icon":"art-gallery","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["ceramic"],"tags":{"craft":"pottery"},"name":"Pottery"},"craft/rigger":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"rigger"},"name":"Rigger"},"craft/roofer":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"roofer"},"name":"Roofer"},"craft/saddler":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"saddler"},"name":"Saddler"},"craft/sailmaker":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"sailmaker"},"name":"Sailmaker"},"craft/sawmill":{"icon":"logging","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["lumber"],"tags":{"craft":"sawmill"},"name":"Sawmill"},"craft/scaffolder":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"scaffolder"},"name":"Scaffolder"},"craft/sculptor":{"icon":"art-gallery","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"sculptor"},"name":"Sculptor"},"craft/shoemaker":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["cobbler"],"tags":{"craft":"shoemaker"},"name":"Shoemaker"},"craft/stonemason":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["masonry"],"tags":{"craft":"stonemason"},"name":"Stonemason"},"craft/tiler":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"tiler"},"name":"Tiler"},"craft/tinsmith":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"tinsmith"},"name":"Tinsmith"},"craft/upholsterer":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"upholsterer"},"name":"Upholsterer"},"craft/watchmaker":{"icon":"poi-clock","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"watchmaker"},"name":"Watchmaker"},"craft/window_construction":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["glass"],"tags":{"craft":"window_construction"},"name":"Window Construction"},"craft/winery":{"icon":"alcohol-shop","fields":["name","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":["name","operator","building_area","address"],"geometry":["point","area"],"terms":["EMS","EMT","rescue"],"tags":{"emergency":"ambulance_station"},"name":"Ambulance Station"},"emergency/defibrillator":{"icon":"defibrillator","fields":["ref","access","opening_hours","indoor","phone"],"geometry":["point","vertex"],"terms":["AED"],"tags":{"emergency":"defibrillator"},"name":"Defibrillator"},"emergency/fire_hydrant":{"icon":"poi-fire-hydrant","fields":["fire_hydrant/type","fire_hydrant/position","ref","operator"],"geometry":["point","vertex"],"terms":["fire plug"],"tags":{"emergency":"fire_hydrant"},"name":"Fire Hydrant"},"emergency/life_ring":{"icon":"circle-stroked","fields":["ref","operator"],"geometry":["point","vertex"],"terms":["life buoy","kisby ring","kisbie ring","perry buoy"],"tags":{"emergency":"life_ring"},"name":"Life Ring"},"emergency/phone":{"icon":"emergency-phone","fields":["operator"],"geometry":["point","vertex"],"tags":{"emergency":"phone"},"name":"Emergency Phone"},"emergency/water_tank":{"icon":"water","fields":["name","operator","ref"],"geometry":["point","vertex"],"terms":["water tank","cistern","reservoir"],"tags":{"emergency":"water_tank"},"name":"Emergency Water Tank"},"entrance":{"icon":"entrance-alt1","geometry":["vertex"],"tags":{"entrance":"*"},"fields":["entrance","access_simple","address"],"name":"Entrance/Exit"},"footway/crossing-raised":{"fields":["crossing","access","surface","kerb","tactile_paving"],"geometry":["line"],"tags":{"highway":"footway","footway":"crossing","traffic_calming":"table"},"reference":{"key":"traffic_calming","value":"table"},"terms":["flat top","hump","speed","slow"],"name":"Raised Street Crossing"},"footway/crossing":{"fields":["crossing","access","surface","kerb","tactile_paving"],"geometry":["line"],"tags":{"highway":"footway","footway":"crossing"},"reference":{"key":"footway","value":"crossing"},"terms":[],"name":"Street Crossing"},"footway/crosswalk-raised":{"icon":"highway-footway","fields":["crossing","access","surface","kerb","tactile_paving"],"geometry":["line"],"tags":{"highway":"footway","footway":"crossing","crossing":"zebra","traffic_calming":"table"},"reference":{"key":"traffic_calming","value":"table"},"terms":["zebra crossing","flat top","hump","speed","slow"],"name":"Raised Pedestrian Crosswalk"},"footway/crosswalk":{"icon":"highway-footway","fields":["crossing","access","surface","kerb","tactile_paving"],"geometry":["line"],"tags":{"highway":"footway","footway":"crossing","crossing":"zebra"},"reference":{"key":"footway","value":"crossing"},"terms":["zebra crossing"],"name":"Pedestrian Crosswalk"},"footway/sidewalk":{"icon":"highway-footway","fields":["surface","lit","width","structure","access"],"geometry":["line"],"tags":{"highway":"footway","footway":"sidewalk"},"reference":{"key":"footway","value":"sidewalk"},"terms":[],"name":"Sidewalk"},"ford":{"geometry":["vertex"],"tags":{"ford":"yes"},"name":"Ford"},"golf/bunker":{"icon":"golf","fields":["name"],"geometry":["area"],"tags":{"golf":"bunker","natural":"sand"},"terms":["hazard","bunker"],"reference":{"key":"golf","value":"bunker"},"name":"Sand Trap"},"golf/fairway":{"icon":"golf","fields":["name"],"geometry":["area"],"tags":{"golf":"fairway","landuse":"grass"},"reference":{"key":"golf","value":"fairway"},"name":"Fairway"},"golf/green":{"icon":"golf","fields":["name"],"geometry":["area"],"tags":{"golf":"green","landuse":"grass","leisure":"pitch","sport":"golf"},"reference":{"key":"golf","value":"green"},"name":"Putting Green"},"golf/hole":{"icon":"golf","fields":["name","ref_golf_hole","par","handicap"],"geometry":["line"],"tags":{"golf":"hole"},"name":"Golf Hole"},"golf/lateral_water_hazard_area":{"icon":"golf","fields":["name"],"geometry":["area"],"tags":{"golf":"lateral_water_hazard","natural":"water"},"reference":{"key":"golf","value":"lateral_water_hazard"},"name":"Lateral Water Hazard"},"golf/lateral_water_hazard_line":{"icon":"golf","fields":["name"],"geometry":["line"],"tags":{"golf":"lateral_water_hazard"},"name":"Lateral Water Hazard"},"golf/rough":{"icon":"golf","fields":["name"],"geometry":["area"],"tags":{"golf":"rough","landuse":"grass"},"reference":{"key":"golf","value":"rough"},"name":"Rough"},"golf/tee":{"icon":"golf","fields":["name"],"geometry":["area"],"tags":{"golf":"tee","landuse":"grass"},"terms":["teeing ground"],"reference":{"key":"golf","value":"tee"},"name":"Tee Box"},"golf/water_hazard_area":{"icon":"golf","fields":["name"],"geometry":["area"],"tags":{"golf":"water_hazard","natural":"water"},"reference":{"key":"golf","value":"water_hazard"},"name":"Water Hazard"},"golf/water_hazard_line":{"icon":"golf","fields":["name"],"geometry":["line"],"tags":{"golf":"water_hazard"},"name":"Water Hazard"},"healthcare":{"icon":"hospital","fields":["name","healthcare","operator","healthcare/speciality","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"healthcare":"*"},"terms":["clinic","doctor","disease","health","institution","sick","surgery","wellness"],"name":"Healthcare Facility"},"healthcare/alternative":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["acupuncture","anthroposophical","applied kinesiology","aromatherapy","ayurveda","herbalism","homeopathy","hydrotherapy","hypnosis","naturopathy","osteopathy","reflexology","reiki","shiatsu","traditional","tuina","unani"],"tags":{"healthcare":"alternative"},"name":"Alternative Medicine"},"healthcare/alternative/chiropractic":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["back","pain","spine"],"tags":{"healthcare":"alternative","healthcare:speciality":"chiropractic"},"name":"Chiropractor"},"healthcare/audiologist":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["ear","hearing","sound"],"tags":{"healthcare":"audiologist"},"name":"Audiologist"},"healthcare/birthing_center":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["baby","childbirth","delivery","labour","labor","pregnancy"],"tags":{"healthcare":"birthing_center"},"name":"Birthing Center"},"healthcare/blood_donation":{"icon":"blood-bank","fields":["name","operator","healthcare/speciality","blood_components","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["blood bank","blood donation","blood transfusion","apheresis","plasmapheresis","plateletpheresis","stem cell donation"],"tags":{"healthcare":"blood_donation"},"name":"Blood Donor Center"},"healthcare/hospice":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["terminal","illness"],"tags":{"healthcare":"hospice"},"name":"Hospice"},"healthcare/midwife":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["baby","childbirth","delivery","labour","labor","pregnancy"],"tags":{"healthcare":"midwife"},"name":"Midwife"},"healthcare/occupational_therapist":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["therapist","therapy"],"tags":{"healthcare":"occupational_therapist"},"name":"Occupational Therapist"},"healthcare/optometrist":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["eye","glasses","lasik","lenses","vision"],"tags":{"healthcare":"optometrist"},"name":"Optometrist"},"healthcare/physiotherapist":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["physical","therapist","therapy"],"tags":{"healthcare":"physiotherapist"},"name":"Physiotherapist"},"healthcare/podiatrist":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["foot","feet","nails"],"tags":{"healthcare":"podiatrist"},"name":"Podiatrist"},"healthcare/psychotherapist":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["anxiety","counselor","depression","mental health","mind","suicide","therapist","therapy"],"tags":{"healthcare":"psychotherapist"},"name":"Psychotherapist"},"healthcare/rehabilitation":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["rehab","therapist","therapy"],"tags":{"healthcare":"rehabilitation"},"name":"Rehabilitation Facility"},"healthcare/speech_therapist":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["speech","therapist","therapy","voice"],"tags":{"healthcare":"speech_therapist"},"name":"Speech Therapist"},"highway/bus_stop":{"icon":"bus","fields":["name","network","operator","bench","shelter"],"geometry":["point","vertex"],"tags":{"highway":"bus_stop"},"name":"Bus Stop / Platform","searchable":false},"highway/bridleway":{"fields":["name","surface","width","structure","access"],"icon":"highway-bridleway","geometry":["line"],"tags":{"highway":"bridleway"},"terms":["bridleway","equestrian","horse"],"name":"Bridle Path"},"highway/bus_guideway":{"icon":"highway-bus_guideway","fields":["name","operator","oneway"],"geometry":["line"],"tags":{"highway":"bus_guideway"},"addTags":{"highway":"bus_guideway","access":"no","bus":"designated"},"removeTags":{"highway":"bus_guideway","access":"no","bus":"designated"},"terms":[],"name":"Bus Guideway"},"highway/corridor":{"icon":"highway-footway","fields":["name","width","level","access_simple"],"geometry":["line"],"tags":{"highway":"corridor"},"terms":["gallery","hall","hallway","indoor","passage","passageway"],"name":"Indoor Corridor"},"highway/crossing-raised":{"fields":["crossing","kerb","tactile_paving"],"geometry":["vertex"],"tags":{"highway":"crossing","traffic_calming":"table"},"reference":{"key":"traffic_calming","value":"table"},"terms":["flat top","hump","speed","slow"],"name":"Raised Street Crossing"},"highway/crossing":{"fields":["crossing","kerb","tactile_paving"],"geometry":["vertex"],"tags":{"highway":"crossing"},"reference":{"key":"highway","value":"crossing"},"terms":[],"name":"Street Crossing"},"highway/crosswalk-raised":{"icon":"poi-foot","fields":["crossing","kerb","tactile_paving"],"geometry":["vertex"],"tags":{"highway":"crossing","crossing":"zebra","traffic_calming":"table"},"reference":{"key":"traffic_calming","value":"table"},"terms":["zebra crossing","flat top","hump","speed","slow"],"name":"Raised Pedestrian Crosswalk"},"highway/crosswalk":{"icon":"poi-foot","fields":["crossing","kerb","tactile_paving"],"geometry":["vertex"],"tags":{"highway":"crossing","crossing":"zebra"},"reference":{"key":"highway","value":"crossing"},"terms":["zebra crossing"],"name":"Pedestrian Crosswalk"},"highway/cycleway":{"icon":"highway-cycleway","fields":["name","oneway","surface","lit","width","structure","access"],"geometry":["line"],"tags":{"highway":"cycleway"},"terms":["bike"],"name":"Cycle Path"},"highway/elevator":{"icon":"poi-elevator","fields":["access_simple","opening_hours","maxweight","ref"],"geometry":["vertex"],"tags":{"highway":"elevator"},"terms":["lift"],"name":"Elevator"},"highway/footway":{"icon":"highway-footway","fields":["name","surface","lit","width","structure","access"],"geometry":["line"],"terms":["hike","hiking","trackway","trail","walk"],"tags":{"highway":"footway"},"name":"Foot Path"},"highway/give_way":{"icon":"poi-yield","fields":["direction_vertex"],"geometry":["vertex"],"tags":{"highway":"give_way"},"terms":["give way","yield","sign"],"name":"Yield Sign"},"highway/living_street":{"icon":"highway-living-street","fields":["name","oneway","maxspeed","lanes","surface","structure","maxheight","access","cycleway"],"geometry":["line"],"tags":{"highway":"living_street"},"name":"Living Street"},"highway/mini_roundabout":{"icon":"circle-stroked","geometry":["vertex"],"tags":{"highway":"mini_roundabout"},"fields":["direction_clock"],"name":"Mini-Roundabout"},"highway/motorway_junction":{"icon":"poi-junction","geometry":["vertex"],"tags":{"highway":"motorway_junction"},"fields":["ref_highway_junction"],"name":"Motorway Junction / Exit"},"highway/motorway_link":{"icon":"highway-motorway-link","fields":["name","ref_road_number","oneway","maxspeed","lanes","surface","structure","maxheight","access"],"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":["name","ref_road_number","oneway_yes","maxspeed","lanes","surface","structure","maxheight","toll","access"],"geometry":["line"],"tags":{"highway":"motorway"},"terms":["autobahn","expressway","freeway","highway","interstate","parkway","thruway","turnpike"],"name":"Motorway"},"highway/path":{"icon":"highway-path","fields":["name","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_area":{"icon":"poi-foot","fields":["name","surface","lit","width","structure","access"],"geometry":["area"],"tags":{"highway":"pedestrian","area":"yes"},"terms":["center","centre","plaza","quad","square","walkway"],"name":"Pedestrian Area"},"highway/pedestrian_line":{"icon":"highway-footway","fields":["name","surface","lit","width","oneway","structure","access"],"geometry":["line"],"tags":{"highway":"pedestrian"},"terms":["center","centre","plaza","quad","square","walkway"],"name":"Pedestrian Street"},"highway/primary_link":{"icon":"highway-primary-link","fields":["name","oneway","maxspeed","lanes","surface","maxheight","ref_road_number","cycleway","structure","access"],"geometry":["line"],"tags":{"highway":"primary_link"},"terms":["ramp","on ramp","off ramp"],"name":"Primary Link"},"highway/primary":{"icon":"highway-primary","fields":["name","oneway","maxspeed","lanes","surface","structure","maxheight","ref_road_number","cycleway","access"],"geometry":["line"],"tags":{"highway":"primary"},"terms":[],"name":"Primary Road"},"highway/raceway":{"icon":"highway-unclassified","fields":["name","oneway","surface","sport_racing_motor","lit","width","lanes","structure"],"geometry":["point","line","area"],"tags":{"highway":"raceway"},"addTags":{"highway":"raceway","sport":"motor"},"terms":["auto*","formula one","kart","motocross","nascar","race*","track"],"name":"Racetrack (Motorsport)"},"highway/residential":{"icon":"highway-residential","fields":["name","oneway","maxspeed","lanes","surface","structure","maxheight","cycleway","access"],"geometry":["line"],"tags":{"highway":"residential"},"terms":[],"name":"Residential Road"},"highway/rest_area":{"icon":"car","fields":["name"],"geometry":["point","vertex","area"],"tags":{"highway":"rest_area"},"terms":["rest stop"],"name":"Rest Area"},"highway/road":{"icon":"highway-road","fields":["name","oneway","maxspeed","lanes","surface","structure","maxheight","access"],"geometry":["line"],"tags":{"highway":"road"},"terms":[],"name":"Unknown Road"},"highway/secondary_link":{"icon":"highway-secondary-link","fields":["name","oneway","maxspeed","lanes","surface","structure","maxheight","ref_road_number","cycleway","access"],"geometry":["line"],"tags":{"highway":"secondary_link"},"terms":["ramp","on ramp","off ramp"],"name":"Secondary Link"},"highway/secondary":{"icon":"highway-secondary","fields":["name","oneway","maxspeed","lanes","surface","structure","maxheight","ref_road_number","cycleway","access"],"geometry":["line"],"tags":{"highway":"secondary"},"terms":[],"name":"Secondary Road"},"highway/service":{"icon":"highway-service","fields":["name","service","oneway","maxspeed","surface","structure","maxheight","access"],"geometry":["line"],"tags":{"highway":"service"},"terms":[],"name":"Service Road"},"highway/service/alley":{"icon":"highway-service","fields":["name","oneway","maxspeed","structure","access","surface","maxheight"],"geometry":["line"],"tags":{"highway":"service","service":"alley"},"reference":{"key":"service","value":"alley"},"name":"Alley"},"highway/service/drive-through":{"icon":"highway-service","fields":["name","oneway","covered","maxheight","maxspeed","structure","access","surface"],"geometry":["line"],"tags":{"highway":"service","service":"drive-through"},"reference":{"key":"service","value":"drive-through"},"name":"Drive-Through"},"highway/service/driveway":{"icon":"highway-service","fields":["name","oneway","maxspeed","structure","access","surface","maxheight"],"geometry":["line"],"tags":{"highway":"service","service":"driveway"},"reference":{"key":"service","value":"driveway"},"name":"Driveway"},"highway/service/emergency_access":{"icon":"highway-service","fields":["name","oneway","maxspeed","structure","access","surface","maxheight"],"geometry":["line"],"tags":{"highway":"service","service":"emergency_access"},"reference":{"key":"service","value":"emergency_access"},"name":"Emergency Access"},"highway/service/parking_aisle":{"icon":"highway-service","fields":["name","oneway","maxspeed","structure","access","surface","maxheight"],"geometry":["line"],"tags":{"highway":"service","service":"parking_aisle"},"reference":{"key":"service","value":"parking_aisle"},"name":"Parking Aisle"},"highway/services":{"icon":"car","fields":["name"],"geometry":["point","vertex","area"],"tags":{"highway":"services"},"terms":["services","travel plaza","service station"],"name":"Service Area"},"highway/speed_camera":{"icon":"attraction","geometry":["point","vertex"],"fields":["direction","ref"],"tags":{"highway":"speed_camera"},"terms":[],"name":"Speed Camera"},"highway/steps":{"icon":"highway-steps","fields":["surface","lit","width","incline_steps","handrail","step_count"],"geometry":["line"],"tags":{"highway":"steps"},"terms":["stairs","staircase"],"name":"Steps"},"highway/stop":{"icon":"poi-stop","fields":["stop","direction_vertex"],"geometry":["vertex"],"tags":{"highway":"stop"},"terms":["stop","halt","sign"],"name":"Stop Sign"},"highway/street_lamp":{"icon":"poi-bulb","geometry":["point","vertex"],"tags":{"highway":"street_lamp"},"fields":["lamp_type","direction","ref"],"terms":["streetlight","street light","lamp","light","gaslight"],"name":"Street Lamp"},"highway/tertiary_link":{"icon":"highway-tertiary-link","fields":["name","oneway","maxspeed","lanes","surface","structure","maxheight","ref_road_number","cycleway","access"],"geometry":["line"],"tags":{"highway":"tertiary_link"},"terms":["ramp","on ramp","off ramp"],"name":"Tertiary Link"},"highway/tertiary":{"icon":"highway-tertiary","fields":["name","oneway","maxspeed","lanes","surface","structure","maxheight","ref_road_number","cycleway","access"],"geometry":["line"],"tags":{"highway":"tertiary"},"terms":[],"name":"Tertiary Road"},"highway/track":{"icon":"highway-track","fields":["name","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","vertex"],"fields":["direction"],"tags":{"highway":"traffic_mirror"},"terms":["blind spot","convex","corner","curved","roadside","round","safety","sphere","visibility"],"name":"Traffic Mirror"},"highway/traffic_signals":{"icon":"poi-traffic-signals","geometry":["vertex"],"tags":{"highway":"traffic_signals"},"fields":["traffic_signals","traffic_signals/direction"],"terms":["light","stoplight","traffic light"],"name":"Traffic Signals"},"highway/trunk_link":{"icon":"highway-trunk-link","fields":["name","ref_road_number","oneway","maxspeed","lanes","surface","structure","maxheight","access"],"geometry":["line"],"tags":{"highway":"trunk_link"},"terms":["ramp","on ramp","off ramp"],"name":"Trunk Link"},"highway/trunk":{"icon":"highway-trunk","fields":["name","ref_road_number","oneway","maxspeed","lanes","surface","structure","maxheight","toll","access"],"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":["name","oneway","maxspeed","lanes","surface","structure","maxheight","cycleway","access"],"geometry":["line"],"tags":{"highway":"unclassified"},"terms":[],"name":"Minor/Unclassified Road"},"historic":{"icon":"poi-ruins","fields":["historic","inscription"],"geometry":["point","vertex","area"],"tags":{"historic":"*"},"name":"Historic Site"},"historic/archaeological_site":{"icon":"poi-ruins","fields":["name","historic/civilization","inscription"],"geometry":["point","vertex","area"],"tags":{"historic":"archaeological_site"},"name":"Archaeological Site"},"historic/boundary_stone":{"icon":"poi-milestone","fields":["name","inscription"],"geometry":["point","vertex"],"tags":{"historic":"boundary_stone"},"name":"Boundary Stone"},"historic/castle":{"icon":"castle","fields":["name","castle_type","building_area","historic/civilization"],"geometry":["point","area"],"tags":{"historic":"castle"},"name":"Castle"},"historic/memorial":{"icon":"monument","fields":["name","memorial","inscription"],"geometry":["point","vertex","area"],"tags":{"historic":"memorial"},"name":"Memorial"},"historic/monument":{"icon":"monument","fields":["name","inscription"],"geometry":["point","vertex","area"],"tags":{"historic":"monument"},"name":"Monument"},"historic/ruins":{"icon":"poi-ruins","fields":["name","historic/civilization","inscription"],"geometry":["point","vertex","area"],"tags":{"historic":"ruins"},"name":"Ruins"},"historic/tomb":{"icon":"cemetery","fields":["name","tomb","building_area","inscription"],"geometry":["point","area"],"tags":{"historic":"tomb"},"name":"Tomb"},"historic/wayside_cross":{"icon":"religious-christian","fields":["name","inscription"],"geometry":["point","vertex","area"],"tags":{"historic":"wayside_cross"},"name":"Wayside Cross"},"historic/wayside_shrine":{"icon":"landmark","fields":["name","inscription"],"geometry":["point","vertex","area"],"tags":{"historic":"wayside_shrine"},"name":"Wayside Shrine"},"junction":{"icon":"poi-junction","fields":["name"],"geometry":["vertex","area"],"tags":{"junction":"yes"},"name":"Junction"},"landuse":{"fields":["name","landuse"],"geometry":["area"],"tags":{"landuse":"*"},"matchScore":0.9,"name":"Land Use"},"landuse/farm":{"icon":"farm","fields":["name","operator","crop"],"geometry":["point","area"],"tags":{"landuse":"farm"},"terms":[],"name":"Farmland","searchable":false},"landuse/allotments":{"geometry":["area"],"fields":["name"],"tags":{"landuse":"allotments"},"terms":["allotment","garden"],"name":"Community Garden"},"landuse/aquaculture":{"icon":"aquarium","fields":["name","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","fields":["name"],"geometry":["area"],"tags":{"landuse":"basin"},"terms":[],"name":"Basin"},"landuse/brownfield":{"geometry":["area"],"fields":["name"],"tags":{"landuse":"brownfield"},"terms":[],"matchScore":0.9,"name":"Brownfield"},"landuse/cemetery":{"icon":"cemetery","fields":["name","religion","denomination"],"geometry":["area"],"tags":{"landuse":"cemetery"},"terms":[],"name":"Cemetery"},"landuse/churchyard":{"fields":["name","religion","denomination"],"geometry":["area"],"tags":{"landuse":"churchyard"},"terms":[],"name":"Churchyard"},"landuse/commercial":{"icon":"suitcase","fields":["name"],"geometry":["area"],"tags":{"landuse":"commercial"},"terms":[],"matchScore":0.9,"name":"Commercial Area"},"landuse/construction":{"fields":["name","construction","operator"],"geometry":["area"],"tags":{"landuse":"construction"},"terms":[],"name":"Construction"},"landuse/farmland":{"icon":"farm","fields":["name","operator","crop","produce"],"geometry":["area"],"tags":{"landuse":"farmland"},"terms":["crop","grow","plant"],"name":"Farmland"},"landuse/farmyard":{"icon":"farm","fields":["name","operator","crop"],"geometry":["area"],"tags":{"landuse":"farmyard"},"terms":["crop","grow","plant"],"name":"Farmyard"},"landuse/forest":{"icon":"park-alt1","fields":["name","leaf_type","leaf_cycle","produce"],"geometry":["area"],"tags":{"landuse":"forest"},"terms":["tree"],"name":"Forest"},"landuse/garages":{"geometry":["area"],"fields":["name"],"tags":{"landuse":"garages"},"terms":[],"name":"Garage Landuse"},"landuse/grass":{"geometry":["area"],"tags":{"landuse":"grass"},"terms":[],"name":"Grass"},"landuse/greenfield":{"geometry":["area"],"fields":["name"],"tags":{"landuse":"greenfield"},"terms":[],"matchScore":0.9,"name":"Greenfield"},"landuse/greenhouse_horticulture":{"icon":"garden","fields":["name","operator"],"geometry":["area"],"terms":["flower","greenhouse","horticulture","grow","vivero"],"tags":{"landuse":"greenhouse_horticulture"},"matchScore":0.9,"name":"Greenhouse Horticulture"},"landuse/harbour":{"icon":"harbor","fields":["name","operator"],"geometry":["area"],"terms":["boat"],"tags":{"landuse":"harbour"},"name":"Harbor"},"landuse/industrial":{"icon":"industry","fields":["name"],"geometry":["area"],"tags":{"landuse":"industrial"},"terms":[],"matchScore":0.9,"name":"Industrial Area"},"landuse/industrial/scrap_yard":{"icon":"car","fields":["name","operator","address","opening_hours"],"geometry":["point","area"],"tags":{"industrial":"scrap_yard"},"addTags":{"landuse":"industrial","industrial":"scrap_yard"},"removeTags":{"landuse":"industrial","industrial":"scrap_yard"},"reference":{"key":"industrial","value":"scrap_yard"},"terms":["car","junk","metal","salvage","scrap","u-pull-it","vehicle","wreck","yard"],"name":"Scrap Yard"},"landuse/industrial/slaughterhouse":{"icon":"slaughterhouse","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"industrial":"slaughterhouse"},"addTags":{"landuse":"industrial","industrial":"slaughterhouse"},"removeTags":{"landuse":"industrial","industrial":"slaughterhouse"},"reference":{"key":"industrial","value":"slaughterhouse"},"terms":["abattoir","beef","butchery","calf","chicken","cow","killing house","meat","pig","pork","poultry","shambles","stockyard"],"name":"Slaughterhouse"},"landuse/landfill":{"geometry":["area"],"fields":["name"],"tags":{"landuse":"landfill"},"terms":["dump"],"name":"Landfill"},"landuse/meadow":{"icon":"garden","geometry":["area"],"fields":["name"],"tags":{"landuse":"meadow"},"terms":[],"name":"Meadow"},"landuse/military":{"icon":"poi-military","fields":["name"],"geometry":["area"],"tags":{"landuse":"military"},"terms":[],"matchScore":0.9,"name":"Military Area"},"landuse/military/airfield":{"icon":"airfield","fields":["name","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":{"icon":"poi-military","fields":["name","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":{"icon":"poi-military","fields":["name","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":{"icon":"barrier","fields":["name"],"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","fields":["name"],"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":{"icon":"poi-military","fields":["name"],"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","fields":["name"],"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":{"icon":"poi-military","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":{"icon":"poi-military","fields":["name","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":{"icon":"poi-military","fields":["name"],"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":{"icon":"poi-military","fields":["name"],"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":["name","operator","trees"],"geometry":["area"],"tags":{"landuse":"orchard"},"terms":["fruit"],"name":"Orchard"},"landuse/plant_nursery":{"icon":"garden","fields":["name","operator","plant"],"geometry":["area"],"tags":{"landuse":"plant_nursery"},"terms":["flower","garden","grow","vivero"],"name":"Plant Nursery"},"landuse/quarry":{"geometry":["area"],"fields":["name"],"tags":{"landuse":"quarry"},"terms":[],"name":"Quarry"},"landuse/railway":{"icon":"rail","fields":["operator"],"geometry":["area"],"tags":{"landuse":"railway"},"terms":["rail","train","track"],"name":"Railway Corridor"},"landuse/recreation_ground":{"icon":"pitch","geometry":["area"],"fields":["name"],"tags":{"landuse":"recreation_ground"},"terms":["playing fields"],"name":"Recreation Ground"},"landuse/religious":{"geometry":["area"],"fields":["name","religion","denomination"],"tags":{"landuse":"religious"},"terms":[],"name":"Religious Area"},"landuse/residential":{"icon":"building","geometry":["area"],"tags":{"landuse":"residential"},"terms":[],"matchScore":0.9,"name":"Residential Area"},"landuse/retail":{"icon":"commercial","geometry":["area"],"fields":["name"],"tags":{"landuse":"retail"},"matchScore":0.9,"name":"Retail Area"},"landuse/vineyard":{"fields":["name","operator","grape_variety"],"geometry":["area"],"tags":{"landuse":"vineyard"},"addTags":{"landuse":"vineyard","crop":"grape"},"removeTags":{"landuse":"vineyard","crop":"grape","grape_variety":"*"},"terms":["grape","wine"],"name":"Vineyard"},"leisure":{"icon":"pitch","fields":["name","leisure"],"geometry":["point","vertex","area"],"tags":{"leisure":"*"},"name":"Leisure"},"leisure/adult_gaming_centre":{"icon":"poi-dice","fields":["name","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":{"icon":"poi-binoculars","fields":["building_area"],"geometry":["point","area"],"tags":{"leisure":"bird_hide"},"terms":["machan","ornithology"],"name":"Bird Hide"},"leisure/bowling_alley":{"icon":"poi-bowling","fields":["name","operator","address","building_area","opening_hours","smoking"],"geometry":["point","area"],"terms":["bowling center"],"tags":{"leisure":"bowling_alley"},"name":"Bowling Alley"},"leisure/common":{"icon":"poi-foot","geometry":["point","area"],"fields":["name"],"terms":["open space"],"tags":{"leisure":"common"},"name":"Common"},"leisure/dance":{"icon":"music","fields":["name","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"],"fields":["name"],"terms":[],"tags":{"leisure":"dog_park"},"name":"Dog Park"},"leisure/firepit":{"icon":"fire-station","geometry":["point","area"],"tags":{"leisure":"firepit"},"terms":["fireplace","campfire"],"name":"Firepit"},"leisure/fitness_centre":{"icon":"pitch","fields":["name","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":["name","sport","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["studio"],"tags":{"leisure":"fitness_centre","sport":"yoga"},"reference":{"key":"sport","value":"yoga"},"name":"Yoga Studio"},"leisure/fitness_station":{"icon":"pitch","fields":["fitness_station","ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station"},"addTags":{"leisure":"fitness_station","sport":"fitness"},"removeTags":{"leisure":"fitness_station","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["exercise","fitness","gym","trim trail"],"name":"Outdoor Fitness Station"},"leisure/fitness_station/balance_beam":{"icon":"pitch","fields":["ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station","fitness_station":"balance_beam"},"addTags":{"leisure":"fitness_station","fitness_station":"balance_beam","sport":"fitness"},"removeTags":{"leisure":"fitness_station","fitness_station":"balance_beam","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["balance","exercise","fitness","gym","trim trail"],"name":"Exercise Balance Beam"},"leisure/fitness_station/box":{"icon":"pitch","fields":["ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station","fitness_station":"box"},"addTags":{"leisure":"fitness_station","fitness_station":"box","sport":"fitness"},"removeTags":{"leisure":"fitness_station","fitness_station":"box","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["box","exercise","fitness","gym","jump","trim trail"],"name":"Exercise Box"},"leisure/fitness_station/horizontal_bar":{"icon":"pitch","fields":["ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station","fitness_station":"horizontal_bar"},"addTags":{"leisure":"fitness_station","fitness_station":"horizontal_bar","sport":"fitness"},"removeTags":{"leisure":"fitness_station","fitness_station":"horizontal_bar","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["bar","chinup","chin up","exercise","fitness","gym","pullup","pull up","trim trail"],"name":"Exercise Horizontal Bar"},"leisure/fitness_station/horizontal_ladder":{"icon":"pitch","fields":["ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station","fitness_station":"horizontal_ladder"},"addTags":{"leisure":"fitness_station","fitness_station":"horizontal_ladder","sport":"fitness"},"removeTags":{"leisure":"fitness_station","fitness_station":"horizontal_ladder","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["bar","chinup","chin up","exercise","fitness","gym","ladder","monkey bars","pullup","pull up","trim trail"],"name":"Exercise Monkey Bars"},"leisure/fitness_station/hyperextension":{"icon":"pitch","fields":["ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station","fitness_station":"hyperextension"},"addTags":{"leisure":"fitness_station","fitness_station":"hyperextension","sport":"fitness"},"removeTags":{"leisure":"fitness_station","fitness_station":"hyperextension","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["back","exercise","extension","fitness","gym","roman chair","trim trail"],"name":"Hyperextension Station"},"leisure/fitness_station/parallel_bars":{"icon":"pitch","fields":["ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station","fitness_station":"parallel_bars"},"addTags":{"leisure":"fitness_station","fitness_station":"parallel_bars","sport":"fitness"},"removeTags":{"leisure":"fitness_station","fitness_station":"parallel_bars","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["bar","dip","exercise","fitness","gym","trim trail"],"name":"Parallel Bars"},"leisure/fitness_station/push-up":{"icon":"pitch","fields":["ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station","fitness_station":"push-up"},"addTags":{"leisure":"fitness_station","fitness_station":"push-up","sport":"fitness"},"removeTags":{"leisure":"fitness_station","fitness_station":"push-up","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["bar","exercise","fitness","gym","pushup","push up","trim trail"],"name":"Push-Up Station"},"leisure/fitness_station/rings":{"icon":"pitch","fields":["ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station","fitness_station":"rings"},"addTags":{"leisure":"fitness_station","fitness_station":"rings","sport":"fitness"},"removeTags":{"leisure":"fitness_station","fitness_station":"rings","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["exercise","fitness","gym","muscle up","pullup","pull up","trim trail"],"name":"Exercise Rings"},"leisure/fitness_station/sign":{"icon":"pitch","fields":["ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station","fitness_station":"sign"},"addTags":{"leisure":"fitness_station","fitness_station":"sign","sport":"fitness"},"removeTags":{"leisure":"fitness_station","fitness_station":"sign","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["exercise","fitness","gym","trim trail"],"name":"Exercise Instruction Sign"},"leisure/fitness_station/sit-up":{"icon":"pitch","fields":["ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station","fitness_station":"sit-up"},"addTags":{"leisure":"fitness_station","fitness_station":"sit-up","sport":"fitness"},"removeTags":{"leisure":"fitness_station","fitness_station":"sit-up","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["crunch","exercise","fitness","gym","situp","sit up","trim trail"],"name":"Sit-Up Station"},"leisure/fitness_station/stairs":{"icon":"pitch","fields":["ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station","fitness_station":"stairs"},"addTags":{"leisure":"fitness_station","fitness_station":"stairs","sport":"fitness"},"removeTags":{"leisure":"fitness_station","fitness_station":"stairs","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["exercise","fitness","gym","steps","trim trail"],"name":"Exercise Stairs"},"leisure/garden":{"icon":"garden","fields":["name","access_simple"],"geometry":["point","vertex","area"],"tags":{"leisure":"garden"},"name":"Garden"},"leisure/golf_course":{"icon":"golf","fields":["name","operator","address","opening_hours"],"geometry":["point","area"],"terms":["links"],"tags":{"leisure":"golf_course"},"name":"Golf Course"},"leisure/hackerspace":{"icon":"commercial","fields":["name","address","building_area","opening_hours","website"],"geometry":["point","area"],"terms":["makerspace","hackspace","hacklab"],"tags":{"leisure":"hackerspace"},"name":"Hackerspace"},"leisure/horse_riding":{"icon":"horse-riding","fields":["name","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":["name","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":["name","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":["name","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"],"fields":["name"],"tags":{"leisure":"nature_reserve"},"terms":["protected","wildlife"],"name":"Nature Reserve"},"leisure/park":{"icon":"park","geometry":["point","area"],"fields":["name"],"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"},"reference":{"key":"sport","value":"american_football"},"terms":[],"name":"American Football Field"},"leisure/pitch/baseball":{"icon":"baseball","fields":["lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"baseball"},"reference":{"key":"sport","value":"baseball"},"terms":[],"name":"Baseball Diamond"},"leisure/pitch/basketball":{"icon":"basketball","fields":["surface","hoops","lit","access_simple"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"basketball"},"reference":{"key":"sport","value":"basketball"},"terms":[],"name":"Basketball Court"},"leisure/pitch/beachvolleyball":{"icon":"basketball","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"beachvolleyball"},"addTags":{"leisure":"pitch","sport":"beachvolleyball","surface":"sand"},"removeTags":{"leisure":"pitch","sport":"beachvolleyball","surface":"sand"},"reference":{"key":"sport","value":"beachvolleyball"},"terms":["volleyball"],"name":"Beach Volleyball Court"},"leisure/pitch/boules":{"icon":"pitch","fields":["boules","surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"boules"},"reference":{"key":"sport","value":"boules"},"terms":["bocce","lyonnaise","pétanque"],"name":"Boules/Bocce Court"},"leisure/pitch/bowls":{"icon":"pitch","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"bowls"},"reference":{"key":"sport","value":"bowls"},"terms":[],"name":"Bowling Green"},"leisure/pitch/cricket":{"icon":"cricket","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"cricket"},"reference":{"key":"sport","value":"cricket"},"terms":[],"name":"Cricket Field"},"leisure/pitch/equestrian":{"icon":"horse-riding","fields":["surface","lit","building"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"equestrian"},"reference":{"key":"sport","value":"equestrian"},"terms":["dressage","equestrian","horse","horseback","riding"],"name":"Riding Arena"},"leisure/pitch/rugby_league":{"icon":"america-football","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"rugby_league"},"reference":{"key":"sport","value":"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"},"reference":{"key":"sport","value":"rugby_union"},"terms":[],"name":"Rugby Union Field"},"leisure/pitch/skateboard":{"icon":"pitch","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"skateboard"},"reference":{"key":"sport","value":"skateboard"},"terms":[],"name":"Skate Park"},"leisure/pitch/soccer":{"icon":"soccer","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"soccer"},"reference":{"key":"sport","value":"soccer"},"terms":["football"],"name":"Soccer Field"},"leisure/pitch/table_tennis":{"icon":"tennis","fields":["lit","access_simple"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"table_tennis"},"reference":{"key":"sport","value":"table_tennis"},"terms":["table tennis","ping pong"],"name":"Ping Pong Table"},"leisure/pitch/tennis":{"icon":"tennis","fields":["surface","lit","access_simple"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"tennis"},"reference":{"key":"sport","value":"tennis"},"terms":[],"name":"Tennis Court"},"leisure/pitch/volleyball":{"icon":"basketball","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"volleyball"},"reference":{"key":"sport","value":"volleyball"},"terms":[],"name":"Volleyball Court"},"leisure/playground":{"icon":"playground","fields":["name","operator","surface","playground/max_age","playground/min_age","access_simple"],"geometry":["point","area"],"terms":["jungle gym","play area"],"tags":{"leisure":"playground"},"name":"Playground"},"leisure/resort":{"icon":"lodging","fields":["name","operator","address","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"resort"},"name":"Resort"},"leisure/running_track":{"icon":"pitch","fields":["surface","sport_racing_nonmotor","lit","width","lanes"],"geometry":["point","line","area"],"tags":{"leisure":"track","sport":"running"},"terms":["race*","running","sprint","track"],"name":"Racetrack (Running)"},"leisure/sauna":{"fields":["name","operator","address","opening_hours","access_simple","fee"],"geometry":["point","area"],"tags":{"leisure":"sauna"},"name":"Sauna"},"leisure/slipway":{"icon":"poi-beach","geometry":["point","line"],"terms":["boat launch","boat ramp"],"tags":{"leisure":"slipway"},"name":"Slipway"},"leisure/sports_centre":{"icon":"pitch","fields":["name","sport","building","address","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"sports_centre"},"terms":[],"name":"Sports Center / Complex"},"leisure/sports_centre/swimming":{"icon":"swimming","fields":["name","access_simple","operator","address","building"],"geometry":["point","area"],"terms":["dive","water"],"tags":{"leisure":"sports_centre","sport":"swimming"},"reference":{"key":"sport","value":"swimming"},"name":"Swimming Pool Facility"},"leisure/stadium":{"icon":"pitch","fields":["name","sport","address"],"geometry":["point","area"],"tags":{"leisure":"stadium"},"name":"Stadium"},"leisure/swimming_pool":{"icon":"swimming","fields":["name","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_nonmotor","lit","width","lanes"],"geometry":["point","line","area"],"tags":{"leisure":"track"},"terms":["cycle","dog","greyhound","horse","race*","track"],"name":"Racetrack (Non-Motorsport)"},"leisure/water_park":{"icon":"swimming","fields":["name","operator","address"],"geometry":["point","area"],"terms":["swim","pool","dive"],"tags":{"leisure":"water_park"},"name":"Water Park"},"line":{"fields":["name"],"geometry":["line"],"tags":{},"name":"Line","matchScore":0.1},"man_made":{"icon":"poi-storage-tank","fields":["name","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":{"icon":"triangle","geometry":["point","area"],"fields":["operator","direction"],"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":{"icon":"poi-chimney","geometry":["point","area"],"tags":{"man_made":"chimney"},"name":"Chimney"},"man_made/crane":{"icon":"poi-crane","fields":["operator","height","crane/type"],"geometry":["point","line","vertex","area"],"tags":{"man_made":"crane"},"name":"Crane"},"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":{"icon":"poi-storage-tank","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":{"icon":"poi-mast","fields":["tower/type","tower/construction","height","communication_multi"],"geometry":["point"],"terms":["antenna","broadcast tower","cell phone tower","cell tower","communication mast","communication tower","guyed tower","mobile phone tower","radio mast","radio tower","television tower","transmission mast","transmission tower","tv tower"],"tags":{"man_made":"mast"},"name":"Mast"},"man_made/monitoring_station":{"icon":"poi-mast","geometry":["point","area"],"fields":["monitoring_multi","operator"],"terms":["weather","earthquake","seismology","air","gps"],"tags":{"man_made":"monitoring_station"},"name":"Monitoring Station"},"man_made/observation":{"icon":"poi-tower","geometry":["point","area"],"terms":["lookout tower","fire tower"],"tags":{"man_made":"tower","tower:type":"observation"},"name":"Observation Tower"},"man_made/petroleum_well":{"icon":"poi-storage-tank","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","jetty"],"tags":{"man_made":"pier"},"name":"Pier"},"man_made/pipeline":{"icon":"pipeline-line","fields":["location","operator","substance"],"geometry":["line"],"tags":{"man_made":"pipeline"},"name":"Pipeline"},"man_made/pumping_station":{"icon":"water","geometry":["point","area"],"tags":{"man_made":"pumping_station"},"name":"Pumping Station"},"man_made/silo":{"icon":"poi-silo","fields":["building_area","crop"],"geometry":["point","area"],"terms":["grain","corn","wheat"],"tags":{"man_made":"silo"},"name":"Silo"},"man_made/storage_tank":{"icon":"poi-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","vertex"],"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","vertex"],"fields":["surveillance","surveillance/type","surveillance/zone","direction"],"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"],"terms":["trig point","triangulation pillar","trigonometrical station"],"tags":{"man_made":"survey_point"},"name":"Survey Point"},"man_made/tower":{"icon":"poi-tower","fields":["tower/type","tower/construction","height"],"geometry":["point","area"],"tags":{"man_made":"tower"},"name":"Tower"},"man_made/wastewater_plant":{"icon":"water","fields":["name","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":["name","operator","address"],"geometry":["point","area"],"tags":{"man_made":"water_works"},"name":"Water Works"},"man_made/watermill":{"icon":"buddhism","fields":["building_area"],"geometry":["point","area"],"terms":["water","wheel","mill"],"tags":{"man_made":"watermill"},"name":"Watermill"},"man_made/windmill":{"icon":"poi-windmill","fields":["building_area"],"geometry":["point","area"],"terms":["wind","wheel","mill"],"tags":{"man_made":"windmill"},"name":"Windmill"},"man_made/works":{"icon":"industry","fields":["name","operator","address","building_area","product"],"geometry":["point","area"],"terms":["assembly","build","brewery","car","plant","plastic","processing","manufacture","refinery"],"tags":{"man_made":"works"},"name":"Factory"},"manhole":{"icon":"circle-stroked","fields":["manhole","operator","label","ref"],"geometry":["point","vertex"],"tags":{"manhole":"*"},"terms":["cover","hole","sewer","sewage","telecom"],"name":"Manhole"},"manhole/drain":{"icon":"water","fields":["operator","ref"],"geometry":["point","vertex"],"tags":{"manhole":"drain"},"terms":["cover","drain","hole","rain","sewer","sewage","storm"],"name":"Storm Drain"},"manhole/telecom":{"icon":"circle-stroked","fields":["operator","ref"],"geometry":["point","vertex"],"tags":{"manhole":"telecom"},"terms":["cover","phone","hole","telecom","telephone","bt"],"name":"Telecom Manhole"},"natural":{"icon":"natural","fields":["name","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":{"icon":"poi-beach","geometry":["point","area"],"fields":["name"],"tags":{"natural":"bay"},"terms":[],"name":"Bay"},"natural/beach":{"icon":"poi-beach","fields":["surface"],"geometry":["point","area"],"tags":{"natural":"beach"},"terms":["shore"],"name":"Beach"},"natural/cave_entrance":{"icon":"triangle","geometry":["point","area"],"fields":["fee","access_simple","direction"],"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":["name","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":{"icon":"water","fields":["name","intermittent"],"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":["name","elevation","volcano/status","volcano/type"],"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","fields":["name","intermittent"],"geometry":["area"],"tags":{"natural":"water","water":"lake"},"reference":{"key":"natural","value":"water"},"terms":["lakelet","loch","mere"],"name":"Lake"},"natural/water/pond":{"icon":"water","fields":["name","intermittent"],"geometry":["area"],"tags":{"natural":"water","water":"pond"},"reference":{"key":"natural","value":"water"},"terms":["lakelet","millpond","tarn","pool","mere"],"name":"Pond"},"natural/water/reservoir":{"icon":"water","fields":["name","intermittent"],"geometry":["area"],"tags":{"natural":"water","water":"reservoir"},"reference":{"key":"natural","value":"water"},"name":"Reservoir"},"natural/wetland":{"icon":"wetland","fields":["wetland"],"geometry":["point","area"],"tags":{"natural":"wetland"},"terms":["bog","marsh","reedbed","swamp","tidalflat"],"name":"Wetland"},"natural/wood":{"icon":"park-alt1","fields":["name","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"},"reference":{"key":"noexit","value":"*"},"name":"No Exit"},"office":{"icon":"suitcase","fields":["name","office","address","building_area","opening_hours","smoking"],"geometry":["point","vertex","area"],"tags":{"office":"*"},"terms":[],"name":"Office"},"office/administrative":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"administrative"},"terms":[],"searchable":false,"name":"Administrative Office"},"office/physician":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"physician"},"searchable":false,"name":"Physician"},"office/travel_agent":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"travel_agent"},"reference":{"key":"shop","value":"travel_agency"},"terms":[],"name":"Travel Agency","searchable":false},"office/accountant":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"accountant"},"terms":[],"name":"Accountant Office"},"office/adoption_agency":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"adoption_agency"},"terms":[],"name":"Adoption Agency"},"office/advertising_agency":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"advertising_agency"},"terms":["ad","ad agency","advert agency","advertising","marketing"],"name":"Advertising Agency"},"office/architect":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"architect"},"terms":[],"name":"Architect Office"},"office/association":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"association"},"terms":["association","non-profit","nonprofit","organization","society"],"name":"Nonprofit Organization Office"},"office/charity":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"charity"},"terms":["charitable organization"],"name":"Charity Office"},"office/company":{"icon":"suitcase","fields":["name","address","building_area","opening_hours","smoking"],"geometry":["point","area"],"tags":{"office":"company"},"terms":[],"name":"Corporate Office"},"office/coworking":{"icon":"suitcase","fields":["name","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"terms":["coworking","office"],"tags":{"office":"coworking"},"reference":{"key":"amenity","value":"coworking_space"},"name":"Coworking Space"},"office/educational_institution":{"icon":"school","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"educational_institution"},"terms":[],"name":"Educational Institution"},"office/employment_agency":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"employment_agency"},"terms":["job"],"name":"Employment Agency"},"office/energy_supplier":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"energy_supplier"},"terms":["electricity","energy company","energy utility","gas utility"],"name":"Energy Supplier Office"},"office/estate_agent":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"estate_agent"},"terms":[],"name":"Real Estate Office"},"office/financial":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"financial"},"terms":[],"name":"Financial Office"},"office/forestry":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"forestry"},"terms":["forest","ranger"],"name":"Forestry Office"},"office/foundation":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"foundation"},"terms":[],"name":"Foundation Office"},"office/government":{"icon":"town-hall","fields":["name","government","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"government"},"terms":[],"name":"Government Office"},"office/government/register_office":{"icon":"town-hall","fields":["name","address","building_area","opening_hours","operator"],"geometry":["point","area"],"terms":["clerk","marriage","death","birth","certificate"],"tags":{"office":"government","government":"register_office"},"reference":{"key":"government","value":"register_office"},"name":"Register Office"},"office/government/tax":{"icon":"town-hall","fields":["name","address","building_area","opening_hours","operator"],"geometry":["point","area"],"terms":["fiscal authorities","revenue office","tax office"],"tags":{"office":"government","government":"tax"},"reference":{"key":"government","value":"tax"},"name":"Tax and Revenue Office"},"office/guide":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"guide"},"terms":["dive guide","mountain guide","tour guide"],"name":"Tour Guide Office"},"office/insurance":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"insurance"},"terms":[],"name":"Insurance Office"},"office/it":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"it"},"terms":["computer","information","software","technology"],"name":"Information Technology Office"},"office/lawyer":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"lawyer"},"terms":[],"name":"Law Office"},"office/lawyer/notary":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"lawyer","lawyer":"notary"},"reference":{"key":"office","value":"notary"},"searchable":false,"name":"Notary Office"},"office/moving_company":{"icon":"warehouse","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"moving_company"},"terms":["relocation"],"name":"Moving Company Office"},"office/newspaper":{"icon":"library","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"newspaper"},"terms":[],"name":"Newspaper Office"},"office/ngo":{"icon":"suitcase","fields":["name","address","building_area","opening_hours","smoking"],"geometry":["point","area"],"tags":{"office":"ngo"},"terms":["ngo","non government","non-government","organization","organisation"],"name":"NGO Office"},"office/notary":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"notary"},"terms":["clerk","deeds","estate","signature","wills"],"name":"Notary Office"},"office/political_party":{"icon":"town-hall","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"political_party"},"terms":[],"name":"Political Party"},"office/private_investigator":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"private_investigator"},"terms":["PI","private eye","private detective"],"name":"Private Investigator Office"},"office/quango":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"quango"},"terms":["ngo","non government","non-government","organization","organisation","quasi autonomous","quasi-autonomous"],"name":"Quasi-NGO Office"},"office/research":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"research"},"terms":[],"name":"Research Office"},"office/surveyor":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"surveyor"},"terms":[],"name":"Surveyor Office"},"office/tax_advisor":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"tax_advisor"},"terms":["tax","tax consultant"],"name":"Tax Advisor Office"},"office/telecommunication":{"icon":"telephone","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"telecommunication"},"terms":["communication","internet","phone","voice"],"name":"Telecom Office"},"office/therapist":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"therapist"},"terms":["therapy"],"name":"Therapist Office"},"office/water_utility":{"icon":"suitcase","fields":["name","address","building_area","opening_hours","operator"],"geometry":["point","area"],"tags":{"office":"water_utility"},"terms":["water board","utility"],"name":"Water Utility Office"},"piste":{"icon":"skiing","fields":["name","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/farm":{"icon":"farm","geometry":["point","area"],"fields":["name"],"tags":{"place":"farm"},"name":"Farm","searchable":false},"place/city":{"icon":"city","fields":["name","population"],"geometry":["point","area"],"tags":{"place":"city"},"name":"City"},"place/hamlet":{"icon":"triangle-stroked","fields":["name","population"],"geometry":["point","area"],"tags":{"place":"hamlet"},"name":"Hamlet"},"place/island":{"icon":"mountain","geometry":["point","area"],"fields":["name"],"terms":["archipelago","atoll","bar","cay","isle","islet","key","reef"],"tags":{"place":"island"},"name":"Island"},"place/islet":{"icon":"mountain","geometry":["point","area"],"fields":["name"],"terms":["archipelago","atoll","bar","cay","isle","islet","key","reef"],"tags":{"place":"islet"},"name":"Islet"},"place/isolated_dwelling":{"icon":"home","geometry":["point","area"],"fields":["name"],"tags":{"place":"isolated_dwelling"},"name":"Isolated Dwelling"},"place/locality":{"icon":"triangle-stroked","geometry":["point","area"],"fields":["name"],"tags":{"place":"locality"},"name":"Locality"},"place/neighbourhood":{"icon":"triangle-stroked","fields":["name","population"],"geometry":["point","area"],"tags":{"place":"neighbourhood"},"terms":["neighbourhood"],"name":"Neighborhood"},"place/plot":{"icon":"triangle-stroked","fields":["name"],"geometry":["point","area"],"tags":{"place":"plot"},"terms":["tract","land","lot","parcel"],"name":"Plot"},"place/quarter":{"icon":"triangle-stroked","fields":["name","population"],"geometry":["point","area"],"tags":{"place":"quarter"},"terms":["boro","borough","quarter"],"name":"Sub-Borough / Quarter"},"place/square":{"geometry":["point","area"],"fields":["name"],"tags":{"place":"square"},"name":"Square"},"place/suburb":{"icon":"triangle-stroked","fields":["name","population"],"geometry":["point","area"],"tags":{"place":"suburb"},"terms":["boro","borough","quarter"],"name":"Borough / Suburb"},"place/town":{"icon":"town","fields":["name","population"],"geometry":["point","area"],"tags":{"place":"town"},"name":"Town"},"place/village":{"icon":"village","fields":["name","population"],"geometry":["point","area"],"tags":{"place":"village"},"name":"Village"},"playground/balance_beam":{"icon":"playground","geometry":["point","line"],"tags":{"playground":"balancebeam"},"name":"Play Balance Beam"},"playground/basket_spinner":{"icon":"playground","geometry":["point"],"terms":["basket rotator"],"tags":{"playground":"basketrotator"},"name":"Basket Spinner"},"playground/basket_swing":{"icon":"playground","geometry":["point"],"tags":{"playground":"basketswing"},"name":"Basket Swing"},"playground/climbing_frame":{"icon":"playground","geometry":["point","area"],"tags":{"playground":"climbingframe"},"name":"Climbing Frame"},"playground/cushion":{"icon":"playground","geometry":["point","area"],"tags":{"playground":"cushion"},"name":"Bouncy Cushion"},"playground/horizontal_bar":{"icon":"pitch","fields":["height"],"geometry":["point"],"terms":["high bar"],"tags":{"playground":"horizontal_bar"},"name":"Play Horizontal Bar"},"playground/rocker":{"icon":"playground","geometry":["point"],"tags":{"playground":"springy"},"name":"Spring Rider","terms":["spring rocker","springy rocker"]},"playground/roundabout":{"icon":"stadium","fields":["bench"],"geometry":["point","area"],"tags":{"playground":"roundabout"},"name":"Play Roundabout","terms":["merry-go-round"]},"playground/sandpit":{"icon":"playground","geometry":["point","area"],"tags":{"playground":"sandpit"},"name":"Sandpit"},"playground/seesaw":{"icon":"playground","geometry":["point"],"tags":{"playground":"seesaw"},"name":"Seesaw"},"playground/slide":{"icon":"playground","geometry":["point","line"],"tags":{"playground":"slide"},"name":"Slide"},"playground/structure":{"icon":"pitch","geometry":["point","area"],"tags":{"playground":"structure"},"name":"Play Structure"},"playground/swing":{"icon":"playground","fields":["playground/baby","wheelchair"],"geometry":["point"],"tags":{"playground":"swing"},"name":"Swing"},"playground/zipwire":{"icon":"playground","geometry":["point","line"],"tags":{"playground":"zipwire"},"name":"Zip Wire"},"point":{"fields":["name"],"geometry":["point"],"tags":{},"name":"Point","matchScore":0.1},"power/sub_station":{"icon":"poi-power","fields":["substation","operator","building","ref"],"geometry":["point","area"],"tags":{"power":"sub_station"},"reference":{"key":"power","value":"substation"},"name":"Substation","searchable":false},"power/generator":{"icon":"poi-power","fields":["operator","generator/source","generator/method","generator/type","generator/output/electricity","ref"],"geometry":["point","vertex","area"],"terms":["hydro","solar","turbine","wind"],"tags":{"power":"generator"},"name":"Power Generator"},"power/generator/source_nuclear":{"icon":"poi-nuclear","fields":["operator","generator/source","generator/method","generator/type","generator/output/electricity","ref"],"geometry":["point","vertex","area"],"terms":["fission","generator","nuclear","nuke","reactor"],"tags":{"power":"generator","generator:source":"nuclear","generator:method":"fission"},"reference":{"key":"generator:source","value":"nuclear"},"name":"Nuclear Reactor"},"power/generator/source_wind":{"icon":"poi-wind","fields":["operator","generator/source","generator/method","generator/type","generator/output/electricity","height","ref"],"geometry":["point","vertex","area"],"terms":["generator","turbine","windmill","wind"],"tags":{"power":"generator","generator:source":"wind","generator:method":"wind_turbine"},"reference":{"key":"generator:source","value":"wind"},"name":"Wind Turbine"},"power/line":{"icon":"power-line","fields":["name","operator","voltage","ref"],"geometry":["line"],"tags":{"power":"line"},"name":"Power Line"},"power/minor_line":{"icon":"power-line","fields":["name","operator","voltage","ref"],"geometry":["line"],"tags":{"power":"minor_line"},"name":"Minor Power Line"},"power/plant":{"icon":"industry","fields":["name","operator","address","plant/output/electricity","start_date"],"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":{"fields":["ref"],"geometry":["vertex"],"tags":{"power":"pole"},"name":"Power Pole"},"power/substation":{"icon":"poi-power","fields":["substation","operator","building","ref"],"geometry":["point","area"],"tags":{"power":"substation"},"name":"Substation"},"power/switch":{"icon":"poi-power","fields":["switch","operator","location","cables","voltage","ref"],"geometry":["point","vertex","area"],"tags":{"power":"switch"},"name":"Power Switch"},"power/tower":{"fields":["ref"],"geometry":["vertex"],"tags":{"power":"tower"},"name":"High-Voltage Tower"},"power/transformer":{"icon":"poi-power","fields":["transformer","operator","location","rating","devices","phases","frequency","voltage/primary","voltage/secondary","voltage/tertiary","windings","windings/configuration","ref"],"geometry":["point","vertex","area"],"tags":{"power":"transformer"},"name":"Transformer"},"public_transport/linear_platform_aerialway":{"icon":"highway-footway","fields":["name","ref_platform","network","operator","surface","lit","bench","shelter"],"geometry":["line"],"tags":{"public_transport":"platform","aerialway":"yes"},"reference":{"key":"public_transport","value":"platform"},"terms":["aerialway","cable car","platform","public transit","public transportation","transit","transportation"],"name":"Aerialway Stop / Platform"},"public_transport/linear_platform_bus":{"icon":"highway-footway","fields":["name","ref_platform","network","operator","surface","lit","bench","shelter"],"geometry":["line"],"tags":{"public_transport":"platform","bus":"yes"},"addTags":{"public_transport":"platform","bus":"yes","highway":"bus_stop"},"removeTags":{"public_transport":"platform","bus":"yes","highway":"bus_stop"},"reference":{"key":"public_transport","value":"platform"},"terms":["bus","platform","public transit","public transportation","transit","transportation"],"name":"Bus Stop / Platform"},"public_transport/linear_platform_ferry":{"icon":"highway-footway","fields":["name","ref_platform","network","operator","surface","lit","bench","shelter"],"geometry":["line"],"tags":{"public_transport":"platform","ferry":"yes"},"reference":{"key":"public_transport","value":"platform"},"terms":["boat","dock","ferry","pier","platform","public transit","public transportation","transit","transportation"],"name":"Ferry Stop / Platform"},"public_transport/linear_platform_light_rail":{"icon":"highway-footway","fields":["name","ref_platform","network","operator","surface","lit","bench","shelter"],"geometry":["line"],"tags":{"public_transport":"platform","light_rail":"yes"},"addTags":{"public_transport":"platform","light_rail":"yes","railway":"platform"},"removeTags":{"public_transport":"platform","light_rail":"yes","railway":"platform"},"reference":{"key":"railway","value":"platform"},"terms":["electric","light rail","platform","public transit","public transportation","rail","track","tram","trolley","transit","transportation"],"name":"Light Rail Stop / Platform"},"public_transport/linear_platform_monorail":{"icon":"highway-footway","fields":["name","ref_platform","network","operator","surface","lit","bench","shelter"],"geometry":["line"],"tags":{"public_transport":"platform","monorail":"yes"},"addTags":{"public_transport":"platform","monorail":"yes","railway":"platform"},"removeTags":{"public_transport":"platform","monorail":"yes","railway":"platform"},"reference":{"key":"railway","value":"platform"},"terms":["monorail","platform","public transit","public transportation","rail","transit","transportation"],"name":"Monorail Stop / Platform"},"public_transport/linear_platform_subway":{"icon":"highway-footway","fields":["name","ref_platform","network","operator","surface","lit","bench","shelter"],"geometry":["line"],"tags":{"public_transport":"platform","train":"yes"},"addTags":{"public_transport":"platform","train":"yes","railway":"platform"},"removeTags":{"public_transport":"platform","train":"yes","railway":"platform"},"reference":{"key":"railway","value":"platform"},"terms":["metro","platform","public transit","public transportation","rail","subway","track","transit","transportation","underground"],"name":"Subway Stop / Platform"},"public_transport/linear_platform_train":{"icon":"highway-footway","fields":["name","ref_platform","network","operator","surface","lit","bench","shelter"],"geometry":["line"],"tags":{"public_transport":"platform","train":"yes"},"addTags":{"public_transport":"platform","train":"yes","railway":"platform"},"removeTags":{"public_transport":"platform","train":"yes","railway":"platform"},"reference":{"key":"railway","value":"platform"},"terms":["platform","public transit","public transportation","rail","track","train","transit","transportation"],"name":"Train Stop / Platform"},"public_transport/linear_platform_tram":{"icon":"highway-footway","fields":["name","ref_platform","network","operator","surface","lit","bench","shelter"],"geometry":["line"],"tags":{"public_transport":"platform","tram":"yes"},"addTags":{"public_transport":"platform","tram":"yes","railway":"platform"},"removeTags":{"public_transport":"platform","tram":"yes","railway":"platform"},"reference":{"key":"public_transport","value":"platform"},"terms":["electric","light rail","platform","public transit","public transportation","rail","streetcar","track","tram","trolley","transit","transportation"],"name":"Tram Stop / Platform"},"public_transport/linear_platform_trolleybus":{"icon":"highway-footway","fields":["name","ref_platform","network","operator","surface","lit","bench","shelter"],"geometry":["line"],"tags":{"public_transport":"platform","trolleybus":"yes"},"addTags":{"public_transport":"platform","trolleybus":"yes","highway":"bus_stop"},"removeTags":{"public_transport":"platform","trolleybus":"yes","highway":"bus_stop"},"reference":{"key":"public_transport","value":"platform"},"terms":["bus","electric","platform","public transit","public transportation","streetcar","trackless","tram","trolley","transit","transportation"],"name":"Trolleybus Stop / Platform"},"public_transport/linear_platform":{"icon":"highway-footway","fields":["name","ref_platform","network","operator","surface","lit","bench","shelter"],"geometry":["line"],"tags":{"public_transport":"platform"},"terms":["platform","public transit","public transportation","transit","transportation"],"name":"Transit Stop / Platform","matchScore":0.2},"public_transport/platform_aerialway":{"icon":"aerialway","fields":["name","ref_platform","network","operator","surface","lit","bench","shelter"],"geometry":["point","area"],"tags":{"public_transport":"platform","aerialway":"yes"},"reference":{"key":"public_transport","value":"platform"},"terms":["aerialway","cable car","platform","public transit","public transportation","transit","transportation"],"name":"Aerialway Stop / Platform"},"public_transport/platform_bus":{"icon":"bus","fields":["name","ref_platform","network","operator","surface","lit","bench","shelter"],"geometry":["point","area"],"tags":{"public_transport":"platform","bus":"yes"},"addTags":{"public_transport":"platform","bus":"yes","highway":"bus_stop"},"removeTags":{"public_transport":"platform","bus":"yes","highway":"bus_stop"},"reference":{"key":"public_transport","value":"platform"},"terms":["bus","platform","public transit","public transportation","transit","transportation"],"name":"Bus Stop / Platform"},"public_transport/platform_ferry":{"icon":"ferry","fields":["name","ref_platform","network","operator","surface","lit","bench","shelter"],"geometry":["point","area"],"tags":{"public_transport":"platform","ferry":"yes"},"reference":{"key":"public_transport","value":"platform"},"terms":["boat","dock","ferry","pier","platform","public transit","public transportation","transit","transportation"],"name":"Ferry Stop / Platform"},"public_transport/platform_light_rail":{"icon":"poi-light-rail","fields":["name","ref_platform","network","operator","surface","lit","bench","shelter"],"geometry":["point","area"],"tags":{"public_transport":"platform","light_rail":"yes"},"addTags":{"public_transport":"platform","light_rail":"yes","railway":"platform"},"removeTags":{"public_transport":"platform","light_rail":"yes","railway":"platform"},"reference":{"key":"railway","value":"platform"},"terms":["electric","light rail","platform","public transit","public transportation","rail","track","tram","trolley","transit","transportation"],"name":"Light Rail Stop / Platform"},"public_transport/platform_monorail":{"icon":"poi-monorail","fields":["name","ref_platform","network","operator","surface","lit","bench","shelter"],"geometry":["point","area"],"tags":{"public_transport":"platform","monorail":"yes"},"addTags":{"public_transport":"platform","monorail":"yes","railway":"platform"},"removeTags":{"public_transport":"platform","monorail":"yes","railway":"platform"},"reference":{"key":"railway","value":"platform"},"terms":["monorail","platform","public transit","public transportation","rail","transit","transportation"],"name":"Monorail Stop / Platform"},"public_transport/platform_subway":{"icon":"poi-subway","fields":["name","ref_platform","network","operator","surface","lit","bench","shelter"],"geometry":["point","area"],"tags":{"public_transport":"platform","train":"yes"},"addTags":{"public_transport":"platform","train":"yes","railway":"platform"},"removeTags":{"public_transport":"platform","train":"yes","railway":"platform"},"reference":{"key":"railway","value":"platform"},"terms":["metro","platform","public transit","public transportation","rail","subway","track","transit","transportation","underground"],"name":"Subway Stop / Platform"},"public_transport/platform_train":{"icon":"rail","fields":["name","ref_platform","network","operator","surface","lit","bench","shelter"],"geometry":["point","area"],"tags":{"public_transport":"platform","train":"yes"},"addTags":{"public_transport":"platform","train":"yes","railway":"platform"},"removeTags":{"public_transport":"platform","train":"yes","railway":"platform"},"reference":{"key":"railway","value":"platform"},"terms":["platform","public transit","public transportation","rail","track","train","transit","transportation"],"name":"Train Stop / Platform"},"public_transport/platform_tram":{"icon":"poi-tram","fields":["name","ref_platform","network","operator","surface","lit","bench","shelter"],"geometry":["point","area"],"tags":{"public_transport":"platform","tram":"yes"},"addTags":{"public_transport":"platform","tram":"yes","railway":"platform"},"removeTags":{"public_transport":"platform","tram":"yes","railway":"platform"},"reference":{"key":"public_transport","value":"platform"},"terms":["electric","light rail","platform","public transit","public transportation","rail","streetcar","track","tram","trolley","transit","transportation"],"name":"Tram Stop / Platform"},"public_transport/platform_trolleybus":{"icon":"poi-trolleybus","fields":["name","ref_platform","network","operator","surface","lit","bench","shelter"],"geometry":["point","area"],"tags":{"public_transport":"platform","trolleybus":"yes"},"addTags":{"public_transport":"platform","trolleybus":"yes","highway":"bus_stop"},"removeTags":{"public_transport":"platform","trolleybus":"yes","highway":"bus_stop"},"reference":{"key":"public_transport","value":"platform"},"terms":["bus","electric","platform","public transit","public transportation","streetcar","trackless","tram","trolley","transit","transportation"],"name":"Trolleybus Stop / Platform"},"public_transport/platform":{"icon":"bus","fields":["name","ref_platform","network","operator","surface","lit","bench","shelter"],"geometry":["point","area"],"tags":{"public_transport":"platform"},"terms":["platform","public transit","public transportation","transit","transportation"],"name":"Transit Stop / Platform","matchScore":0.2},"public_transport/station_aerialway":{"icon":"aerialway","fields":["name","network","operator","aerialway/access","aerialway/summer/access","elevation","building_area","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"public_transport":"station","aerialway":"yes"},"reference":{"key":"aerialway","value":"station"},"terms":["aerialway","cable car","public transit","public transportation","station","terminal","transit","transportation"],"name":"Aerialway Station"},"public_transport/station_bus":{"icon":"bus","fields":["name","network","operator","address","building_area","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"public_transport":"station","bus":"yes"},"addTags":{"public_transport":"station","bus":"yes","amenity":"bus_station"},"removeTags":{"public_transport":"station","bus":"yes","amenity":"bus_station"},"reference":{"key":"amenity","value":"bus_station"},"terms":["bus","public transit","public transportation","station","terminal","transit","transportation"],"name":"Bus Station / Terminal"},"public_transport/station_ferry":{"icon":"ferry","fields":["name","network","operator","address","building_area","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"public_transport":"station","ferry":"yes"},"addTags":{"public_transport":"station","ferry":"yes","amenity":"ferry_terminal"},"removeTags":{"public_transport":"station","ferry":"yes","amenity":"ferry_terminal"},"reference":{"key":"amenity","value":"ferry_terminal"},"terms":["boat","dock","ferry","pier","public transit","public transportation","station","terminal","transit","transportation"],"name":"Ferry Station / Terminal"},"public_transport/station_light_rail":{"icon":"poi-light-rail","fields":["name","network","operator","address","building_area","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"public_transport":"station","light_rail":"yes"},"addTags":{"public_transport":"station","light_rail":"yes","railway":"station","station":"light_rail"},"removeTags":{"public_transport":"station","light_rail":"yes","railway":"station","station":"light_rail"},"reference":{"key":"station","value":"light_rail"},"terms":["electric","light rail","public transit","public transportation","rail","station","terminal","track","tram","trolley","transit","transportation"],"name":"Light Rail Station"},"public_transport/station_monorail":{"icon":"poi-monorail","fields":["name","network","operator","address","building_area","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"public_transport":"station","monorail":"yes"},"addTags":{"public_transport":"station","monorail":"yes","railway":"station"},"removeTags":{"public_transport":"station","monorail":"yes","railway":"station"},"reference":{"key":"railway","value":"station"},"terms":["monorail","public transit","public transportation","rail","station","terminal","transit","transportation"],"name":"Monorail Station"},"public_transport/station_subway":{"icon":"poi-subway","fields":["name","network","operator","address","building_area","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"public_transport":"station","subway":"yes"},"addTags":{"public_transport":"station","subway":"yes","railway":"station","station":"subway"},"removeTags":{"public_transport":"station","subway":"yes","railway":"station","station":"subway"},"reference":{"key":"station","value":"subway"},"terms":["metro","public transit","public transportation","rail","station","subway","terminal","track","transit","transportation","underground"],"name":"Subway Station"},"public_transport/station_train_halt":{"icon":"rail","fields":["name","network","operator","address","building_area","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"public_transport":"station","train":"yes","railway":"halt"},"reference":{"key":"railway","value":"halt"},"terms":["halt","public transit","public transportation","rail","station","track","train","transit","transportation","whistle stop"],"name":"Train Station (Halt / Request)"},"public_transport/station_train":{"icon":"rail","fields":["name","network","operator","address","building_area","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"public_transport":"station","train":"yes"},"addTags":{"public_transport":"station","train":"yes","railway":"station"},"removeTags":{"public_transport":"station","train":"yes","railway":"station"},"reference":{"key":"railway","value":"station"},"terms":["public transit","public transportation","rail","station","terminal","track","train","transit","transportation"],"name":"Train Station"},"public_transport/station_tram":{"icon":"poi-tram","fields":["name","network","operator","address","building_area","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"public_transport":"station","tram":"yes"},"reference":{"key":"public_transport","value":"station"},"terms":["electric","light rail","public transit","public transportation","rail","station","streetcar","terminal","track","tram","trolley","transit","transportation"],"name":"Tram Station"},"public_transport/station_trolleybus":{"icon":"poi-trolleybus","fields":["name","network","operator","address","building_area","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"public_transport":"station","trolleybus":"yes"},"addTags":{"public_transport":"station","trolleybus":"yes","amenity":"bus_station"},"removeTags":{"public_transport":"station","trolleybus":"yes","amenity":"bus_station"},"reference":{"key":"amenity","value":"bus_station"},"terms":["bus","electric","public transit","public transportation","station","streetcar","terminal","trackless","tram","trolley","transit","transportation"],"name":"Trolleybus Station / Terminal"},"public_transport/station":{"icon":"rail","fields":["name","network","operator","address","building_area","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"public_transport":"station"},"terms":["public transit","public transportation","station","terminal","transit","transportation"],"name":"Transit Station","matchScore":0.2},"public_transport/stop_area":{"icon":"bus","fields":["name","ref","network","operator"],"geometry":["relation"],"tags":{"type":"public_transport","public_transport":"stop_area"},"addTags":{"type":"public_transport","public_transport":"stop_area","public_transport:version":"2"},"removeTags":{"type":"public_transport","public_transport":"stop_area","public_transport:version":"2"},"reference":{"key":"public_transport","value":"stop_area"},"name":"Transit Stop Area"},"public_transport/stop_position_aerialway":{"icon":"aerialway","fields":["name","ref_stop_position","network","operator"],"geometry":["vertex"],"tags":{"public_transport":"stop_position","aerialway":"yes"},"reference":{"key":"public_transport","value":"stop_position"},"terms":["aerialway","cable car","public transit","public transportation","transit","transportation"],"name":"Aerialway Stopping Location"},"public_transport/stop_position_bus":{"icon":"bus","fields":["name","ref_stop_position","network","operator"],"geometry":["vertex"],"tags":{"public_transport":"stop_position","bus":"yes"},"reference":{"key":"public_transport","value":"stop_position"},"terms":["bus","public transit","public transportation","transit","transportation"],"name":"Bus Stopping Location"},"public_transport/stop_position_ferry":{"icon":"ferry","fields":["name","ref_stop_position","network","operator"],"geometry":["vertex"],"tags":{"public_transport":"stop_position","ferry":"yes"},"reference":{"key":"public_transport","value":"stop_position"},"terms":["boat","dock","ferry","pier","public transit","public transportation","transit","transportation"],"name":"Ferry Stopping Location"},"public_transport/stop_position_light_rail":{"icon":"poi-light-rail","fields":["name","ref_stop_position","network","operator"],"geometry":["vertex"],"tags":{"public_transport":"stop_position","light_rail":"yes"},"addTags":{"public_transport":"stop_position","light_rail":"yes","railway":"stop"},"removeTags":{"public_transport":"stop_position","light_rail":"yes","railway":"stop"},"reference":{"key":"railway","value":"stop"},"terms":["electric","light rail","public transit","public transportation","rail","track","tram","trolley","transit","transportation"],"name":"Light Rail Stopping Location"},"public_transport/stop_position_monorail":{"icon":"poi-monorail","fields":["name","ref_stop_position","network","operator"],"geometry":["vertex"],"tags":{"public_transport":"stop_position","monorail":"yes"},"addTags":{"public_transport":"stop_position","monorail":"yes","railway":"stop"},"removeTags":{"public_transport":"stop_position","monorail":"yes","railway":"stop"},"reference":{"key":"railway","value":"stop"},"terms":["monorail","public transit","public transportation","rail","transit","transportation"],"name":"Monorail Stopping Location"},"public_transport/stop_position_subway":{"icon":"poi-subway","fields":["name","ref_stop_position","network","operator"],"geometry":["vertex"],"tags":{"public_transport":"stop_position","subway":"yes"},"addTags":{"public_transport":"stop_position","subway":"yes","railway":"stop"},"removeTags":{"public_transport":"stop_position","subway":"yes","railway":"stop"},"reference":{"key":"railway","value":"stop"},"terms":["metro","public transit","public transportation","rail","subway","track","transit","transportation","underground"],"name":"Subway Stopping Location"},"public_transport/stop_position_train":{"icon":"rail","fields":["name","ref_stop_position","network","operator"],"geometry":["vertex"],"tags":{"public_transport":"stop_position","train":"yes"},"addTags":{"public_transport":"stop_position","train":"yes","railway":"stop"},"removeTags":{"public_transport":"stop_position","train":"yes","railway":"stop"},"reference":{"key":"railway","value":"stop"},"terms":["public transit","public transportation","rail","track","train","transit","transportation"],"name":"Train Stopping Location"},"public_transport/stop_position_tram":{"icon":"poi-tram","fields":["name","ref_stop_position","network","operator"],"geometry":["vertex"],"tags":{"public_transport":"stop_position","tram":"yes"},"addTags":{"public_transport":"stop_position","tram":"yes","railway":"tram_stop"},"removeTags":{"public_transport":"stop_position","tram":"yes","railway":"tram_stop"},"reference":{"key":"public_transport","value":"stop_position"},"terms":["electric","light rail","public transit","public transportation","rail","streetcar","track","tram","trolley","transit","transportation"],"name":"Tram Stopping Location"},"public_transport/stop_position_trolleybus":{"icon":"poi-trolleybus","fields":["name","ref_stop_position","network","operator"],"geometry":["vertex"],"tags":{"public_transport":"stop_position","trolleybus":"yes"},"reference":{"key":"public_transport","value":"stop_position"},"terms":["bus","electric","public transit","public transportation","streetcar","trackless","tram","trolley","transit","transportation"],"name":"Trolleybus Stopping Location"},"public_transport/stop_position":{"icon":"bus","fields":["name","ref_stop_position","network","operator"],"geometry":["vertex"],"tags":{"public_transport":"stop_position"},"terms":["public transit","public transportation","transit","transportation"],"name":"Transit Stopping Location","matchScore":0.2},"railway/halt":{"icon":"rail","geometry":["point","vertex"],"tags":{"railway":"halt"},"terms":["break","interrupt","rest","wait","interruption"],"name":"Train Station (Halt / Request)","searchable":false},"railway/platform":{"icon":"highway-footway","fields":["name","ref_platform","surface","lit","shelter"],"geometry":["line","area"],"tags":{"railway":"platform"},"name":"Train Stop / Platform","searchable":false},"railway/station":{"icon":"rail","fields":["name","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":"Train Station","searchable":false},"railway/tram_stop":{"icon":"poi-tram","fields":["name","network","operator"],"geometry":["vertex"],"tags":{"railway":"tram_stop"},"terms":["light rail","streetcar","tram","trolley"],"name":"Tram Stopping Position","searchable":false},"railway/abandoned":{"icon":"railway-abandoned","geometry":["line"],"tags":{"railway":"abandoned"},"fields":["name","structure","service_rail"],"terms":[],"name":"Abandoned Railway"},"railway/buffer_stop":{"icon":"poi-buffer-stop","geometry":["vertex"],"tags":{"railway":"buffer_stop"},"terms":["stop","halt","buffer"],"name":"Buffer Stop"},"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/derail":{"icon":"roadblock","geometry":["vertex"],"tags":{"railway":"derail"},"terms":["derailer"],"name":"Railway Derailer"},"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/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/light_rail":{"icon":"railway-light-rail","geometry":["line"],"tags":{"railway":"light_rail"},"fields":["name","structure","gauge","electrified","service_rail"],"terms":["light rail","streetcar","trolley"],"name":"Light Rail"},"railway/milestone":{"icon":"poi-milestone","geometry":["point","vertex"],"fields":["railway/position"],"tags":{"railway":"milestone"},"terms":["milestone","marker"],"name":"Railway Milestone"},"railway/miniature":{"icon":"railway-rail","geometry":["line"],"tags":{"railway":"miniature"},"fields":["name","structure","gauge","electrified","service_rail"],"terms":["rideable miniature railway","narrow gauge railway","minimum gauge railway"],"name":"Miniature Railway"},"railway/monorail":{"icon":"railway-monorail","geometry":["line"],"tags":{"railway":"monorail"},"fields":["name","structure","electrified","service_rail"],"terms":[],"name":"Monorail"},"railway/narrow_gauge":{"icon":"railway-rail","geometry":["line"],"tags":{"railway":"narrow_gauge"},"fields":["name","structure","gauge","electrified","service_rail"],"terms":["narrow gauge railway","narrow gauge railroad"],"name":"Narrow Gauge Rail"},"railway/rail":{"icon":"railway-rail","geometry":["line"],"tags":{"railway":"rail"},"fields":["name","structure","gauge","electrified","maxspeed","service_rail"],"terms":[],"name":"Rail"},"railway/signal":{"icon":"poi-railway-signals","geometry":["point","vertex"],"fields":["railway/position","railway/signal/direction","ref"],"tags":{"railway":"signal"},"terms":["signal","lights"],"name":"Railway Signal"},"railway/subway_entrance":{"icon":"entrance","geometry":["point","vertex"],"fields":["name"],"tags":{"railway":"subway_entrance"},"terms":["metro","transit"],"name":"Subway Entrance"},"railway/subway":{"icon":"railway-subway","geometry":["line"],"tags":{"railway":"subway"},"fields":["name","structure","gauge","electrified","service_rail"],"terms":["metro","transit"],"name":"Subway"},"railway/switch":{"icon":"poi-junction","geometry":["vertex"],"tags":{"railway":"switch"},"terms":["switch","points"],"name":"Railway Switch"},"railway/train_wash":{"icon":"rail","geometry":["point","vertex","area"],"fields":["operator","building_area"],"tags":{"railway":"wash"},"terms":["wash","clean"],"name":"Train Wash"},"railway/tram":{"icon":"railway-light-rail","geometry":["line"],"tags":{"railway":"tram"},"fields":["name","structure","gauge","electrified","service_rail"],"terms":["light rail","streetcar","tram","trolley"],"name":"Tram"},"relation":{"icon":"relation","fields":["name","relation"],"geometry":["relation"],"tags":{},"name":"Relation"},"route/ferry":{"icon":"ferry-line","geometry":["line"],"fields":["name","operator","duration","access"],"tags":{"route":"ferry"},"name":"Ferry Route"},"shop":{"icon":"shop","fields":["name","shop","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"*"},"terms":[],"name":"Shop"},"shop/fishmonger":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"fishmonger"},"reference":{"key":"shop","value":"seafood"},"name":"Fishmonger","searchable":false},"shop/furnace":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["oven","stove"],"tags":{"shop":"furnace"},"name":"Furnace Store","searchable":false},"shop/vacant":{"icon":"shop","fields":["name","address","building_area"],"geometry":["point","area"],"tags":{"shop":"vacant"},"name":"Vacant Shop","searchable":false},"shop/agrarian":{"icon":"shop","fields":["name","operator","agrarian","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["agricultural inputs","agricultural machines","seeds","pesticides","fertilizer","agricultural tools"],"tags":{"shop":"agrarian"},"name":"Agriculture Shop"},"shop/alcohol":{"icon":"alcohol-shop","fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"geometry":["point","area"],"terms":["alcohol","beer","booze","wine"],"tags":{"shop":"alcohol"},"name":"Liquor Store"},"shop/anime":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"anime"},"terms":["manga","japan","cosplay","figurine","dakimakura"],"name":"Anime Shop"},"shop/antiques":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"antiques"},"name":"Antiques Shop"},"shop/appliance":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["air conditioner","appliance","dishwasher","dryer","freezer","fridge","grill","kitchen","oven","refrigerator","stove","washer","washing machine"],"tags":{"shop":"appliance"},"name":"Appliance Store"},"shop/art":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["art*","exhibit*","gallery"],"tags":{"shop":"art"},"name":"Art Store"},"shop/baby_goods":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"baby_goods"},"name":"Baby Goods Store"},"shop/bag":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["handbag","purse"],"tags":{"shop":"bag"},"name":"Bag/Luggage Store"},"shop/bakery":{"icon":"bakery","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"bakery"},"name":"Bakery"},"shop/bathroom_furnishing":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"bathroom_furnishing"},"name":"Bathroom Furnishing Store"},"shop/beauty":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["spa","salon","tanning"],"tags":{"shop":"beauty"},"name":"Beauty Shop"},"shop/beauty/nails":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["manicure","pedicure"],"tags":{"shop":"beauty","beauty":"nails"},"reference":{"key":"shop","value":"beauty"},"name":"Nail Salon"},"shop/beauty/tanning":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"beauty","beauty":"tanning"},"reference":{"key":"leisure","value":"tanning_salon"},"name":"Tanning Salon"},"shop/bed":{"icon":"lodging","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"bed"},"name":"Bedding/Mattress Store"},"shop/beverages":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"beverages"},"name":"Beverage Store"},"shop/bicycle":{"icon":"bicycle","fields":["name","operator","address","building_area","service/bicycle","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["bike","repair"],"tags":{"shop":"bicycle"},"name":"Bicycle Shop"},"shop/bookmaker":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["betting"],"tags":{"shop":"bookmaker"},"name":"Bookmaker"},"shop/books":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"shop":"books"},"name":"Book Store"},"shop/boutique":{"icon":"shop","fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"boutique"},"name":"Boutique"},"shop/butcher":{"icon":"slaughterhouse","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["meat"],"tags":{"shop":"butcher"},"name":"Butcher"},"shop/candles":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"candles"},"name":"Candle Shop"},"shop/car_parts":{"icon":"car","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["auto"],"tags":{"shop":"car_parts"},"name":"Car Parts Store"},"shop/car_repair":{"icon":"car","fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["auto","garage","service"],"tags":{"shop":"car_repair"},"name":"Car Repair Shop"},"shop/car":{"icon":"car","fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["auto"],"tags":{"shop":"car"},"name":"Car Dealership"},"shop/carpet":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["rug"],"tags":{"shop":"carpet"},"name":"Carpet Store"},"shop/charity":{"icon":"shop","fields":["name","operator","address","building_area","second_hand","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["thrift","op shop","nonprofit"],"tags":{"shop":"charity"},"name":"Charity Store"},"shop/cheese":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"cheese"},"name":"Cheese Store"},"shop/chemist":{"icon":"grocery","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"chemist"},"terms":["med*","drug*","gift"],"name":"Drugstore"},"shop/chocolate":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"chocolate"},"name":"Chocolate Store"},"shop/clothes":{"icon":"clothing-store","fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"clothes"},"name":"Clothing Store"},"shop/coffee":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"coffee"},"name":"Coffee Store"},"shop/computer":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"computer"},"name":"Computer Store"},"shop/confectionery":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["sweet"],"tags":{"shop":"confectionery"},"name":"Candy Store"},"shop/convenience":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"convenience"},"name":"Convenience Store"},"shop/copyshop":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"copyshop"},"name":"Copy Store"},"shop/cosmetics":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"cosmetics"},"name":"Cosmetics Store"},"shop/craft":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"craft"},"terms":["art*","paint*","frame"],"name":"Arts and Crafts Store"},"shop/curtain":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["drape*","window"],"tags":{"shop":"curtain"},"name":"Curtain Store"},"shop/dairy":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["milk","egg","cheese"],"tags":{"shop":"dairy"},"name":"Dairy Store"},"shop/deli":{"icon":"restaurant","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["lunch","meat","sandwich"],"tags":{"shop":"deli"},"name":"Deli"},"shop/department_store":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"department_store"},"name":"Department Store"},"shop/doityourself":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"doityourself"},"name":"DIY Store"},"shop/dry_cleaning":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"dry_cleaning"},"name":"Dry Cleaner"},"shop/e-cigarette":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"e-cigarette"},"terms":["electronic","vapor"],"name":"E-Cigarette Shop"},"shop/electronics":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["appliance","audio","blueray","camera","computer","dvd","home theater","radio","speaker","tv","video"],"tags":{"shop":"electronics"},"name":"Electronics Store"},"shop/erotic":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["sex","porn"],"tags":{"shop":"erotic"},"name":"Erotic Store"},"shop/fabric":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["sew"],"tags":{"shop":"fabric"},"name":"Fabric Store"},"shop/farm":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["farm shop","farm stand"],"tags":{"shop":"farm"},"name":"Produce Stand"},"shop/fashion":{"icon":"shop","fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"fashion"},"name":"Fashion Store"},"shop/florist":{"icon":"florist","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["flower"],"tags":{"shop":"florist"},"name":"Florist"},"shop/frame":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"frame"},"terms":["art*","paint*","photo*","frame"],"name":"Framing Shop"},"shop/funeral_directors":{"icon":"cemetery","fields":["name","operator","address","building_area","religion","denomination"],"geometry":["point","area"],"terms":["undertaker","memorial home"],"tags":{"shop":"funeral_directors"},"name":"Funeral Home"},"shop/furniture":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["chair","sofa","table"],"tags":{"shop":"furniture"},"name":"Furniture Store"},"shop/garden_centre":{"icon":"garden-center","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["landscape","mulch","shrub","tree"],"tags":{"shop":"garden_centre"},"name":"Garden Center"},"shop/gas":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["cng","lpg","natural gas","propane","refill","tank"],"tags":{"shop":"gas"},"name":"Bottled Gas Shop"},"shop/gift":{"icon":"gift","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["souvenir"],"tags":{"shop":"gift"},"name":"Gift Shop"},"shop/greengrocer":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["fruit","vegetable"],"tags":{"shop":"greengrocer"},"name":"Greengrocer"},"shop/hairdresser":{"icon":"hairdresser","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["barber"],"tags":{"shop":"hairdresser"},"name":"Hairdresser"},"shop/hardware":{"icon":"poi-tool","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"hardware"},"name":"Hardware Store"},"shop/hearing_aids":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"hearing_aids"},"name":"Hearing Aids Store"},"shop/herbalist":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"herbalist"},"name":"Herbalist"},"shop/hifi":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["stereo","video"],"tags":{"shop":"hifi"},"name":"Hifi Store"},"shop/houseware":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["home","household"],"tags":{"shop":"houseware"},"name":"Houseware Store"},"shop/interior_decoration":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"interior_decoration"},"name":"Interior Decoration Store"},"shop/jewelry":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["diamond","gem","ring"],"tags":{"shop":"jewelry"},"name":"Jeweler"},"shop/kiosk":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"kiosk"},"name":"Kiosk"},"shop/kitchen":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"kitchen"},"name":"Kitchen Design Store"},"shop/laundry":{"icon":"laundry","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"laundry"},"name":"Laundry"},"shop/leather":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"leather"},"name":"Leather Store"},"shop/locksmith":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["key","lockpick"],"tags":{"shop":"locksmith"},"name":"Locksmith"},"shop/lottery":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"lottery"},"name":"Lottery Shop"},"shop/mall":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["shopping"],"tags":{"shop":"mall"},"name":"Mall"},"shop/massage":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"massage"},"name":"Massage Shop"},"shop/medical_supply":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"medical_supply"},"name":"Medical Supply Store"},"shop/mobile_phone":{"icon":"mobile-phone","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"mobile_phone"},"name":"Mobile Phone Store"},"shop/money_lender":{"icon":"bank","fields":["name","operator","address","building_area","opening_hours","currency_multi"],"geometry":["point","area"],"tags":{"shop":"money_lender"},"name":"Money Lender"},"shop/motorcycle":{"icon":"scooter","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["bike"],"tags":{"shop":"motorcycle"},"name":"Motorcycle Dealership"},"shop/music":{"icon":"music","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["CD","vinyl"],"tags":{"shop":"music"},"name":"Music Store"},"shop/musical_instrument":{"icon":"music","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["guitar"],"tags":{"shop":"musical_instrument"},"name":"Musical Instrument Store"},"shop/newsagent":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"newsagent"},"name":"Newspaper/Magazine Shop"},"shop/nutrition_supplements":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"nutrition_supplements"},"name":"Nutrition Supplements Store"},"shop/optician":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["eye","glasses"],"tags":{"shop":"optician"},"name":"Optician"},"shop/organic":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"supermarket","organic":"only"},"name":"Organic Goods Store"},"shop/outdoor":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["camping","climbing","hiking"],"tags":{"shop":"outdoor"},"name":"Outdoors Store"},"shop/paint":{"icon":"water","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"paint"},"name":"Paint Store"},"shop/pastry":{"icon":"bakery","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"pastry"},"terms":["patisserie","cake shop","cakery"],"name":"Pastry Shop"},"shop/pawnbroker":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"pawnbroker"},"name":"Pawn Shop"},"shop/perfumery":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"perfumery"},"name":"Perfume Store"},"shop/pet":{"icon":"dog-park","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["animal","cat","dog","fish","kitten","puppy","reptile"],"tags":{"shop":"pet"},"name":"Pet Store"},"shop/photo":{"icon":"attraction","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["camera","film"],"tags":{"shop":"photo"},"name":"Photography Store"},"shop/pyrotechnics":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"pyrotechnics"},"name":"Fireworks Store"},"shop/radiotechnics":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"radiotechnics"},"name":"Radio/Electronic Component Store"},"shop/religion":{"icon":"shop","fields":["name","operator","address","building_area","religion","denomination","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"religion"},"name":"Religious Store"},"shop/scuba_diving":{"icon":"swimming","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"scuba_diving"},"name":"Scuba Diving Shop"},"shop/seafood":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["fishmonger"],"tags":{"shop":"seafood"},"name":"Seafood Shop"},"shop/second_hand":{"icon":"shop","fields":["name","operator","address","building_area","second_hand","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["secondhand","second hand","resale","thrift","used"],"tags":{"shop":"second_hand"},"name":"Consignment/Thrift Store"},"shop/shoes":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"shoes"},"name":"Shoe Store"},"shop/sports":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"sports"},"name":"Sporting Goods Store"},"shop/stationery":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["card","paper"],"tags":{"shop":"stationery"},"name":"Stationery Store"},"shop/storage_rental":{"icon":"shop","fields":["name","operator","address","building","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"storage_rental"},"name":"Storage Rental"},"shop/supermarket":{"icon":"grocery","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["grocery","store","shop"],"tags":{"shop":"supermarket"},"name":"Supermarket"},"shop/tailor":{"icon":"clothing-store","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["clothes","suit"],"tags":{"shop":"tailor"},"name":"Tailor"},"shop/tattoo":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"tattoo"},"name":"Tattoo Parlor"},"shop/tea":{"icon":"teahouse","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"tea"},"name":"Tea Store"},"shop/ticket":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"ticket"},"name":"Ticket Seller"},"shop/tiles":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"tiles"},"name":"Tile Shop"},"shop/tobacco":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"tobacco"},"name":"Tobacco Shop"},"shop/toys":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"toys"},"name":"Toy Store"},"shop/trade":{"icon":"shop","fields":["name","trade","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"trade"},"name":"Trade Shop"},"shop/travel_agency":{"icon":"suitcase","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"travel_agency"},"name":"Travel Agency"},"shop/tyres":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"tyres"},"name":"Tire Store"},"shop/vacuum_cleaner":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"vacuum_cleaner"},"name":"Vacuum Cleaner Store"},"shop/variety_store":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"variety_store"},"name":"Variety Store"},"shop/video_games":{"icon":"gaming","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"video_games"},"name":"Video Game Store"},"shop/video":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["DVD"],"tags":{"shop":"video"},"name":"Video Store"},"shop/watches":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"watches"},"name":"Watches Shop"},"shop/water_sports":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"water_sports"},"name":"Watersport/Swim Shop"},"shop/weapons":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"terms":["ammo","gun","knife","knives"],"tags":{"shop":"weapons"},"name":"Weapon Shop"},"shop/window_blind":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"window_blind"},"name":"Window Blind Store"},"shop/wine":{"icon":"alcohol-shop","fields":["name","operator","address","building_area","opening_hours","payment_multi"],"geometry":["point","area"],"tags":{"shop":"wine"},"name":"Wine Shop"},"tourism":{"icon":"attraction","fields":["name","tourism"],"geometry":["point","vertex","area"],"tags":{"tourism":"*"},"name":"Tourism"},"tourism/alpine_hut":{"icon":"lodging","fields":["name","operator","address","building_area","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"terms":["climbing hut"],"tags":{"tourism":"alpine_hut"},"name":"Alpine Hut"},"tourism/apartment":{"icon":"lodging","fields":["name","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":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["fish","sea","water"],"tags":{"tourism":"aquarium"},"name":"Aquarium"},"tourism/artwork":{"icon":"art-gallery","fields":["name","artwork_type","artist"],"geometry":["point","vertex","area"],"tags":{"tourism":"artwork"},"terms":["mural","sculpture","statue"],"name":"Artwork"},"tourism/attraction":{"icon":"star","fields":["name","operator","address"],"geometry":["point","vertex","area"],"tags":{"tourism":"attraction"},"name":"Tourist Attraction"},"tourism/camp_site":{"icon":"campsite","fields":["name","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":["name","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":["name","operator","address","building_area","smoking","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"terms":["holiday","holiday cottage","holiday home","vacation","vacation home"],"tags":{"tourism":"chalet"},"name":"Holiday Cottage"},"tourism/gallery":{"icon":"art-gallery","fields":["name","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":["name","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":["name","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":["name","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":["name","operator","board_type","direction"],"geometry":["point","vertex"],"tags":{"tourism":"information","information":"board"},"reference":{"key":"information","value":"board"},"name":"Information Board"},"tourism/information/guidepost":{"icon":"information","fields":["name","elevation","operator","ref"],"geometry":["point","vertex"],"terms":["signpost"],"tags":{"tourism":"information","information":"guidepost"},"reference":{"key":"information","value":"guidepost"},"name":"Guidepost"},"tourism/information/map":{"icon":"information","fields":["operator","map_type","map_size","direction"],"geometry":["point","vertex"],"tags":{"tourism":"information","information":"map"},"reference":{"key":"information","value":"map"},"name":"Map"},"tourism/information/office":{"icon":"information","fields":["name","operator","address","building_area"],"geometry":["point","vertex","area"],"tags":{"tourism":"information","information":"office"},"reference":{"key":"information","value":"office"},"name":"Tourist Information Office"},"tourism/motel":{"icon":"lodging","fields":["name","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":["name","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":["name","operator","address","smoking"],"geometry":["point","vertex","area"],"terms":["camp"],"tags":{"tourism":"picnic_site"},"name":"Picnic Site"},"tourism/theme_park":{"icon":"amusement-park","fields":["name","operator","address","opening_hours"],"geometry":["point","area"],"tags":{"tourism":"theme_park"},"name":"Theme Park"},"tourism/viewpoint":{"icon":"poi-binoculars","geometry":["point","vertex"],"fields":["direction"],"tags":{"tourism":"viewpoint"},"name":"Viewpoint"},"tourism/wilderness_hut":{"icon":"lodging","fields":["name","operator","address","building_area"],"geometry":["point","area"],"terms":["wilderness hut","backcountry hut","bothy"],"tags":{"tourism":"wilderness_hut"},"name":"Wilderness Hut"},"tourism/zoo":{"icon":"zoo","fields":["name","operator","address","opening_hours"],"geometry":["point","area"],"terms":["animal"],"tags":{"tourism":"zoo"},"name":"Zoo"},"traffic_calming":{"icon":"poi-warning","fields":["traffic_calming","direction_vertex"],"geometry":["vertex","line"],"tags":{"traffic_calming":"*"},"terms":["bump","hump","slow","speed"],"name":"Traffic Calming"},"traffic_calming/bump":{"icon":"poi-warning","fields":["surface","direction_vertex"],"geometry":["vertex","line"],"terms":["hump","speed","slow"],"tags":{"traffic_calming":"bump"},"name":"Speed Bump"},"traffic_calming/chicane":{"icon":"poi-warning","fields":["direction_vertex"],"geometry":["vertex","line"],"terms":["driveway link","speed","slow"],"tags":{"traffic_calming":"chicane"},"name":"Traffic Chicane"},"traffic_calming/choker":{"icon":"poi-warning","fields":["direction_vertex"],"geometry":["vertex","line"],"terms":["speed","slow"],"tags":{"traffic_calming":"choker"},"name":"Traffic Choker"},"traffic_calming/cushion":{"icon":"poi-warning","fields":["surface","direction_vertex"],"geometry":["vertex","line"],"terms":["bump","hump","speed","slow"],"tags":{"traffic_calming":"cushion"},"name":"Speed Cushion"},"traffic_calming/dip":{"icon":"poi-warning","fields":["surface","direction_vertex"],"geometry":["vertex","line"],"terms":["speed","slow"],"tags":{"traffic_calming":"dip"},"name":"Dip"},"traffic_calming/hump":{"icon":"poi-warning","fields":["surface","direction_vertex"],"geometry":["vertex","line"],"terms":["bump","speed","slow"],"tags":{"traffic_calming":"hump"},"name":"Speed Hump"},"traffic_calming/island":{"icon":"poi-warning","geometry":["vertex"],"terms":["circle","roundabout","slow"],"tags":{"traffic_calming":"island"},"name":"Traffic Island"},"traffic_calming/rumble_strip":{"icon":"poi-warning","fields":["direction_vertex"],"geometry":["vertex","line"],"terms":["audible lines","sleeper lines","growlers"],"tags":{"traffic_calming":"rumble_strip"},"name":"Rumble Strip"},"traffic_calming/table":{"icon":"poi-warning","fields":["surface"],"geometry":["vertex"],"tags":{"traffic_calming":"table"},"terms":["flat top","hump","speed","slow"],"name":"Speed Table"},"type/multipolygon":{"icon":"multipolygon","geometry":["area","relation"],"tags":{"type":"multipolygon"},"removeTags":{},"name":"Multipolygon","searchable":false,"matchScore":0.1},"type/boundary":{"icon":"boundary","fields":["name","boundary"],"geometry":["relation"],"tags":{"type":"boundary"},"name":"Boundary"},"type/boundary/administrative":{"icon":"boundary","fields":["name","admin_level"],"geometry":["relation"],"tags":{"type":"boundary","boundary":"administrative"},"reference":{"key":"boundary","value":"administrative"},"name":"Administrative Boundary"},"type/restriction":{"icon":"restriction","fields":["name","restriction","except"],"geometry":["relation"],"tags":{"type":"restriction"},"name":"Restriction"},"type/restriction/no_left_turn":{"icon":"restriction-no-left-turn","fields":["except"],"geometry":["relation"],"tags":{"type":"restriction","restriction":"no_left_turn"},"name":"No Left Turn"},"type/restriction/no_right_turn":{"icon":"restriction-no-right-turn","fields":["except"],"geometry":["relation"],"tags":{"type":"restriction","restriction":"no_right_turn"},"name":"No Right Turn"},"type/restriction/no_straight_on":{"icon":"restriction-no-straight-on","fields":["except"],"geometry":["relation"],"tags":{"type":"restriction","restriction":"no_straight_on"},"name":"No Straight On"},"type/restriction/no_u_turn":{"icon":"restriction-no-u-turn","fields":["except"],"geometry":["relation"],"tags":{"type":"restriction","restriction":"no_u_turn"},"name":"No U-turn"},"type/restriction/only_left_turn":{"icon":"restriction-only-left-turn","fields":["except"],"geometry":["relation"],"tags":{"type":"restriction","restriction":"only_left_turn"},"name":"Left Turn Only"},"type/restriction/only_right_turn":{"icon":"restriction-only-right-turn","fields":["except"],"geometry":["relation"],"tags":{"type":"restriction","restriction":"only_right_turn"},"name":"Right Turn Only"},"type/restriction/only_straight_on":{"icon":"restriction-only-straight-on","fields":["except"],"geometry":["relation"],"tags":{"type":"restriction","restriction":"only_straight_on"},"name":"No Turns"},"type/route_master":{"icon":"route-master","fields":["name","route_master","ref","operator","network"],"geometry":["relation"],"tags":{"type":"route_master"},"name":"Route Master"},"type/route":{"icon":"route","fields":["name","route","ref_route","operator","network"],"geometry":["relation"],"tags":{"type":"route"},"name":"Route"},"type/route/bicycle":{"icon":"route-bicycle","fields":["name","ref_route","network_bicycle","cycle_network"],"geometry":["relation"],"tags":{"type":"route","route":"bicycle"},"name":"Cycle Route"},"type/route/bus":{"icon":"route-bus","fields":["name","ref_route","operator","network"],"geometry":["relation"],"tags":{"type":"route","route":"bus"},"name":"Bus Route"},"type/route/detour":{"icon":"route-detour","fields":["name","ref_route"],"geometry":["relation"],"tags":{"type":"route","route":"detour"},"name":"Detour Route"},"type/route/ferry":{"icon":"route-ferry","fields":["name","ref_route","operator","network"],"geometry":["relation"],"tags":{"type":"route","route":"ferry"},"name":"Ferry Route"},"type/route/foot":{"icon":"route-foot","fields":["name","ref_route","operator","network_foot"],"geometry":["relation"],"tags":{"type":"route","route":"foot"},"name":"Foot Route"},"type/route/hiking":{"icon":"route-foot","fields":["name","ref_route","operator","network_foot"],"geometry":["relation"],"tags":{"type":"route","route":"hiking"},"name":"Hiking Route"},"type/route/horse":{"icon":"route-horse","fields":["name","ref_route","operator","network_horse"],"geometry":["relation"],"tags":{"type":"route","route":"horse"},"name":"Riding Route"},"type/route/light_rail":{"icon":"route-light-rail","fields":["name","ref_route","operator","network"],"geometry":["relation"],"tags":{"type":"route","route":"light_rail"},"name":"Light Rail Route"},"type/route/pipeline":{"icon":"route-pipeline","fields":["name","ref_route","operator"],"geometry":["relation"],"tags":{"type":"route","route":"pipeline"},"name":"Pipeline Route"},"type/route/piste":{"icon":"route-piste","fields":["name","ref_route","operator","network"],"geometry":["relation"],"tags":{"type":"route","route":"piste"},"name":"Piste/Ski Route"},"type/route/power":{"icon":"route-power","fields":["name","ref_route","operator"],"geometry":["relation"],"tags":{"type":"route","route":"power"},"name":"Power Route"},"type/route/road":{"icon":"route-road","fields":["name","ref_route","network_road"],"geometry":["relation"],"tags":{"type":"route","route":"road"},"name":"Road Route"},"type/route/subway":{"icon":"route-subway","fields":["name","ref_route","operator","network"],"geometry":["relation"],"tags":{"type":"route","route":"subway"},"name":"Subway Route"},"type/route/train":{"icon":"route-train","fields":["name","ref_route","operator","network"],"geometry":["relation"],"tags":{"type":"route","route":"train"},"name":"Train Route"},"type/route/tram":{"icon":"route-tram","fields":["name","ref_route","operator","network"],"geometry":["relation"],"tags":{"type":"route","route":"tram"},"name":"Tram Route"},"type/site":{"icon":"relation","fields":["name","site"],"geometry":["relation"],"tags":{"type":"site"},"name":"Site"},"type/waterway":{"icon":"route-water","fields":["name","waterway","ref"],"geometry":["relation"],"tags":{"type":"waterway"},"name":"Waterway"},"vertex":{"fields":["name"],"geometry":["vertex"],"tags":{},"name":"Other","matchScore":0.1},"waterway/boatyard":{"icon":"harbor","fields":["name","operator"],"geometry":["area","vertex","point"],"tags":{"waterway":"boatyard"},"name":"Boatyard"},"waterway/canal":{"icon":"waterway-canal","fields":["name","width","intermittent"],"geometry":["line"],"tags":{"waterway":"canal"},"name":"Canal"},"waterway/dam":{"icon":"dam","geometry":["point","vertex","line","area"],"fields":["name"],"tags":{"waterway":"dam"},"name":"Dam"},"waterway/ditch":{"icon":"waterway-ditch","fields":["structure_waterway","intermittent"],"geometry":["line"],"tags":{"waterway":"ditch"},"name":"Ditch"},"waterway/dock":{"icon":"harbor","fields":["name","dock","operator"],"geometry":["area","vertex","point"],"terms":["boat","ship","vessel","marine"],"tags":{"waterway":"dock"},"name":"Wet Dock / Dry Dock"},"waterway/drain":{"icon":"waterway-ditch","fields":["structure_waterway","intermittent"],"geometry":["line"],"tags":{"waterway":"drain"},"name":"Drain"},"waterway/fuel":{"icon":"fuel","fields":["name","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":["name","structure_waterway","width","intermittent"],"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":{"icon":"poi-storage-tank","fields":["name","operator","access_simple","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_intermittent":{"icon":"waterway-stream","fields":["name","structure_waterway","width","intermittent"],"geometry":["line"],"terms":["arroyo","beck","branch","brook","burn","course","creek","drift","flood","flow","gully","run","runnel","rush","spate","spritz","tributary","wadi","wash","watercourse"],"tags":{"waterway":"stream","intermittent":"yes"},"reference":{"key":"waterway","value":"stream"},"name":"Intermittent Stream"},"waterway/stream":{"icon":"waterway-stream","fields":["name","structure_waterway","width","intermittent"],"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":["name","height","width","intermittent"],"geometry":["vertex"],"terms":["fall"],"tags":{"waterway":"waterfall"},"name":"Waterfall"},"waterway/weir":{"icon":"dam","geometry":["vertex","line"],"tags":{"waterway":"weir"},"name":"Weir"},"amenity/arts_centre/Świetlica wiejska":{"tags":{"name":"Świetlica wiejska","amenity":"arts_centre"},"name":"Świetlica wiejska","icon":"theatre","geometry":["point","area"],"fields":["name","address","building_area","opening_hours"],"suggestion":true},"amenity/arts_centre/Дом культуры":{"tags":{"name":"Дом культуры","amenity":"arts_centre"},"name":"Дом культуры","icon":"theatre","geometry":["point","area"],"fields":["name","address","building_area","opening_hours"],"suggestion":true},"amenity/bank/ABANCA":{"tags":{"name":"ABANCA","amenity":"bank"},"name":"ABANCA","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ASB Bank":{"tags":{"name":"ASB Bank","amenity":"bank"},"name":"ASB Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ATB Financial":{"tags":{"name":"ATB Financial","amenity":"bank"},"name":"ATB Financial","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Agribank":{"tags":{"name":"Agribank","amenity":"bank"},"name":"Agribank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Akbank":{"tags":{"name":"Akbank","amenity":"bank"},"name":"Akbank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Allahabad Bank":{"tags":{"name":"Allahabad Bank","amenity":"bank"},"name":"Allahabad Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Allied Bank":{"tags":{"name":"Allied Bank","amenity":"bank"},"name":"Allied Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Andhra Bank":{"tags":{"name":"Andhra Bank","amenity":"bank"},"name":"Andhra Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Antonveneta":{"tags":{"name":"Antonveneta","amenity":"bank"},"name":"Antonveneta","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Asia United Bank":{"tags":{"name":"Asia United Bank","amenity":"bank"},"name":"Asia United Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Askari Bank":{"tags":{"name":"Askari Bank","amenity":"bank"},"name":"Askari Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Associated Bank":{"tags":{"name":"Associated Bank","amenity":"bank"},"name":"Associated Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BAC":{"tags":{"name":"BAC","amenity":"bank"},"name":"BAC","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BBBank":{"tags":{"name":"BBBank","amenity":"bank"},"name":"BBBank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BBVA Bancomer":{"tags":{"name":"BBVA Bancomer","amenity":"bank"},"name":"BBVA Bancomer","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BBVA Compass":{"tags":{"name":"BBVA Compass","amenity":"bank"},"name":"BBVA Compass","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BBVA Continental":{"tags":{"name":"BBVA Continental","amenity":"bank"},"name":"BBVA Continental","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BBVA Francés":{"tags":{"name":"BBVA Francés","amenity":"bank"},"name":"BBVA Francés","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BCA":{"tags":{"name":"BCA","amenity":"bank"},"name":"BCA","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BCP":{"tags":{"name":"BCP","amenity":"bank"},"name":"BCP","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BGŻ BNP Paribas":{"tags":{"name":"BGŻ BNP Paribas","amenity":"bank"},"name":"BGŻ BNP Paribas","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BMCE":{"tags":{"name":"BMCE","amenity":"bank"},"name":"BMCE","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BMN":{"tags":{"name":"BMN","amenity":"bank"},"name":"BMN","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BMO Harris Bank":{"tags":{"name":"BMO Harris Bank","amenity":"bank"},"name":"BMO Harris Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BNA":{"tags":{"name":"BNA","amenity":"bank"},"name":"BNA","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BNI":{"tags":{"name":"BNI","amenity":"bank"},"name":"BNI","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BPH":{"tags":{"name":"BPH","amenity":"bank"},"name":"BPH","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BPI Family Savings Bank":{"tags":{"name":"BPI Family Savings Bank","amenity":"bank"},"name":"BPI Family Savings Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BRED":{"tags":{"name":"BRED","amenity":"bank"},"name":"BRED","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BRI":{"tags":{"name":"BRI","amenity":"bank"},"name":"BRI","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banc Sabadell":{"tags":{"name":"Banc Sabadell","amenity":"bank"},"name":"Banc Sabadell","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banca March":{"tags":{"name":"Banca March","amenity":"bank"},"name":"Banca March","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banca Popolare di Milano":{"tags":{"name":"Banca Popolare di Milano","amenity":"bank"},"name":"Banca Popolare di Milano","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banca Popolare di Novara":{"tags":{"name":"Banca Popolare di Novara","amenity":"bank"},"name":"Banca Popolare di Novara","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banca Popolare di Sondrio":{"tags":{"name":"Banca Popolare di Sondrio","amenity":"bank"},"name":"Banca Popolare di Sondrio","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banca Popolare di Verona":{"tags":{"name":"Banca Popolare di Verona","amenity":"bank"},"name":"Banca Popolare di Verona","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banca Românească":{"tags":{"name":"Banca Românească","amenity":"bank"},"name":"Banca Românească","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banca Sella":{"tags":{"name":"Banca Sella","amenity":"bank"},"name":"Banca Sella","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Agrario":{"tags":{"name":"Banco Agrario","amenity":"bank"},"name":"Banco Agrario","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Azteca":{"tags":{"name":"Banco Azteca","amenity":"bank"},"name":"Banco Azteca","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Continental":{"tags":{"name":"Banco Continental","amenity":"bank"},"name":"Banco Continental","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Fassil":{"tags":{"name":"Banco Fassil","amenity":"bank"},"name":"Banco Fassil","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco General":{"tags":{"name":"Banco General","amenity":"bank"},"name":"Banco General","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Industrial":{"tags":{"name":"Banco Industrial","amenity":"bank"},"name":"Banco Industrial","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Internacional":{"tags":{"name":"Banco Internacional","amenity":"bank"},"name":"Banco Internacional","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Nacional":{"tags":{"name":"Banco Nacional","amenity":"bank"},"name":"Banco Nacional","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Pichincha":{"tags":{"name":"Banco Pichincha","amenity":"bank"},"name":"Banco Pichincha","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Sabadell":{"tags":{"name":"Banco Sabadell","amenity":"bank"},"name":"Banco Sabadell","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Sol":{"tags":{"name":"Banco Sol","amenity":"bank"},"name":"Banco Sol","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco de Bogotá":{"tags":{"name":"Banco de Bogotá","amenity":"bank"},"name":"Banco de Bogotá","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco de Occidente":{"tags":{"name":"Banco de Occidente","amenity":"bank"},"name":"Banco de Occidente","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco de Venezuela":{"tags":{"name":"Banco de Venezuela","amenity":"bank"},"name":"Banco de Venezuela","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco de la Nación Argentina":{"tags":{"name":"Banco de la Nación Argentina","amenity":"bank"},"name":"Banco de la Nación Argentina","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco di Napoli":{"tags":{"name":"Banco di Napoli","amenity":"bank"},"name":"Banco di Napoli","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco di Sardegna":{"tags":{"name":"Banco di Sardegna","amenity":"bank"},"name":"Banco di Sardegna","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco do Nordeste":{"tags":{"name":"Banco do Nordeste","amenity":"bank"},"name":"Banco do Nordeste","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bangkok Bank":{"tags":{"name":"Bangkok Bank","amenity":"bank"},"name":"Bangkok Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank Al Habib":{"tags":{"name":"Bank Al Habib","amenity":"bank"},"name":"Bank Al Habib","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank Alfalah":{"tags":{"name":"Bank Alfalah","amenity":"bank"},"name":"Bank Alfalah","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank BCA":{"tags":{"name":"Bank BCA","amenity":"bank"},"name":"Bank BCA","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank BNI":{"tags":{"name":"Bank BNI","amenity":"bank"},"name":"Bank BNI","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank BPH":{"tags":{"name":"Bank BPH","amenity":"bank"},"name":"Bank BPH","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank Danamon":{"tags":{"name":"Bank Danamon","amenity":"bank"},"name":"Bank Danamon","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank Mega":{"tags":{"name":"Bank Mega","amenity":"bank"},"name":"Bank Mega","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank Zachodni WBK":{"tags":{"name":"Bank Zachodni WBK","amenity":"bank"},"name":"Bank Zachodni WBK","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of Africa":{"tags":{"name":"Bank of Africa","amenity":"bank"},"name":"Bank of Africa","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of Baroda":{"tags":{"name":"Bank of Baroda","amenity":"bank"},"name":"Bank of Baroda","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of Ceylon":{"tags":{"name":"Bank of Ceylon","amenity":"bank"},"name":"Bank of Ceylon","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of China":{"tags":{"name":"Bank of China","amenity":"bank"},"name":"Bank of China","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of Commerce":{"tags":{"name":"Bank of Commerce","amenity":"bank"},"name":"Bank of Commerce","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of India":{"tags":{"name":"Bank of India","amenity":"bank"},"name":"Bank of India","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of New Zealand":{"tags":{"name":"Bank of New Zealand","amenity":"bank"},"name":"Bank of New Zealand","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banner Bank":{"tags":{"name":"Banner Bank","amenity":"bank"},"name":"Banner Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banque Atlantique":{"tags":{"name":"Banque Atlantique","amenity":"bank"},"name":"Banque Atlantique","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banrisul":{"tags":{"name":"Banrisul","amenity":"bank"},"name":"Banrisul","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banrural":{"tags":{"name":"Banrural","amenity":"bank"},"name":"Banrural","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bcc":{"tags":{"name":"Bcc","amenity":"bank"},"name":"Bcc","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Budapest Bank":{"tags":{"name":"Budapest Bank","amenity":"bank"},"name":"Budapest Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CBAO":{"tags":{"name":"CBAO","amenity":"bank"},"name":"CBAO","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CEC Bank":{"tags":{"name":"CEC Bank","amenity":"bank"},"name":"CEC Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CGD":{"tags":{"name":"CGD","amenity":"bank"},"name":"CGD","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CIB Bank":{"tags":{"name":"CIB Bank","amenity":"bank"},"name":"CIB Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CIMB Bank":{"tags":{"name":"CIMB Bank","amenity":"bank"},"name":"CIMB Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CNEP":{"tags":{"name":"CNEP","amenity":"bank"},"name":"CNEP","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caisse Desjardins":{"tags":{"name":"Caisse Desjardins","amenity":"bank"},"name":"Caisse Desjardins","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CaixaBank":{"tags":{"name":"CaixaBank","amenity":"bank"},"name":"CaixaBank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caja España":{"tags":{"name":"Caja España","amenity":"bank"},"name":"Caja España","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caja Rural de Jaén":{"tags":{"name":"Caja Rural de Jaén","amenity":"bank"},"name":"Caja Rural de Jaén","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CajaSur":{"tags":{"name":"CajaSur","amenity":"bank"},"name":"CajaSur","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Carige":{"tags":{"name":"Carige","amenity":"bank"},"name":"Carige","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Cariparma":{"tags":{"name":"Cariparma","amenity":"bank"},"name":"Cariparma","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CatalunyaCaixa":{"tags":{"name":"CatalunyaCaixa","amenity":"bank"},"name":"CatalunyaCaixa","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Central Bank of India":{"tags":{"name":"Central Bank of India","amenity":"bank"},"name":"Central Bank of India","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Chase":{"tags":{"name":"Chase","amenity":"bank"},"name":"Chase","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/China Bank Savings":{"tags":{"name":"China Bank Savings","amenity":"bank"},"name":"China Bank Savings","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/China Construction Bank":{"tags":{"name":"China Construction Bank","amenity":"bank"},"name":"China Construction Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Clydesdale Bank":{"tags":{"name":"Clydesdale Bank","amenity":"bank"},"name":"Clydesdale Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Columbia Bank":{"tags":{"name":"Columbia Bank","amenity":"bank"},"name":"Columbia Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Comerica Bank":{"tags":{"name":"Comerica Bank","amenity":"bank"},"name":"Comerica Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Commerce Bank":{"tags":{"name":"Commerce Bank","amenity":"bank"},"name":"Commerce Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Commercial Bank":{"tags":{"name":"Commercial Bank","amenity":"bank"},"name":"Commercial Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Corporation Bank":{"tags":{"name":"Corporation Bank","amenity":"bank"},"name":"Corporation Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Credem":{"tags":{"name":"Credem","amenity":"bank"},"name":"Credem","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Credicoop":{"tags":{"name":"Credicoop","amenity":"bank"},"name":"Credicoop","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Crelan":{"tags":{"name":"Crelan","amenity":"bank"},"name":"Crelan","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Crédito Agrícola":{"tags":{"name":"Crédito Agrícola","amenity":"bank"},"name":"Crédito Agrícola","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Cбербанк":{"tags":{"name":"Cбербанк","amenity":"bank"},"name":"Cбербанк","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Denizbank":{"tags":{"name":"Denizbank","amenity":"bank"},"name":"Denizbank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Desjardins":{"tags":{"name":"Desjardins","amenity":"bank"},"name":"Desjardins","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Dubai Islamic Bank":{"tags":{"name":"Dubai Islamic Bank","amenity":"bank"},"name":"Dubai Islamic Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/EastWest Bank":{"tags":{"name":"EastWest Bank","amenity":"bank"},"name":"EastWest Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Express Union":{"tags":{"name":"Express Union","amenity":"bank"},"name":"Express Union","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Federal Bank":{"tags":{"name":"Federal Bank","amenity":"bank"},"name":"Federal Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Finansbank":{"tags":{"name":"Finansbank","amenity":"bank"},"name":"Finansbank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/First Bank":{"tags":{"name":"First Bank","amenity":"bank"},"name":"First Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/First Citizens Bank":{"tags":{"name":"First Citizens Bank","amenity":"bank"},"name":"First Citizens Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Galicia":{"tags":{"name":"Galicia","amenity":"bank"},"name":"Galicia","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Garanti":{"tags":{"name":"Garanti","amenity":"bank"},"name":"Garanti","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Garanti Bankası":{"tags":{"name":"Garanti Bankası","amenity":"bank"},"name":"Garanti Bankası","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Groupama":{"tags":{"name":"Groupama","amenity":"bank"},"name":"Groupama","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/HNB":{"tags":{"name":"HNB","amenity":"bank"},"name":"HNB","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Halkbank":{"tags":{"name":"Halkbank","amenity":"bank"},"name":"Halkbank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Hong Leong Bank":{"tags":{"name":"Hong Leong Bank","amenity":"bank"},"name":"Hong Leong Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Hrvatska poštanska banka":{"tags":{"name":"Hrvatska poštanska banka","amenity":"bank"},"name":"Hrvatska poštanska banka","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Huntington Bank":{"tags":{"name":"Huntington Bank","amenity":"bank"},"name":"Huntington Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ICBC":{"tags":{"name":"ICBC","amenity":"bank"},"name":"ICBC","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/IDBI Bank":{"tags":{"name":"IDBI Bank","amenity":"bank"},"name":"IDBI Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Indian Bank":{"tags":{"name":"Indian Bank","amenity":"bank"},"name":"Indian Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Indian Overseas Bank":{"tags":{"name":"Indian Overseas Bank","amenity":"bank"},"name":"Indian Overseas Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Interbank":{"tags":{"name":"Interbank","amenity":"bank"},"name":"Interbank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/K&H Bank":{"tags":{"name":"K&H Bank","amenity":"bank"},"name":"K&H Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Kasa Stefczyka":{"tags":{"name":"Kasa Stefczyka","amenity":"bank"},"name":"Kasa Stefczyka","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Kutxabank":{"tags":{"name":"Kutxabank","amenity":"bank"},"name":"Kutxabank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Laboral Kutxa":{"tags":{"name":"Laboral Kutxa","amenity":"bank"},"name":"Laboral Kutxa","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Liberbank":{"tags":{"name":"Liberbank","amenity":"bank"},"name":"Liberbank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/MCB":{"tags":{"name":"MCB","amenity":"bank"},"name":"MCB","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/MCB Bank":{"tags":{"name":"MCB Bank","amenity":"bank"},"name":"MCB Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/MONETA Money Bank":{"tags":{"name":"MONETA Money Bank","amenity":"bank"},"name":"MONETA Money Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Macro":{"tags":{"name":"Macro","amenity":"bank"},"name":"Macro","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Meezan Bank":{"tags":{"name":"Meezan Bank","amenity":"bank"},"name":"Meezan Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Metro Bank":{"tags":{"name":"Metro Bank","amenity":"bank"},"name":"Metro Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Millennium BCP":{"tags":{"name":"Millennium BCP","amenity":"bank"},"name":"Millennium BCP","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Montepio":{"tags":{"name":"Montepio","amenity":"bank"},"name":"Montepio","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/NSB":{"tags":{"name":"NSB","amenity":"bank"},"name":"NSB","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Novo Banco":{"tags":{"name":"Novo Banco","amenity":"bank"},"name":"Novo Banco","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Occidental de Descuento":{"tags":{"name":"Occidental de Descuento","amenity":"bank"},"name":"Occidental de Descuento","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/One Network Bank":{"tags":{"name":"One Network Bank","amenity":"bank"},"name":"One Network Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/PKO":{"tags":{"name":"PKO","amenity":"bank"},"name":"PKO","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/PNC":{"tags":{"name":"PNC","amenity":"bank"},"name":"PNC","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Patagonia":{"tags":{"name":"Patagonia","amenity":"bank"},"name":"Patagonia","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Philippine National Bank":{"tags":{"name":"Philippine National Bank","amenity":"bank"},"name":"Philippine National Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Piraeus Bank":{"tags":{"name":"Piraeus Bank","amenity":"bank"},"name":"Piraeus Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Popular":{"tags":{"name":"Popular","amenity":"bank"},"name":"Popular","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Postbank Finanzcenter":{"tags":{"name":"Postbank Finanzcenter","amenity":"bank"},"name":"Postbank Finanzcenter","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Public Bank":{"tags":{"name":"Public Bank","amenity":"bank"},"name":"Public Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Punjab National Bank":{"tags":{"name":"Punjab National Bank","amenity":"bank"},"name":"Punjab National Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/RBC Financial Group":{"tags":{"name":"RBC Financial Group","amenity":"bank"},"name":"RBC Financial Group","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/RCBC Savings Bank":{"tags":{"name":"RCBC Savings Bank","amenity":"bank"},"name":"RCBC Savings Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Raiffeisen Polbank":{"tags":{"name":"Raiffeisen Polbank","amenity":"bank"},"name":"Raiffeisen Polbank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Republic Bank":{"tags":{"name":"Republic Bank","amenity":"bank"},"name":"Republic Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Royal Bank of Canada":{"tags":{"name":"Royal Bank of Canada","amenity":"bank"},"name":"Royal Bank of Canada","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/SNS Bank":{"tags":{"name":"SNS Bank","amenity":"bank"},"name":"SNS Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Sabadell":{"tags":{"name":"Sabadell","amenity":"bank"},"name":"Sabadell","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Sampath Bank":{"tags":{"name":"Sampath Bank","amenity":"bank"},"name":"Sampath Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Santander Río":{"tags":{"name":"Santander Río","amenity":"bank"},"name":"Santander Río","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Sicredi":{"tags":{"name":"Sicredi","amenity":"bank"},"name":"Sicredi","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Stanbic Bank":{"tags":{"name":"Stanbic Bank","amenity":"bank"},"name":"Stanbic Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Standard Chartered":{"tags":{"name":"Standard Chartered","amenity":"bank"},"name":"Standard Chartered","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Standard Chartered Bank":{"tags":{"name":"Standard Chartered Bank","amenity":"bank"},"name":"Standard Chartered Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Supervielle":{"tags":{"name":"Supervielle","amenity":"bank"},"name":"Supervielle","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Syndicate Bank":{"tags":{"name":"Syndicate Bank","amenity":"bank"},"name":"Syndicate Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/TCF Bank":{"tags":{"name":"TCF Bank","amenity":"bank"},"name":"TCF Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/TEB":{"tags":{"name":"TEB","amenity":"bank"},"name":"TEB","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Takarékszövetkezet":{"tags":{"name":"Takarékszövetkezet","amenity":"bank"},"name":"Takarékszövetkezet","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Türkiye İş Bankası":{"tags":{"name":"Türkiye İş Bankası","amenity":"bank"},"name":"Türkiye İş Bankası","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/UCO Bank":{"tags":{"name":"UCO Bank","amenity":"bank"},"name":"UCO Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/UOB":{"tags":{"name":"UOB","amenity":"bank"},"name":"UOB","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Umpqua Bank":{"tags":{"name":"Umpqua Bank","amenity":"bank"},"name":"Umpqua Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Unicaja Banco":{"tags":{"name":"Unicaja Banco","amenity":"bank"},"name":"Unicaja Banco","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/United Bank":{"tags":{"name":"United Bank","amenity":"bank"},"name":"United Bank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Vakıfbank":{"tags":{"name":"Vakıfbank","amenity":"bank"},"name":"Vakıfbank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Veneto Banca":{"tags":{"name":"Veneto Banca","amenity":"bank"},"name":"Veneto Banca","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Vijaya Bank":{"tags":{"name":"Vijaya Bank","amenity":"bank"},"name":"Vijaya Bank","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Volks- und Raiffeisenbank":{"tags":{"name":"Volks- und Raiffeisenbank","amenity":"bank"},"name":"Volks- und Raiffeisenbank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Volksbank Mittelhessen":{"tags":{"name":"Volksbank Mittelhessen","amenity":"bank"},"name":"Volksbank Mittelhessen","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Volksbank Raiffeisenbank":{"tags":{"name":"Volksbank Raiffeisenbank","amenity":"bank"},"name":"Volksbank Raiffeisenbank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Washington Federal":{"tags":{"name":"Washington Federal","amenity":"bank"},"name":"Washington Federal","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Yorkshire Building Society":{"tags":{"name":"Yorkshire Building Society","amenity":"bank"},"name":"Yorkshire Building Society","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Zagrebačka banka":{"tags":{"name":"Zagrebačka banka","amenity":"bank"},"name":"Zagrebačka banka","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Ziraat Bankası":{"tags":{"name":"Ziraat Bankası","amenity":"bank"},"name":"Ziraat Bankası","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/mBank":{"tags":{"name":"mBank","amenity":"bank"},"name":"mBank","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/İş Bankası":{"tags":{"name":"İş Bankası","amenity":"bank"},"name":"İş Bankası","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Εθνική Τράπεζα":{"tags":{"name":"Εθνική Τράπεζα","amenity":"bank"},"name":"Εθνική Τράπεζα","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Πειραιώς":{"tags":{"name":"Πειραιώς","amenity":"bank"},"name":"Πειραιώς","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Τράπεζα Πειραιώς":{"tags":{"name":"Τράπεζα Πειραιώς","amenity":"bank"},"name":"Τράπεζα Πειραιώς","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Авангард":{"tags":{"name":"Авангард","amenity":"bank"},"name":"Авангард","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Альфа-Банк":{"tags":{"name":"Альфа-Банк","amenity":"bank"},"name":"Альфа-Банк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Банк Москвы":{"tags":{"name":"Банк Москвы","amenity":"bank"},"name":"Банк Москвы","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Банка ДСК":{"tags":{"name":"Банка ДСК","amenity":"bank"},"name":"Банка ДСК","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Белагропромбанк":{"tags":{"name":"Белагропромбанк","amenity":"bank"},"name":"Белагропромбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Беларусбанк":{"tags":{"name":"Беларусбанк","amenity":"bank"},"name":"Беларусбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Белинвестбанк":{"tags":{"name":"Белинвестбанк","amenity":"bank"},"name":"Белинвестбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Бинбанк":{"tags":{"name":"Бинбанк","amenity":"bank"},"name":"Бинбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ВТБ":{"tags":{"name":"ВТБ","amenity":"bank"},"name":"ВТБ","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Возрождение":{"tags":{"name":"Возрождение","amenity":"bank"},"name":"Возрождение","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Газпромбанк":{"tags":{"name":"Газпромбанк","amenity":"bank"},"name":"Газпромбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Генбанк":{"tags":{"name":"Генбанк","amenity":"bank"},"name":"Генбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Казкоммерцбанк":{"tags":{"name":"Казкоммерцбанк","amenity":"bank"},"name":"Казкоммерцбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/МДМ Банк":{"tags":{"name":"МДМ Банк","amenity":"bank"},"name":"МДМ Банк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Московский индустриальный банк":{"tags":{"name":"Московский индустриальный банк","amenity":"bank"},"name":"Московский индустриальный банк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Мособлбанк":{"tags":{"name":"Мособлбанк","amenity":"bank"},"name":"Мособлбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Народный банк":{"tags":{"name":"Народный банк","amenity":"bank"},"name":"Народный банк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ОТП Банк":{"tags":{"name":"ОТП Банк","amenity":"bank"},"name":"ОТП Банк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Открытие":{"tags":{"name":"Открытие","amenity":"bank"},"name":"Открытие","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Ощадбанк":{"tags":{"name":"Ощадбанк","amenity":"bank"},"name":"Ощадбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ПУМБ":{"tags":{"name":"ПУМБ","amenity":"bank"},"name":"ПУМБ","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Почта Банк":{"tags":{"name":"Почта Банк","amenity":"bank"},"name":"Почта Банк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ПриватБанк":{"tags":{"name":"ПриватБанк","amenity":"bank"},"name":"ПриватБанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Приватбанк":{"tags":{"name":"Приватбанк","amenity":"bank"},"name":"Приватбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Приднестровский Сбербанк":{"tags":{"name":"Приднестровский Сбербанк","amenity":"bank"},"name":"Приднестровский Сбербанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Приорбанк":{"tags":{"name":"Приорбанк","amenity":"bank"},"name":"Приорбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Промсвязьбанк":{"tags":{"name":"Промсвязьбанк","amenity":"bank"},"name":"Промсвязьбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/РНКБ":{"tags":{"name":"РНКБ","amenity":"bank"},"name":"РНКБ","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Райффайзен":{"tags":{"name":"Райффайзен","amenity":"bank"},"name":"Райффайзен","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Райффайзен Банк Аваль":{"tags":{"name":"Райффайзен Банк Аваль","amenity":"bank"},"name":"Райффайзен Банк Аваль","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Райффайзенбанк":{"tags":{"name":"Райффайзенбанк","amenity":"bank"},"name":"Райффайзенбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Росбанк":{"tags":{"name":"Росбанк","amenity":"bank"},"name":"Росбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Россельхозбанк":{"tags":{"name":"Россельхозбанк","amenity":"bank"},"name":"Россельхозбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Русский стандарт":{"tags":{"name":"Русский стандарт","amenity":"bank"},"name":"Русский стандарт","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Сбербанк":{"tags":{"name":"Сбербанк","amenity":"bank"},"name":"Сбербанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Совкомбанк":{"tags":{"name":"Совкомбанк","amenity":"bank"},"name":"Совкомбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/УкрСиббанк":{"tags":{"name":"УкрСиббанк","amenity":"bank"},"name":"УкрСиббанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Укрсоцбанк":{"tags":{"name":"Укрсоцбанк","amenity":"bank"},"name":"Укрсоцбанк","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Уралсиб":{"tags":{"name":"Уралсиб","amenity":"bank"},"name":"Уралсиб","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Хоум Кредит":{"tags":{"name":"Хоум Кредит","amenity":"bank"},"name":"Хоум Кредит","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/בנק הפועלים":{"tags":{"name":"בנק הפועלים","amenity":"bank"},"name":"בנק הפועלים","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/בנק לאומי":{"tags":{"name":"בנק לאומי","amenity":"bank"},"name":"בנק לאומי","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک":{"tags":{"name":"بانک","amenity":"bank"},"name":"بانک","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک آینده":{"tags":{"name":"بانک آینده","amenity":"bank"},"name":"بانک آینده","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک اقتصاد نوین":{"tags":{"name":"بانک اقتصاد نوین","amenity":"bank"},"name":"بانک اقتصاد نوین","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک انصار":{"tags":{"name":"بانک انصار","amenity":"bank"},"name":"بانک انصار","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک تجارت":{"tags":{"name":"بانک تجارت","amenity":"bank"},"name":"بانک تجارت","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک رفاه":{"tags":{"name":"بانک رفاه","amenity":"bank"},"name":"بانک رفاه","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک رفاه کارگران":{"tags":{"name":"بانک رفاه کارگران","amenity":"bank"},"name":"بانک رفاه کارگران","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک سپه":{"tags":{"name":"بانک سپه","amenity":"bank"},"name":"بانک سپه","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک شهر":{"tags":{"name":"بانک شهر","amenity":"bank"},"name":"بانک شهر","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک صادرات":{"tags":{"name":"بانک صادرات","amenity":"bank"},"name":"بانک صادرات","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک قوامین":{"tags":{"name":"بانک قوامین","amenity":"bank"},"name":"بانک قوامین","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک مسکن":{"tags":{"name":"بانک مسکن","amenity":"bank"},"name":"بانک مسکن","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک ملت":{"tags":{"name":"بانک ملت","amenity":"bank"},"name":"بانک ملت","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک ملی":{"tags":{"name":"بانک ملی","amenity":"bank"},"name":"بانک ملی","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک ملی ایران":{"tags":{"name":"بانک ملی ایران","amenity":"bank"},"name":"بانک ملی ایران","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک مهر اقتصاد":{"tags":{"name":"بانک مهر اقتصاد","amenity":"bank"},"name":"بانک مهر اقتصاد","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک پارسیان":{"tags":{"name":"بانک پارسیان","amenity":"bank"},"name":"بانک پارسیان","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک پاسارگاد":{"tags":{"name":"بانک پاسارگاد","amenity":"bank"},"name":"بانک پاسارگاد","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/بانک کشاورزی":{"tags":{"name":"بانک کشاورزی","amenity":"bank"},"name":"بانک کشاورزی","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/صادرات":{"tags":{"name":"صادرات","amenity":"bank"},"name":"صادرات","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ملی":{"tags":{"name":"ملی","amenity":"bank"},"name":"ملی","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/پست بانک":{"tags":{"name":"پست بانک","amenity":"bank"},"name":"پست بانک","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ธนาคารกรุงเทพ":{"tags":{"name":"ธนาคารกรุงเทพ","amenity":"bank"},"name":"ธนาคารกรุงเทพ","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ธนาคารกรุงไทย":{"tags":{"name":"ธนาคารกรุงไทย","amenity":"bank"},"name":"ธนาคารกรุงไทย","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ธนาคารกสิกรไทย":{"tags":{"name":"ธนาคารกสิกรไทย","amenity":"bank"},"name":"ธนาคารกสิกรไทย","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ธนาคารออมสิน":{"tags":{"name":"ธนาคารออมสิน","amenity":"bank"},"name":"ธนาคารออมสิน","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ธนาคารไทยพาณิชย์":{"tags":{"name":"ธนาคารไทยพาณิชย์","amenity":"bank"},"name":"ธนาคารไทยพาณิชย์","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/みずほ銀行":{"tags":{"name":"みずほ銀行","amenity":"bank"},"name":"みずほ銀行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/りそな銀行":{"tags":{"name":"りそな銀行","amenity":"bank"},"name":"りそな銀行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/三井住友銀行":{"tags":{"name":"三井住友銀行","amenity":"bank"},"name":"三井住友銀行","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/中国农业银行":{"tags":{"name":"中国农业银行","amenity":"bank"},"name":"中国农业银行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/中国工商银行":{"tags":{"name":"中国工商银行","amenity":"bank"},"name":"中国工商银行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/中国建设银行":{"tags":{"name":"中国建设银行","amenity":"bank"},"name":"中国建设银行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/中国邮政储蓄银行":{"tags":{"name":"中国邮政储蓄银行","amenity":"bank"},"name":"中国邮政储蓄银行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/中国银行":{"tags":{"name":"中国银行","amenity":"bank"},"name":"中国银行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/交通银行":{"tags":{"name":"交通银行","amenity":"bank"},"name":"交通银行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/京都中央信用金庫":{"tags":{"name":"京都中央信用金庫","amenity":"bank"},"name":"京都中央信用金庫","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/京都銀行":{"tags":{"name":"京都銀行","amenity":"bank"},"name":"京都銀行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/农业银行":{"tags":{"name":"农业银行","amenity":"bank"},"name":"农业银行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/北海道銀行":{"tags":{"name":"北海道銀行","amenity":"bank"},"name":"北海道銀行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/合作金庫銀行":{"tags":{"name":"合作金庫銀行","amenity":"bank"},"name":"合作金庫銀行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/土地銀行":{"tags":{"name":"土地銀行","amenity":"bank"},"name":"土地銀行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/工商银行":{"tags":{"name":"工商银行","amenity":"bank"},"name":"工商银行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/建设银行":{"tags":{"name":"建设银行","amenity":"bank"},"name":"建设银行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/彰化銀行":{"tags":{"name":"彰化銀行","amenity":"bank"},"name":"彰化銀行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/招商银行":{"tags":{"name":"招商银行","amenity":"bank"},"name":"招商银行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/横浜銀行":{"tags":{"name":"横浜銀行","amenity":"bank"},"name":"横浜銀行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/第一銀行":{"tags":{"name":"第一銀行","amenity":"bank"},"name":"第一銀行","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/華南銀行":{"tags":{"name":"華南銀行","amenity":"bank"},"name":"華南銀行","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/기업은행":{"tags":{"name":"기업은행","amenity":"bank"},"name":"기업은행","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/농협":{"tags":{"name":"농협","amenity":"bank"},"name":"농협","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/새마을금고":{"tags":{"name":"새마을금고","amenity":"bank"},"name":"새마을금고","icon":"bank","geometry":["point","area"],"fields":["name","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":["name","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":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/하나은행":{"tags":{"name":"하나은행","amenity":"bank"},"name":"하나은행","icon":"bank","geometry":["point","area"],"fields":["name","atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bar/Bar Centrale":{"tags":{"name":"Bar Centrale","amenity":"bar"},"name":"Bar Centrale","icon":"bar","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/bar/Bar Sport":{"tags":{"name":"Bar Sport","amenity":"bar"},"name":"Bar Sport","icon":"bar","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/bar/Beach Bar":{"tags":{"name":"Beach Bar","amenity":"bar"},"name":"Beach Bar","icon":"bar","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/bar/Pool Bar":{"tags":{"name":"Pool Bar","amenity":"bar"},"name":"Pool Bar","icon":"bar","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/bicycle_rental/Bicing":{"tags":{"name":"Bicing","amenity":"bicycle_rental"},"name":"Bicing","icon":"bicycle","geometry":["point","vertex","area"],"fields":["capacity","network","operator","payment_multi"],"suggestion":true},"amenity/bicycle_rental/Call a Bike":{"tags":{"name":"Call a Bike","amenity":"bicycle_rental"},"name":"Call a Bike","icon":"bicycle","geometry":["point","vertex","area"],"fields":["capacity","network","operator","payment_multi"],"suggestion":true},"amenity/bicycle_rental/Grid":{"tags":{"name":"Grid","amenity":"bicycle_rental"},"name":"Grid","icon":"bicycle","geometry":["point","vertex","area"],"fields":["capacity","network","operator","payment_multi"],"suggestion":true},"amenity/bicycle_rental/Mibici":{"tags":{"name":"Mibici","amenity":"bicycle_rental"},"name":"Mibici","icon":"bicycle","geometry":["point","vertex","area"],"fields":["capacity","network","operator","payment_multi"],"suggestion":true},"amenity/bicycle_rental/metropolradruhr":{"tags":{"name":"metropolradruhr","amenity":"bicycle_rental"},"name":"metropolradruhr","icon":"bicycle","geometry":["point","vertex","area"],"fields":["capacity","network","operator","payment_multi"],"suggestion":true},"amenity/bureau_de_change/Abitab":{"tags":{"name":"Abitab","amenity":"bureau_de_change"},"name":"Abitab","icon":"bank","geometry":["point","vertex"],"fields":["name","operator","currency_multi"],"suggestion":true},"amenity/bureau_de_change/Change":{"tags":{"name":"Change","amenity":"bureau_de_change"},"name":"Change","icon":"bank","geometry":["point","vertex"],"fields":["name","operator","currency_multi"],"suggestion":true},"amenity/bureau_de_change/Travelex":{"tags":{"name":"Travelex","amenity":"bureau_de_change"},"name":"Travelex","icon":"bank","geometry":["point","vertex"],"fields":["name","operator","currency_multi"],"suggestion":true},"amenity/cafe/85度C":{"tags":{"name":"85度C","amenity":"cafe"},"name":"85度C","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Bar Kafe":{"tags":{"name":"Bar Kafe","amenity":"cafe"},"name":"Bar Kafe","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Barista":{"tags":{"name":"Barista","amenity":"cafe"},"name":"Barista","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Bonafide":{"tags":{"name":"Bonafide","amenity":"cafe"},"name":"Bonafide","icon":"cafe","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Cafe Nero":{"tags":{"name":"Cafe Nero","amenity":"cafe"},"name":"Cafe Nero","icon":"cafe","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Cafetería":{"tags":{"name":"Cafetería","amenity":"cafe"},"name":"Cafetería","icon":"cafe","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Café Amazon":{"tags":{"name":"Café Amazon","amenity":"cafe"},"name":"Café Amazon","icon":"cafe","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Café de la Place":{"tags":{"name":"Café de la Place","amenity":"cafe"},"name":"Café de la Place","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Café des Sports":{"tags":{"name":"Café des Sports","amenity":"cafe"},"name":"Café des Sports","icon":"cafe","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Coffee Fellows":{"tags":{"name":"Coffee Fellows","amenity":"cafe"},"name":"Coffee Fellows","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Coffee House":{"tags":{"name":"Coffee House","amenity":"cafe"},"name":"Coffee House","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Coffee Island":{"tags":{"name":"Coffee Island","amenity":"cafe"},"name":"Coffee Island","icon":"cafe","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Country Style":{"tags":{"name":"Country Style","amenity":"cafe"},"name":"Country Style","icon":"cafe","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Eiscafe Dolomiti":{"tags":{"name":"Eiscafe Dolomiti","amenity":"cafe"},"name":"Eiscafe Dolomiti","icon":"cafe","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Havanna":{"tags":{"name":"Havanna","amenity":"cafe"},"name":"Havanna","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Internet Cafe":{"tags":{"name":"Internet Cafe","amenity":"cafe"},"name":"Internet Cafe","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Kafe":{"tags":{"name":"Kafe","amenity":"cafe"},"name":"Kafe","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Krispy Kreme":{"tags":{"name":"Krispy Kreme","amenity":"cafe"},"name":"Krispy Kreme","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Le Pain Quotidien":{"tags":{"name":"Le Pain Quotidien","amenity":"cafe"},"name":"Le Pain Quotidien","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/McCafé":{"tags":{"name":"McCafé","amenity":"cafe","cuisine":"coffee_shop"},"name":"McCafé","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Peet's Coffee & Tea":{"tags":{"name":"Peet's Coffee & Tea","amenity":"cafe"},"name":"Peet's Coffee & Tea","icon":"cafe","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Prime":{"tags":{"name":"Prime","amenity":"cafe"},"name":"Prime","icon":"cafe","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Starbucks":{"tags":{"name":"Starbucks","cuisine":"coffee_shop","amenity":"cafe"},"name":"Starbucks","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/The Coffee Bean & Tea Leaf":{"tags":{"name":"The Coffee Bean & Tea Leaf","amenity":"cafe"},"name":"The Coffee Bean & Tea Leaf","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/The Coffee Club":{"tags":{"name":"The Coffee Club","amenity":"cafe"},"name":"The Coffee Club","icon":"cafe","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Tim Hortons":{"tags":{"name":"Tim Hortons","amenity":"cafe"},"name":"Tim Hortons","icon":"cafe","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Wayne's Coffee":{"tags":{"name":"Wayne's Coffee","amenity":"cafe"},"name":"Wayne's Coffee","icon":"cafe","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/car_rental/Alamo":{"tags":{"name":"Alamo","amenity":"car_rental"},"name":"Alamo","icon":"car","geometry":["point","area"],"fields":["name","operator","payment_multi"],"suggestion":true},"amenity/car_rental/Avis":{"tags":{"name":"Avis","amenity":"car_rental"},"name":"Avis","icon":"car","geometry":["point","area"],"fields":["name","operator","payment_multi"],"suggestion":true},"amenity/car_rental/Budget":{"tags":{"name":"Budget","amenity":"car_rental"},"name":"Budget","icon":"car","geometry":["point","area"],"fields":["name","operator","payment_multi"],"suggestion":true},"amenity/car_rental/Enterprise":{"tags":{"name":"Enterprise","amenity":"car_rental"},"name":"Enterprise","icon":"car","geometry":["point","area"],"fields":["name","operator","payment_multi"],"suggestion":true},"amenity/car_rental/Enterprise Rent-a-Car":{"tags":{"name":"Enterprise Rent-a-Car","amenity":"car_rental"},"name":"Enterprise Rent-a-Car","icon":"car","geometry":["point","area"],"fields":["name","operator","payment_multi"],"suggestion":true},"amenity/car_rental/Europcar":{"tags":{"name":"Europcar","amenity":"car_rental"},"name":"Europcar","icon":"car","geometry":["point","area"],"fields":["name","operator","payment_multi"],"suggestion":true},"amenity/car_rental/Hertz":{"tags":{"name":"Hertz","amenity":"car_rental"},"name":"Hertz","icon":"car","geometry":["point","area"],"fields":["name","operator","payment_multi"],"suggestion":true},"amenity/car_rental/Localiza":{"tags":{"name":"Localiza","amenity":"car_rental"},"name":"Localiza","icon":"car","geometry":["point","area"],"fields":["name","operator","payment_multi"],"suggestion":true},"amenity/car_rental/Sixt":{"tags":{"name":"Sixt","amenity":"car_rental"},"name":"Sixt","icon":"car","geometry":["point","area"],"fields":["name","operator","payment_multi"],"suggestion":true},"amenity/car_rental/Thrifty":{"tags":{"name":"Thrifty","amenity":"car_rental"},"name":"Thrifty","icon":"car","geometry":["point","area"],"fields":["name","operator","payment_multi"],"suggestion":true},"amenity/car_rental/U-Haul":{"tags":{"name":"U-Haul","amenity":"car_rental"},"name":"U-Haul","icon":"car","geometry":["point","area"],"fields":["name","operator","payment_multi"],"suggestion":true},"amenity/car_rental/オリックスレンタカー":{"tags":{"name":"オリックスレンタカー","amenity":"car_rental"},"name":"オリックスレンタカー","icon":"car","geometry":["point","area"],"fields":["name","operator","payment_multi"],"suggestion":true},"amenity/car_rental/トヨタレンタカー":{"tags":{"name":"トヨタレンタカー","amenity":"car_rental"},"name":"トヨタレンタカー","icon":"car","geometry":["point","area"],"fields":["name","operator","payment_multi"],"suggestion":true},"amenity/car_rental/トヨタレンタリース":{"tags":{"name":"トヨタレンタリース","amenity":"car_rental"},"name":"トヨタレンタリース","icon":"car","geometry":["point","area"],"fields":["name","operator","payment_multi"],"suggestion":true},"amenity/car_rental/ニッポンレンタカー":{"tags":{"name":"ニッポンレンタカー","amenity":"car_rental"},"name":"ニッポンレンタカー","icon":"car","geometry":["point","area"],"fields":["name","operator","payment_multi"],"suggestion":true},"amenity/car_wash/Autolavaggio":{"tags":{"name":"Autolavaggio","amenity":"car_wash"},"name":"Autolavaggio","icon":"car","geometry":["point","area"],"fields":["address","building_area","opening_hours","payment_multi"],"suggestion":true},"amenity/car_wash/H-E-B Car Wash":{"tags":{"name":"H-E-B Car Wash","amenity":"car_wash"},"name":"H-E-B Car Wash","icon":"car","geometry":["point","area"],"fields":["address","building_area","opening_hours","payment_multi"],"suggestion":true},"amenity/car_wash/Lavage Auto":{"tags":{"name":"Lavage Auto","amenity":"car_wash"},"name":"Lavage Auto","icon":"car","geometry":["point","area"],"fields":["address","building_area","opening_hours","payment_multi"],"suggestion":true},"amenity/car_wash/Lavazh":{"tags":{"name":"Lavazh","amenity":"car_wash"},"name":"Lavazh","icon":"car","geometry":["point","area"],"fields":["address","building_area","opening_hours","payment_multi"],"suggestion":true},"amenity/car_wash/Myjnia":{"tags":{"name":"Myjnia","amenity":"car_wash"},"name":"Myjnia","icon":"car","geometry":["point","area"],"fields":["address","building_area","opening_hours","payment_multi"],"suggestion":true},"amenity/car_wash/Myjnia bezdotykowa":{"tags":{"name":"Myjnia bezdotykowa","amenity":"car_wash"},"name":"Myjnia bezdotykowa","icon":"car","geometry":["point","area"],"fields":["address","building_area","opening_hours","payment_multi"],"suggestion":true},"amenity/car_wash/Myjnia samochodowa":{"tags":{"name":"Myjnia samochodowa","amenity":"car_wash"},"name":"Myjnia samochodowa","icon":"car","geometry":["point","area"],"fields":["address","building_area","opening_hours","payment_multi"],"suggestion":true},"amenity/car_wash/Spălătorie Auto":{"tags":{"name":"Spălătorie Auto","amenity":"car_wash"},"name":"Spălătorie Auto","icon":"car","geometry":["point","area"],"fields":["address","building_area","opening_hours","payment_multi"],"suggestion":true},"amenity/car_wash/Spălătorie auto":{"tags":{"name":"Spălătorie auto","amenity":"car_wash"},"name":"Spălătorie auto","icon":"car","geometry":["point","area"],"fields":["address","building_area","opening_hours","payment_multi"],"suggestion":true},"amenity/car_wash/Автомийка":{"tags":{"name":"Автомийка","amenity":"car_wash"},"name":"Автомийка","icon":"car","geometry":["point","area"],"fields":["address","building_area","opening_hours","payment_multi"],"suggestion":true},"amenity/cinema/Cinema City":{"tags":{"name":"Cinema City","amenity":"cinema"},"name":"Cinema City","icon":"cinema","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","payment_multi"],"suggestion":true},"amenity/cinema/Cinemark":{"tags":{"name":"Cinemark","amenity":"cinema"},"name":"Cinemark","icon":"cinema","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","payment_multi"],"suggestion":true},"amenity/cinema/Cinemex":{"tags":{"name":"Cinemex","amenity":"cinema"},"name":"Cinemex","icon":"cinema","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","payment_multi"],"suggestion":true},"amenity/cinema/Cinepolis":{"tags":{"name":"Cinepolis","amenity":"cinema"},"name":"Cinepolis","icon":"cinema","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","payment_multi"],"suggestion":true},"amenity/cinema/Cineworld":{"tags":{"name":"Cineworld","amenity":"cinema"},"name":"Cineworld","icon":"cinema","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","payment_multi"],"suggestion":true},"amenity/cinema/Odeon":{"tags":{"name":"Odeon","amenity":"cinema"},"name":"Odeon","icon":"cinema","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","payment_multi"],"suggestion":true},"amenity/clinic/ФАП":{"tags":{"name":"ФАП","healthcare":"clinic","amenity":"clinic"},"name":"ФАП","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"suggestion":true},"amenity/dentist/Aspen Dental":{"tags":{"name":"Aspen Dental","healthcare":"dentist","amenity":"dentist"},"name":"Aspen Dental","icon":"dentist","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"suggestion":true},"amenity/dentist/Family Dentistry":{"tags":{"name":"Family Dentistry","healthcare":"dentist","amenity":"dentist"},"name":"Family Dentistry","icon":"dentist","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"suggestion":true},"amenity/dentist/Vitaldent":{"tags":{"name":"Vitaldent","healthcare":"dentist","amenity":"dentist"},"name":"Vitaldent","icon":"dentist","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"suggestion":true},"amenity/dentist/Стоматолог":{"tags":{"name":"Стоматолог","healthcare":"dentist","amenity":"dentist"},"name":"Стоматолог","icon":"dentist","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"suggestion":true},"amenity/dentist/Стоматологія":{"tags":{"name":"Стоматологія","healthcare":"dentist","amenity":"dentist"},"name":"Стоматологія","icon":"dentist","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"suggestion":true},"amenity/doctors/Háziorvosi rendelő":{"tags":{"name":"Háziorvosi rendelő","healthcare":"doctor","amenity":"doctors"},"name":"Háziorvosi rendelő","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"suggestion":true},"amenity/doctors/Инвитро":{"tags":{"name":"Инвитро","healthcare":"doctor","amenity":"doctors"},"name":"Инвитро","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"suggestion":true},"amenity/driving_school/Автодром":{"tags":{"name":"Автодром","amenity":"driving_school"},"name":"Автодром","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"amenity/fast_food/A&W":{"tags":{"name":"A&W","amenity":"fast_food"},"name":"A&W","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Angel's Burger":{"tags":{"name":"Angel's Burger","amenity":"fast_food"},"name":"Angel's Burger","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Antalya":{"tags":{"name":"Antalya","amenity":"fast_food"},"name":"Antalya","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Asia Bistro":{"tags":{"name":"Asia Bistro","amenity":"fast_food"},"name":"Asia Bistro","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Asia Wok":{"tags":{"name":"Asia Wok","amenity":"fast_food"},"name":"Asia Wok","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Bistro":{"tags":{"name":"Bistro","amenity":"fast_food"},"name":"Bistro","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Bob's":{"tags":{"name":"Bob's","amenity":"fast_food"},"name":"Bob's","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Bojangles":{"tags":{"name":"Bojangles","amenity":"fast_food"},"name":"Bojangles","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Booster Juice":{"tags":{"name":"Booster Juice","amenity":"fast_food"},"name":"Booster Juice","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Braum's":{"tags":{"name":"Braum's","amenity":"fast_food"},"name":"Braum's","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Burger Machine":{"tags":{"name":"Burger Machine","amenity":"fast_food"},"name":"Burger Machine","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Büfé":{"tags":{"name":"Büfé","amenity":"fast_food"},"name":"Büfé","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Captain D's":{"tags":{"name":"Captain D's","amenity":"fast_food"},"name":"Captain D's","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Chicken Express":{"tags":{"name":"Chicken Express","amenity":"fast_food"},"name":"Chicken Express","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/CoCo壱番屋":{"tags":{"name":"CoCo壱番屋","amenity":"fast_food"},"name":"CoCo壱番屋","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Cold Stone Creamery":{"tags":{"name":"Cold Stone Creamery","amenity":"fast_food"},"name":"Cold Stone Creamery","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Cook Out":{"tags":{"name":"Cook Out","amenity":"fast_food"},"name":"Cook Out","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/DQ":{"tags":{"name":"DQ","amenity":"fast_food"},"name":"DQ","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Everest":{"tags":{"name":"Everest","amenity":"fast_food"},"name":"Everest","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Extreme Pita":{"tags":{"name":"Extreme Pita","amenity":"fast_food"},"name":"Extreme Pita","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Fazoli's":{"tags":{"name":"Fazoli's","amenity":"fast_food"},"name":"Fazoli's","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Firehouse Subs":{"tags":{"name":"Firehouse Subs","amenity":"fast_food"},"name":"Firehouse Subs","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Fish and Chips":{"tags":{"name":"Fish and Chips","amenity":"fast_food"},"name":"Fish and Chips","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Greenwich":{"tags":{"name":"Greenwich","amenity":"fast_food"},"name":"Greenwich","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Habib's":{"tags":{"name":"Habib's","amenity":"fast_food"},"name":"Habib's","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Istanbul Kebab":{"tags":{"name":"Istanbul Kebab","amenity":"fast_food"},"name":"Istanbul Kebab","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Jersey Mike's Subs":{"tags":{"name":"Jersey Mike's Subs","amenity":"fast_food"},"name":"Jersey Mike's Subs","icon":"fast-food","geometry":["point","area"],"fields":["name","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","cuisine":"sandwich","amenity":"fast_food"},"name":"Jimmy John's","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/KFC/Taco Bell":{"tags":{"name":"KFC/Taco Bell","amenity":"fast_food"},"name":"KFC/Taco Bell","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Kebab House":{"tags":{"name":"Kebab House","amenity":"fast_food"},"name":"Kebab House","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Kebabai":{"tags":{"name":"Kebabai","amenity":"fast_food"},"name":"Kebabai","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Krystal":{"tags":{"name":"Krystal","amenity":"fast_food"},"name":"Krystal","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Little Caesars Pizza":{"tags":{"name":"Little Caesars Pizza","amenity":"fast_food"},"name":"Little Caesars Pizza","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Lotteria":{"tags":{"name":"Lotteria","amenity":"fast_food"},"name":"Lotteria","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Max":{"tags":{"name":"Max","amenity":"fast_food"},"name":"Max","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Minute Burger":{"tags":{"name":"Minute Burger","amenity":"fast_food"},"name":"Minute Burger","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/New York Pizza":{"tags":{"name":"New York Pizza","amenity":"fast_food"},"name":"New York Pizza","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Papa Murphy's":{"tags":{"name":"Papa Murphy's","amenity":"fast_food"},"name":"Papa Murphy's","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Pinulito":{"tags":{"name":"Pinulito","amenity":"fast_food"},"name":"Pinulito","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Pita Pit":{"tags":{"name":"Pita Pit","amenity":"fast_food"},"name":"Pita Pit","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Pizza Hut Delivery":{"tags":{"name":"Pizza Hut Delivery","amenity":"fast_food"},"name":"Pizza Hut Delivery","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Pizza King":{"tags":{"name":"Pizza King","amenity":"fast_food"},"name":"Pizza King","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Pollo Granjero":{"tags":{"name":"Pollo Granjero","amenity":"fast_food"},"name":"Pollo Granjero","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Popeyes Louisiana Kitchen":{"tags":{"name":"Popeyes Louisiana Kitchen","amenity":"fast_food"},"name":"Popeyes Louisiana Kitchen","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Qdoba":{"tags":{"name":"Qdoba","amenity":"fast_food"},"name":"Qdoba","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Quick":{"tags":{"name":"Quick","amenity":"fast_food"},"name":"Quick","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Quiznos":{"tags":{"name":"Quiznos","amenity":"fast_food"},"name":"Quiznos","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Rally's":{"tags":{"name":"Rally's","amenity":"fast_food"},"name":"Rally's","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Sbarro":{"tags":{"name":"Sbarro","amenity":"fast_food"},"name":"Sbarro","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Schlotzsky's Deli":{"tags":{"name":"Schlotzsky's Deli","amenity":"fast_food"},"name":"Schlotzsky's Deli","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Subway":{"tags":{"name":"Subway","amenity":"fast_food"},"name":"Subway","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Taco Bueno":{"tags":{"name":"Taco Bueno","amenity":"fast_food"},"name":"Taco Bueno","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Taco Cabana":{"tags":{"name":"Taco Cabana","amenity":"fast_food"},"name":"Taco Cabana","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Taco Del Mar":{"tags":{"name":"Taco Del Mar","amenity":"fast_food"},"name":"Taco Del Mar","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Thai Express":{"tags":{"name":"Thai Express","amenity":"fast_food"},"name":"Thai Express","icon":"fast-food","geometry":["point","area"],"fields":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/The Pizza Company":{"tags":{"name":"The Pizza Company","amenity":"fast_food"},"name":"The Pizza Company","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Wienerschnitzel":{"tags":{"name":"Wienerschnitzel","amenity":"fast_food"},"name":"Wienerschnitzel","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Стардог!s":{"tags":{"name":"Стардог!s","amenity":"fast_food"},"name":"Стардог!s","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/ケンタッキーフライドチキン":{"tags":{"name":"ケンタッキーフライドチキン","cuisine":"chicken","name:en":"KFC","amenity":"fast_food"},"name":"ケンタッキーフライドチキン","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/マクドナルド":{"tags":{"name":"マクドナルド","cuisine":"burger","name:en":"McDonald's","amenity":"fast_food"},"name":"マクドナルド","icon":"fast-food","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fuel/76":{"tags":{"name":"76","amenity":"fuel"},"name":"76","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_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":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/ADNOC":{"tags":{"name":"ADNOC","amenity":"fuel"},"name":"ADNOC","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/ANP":{"tags":{"name":"ANP","amenity":"fuel"},"name":"ANP","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/ARAL":{"tags":{"name":"ARAL","amenity":"fuel"},"name":"ARAL","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Aegean":{"tags":{"name":"Aegean","amenity":"fuel"},"name":"Aegean","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Afriquia":{"tags":{"name":"Afriquia","amenity":"fuel"},"name":"Afriquia","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Agip":{"tags":{"name":"Agip","amenity":"fuel"},"name":"Agip","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Agrola":{"tags":{"name":"Agrola","amenity":"fuel"},"name":"Agrola","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Alon":{"tags":{"name":"Alon","amenity":"fuel"},"name":"Alon","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Alpet":{"tags":{"name":"Alpet","amenity":"fuel"},"name":"Alpet","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Api":{"tags":{"name":"Api","amenity":"fuel"},"name":"Api","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Aral":{"tags":{"name":"Aral","amenity":"fuel"},"name":"Aral","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Arco":{"tags":{"name":"Arco","amenity":"fuel"},"name":"Arco","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Avanti":{"tags":{"name":"Avanti","amenity":"fuel"},"name":"Avanti","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Avia":{"tags":{"name":"Avia","amenity":"fuel"},"name":"Avia","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/BEBECO":{"tags":{"name":"BEBECO","amenity":"fuel"},"name":"BEBECO","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/BFT":{"tags":{"name":"BFT","amenity":"fuel"},"name":"BFT","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/BHPetrol":{"tags":{"name":"BHPetrol","amenity":"fuel"},"name":"BHPetrol","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/BP":{"tags":{"name":"BP","amenity":"fuel"},"name":"BP","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/BR":{"tags":{"name":"BR","amenity":"fuel"},"name":"BR","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Bangchak":{"tags":{"name":"Bangchak","amenity":"fuel"},"name":"Bangchak","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Benzina":{"tags":{"name":"Benzina","amenity":"fuel"},"name":"Benzina","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Bharat Petroleum":{"tags":{"name":"Bharat Petroleum","amenity":"fuel"},"name":"Bharat Petroleum","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Bliska":{"tags":{"name":"Bliska","amenity":"fuel"},"name":"Bliska","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/CAMPSA":{"tags":{"name":"CAMPSA","amenity":"fuel"},"name":"CAMPSA","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/CARREFOUR":{"tags":{"name":"CARREFOUR","amenity":"fuel"},"name":"CARREFOUR","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/CEPSA":{"tags":{"name":"CEPSA","amenity":"fuel"},"name":"CEPSA","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/CNG":{"tags":{"name":"CNG","amenity":"fuel"},"name":"CNG","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Caltex":{"tags":{"name":"Caltex","amenity":"fuel"},"name":"Caltex","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Campsa":{"tags":{"name":"Campsa","amenity":"fuel"},"name":"Campsa","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_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":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Cenex":{"tags":{"name":"Cenex","amenity":"fuel"},"name":"Cenex","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Cepsa":{"tags":{"name":"Cepsa","amenity":"fuel"},"name":"Cepsa","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Ceypetco":{"tags":{"name":"Ceypetco","amenity":"fuel"},"name":"Ceypetco","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Chevron":{"tags":{"name":"Chevron","amenity":"fuel"},"name":"Chevron","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Citgo":{"tags":{"name":"Citgo","amenity":"fuel"},"name":"Citgo","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Clark":{"tags":{"name":"Clark","amenity":"fuel"},"name":"Clark","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Coles Express":{"tags":{"name":"Coles Express","amenity":"fuel"},"name":"Coles Express","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Conoco":{"tags":{"name":"Conoco","amenity":"fuel"},"name":"Conoco","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Copec":{"tags":{"name":"Copec","amenity":"fuel"},"name":"Copec","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Copetrol":{"tags":{"name":"Copetrol","amenity":"fuel"},"name":"Copetrol","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Cosmo":{"tags":{"name":"Cosmo","amenity":"fuel"},"name":"Cosmo","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Costco Gas":{"tags":{"name":"Costco Gas","amenity":"fuel"},"name":"Costco Gas","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Costco Gasoline":{"tags":{"name":"Costco Gasoline","amenity":"fuel"},"name":"Costco Gasoline","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Crodux":{"tags":{"name":"Crodux","amenity":"fuel"},"name":"Crodux","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Delta":{"tags":{"name":"Delta","amenity":"fuel"},"name":"Delta","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Diamond Shamrock":{"tags":{"name":"Diamond Shamrock","amenity":"fuel"},"name":"Diamond Shamrock","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Drummed Fuel":{"tags":{"name":"Drummed Fuel","amenity":"fuel"},"name":"Drummed Fuel","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/EKO":{"tags":{"name":"EKO","amenity":"fuel"},"name":"EKO","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/ENEOS":{"tags":{"name":"ENEOS","amenity":"fuel"},"name":"ENEOS","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/ENI":{"tags":{"name":"ENI","amenity":"fuel"},"name":"ENI","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/ERG":{"tags":{"name":"ERG","amenity":"fuel"},"name":"ERG","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Elan":{"tags":{"name":"Elan","amenity":"fuel"},"name":"Elan","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Eneos":{"tags":{"name":"Eneos","amenity":"fuel"},"name":"Eneos","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Engen":{"tags":{"name":"Engen","amenity":"fuel"},"name":"Engen","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Eni":{"tags":{"name":"Eni","amenity":"fuel"},"name":"Eni","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Erg":{"tags":{"name":"Erg","amenity":"fuel"},"name":"Erg","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Esso":{"tags":{"name":"Esso","amenity":"fuel"},"name":"Esso","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Esso Express":{"tags":{"name":"Esso Express","amenity":"fuel"},"name":"Esso Express","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/EuroOil":{"tags":{"name":"EuroOil","amenity":"fuel"},"name":"EuroOil","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Exxon":{"tags":{"name":"Exxon","amenity":"fuel"},"name":"Exxon","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/F24":{"tags":{"name":"F24","amenity":"fuel"},"name":"F24","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Firezone":{"tags":{"name":"Firezone","amenity":"fuel"},"name":"Firezone","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Flying V":{"tags":{"name":"Flying V","amenity":"fuel"},"name":"Flying V","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/GALP":{"tags":{"name":"GALP","amenity":"fuel"},"name":"GALP","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Gazprom":{"tags":{"name":"Gazprom","amenity":"fuel"},"name":"Gazprom","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/GetGo":{"tags":{"name":"GetGo","amenity":"fuel"},"name":"GetGo","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Goil":{"tags":{"name":"Goil","amenity":"fuel"},"name":"Goil","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Gulf":{"tags":{"name":"Gulf","amenity":"fuel"},"name":"Gulf","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/H-E-B Fuel":{"tags":{"name":"H-E-B Fuel","amenity":"fuel"},"name":"H-E-B Fuel","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/H-E-B Gas":{"tags":{"name":"H-E-B Gas","amenity":"fuel"},"name":"H-E-B Gas","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/HEM":{"tags":{"name":"HEM","amenity":"fuel"},"name":"HEM","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/HP":{"tags":{"name":"HP","amenity":"fuel"},"name":"HP","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/HP Petrol Pump":{"tags":{"name":"HP Petrol Pump","amenity":"fuel"},"name":"HP Petrol Pump","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Helios":{"tags":{"name":"Helios","amenity":"fuel"},"name":"Helios","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Hess":{"tags":{"name":"Hess","amenity":"fuel"},"name":"Hess","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Hindustan Petroleum":{"tags":{"name":"Hindustan Petroleum","amenity":"fuel"},"name":"Hindustan Petroleum","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Holiday":{"tags":{"name":"Holiday","amenity":"fuel"},"name":"Holiday","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Husky":{"tags":{"name":"Husky","amenity":"fuel"},"name":"Husky","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/IES":{"tags":{"name":"IES","amenity":"fuel"},"name":"IES","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/IP":{"tags":{"name":"IP","amenity":"fuel"},"name":"IP","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Independent Fuel Station":{"tags":{"name":"Independent Fuel Station","amenity":"fuel"},"name":"Independent Fuel Station","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Indian Oil":{"tags":{"name":"Indian Oil","amenity":"fuel"},"name":"Indian Oil","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Indipend.":{"tags":{"name":"Indipend.","amenity":"fuel"},"name":"Indipend.","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Ingo":{"tags":{"name":"Ingo","amenity":"fuel"},"name":"Ingo","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Ipiranga":{"tags":{"name":"Ipiranga","amenity":"fuel"},"name":"Ipiranga","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Irving":{"tags":{"name":"Irving","amenity":"fuel"},"name":"Irving","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/JA-SS":{"tags":{"name":"JA-SS","amenity":"fuel"},"name":"JA-SS","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/JOMO":{"tags":{"name":"JOMO","amenity":"fuel"},"name":"JOMO","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Jet":{"tags":{"name":"Jet","amenity":"fuel"},"name":"Jet","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Jetti":{"tags":{"name":"Jetti","amenity":"fuel"},"name":"Jetti","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Kangaroo":{"tags":{"name":"Kangaroo","amenity":"fuel"},"name":"Kangaroo","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Kobil":{"tags":{"name":"Kobil","amenity":"fuel"},"name":"Kobil","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Kroger Fuel":{"tags":{"name":"Kroger Fuel","amenity":"fuel"},"name":"Kroger Fuel","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Kum & Go":{"tags":{"name":"Kum & Go","amenity":"fuel"},"name":"Kum & Go","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Kwik Trip":{"tags":{"name":"Kwik Trip","amenity":"fuel"},"name":"Kwik Trip","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/LPG":{"tags":{"name":"LPG","amenity":"fuel"},"name":"LPG","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/LPG Station":{"tags":{"name":"LPG Station","amenity":"fuel"},"name":"LPG Station","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/LUKOIL":{"tags":{"name":"LUKOIL","amenity":"fuel"},"name":"LUKOIL","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Liberty":{"tags":{"name":"Liberty","amenity":"fuel"},"name":"Liberty","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Lotos":{"tags":{"name":"Lotos","amenity":"fuel"},"name":"Lotos","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Lotos Optima":{"tags":{"name":"Lotos Optima","amenity":"fuel"},"name":"Lotos Optima","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Love's":{"tags":{"name":"Love's","amenity":"fuel"},"name":"Love's","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Lukoil":{"tags":{"name":"Lukoil","amenity":"fuel"},"name":"Lukoil","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/MEROIL":{"tags":{"name":"MEROIL","amenity":"fuel"},"name":"MEROIL","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/MOL":{"tags":{"name":"MOL","amenity":"fuel"},"name":"MOL","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/MRS":{"tags":{"name":"MRS","amenity":"fuel"},"name":"MRS","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Marathon":{"tags":{"name":"Marathon","amenity":"fuel"},"name":"Marathon","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Maverik":{"tags":{"name":"Maverik","amenity":"fuel"},"name":"Maverik","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Maxol":{"tags":{"name":"Maxol","amenity":"fuel"},"name":"Maxol","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Metano":{"tags":{"name":"Metano","amenity":"fuel"},"name":"Metano","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Migrol":{"tags":{"name":"Migrol","amenity":"fuel"},"name":"Migrol","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Minipump":{"tags":{"name":"Minipump","amenity":"fuel"},"name":"Minipump","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Mobil":{"tags":{"name":"Mobil","amenity":"fuel"},"name":"Mobil","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Mobile":{"tags":{"name":"Mobile","amenity":"fuel"},"name":"Mobile","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Mol":{"tags":{"name":"Mol","amenity":"fuel"},"name":"Mol","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Moya":{"tags":{"name":"Moya","amenity":"fuel"},"name":"Moya","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Murphy USA":{"tags":{"name":"Murphy USA","amenity":"fuel"},"name":"Murphy USA","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Neste":{"tags":{"name":"Neste","amenity":"fuel"},"name":"Neste","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/OIL!":{"tags":{"name":"OIL!","amenity":"fuel"},"name":"OIL!","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/OK":{"tags":{"name":"OK","amenity":"fuel"},"name":"OK","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/OKQ8":{"tags":{"name":"OKQ8","amenity":"fuel"},"name":"OKQ8","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/OMV":{"tags":{"name":"OMV","amenity":"fuel"},"name":"OMV","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Oilibya":{"tags":{"name":"Oilibya","amenity":"fuel"},"name":"Oilibya","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Opet":{"tags":{"name":"Opet","amenity":"fuel"},"name":"Opet","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Orlen":{"tags":{"name":"Orlen","amenity":"fuel"},"name":"Orlen","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/PETRONOR":{"tags":{"name":"PETRONOR","amenity":"fuel"},"name":"PETRONOR","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/PSO":{"tags":{"name":"PSO","amenity":"fuel"},"name":"PSO","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/PSO Petrol Pump":{"tags":{"name":"PSO Petrol Pump","amenity":"fuel"},"name":"PSO Petrol Pump","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/PT":{"tags":{"name":"PT","amenity":"fuel"},"name":"PT","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/PTT":{"tags":{"name":"PTT","amenity":"fuel"},"name":"PTT","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/PV Oil":{"tags":{"name":"PV Oil","amenity":"fuel"},"name":"PV Oil","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Pacific Pride":{"tags":{"name":"Pacific Pride","amenity":"fuel"},"name":"Pacific Pride","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Pecsa":{"tags":{"name":"Pecsa","amenity":"fuel"},"name":"Pecsa","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Pemex":{"tags":{"name":"Pemex","amenity":"fuel"},"name":"Pemex","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Pertamina":{"tags":{"name":"Pertamina","amenity":"fuel"},"name":"Pertamina","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Petro":{"tags":{"name":"Petro","amenity":"fuel"},"name":"Petro","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Petro-Canada":{"tags":{"name":"Petro-Canada","amenity":"fuel"},"name":"Petro-Canada","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Petrobras":{"tags":{"name":"Petrobras","amenity":"fuel"},"name":"Petrobras","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Petrochina":{"tags":{"name":"Petrochina","amenity":"fuel"},"name":"Petrochina","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Petroecuador":{"tags":{"name":"Petroecuador","amenity":"fuel"},"name":"Petroecuador","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Petrol Ofisi":{"tags":{"name":"Petrol Ofisi","amenity":"fuel"},"name":"Petrol Ofisi","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Petrolimex":{"tags":{"name":"Petrolimex","amenity":"fuel"},"name":"Petrolimex","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Petrom":{"tags":{"name":"Petrom","amenity":"fuel"},"name":"Petrom","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Petron":{"tags":{"name":"Petron","amenity":"fuel"},"name":"Petron","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Petronas":{"tags":{"name":"Petronas","amenity":"fuel"},"name":"Petronas","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Petroperu":{"tags":{"name":"Petroperu","amenity":"fuel"},"name":"Petroperu","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Phillips 66":{"tags":{"name":"Phillips 66","amenity":"fuel"},"name":"Phillips 66","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Phoenix":{"tags":{"name":"Phoenix","amenity":"fuel"},"name":"Phoenix","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Pilot":{"tags":{"name":"Pilot","amenity":"fuel"},"name":"Pilot","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Pioneer":{"tags":{"name":"Pioneer","amenity":"fuel"},"name":"Pioneer","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Posto":{"tags":{"name":"Posto","amenity":"fuel"},"name":"Posto","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Posto Atem":{"tags":{"name":"Posto Atem","amenity":"fuel"},"name":"Posto Atem","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Posto BR":{"tags":{"name":"Posto BR","amenity":"fuel"},"name":"Posto BR","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Posto Ipiranga":{"tags":{"name":"Posto Ipiranga","amenity":"fuel"},"name":"Posto Ipiranga","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Posto Shell":{"tags":{"name":"Posto Shell","amenity":"fuel"},"name":"Posto Shell","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Primax":{"tags":{"name":"Primax","amenity":"fuel"},"name":"Primax","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Prio":{"tags":{"name":"Prio","amenity":"fuel"},"name":"Prio","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Puma":{"tags":{"name":"Puma","amenity":"fuel"},"name":"Puma","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Q1":{"tags":{"name":"Q1","amenity":"fuel"},"name":"Q1","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Q8":{"tags":{"name":"Q8","amenity":"fuel"},"name":"Q8","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Q8 Easy":{"tags":{"name":"Q8 Easy","amenity":"fuel"},"name":"Q8 Easy","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/QuikTrip":{"tags":{"name":"QuikTrip","amenity":"fuel"},"name":"QuikTrip","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/REPSOL":{"tags":{"name":"REPSOL","amenity":"fuel"},"name":"REPSOL","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/RaceTrac":{"tags":{"name":"RaceTrac","amenity":"fuel"},"name":"RaceTrac","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Repsol":{"tags":{"name":"Repsol","amenity":"fuel"},"name":"Repsol","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Rompetrol":{"tags":{"name":"Rompetrol","amenity":"fuel"},"name":"Rompetrol","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Rubis":{"tags":{"name":"Rubis","amenity":"fuel"},"name":"Rubis","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/SB Tank":{"tags":{"name":"SB Tank","amenity":"fuel"},"name":"SB Tank","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/SPBU":{"tags":{"name":"SPBU","amenity":"fuel"},"name":"SPBU","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Sasol":{"tags":{"name":"Sasol","amenity":"fuel"},"name":"Sasol","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Sea Oil":{"tags":{"name":"Sea Oil","amenity":"fuel"},"name":"Sea Oil","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Sheetz":{"tags":{"name":"Sheetz","amenity":"fuel"},"name":"Sheetz","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Shell":{"tags":{"name":"Shell","amenity":"fuel"},"name":"Shell","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Shell Express":{"tags":{"name":"Shell Express","amenity":"fuel"},"name":"Shell Express","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Sinclair":{"tags":{"name":"Sinclair","amenity":"fuel"},"name":"Sinclair","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Sinopec":{"tags":{"name":"Sinopec","amenity":"fuel"},"name":"Sinopec","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Sinopec Fuel":{"tags":{"name":"Sinopec Fuel","amenity":"fuel"},"name":"Sinopec Fuel","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Slovnaft":{"tags":{"name":"Slovnaft","amenity":"fuel"},"name":"Slovnaft","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Socar":{"tags":{"name":"Socar","amenity":"fuel"},"name":"Socar","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Sokimex":{"tags":{"name":"Sokimex","amenity":"fuel"},"name":"Sokimex","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Speedway":{"tags":{"name":"Speedway","amenity":"fuel"},"name":"Speedway","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/St1":{"tags":{"name":"St1","amenity":"fuel"},"name":"St1","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Star":{"tags":{"name":"Star","amenity":"fuel"},"name":"Star","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Star Oil":{"tags":{"name":"Star Oil","amenity":"fuel"},"name":"Star Oil","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_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":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Statoil":{"tags":{"name":"Statoil","amenity":"fuel"},"name":"Statoil","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Sunoco":{"tags":{"name":"Sunoco","amenity":"fuel"},"name":"Sunoco","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Tamoil":{"tags":{"name":"Tamoil","amenity":"fuel"},"name":"Tamoil","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Tango":{"tags":{"name":"Tango","amenity":"fuel"},"name":"Tango","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Teboil":{"tags":{"name":"Teboil","amenity":"fuel"},"name":"Teboil","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Tela":{"tags":{"name":"Tela","amenity":"fuel"},"name":"Tela","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Terpel":{"tags":{"name":"Terpel","amenity":"fuel"},"name":"Terpel","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Texaco":{"tags":{"name":"Texaco","amenity":"fuel"},"name":"Texaco","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Tinq":{"tags":{"name":"Tinq","amenity":"fuel"},"name":"Tinq","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Topaz":{"tags":{"name":"Topaz","amenity":"fuel"},"name":"Topaz","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Total":{"tags":{"name":"Total","amenity":"fuel"},"name":"Total","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Total Access":{"tags":{"name":"Total Access","amenity":"fuel"},"name":"Total Access","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Total Erg":{"tags":{"name":"Total Erg","amenity":"fuel"},"name":"Total Erg","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/TotalErg":{"tags":{"name":"TotalErg","amenity":"fuel"},"name":"TotalErg","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Turkey Hill":{"tags":{"name":"Turkey Hill","amenity":"fuel"},"name":"Turkey Hill","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Turmöl":{"tags":{"name":"Turmöl","amenity":"fuel"},"name":"Turmöl","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Ultramar":{"tags":{"name":"Ultramar","amenity":"fuel"},"name":"Ultramar","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/United":{"tags":{"name":"United","amenity":"fuel"},"name":"United","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Uno":{"tags":{"name":"Uno","amenity":"fuel"},"name":"Uno","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Uno-X":{"tags":{"name":"Uno-X","amenity":"fuel"},"name":"Uno-X","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Valero":{"tags":{"name":"Valero","amenity":"fuel"},"name":"Valero","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Vito":{"tags":{"name":"Vito","amenity":"fuel"},"name":"Vito","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/WOG":{"tags":{"name":"WOG","amenity":"fuel"},"name":"WOG","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Westfalen":{"tags":{"name":"Westfalen","amenity":"fuel"},"name":"Westfalen","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Woolworths Petrol":{"tags":{"name":"Woolworths Petrol","amenity":"fuel"},"name":"Woolworths Petrol","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Z":{"tags":{"name":"Z","amenity":"fuel"},"name":"Z","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/bft":{"tags":{"name":"bft","amenity":"fuel"},"name":"bft","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/eni":{"tags":{"name":"eni","amenity":"fuel"},"name":"eni","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/ΕΚΟ":{"tags":{"name":"ΕΚΟ","amenity":"fuel"},"name":"ΕΚΟ","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/АГЗС":{"tags":{"name":"АГЗС","amenity":"fuel"},"name":"АГЗС","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/АЗС":{"tags":{"name":"АЗС","amenity":"fuel"},"name":"АЗС","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Авіас":{"tags":{"name":"Авіас","amenity":"fuel"},"name":"Авіас","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/БРСМ-Нафта":{"tags":{"name":"БРСМ-Нафта","amenity":"fuel"},"name":"БРСМ-Нафта","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Башнефть":{"tags":{"name":"Башнефть","amenity":"fuel"},"name":"Башнефть","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Белоруснефть":{"tags":{"name":"Белоруснефть","amenity":"fuel"},"name":"Белоруснефть","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Газовая заправка":{"tags":{"name":"Газовая заправка","amenity":"fuel"},"name":"Газовая заправка","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Газпромнефть":{"tags":{"name":"Газпромнефть","amenity":"fuel"},"name":"Газпромнефть","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Гелиос":{"tags":{"name":"Гелиос","amenity":"fuel"},"name":"Гелиос","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/ЕКА":{"tags":{"name":"ЕКА","amenity":"fuel"},"name":"ЕКА","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Заправка":{"tags":{"name":"Заправка","amenity":"fuel"},"name":"Заправка","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/КазМунайГаз":{"tags":{"name":"КазМунайГаз","amenity":"fuel"},"name":"КазМунайГаз","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Лукойл":{"tags":{"name":"Лукойл","amenity":"fuel"},"name":"Лукойл","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Макпетрол":{"tags":{"name":"Макпетрол","amenity":"fuel"},"name":"Макпетрол","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/НК Альянс":{"tags":{"name":"НК Альянс","amenity":"fuel"},"name":"НК Альянс","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Нефтьмагистраль":{"tags":{"name":"Нефтьмагистраль","amenity":"fuel"},"name":"Нефтьмагистраль","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/ОККО":{"tags":{"name":"ОККО","amenity":"fuel"},"name":"ОККО","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/ОМВ":{"tags":{"name":"ОМВ","amenity":"fuel"},"name":"ОМВ","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Октан":{"tags":{"name":"Октан","amenity":"fuel"},"name":"Октан","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/ПТК":{"tags":{"name":"ПТК","amenity":"fuel"},"name":"ПТК","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Петрол":{"tags":{"name":"Петрол","amenity":"fuel"},"name":"Петрол","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Пропан":{"tags":{"name":"Пропан","amenity":"fuel"},"name":"Пропан","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Роснефть":{"tags":{"name":"Роснефть","amenity":"fuel"},"name":"Роснефть","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Сибнефть":{"tags":{"name":"Сибнефть","amenity":"fuel"},"name":"Сибнефть","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Сургутнефтегаз":{"tags":{"name":"Сургутнефтегаз","amenity":"fuel"},"name":"Сургутнефтегаз","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/ТНК":{"tags":{"name":"ТНК","amenity":"fuel"},"name":"ТНК","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Татнефтепродукт":{"tags":{"name":"Татнефтепродукт","amenity":"fuel"},"name":"Татнефтепродукт","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Татнефть":{"tags":{"name":"Татнефть","amenity":"fuel"},"name":"Татнефть","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/Укрнафта":{"tags":{"name":"Укрнафта","amenity":"fuel"},"name":"Укрнафта","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/דור אלון":{"tags":{"name":"דור אלון","amenity":"fuel"},"name":"דור אלון","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/דלק":{"tags":{"name":"דלק","amenity":"fuel"},"name":"דלק","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/סונול":{"tags":{"name":"סונול","amenity":"fuel"},"name":"סונול","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/פז":{"tags":{"name":"פז","amenity":"fuel"},"name":"פז","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/محطة وقود":{"tags":{"name":"محطة وقود","amenity":"fuel"},"name":"محطة وقود","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/محطه وقود":{"tags":{"name":"محطه وقود","amenity":"fuel"},"name":"محطه وقود","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/پمپ بنزین":{"tags":{"name":"پمپ بنزین","amenity":"fuel"},"name":"پمپ بنزین","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/پمپ گاز":{"tags":{"name":"پمپ گاز","amenity":"fuel"},"name":"پمپ گاز","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/บางจาก":{"tags":{"name":"บางจาก","amenity":"fuel"},"name":"บางจาก","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/ป.ต.ท.":{"tags":{"name":"ป.ต.ท.","amenity":"fuel"},"name":"ป.ต.ท.","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/เชลล์":{"tags":{"name":"เชลล์","amenity":"fuel"},"name":"เชลล์","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/เอสโซ่":{"tags":{"name":"เอสโซ่","amenity":"fuel"},"name":"เอสโซ่","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/エッソ":{"tags":{"name":"エッソ","amenity":"fuel"},"name":"エッソ","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/エネオス":{"tags":{"name":"エネオス","amenity":"fuel"},"name":"エネオス","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/コスモ石油":{"tags":{"name":"コスモ石油","amenity":"fuel"},"name":"コスモ石油","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/ゼネラル":{"tags":{"name":"ゼネラル","amenity":"fuel"},"name":"ゼネラル","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/中国石化":{"tags":{"name":"中国石化","amenity":"fuel"},"name":"中国石化","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/中国石化 Sinopec":{"tags":{"name":"中国石化 Sinopec","amenity":"fuel"},"name":"中国石化 Sinopec","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/中国石油":{"tags":{"name":"中国石油","amenity":"fuel"},"name":"中国石油","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/中油":{"tags":{"name":"中油","amenity":"fuel"},"name":"中油","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/出光":{"tags":{"name":"出光","name:en":"IDEMITSU","amenity":"fuel"},"name":"出光","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/加油站":{"tags":{"name":"加油站","amenity":"fuel"},"name":"加油站","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/台灣中油":{"tags":{"name":"台灣中油","amenity":"fuel"},"name":"台灣中油","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/fuel/昭和シェル":{"tags":{"name":"昭和シェル","amenity":"fuel"},"name":"昭和シェル","icon":"fuel","geometry":["point","area"],"fields":["name","operator","address","fuel_multi","opening_hours","payment_multi"],"suggestion":true},"amenity/hospital/Cruz Roja":{"tags":{"name":"Cruz Roja","healthcare":"hospital","amenity":"hospital"},"name":"Cruz Roja","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","emergency"],"suggestion":true},"amenity/hospital/IMSS":{"tags":{"name":"IMSS","healthcare":"hospital","amenity":"hospital"},"name":"IMSS","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","emergency"],"suggestion":true},"amenity/hospital/Инфекционное отделение":{"tags":{"name":"Инфекционное отделение","healthcare":"hospital","amenity":"hospital"},"name":"Инфекционное отделение","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","emergency"],"suggestion":true},"amenity/hospital/Кожно-венерологический диспансер":{"tags":{"name":"Кожно-венерологический диспансер","healthcare":"hospital","amenity":"hospital"},"name":"Кожно-венерологический диспансер","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","emergency"],"suggestion":true},"amenity/hospital/Районная больница":{"tags":{"name":"Районная больница","healthcare":"hospital","amenity":"hospital"},"name":"Районная больница","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","emergency"],"suggestion":true},"amenity/hospital/Роддом":{"tags":{"name":"Роддом","healthcare":"hospital","amenity":"hospital"},"name":"Роддом","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","emergency"],"suggestion":true},"amenity/hospital/Родильный дом":{"tags":{"name":"Родильный дом","healthcare":"hospital","amenity":"hospital"},"name":"Родильный дом","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","emergency"],"suggestion":true},"amenity/hospital/Скорая помощь":{"tags":{"name":"Скорая помощь","healthcare":"hospital","amenity":"hospital"},"name":"Скорая помощь","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","emergency"],"suggestion":true},"amenity/hospital/ЦРБ":{"tags":{"name":"ЦРБ","healthcare":"hospital","amenity":"hospital"},"name":"ЦРБ","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","emergency"],"suggestion":true},"amenity/hospital/Центральная районная больница":{"tags":{"name":"Центральная районная больница","healthcare":"hospital","amenity":"hospital"},"name":"Центральная районная больница","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","emergency"],"suggestion":true},"amenity/hospital/โรงพยาบาลส่งเสริมสุขภาพตำบล":{"tags":{"name":"โรงพยาบาลส่งเสริมสุขภาพตำบล","healthcare":"hospital","amenity":"hospital"},"name":"โรงพยาบาลส่งเสริมสุขภาพตำบล","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","emergency"],"suggestion":true},"amenity/ice_cream/Grido":{"tags":{"name":"Grido","amenity":"ice_cream"},"name":"Grido","icon":"ice-cream","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","takeaway","delivery","outdoor_seating"],"suggestion":true},"amenity/kindergarten/Anganwadi":{"tags":{"name":"Anganwadi","amenity":"kindergarten"},"name":"Anganwadi","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Arche Noah":{"tags":{"name":"Arche Noah","amenity":"kindergarten"},"name":"Arche Noah","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/CONAFE Preescolar":{"tags":{"name":"CONAFE Preescolar","amenity":"kindergarten"},"name":"CONAFE Preescolar","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Educacion Inicial de CONAFE No Escolarizado":{"tags":{"name":"Educacion Inicial de CONAFE No Escolarizado","amenity":"kindergarten"},"name":"Educacion Inicial de CONAFE No Escolarizado","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Estefania Casta�eda":{"tags":{"name":"Estefania Casta�eda","amenity":"kindergarten"},"name":"Estefania Casta�eda","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Evangelischer Kindergarten":{"tags":{"name":"Evangelischer Kindergarten","amenity":"kindergarten"},"name":"Evangelischer Kindergarten","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Federico Froebel":{"tags":{"name":"Federico Froebel","amenity":"kindergarten"},"name":"Federico Froebel","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Gabriela Mistral":{"tags":{"name":"Gabriela Mistral","amenity":"kindergarten"},"name":"Gabriela Mistral","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Jean Piaget":{"tags":{"name":"Jean Piaget","amenity":"kindergarten"},"name":"Jean Piaget","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Katholischer Kindergarten":{"tags":{"name":"Katholischer Kindergarten","amenity":"kindergarten"},"name":"Katholischer Kindergarten","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Kindergarten Regenbogen":{"tags":{"name":"Kindergarten Regenbogen","amenity":"kindergarten"},"name":"Kindergarten Regenbogen","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Kindergarten St. Josef":{"tags":{"name":"Kindergarten St. Josef","amenity":"kindergarten"},"name":"Kindergarten St. Josef","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Kindergarten St. Martin":{"tags":{"name":"Kindergarten St. Martin","amenity":"kindergarten"},"name":"Kindergarten St. Martin","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Maria Montessori":{"tags":{"name":"Maria Montessori","amenity":"kindergarten"},"name":"Maria Montessori","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/PAUD":{"tags":{"name":"PAUD","amenity":"kindergarten"},"name":"PAUD","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Pusteblume":{"tags":{"name":"Pusteblume","amenity":"kindergarten"},"name":"Pusteblume","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Rosaura Zapata":{"tags":{"name":"Rosaura Zapata","amenity":"kindergarten"},"name":"Rosaura Zapata","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Sor Juana Ines De La Cruz":{"tags":{"name":"Sor Juana Ines De La Cruz","amenity":"kindergarten"},"name":"Sor Juana Ines De La Cruz","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Spatzennest":{"tags":{"name":"Spatzennest","amenity":"kindergarten"},"name":"Spatzennest","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Städtischer Kindergarten":{"tags":{"name":"Städtischer Kindergarten","amenity":"kindergarten"},"name":"Städtischer Kindergarten","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Villa Kunterbunt":{"tags":{"name":"Villa Kunterbunt","amenity":"kindergarten"},"name":"Villa Kunterbunt","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Waldkindergarten":{"tags":{"name":"Waldkindergarten","amenity":"kindergarten"},"name":"Waldkindergarten","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Waldorfkindergarten":{"tags":{"name":"Waldorfkindergarten","amenity":"kindergarten"},"name":"Waldorfkindergarten","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Óvoda":{"tags":{"name":"Óvoda","amenity":"kindergarten"},"name":"Óvoda","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детсад":{"tags":{"name":"Детсад","amenity":"kindergarten"},"name":"Детсад","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад Солнышко":{"tags":{"name":"Детский сад Солнышко","amenity":"kindergarten"},"name":"Детский сад Солнышко","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад № 1":{"tags":{"name":"Детский сад № 1","amenity":"kindergarten"},"name":"Детский сад № 1","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №1":{"tags":{"name":"Детский сад №1","amenity":"kindergarten"},"name":"Детский сад №1","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №10":{"tags":{"name":"Детский сад №10","amenity":"kindergarten"},"name":"Детский сад №10","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №11":{"tags":{"name":"Детский сад №11","amenity":"kindergarten"},"name":"Детский сад №11","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №12":{"tags":{"name":"Детский сад №12","amenity":"kindergarten"},"name":"Детский сад №12","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №13":{"tags":{"name":"Детский сад №13","amenity":"kindergarten"},"name":"Детский сад №13","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №14":{"tags":{"name":"Детский сад №14","amenity":"kindergarten"},"name":"Детский сад №14","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №15":{"tags":{"name":"Детский сад №15","amenity":"kindergarten"},"name":"Детский сад №15","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №16":{"tags":{"name":"Детский сад №16","amenity":"kindergarten"},"name":"Детский сад №16","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №17":{"tags":{"name":"Детский сад №17","amenity":"kindergarten"},"name":"Детский сад №17","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №18":{"tags":{"name":"Детский сад №18","amenity":"kindergarten"},"name":"Детский сад №18","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №19":{"tags":{"name":"Детский сад №19","amenity":"kindergarten"},"name":"Детский сад №19","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №2":{"tags":{"name":"Детский сад №2","amenity":"kindergarten"},"name":"Детский сад №2","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №22":{"tags":{"name":"Детский сад №22","amenity":"kindergarten"},"name":"Детский сад №22","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №24":{"tags":{"name":"Детский сад №24","amenity":"kindergarten"},"name":"Детский сад №24","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №25":{"tags":{"name":"Детский сад №25","amenity":"kindergarten"},"name":"Детский сад №25","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №27":{"tags":{"name":"Детский сад №27","amenity":"kindergarten"},"name":"Детский сад №27","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №29":{"tags":{"name":"Детский сад №29","amenity":"kindergarten"},"name":"Детский сад №29","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №3":{"tags":{"name":"Детский сад №3","amenity":"kindergarten"},"name":"Детский сад №3","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №33":{"tags":{"name":"Детский сад №33","amenity":"kindergarten"},"name":"Детский сад №33","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №4":{"tags":{"name":"Детский сад №4","amenity":"kindergarten"},"name":"Детский сад №4","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №5":{"tags":{"name":"Детский сад №5","amenity":"kindergarten"},"name":"Детский сад №5","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №6":{"tags":{"name":"Детский сад №6","amenity":"kindergarten"},"name":"Детский сад №6","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №7":{"tags":{"name":"Детский сад №7","amenity":"kindergarten"},"name":"Детский сад №7","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №8":{"tags":{"name":"Детский сад №8","amenity":"kindergarten"},"name":"Детский сад №8","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Детский сад №9":{"tags":{"name":"Детский сад №9","amenity":"kindergarten"},"name":"Детский сад №9","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Дитячий садок":{"tags":{"name":"Дитячий садок","amenity":"kindergarten"},"name":"Дитячий садок","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/Солнышко":{"tags":{"name":"Солнышко","amenity":"kindergarten"},"name":"Солнышко","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/საბავშვო ბაღი":{"tags":{"name":"საბავშვო ბაღი","amenity":"kindergarten"},"name":"საბავშვო ბაღი","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/kindergarten/中央保育所":{"tags":{"name":"中央保育所","amenity":"kindergarten"},"name":"中央保育所","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/library/Biblioteca Comunale":{"tags":{"name":"Biblioteca Comunale","amenity":"library"},"name":"Biblioteca Comunale","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid","ref/isil"],"suggestion":true},"amenity/library/Biblioteca comunale":{"tags":{"name":"Biblioteca comunale","amenity":"library"},"name":"Biblioteca comunale","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid","ref/isil"],"suggestion":true},"amenity/library/Biblioteka Publiczna":{"tags":{"name":"Biblioteka Publiczna","amenity":"library"},"name":"Biblioteka Publiczna","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid","ref/isil"],"suggestion":true},"amenity/library/Bibliothèque Municipale":{"tags":{"name":"Bibliothèque Municipale","amenity":"library"},"name":"Bibliothèque Municipale","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid","ref/isil"],"suggestion":true},"amenity/library/Bibliothèque municipale":{"tags":{"name":"Bibliothèque municipale","amenity":"library"},"name":"Bibliothèque municipale","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid","ref/isil"],"suggestion":true},"amenity/library/Bücherei":{"tags":{"name":"Bücherei","amenity":"library"},"name":"Bücherei","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid","ref/isil"],"suggestion":true},"amenity/library/Central Library":{"tags":{"name":"Central Library","amenity":"library"},"name":"Central Library","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid","ref/isil"],"suggestion":true},"amenity/library/Gemeindebücherei":{"tags":{"name":"Gemeindebücherei","amenity":"library"},"name":"Gemeindebücherei","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid","ref/isil"],"suggestion":true},"amenity/library/Gminna Biblioteka Publiczna":{"tags":{"name":"Gminna Biblioteka Publiczna","amenity":"library"},"name":"Gminna Biblioteka Publiczna","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid","ref/isil"],"suggestion":true},"amenity/library/Miejska Biblioteka Publiczna":{"tags":{"name":"Miejska Biblioteka Publiczna","amenity":"library"},"name":"Miejska Biblioteka Publiczna","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid","ref/isil"],"suggestion":true},"amenity/library/Médiathèque":{"tags":{"name":"Médiathèque","amenity":"library"},"name":"Médiathèque","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid","ref/isil"],"suggestion":true},"amenity/library/Městská knihovna":{"tags":{"name":"Městská knihovna","amenity":"library"},"name":"Městská knihovna","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid","ref/isil"],"suggestion":true},"amenity/library/Public Library":{"tags":{"name":"Public Library","amenity":"library"},"name":"Public Library","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid","ref/isil"],"suggestion":true},"amenity/library/Stadtbibliothek":{"tags":{"name":"Stadtbibliothek","amenity":"library"},"name":"Stadtbibliothek","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid","ref/isil"],"suggestion":true},"amenity/library/Stadtbücherei":{"tags":{"name":"Stadtbücherei","amenity":"library"},"name":"Stadtbücherei","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid","ref/isil"],"suggestion":true},"amenity/library/Городская библиотека":{"tags":{"name":"Городская библиотека","amenity":"library"},"name":"Городская библиотека","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid","ref/isil"],"suggestion":true},"amenity/library/Детская библиотека":{"tags":{"name":"Детская библиотека","amenity":"library"},"name":"Детская библиотека","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid","ref/isil"],"suggestion":true},"amenity/library/Центральная библиотека":{"tags":{"name":"Центральная библиотека","amenity":"library"},"name":"Центральная библиотека","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid","ref/isil"],"suggestion":true},"amenity/library/Центральная городская библиотека":{"tags":{"name":"Центральная городская библиотека","amenity":"library"},"name":"Центральная городская библиотека","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid","ref/isil"],"suggestion":true},"amenity/library/图书馆":{"tags":{"name":"图书馆","amenity":"library"},"name":"图书馆","icon":"library","geometry":["point","area"],"fields":["name","operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid","ref/isil"],"suggestion":true},"amenity/pharmacy/36.6":{"tags":{"name":"36.6","healthcare":"pharmacy","amenity":"pharmacy"},"name":"36.6","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Adler-Apotheke":{"tags":{"name":"Adler-Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Adler-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Alte Apotheke":{"tags":{"name":"Alte Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Alte Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Apollo Pharmacy":{"tags":{"name":"Apollo Pharmacy","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Apollo Pharmacy","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Apotek":{"tags":{"name":"Apotek","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Apotek","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Apotek Hjärtat":{"tags":{"name":"Apotek Hjärtat","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Apotek Hjärtat","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Apotheke am Markt":{"tags":{"name":"Apotheke am Markt","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Apotheke am Markt","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Bahnhof Apotheke":{"tags":{"name":"Bahnhof Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Bahnhof Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Bahnhof-Apotheke":{"tags":{"name":"Bahnhof-Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Bahnhof-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Bartell Drugs":{"tags":{"name":"Bartell Drugs","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Bartell Drugs","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Benavides":{"tags":{"name":"Benavides","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Benavides","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Benu":{"tags":{"name":"Benu","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Benu","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Boots":{"tags":{"name":"Boots","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Boots","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Botica":{"tags":{"name":"Botica","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Botica","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Brunnen-Apotheke":{"tags":{"name":"Brunnen-Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Brunnen-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Burg-Apotheke":{"tags":{"name":"Burg-Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Burg-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Bären-Apotheke":{"tags":{"name":"Bären-Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Bären-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/CVS":{"tags":{"name":"CVS","healthcare":"pharmacy","amenity":"pharmacy"},"name":"CVS","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Camelia":{"tags":{"name":"Camelia","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Camelia","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Catena":{"tags":{"name":"Catena","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Catena","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Chemist Warehouse":{"tags":{"name":"Chemist Warehouse","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Chemist Warehouse","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Clicks":{"tags":{"name":"Clicks","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Clicks","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Cruz Azul":{"tags":{"name":"Cruz Azul","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Cruz Azul","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Cruz Verde":{"tags":{"name":"Cruz Verde","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Cruz Verde","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Dbam o Zdrowie":{"tags":{"name":"Dbam o Zdrowie","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Dbam o Zdrowie","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Dr. Max":{"tags":{"name":"Dr. Max","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Dr. Max","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Droga Raia":{"tags":{"name":"Droga Raia","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Droga Raia","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Drogaria São Paulo":{"tags":{"name":"Drogaria São Paulo","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Drogaria São Paulo","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Drogasil":{"tags":{"name":"Drogasil","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Drogasil","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Duane Reade":{"tags":{"name":"Duane Reade","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Duane Reade","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Eczane":{"tags":{"name":"Eczane","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Eczane","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Engel-Apotheke":{"tags":{"name":"Engel-Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Engel-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Eurovaistinė":{"tags":{"name":"Eurovaistinė","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Eurovaistinė","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Familiprix":{"tags":{"name":"Familiprix","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Familiprix","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Farmacenter":{"tags":{"name":"Farmacenter","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Farmacenter","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Farmacia Centrale":{"tags":{"name":"Farmacia Centrale","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Farmacia Centrale","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Farmacia Comunale":{"tags":{"name":"Farmacia Comunale","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Farmacia Comunale","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Farmacia Guadalajara":{"tags":{"name":"Farmacia Guadalajara","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Farmacia Guadalajara","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Farmacia del Ahorro":{"tags":{"name":"Farmacia del Ahorro","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Farmacia del Ahorro","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Farmacias Ahumada":{"tags":{"name":"Farmacias Ahumada","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Farmacias Ahumada","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Farmacias Cruz Azul":{"tags":{"name":"Farmacias Cruz Azul","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Farmacias Cruz Azul","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Farmacias Cruz Verde":{"tags":{"name":"Farmacias Cruz Verde","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Farmacias Cruz Verde","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Farmacias Económicas":{"tags":{"name":"Farmacias Económicas","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Farmacias Económicas","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Farmacias Guadalajara":{"tags":{"name":"Farmacias Guadalajara","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Farmacias Guadalajara","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Farmacias SalcoBrand":{"tags":{"name":"Farmacias SalcoBrand","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Farmacias SalcoBrand","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Farmacias Sana Sana":{"tags":{"name":"Farmacias Sana Sana","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Farmacias Sana Sana","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Farmacias Similares":{"tags":{"name":"Farmacias Similares","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Farmacias Similares","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Farmacias del Ahorro":{"tags":{"name":"Farmacias del Ahorro","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Farmacias del Ahorro","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Farmacity":{"tags":{"name":"Farmacity","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Farmacity","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Farmahorro":{"tags":{"name":"Farmahorro","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Farmahorro","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Farmatodo":{"tags":{"name":"Farmatodo","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Farmatodo","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Felicia":{"tags":{"name":"Felicia","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Felicia","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Fybeca":{"tags":{"name":"Fybeca","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Fybeca","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Generika Drugstore":{"tags":{"name":"Generika Drugstore","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Generika Drugstore","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Gintarinė vaistinė":{"tags":{"name":"Gintarinė vaistinė","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Gintarinė vaistinė","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Guardian":{"tags":{"name":"Guardian","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Guardian","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Gyógyszertár":{"tags":{"name":"Gyógyszertár","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Gyógyszertár","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/H-E-B Pharmacy":{"tags":{"name":"H-E-B Pharmacy","healthcare":"pharmacy","amenity":"pharmacy"},"name":"H-E-B Pharmacy","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Hirsch-Apotheke":{"tags":{"name":"Hirsch-Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Hirsch-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Hubertus Apotheke":{"tags":{"name":"Hubertus Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Hubertus Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Inkafarma":{"tags":{"name":"Inkafarma","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Inkafarma","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Jean Coutu":{"tags":{"name":"Jean Coutu","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Jean Coutu","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Kinney Drugs":{"tags":{"name":"Kinney Drugs","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Kinney Drugs","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Kur-Apotheke":{"tags":{"name":"Kur-Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Kur-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Linden-Apotheke":{"tags":{"name":"Linden-Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Linden-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Ljekarna":{"tags":{"name":"Ljekarna","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Ljekarna","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Lloyds Pharmacy":{"tags":{"name":"Lloyds Pharmacy","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Lloyds Pharmacy","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Lékárna":{"tags":{"name":"Lékárna","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Lékárna","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Löwen-Apotheke":{"tags":{"name":"Löwen-Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Löwen-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Marien-Apotheke":{"tags":{"name":"Marien-Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Marien-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Markt-Apotheke":{"tags":{"name":"Markt-Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Markt-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Mercury Drug":{"tags":{"name":"Mercury Drug","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Mercury Drug","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Mifarma":{"tags":{"name":"Mifarma","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Mifarma","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Mēness aptieka":{"tags":{"name":"Mēness aptieka","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Mēness aptieka","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Neue Apotheke":{"tags":{"name":"Neue Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Neue Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Pague Menos":{"tags":{"name":"Pague Menos","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Pague Menos","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Panvel":{"tags":{"name":"Panvel","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Panvel","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Park-Apotheke":{"tags":{"name":"Park-Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Park-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Pharmacie Centrale":{"tags":{"name":"Pharmacie Centrale","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Pharmacie Centrale","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Pharmacie Principale":{"tags":{"name":"Pharmacie Principale","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Pharmacie Principale","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Pharmacie de l'Hôtel de Ville":{"tags":{"name":"Pharmacie de l'Hôtel de Ville","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Pharmacie de l'Hôtel de Ville","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Pharmacie de la Gare":{"tags":{"name":"Pharmacie de la Gare","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Pharmacie de la Gare","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Pharmacie de la Mairie":{"tags":{"name":"Pharmacie de la Mairie","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Pharmacie de la Mairie","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Pharmacie de la Poste":{"tags":{"name":"Pharmacie de la Poste","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Pharmacie de la Poste","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Pharmacie du Centre":{"tags":{"name":"Pharmacie du Centre","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Pharmacie du Centre","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Pharmacie du Marché":{"tags":{"name":"Pharmacie du Marché","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Pharmacie du Marché","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Pharmacie du Parc":{"tags":{"name":"Pharmacie du Parc","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Pharmacie du Parc","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Pharmaprix":{"tags":{"name":"Pharmaprix","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Pharmaprix","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Pharmasave":{"tags":{"name":"Pharmasave","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Pharmasave","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Punkt Apteczny":{"tags":{"name":"Punkt Apteczny","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Punkt Apteczny","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Rathaus-Apotheke":{"tags":{"name":"Rathaus-Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Rathaus-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Rats-Apotheke":{"tags":{"name":"Rats-Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Rats-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Rexall":{"tags":{"name":"Rexall","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Rexall","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Rite Aid":{"tags":{"name":"Rite Aid","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Rite Aid","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Rose Pharmacy":{"tags":{"name":"Rose Pharmacy","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Rose Pharmacy","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Rosen-Apotheke":{"tags":{"name":"Rosen-Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Rosen-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Rowlands Pharmacy":{"tags":{"name":"Rowlands Pharmacy","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Rowlands Pharmacy","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/SalcoBrand":{"tags":{"name":"SalcoBrand","healthcare":"pharmacy","amenity":"pharmacy"},"name":"SalcoBrand","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Sana Sana":{"tags":{"name":"Sana Sana","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Sana Sana","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Schloss-Apotheke":{"tags":{"name":"Schloss-Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Schloss-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Sensiblu":{"tags":{"name":"Sensiblu","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Sensiblu","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Shoppers Drug Mart":{"tags":{"name":"Shoppers Drug Mart","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Shoppers Drug Mart","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Sonnen-Apotheke":{"tags":{"name":"Sonnen-Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Sonnen-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/South Star Drug":{"tags":{"name":"South Star Drug","healthcare":"pharmacy","amenity":"pharmacy"},"name":"South Star Drug","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Stadt-Apotheke":{"tags":{"name":"Stadt-Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Stadt-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Stern-Apotheke":{"tags":{"name":"Stern-Apotheke","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Stern-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Superdrug":{"tags":{"name":"Superdrug","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Superdrug","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/São João":{"tags":{"name":"São João","healthcare":"pharmacy","amenity":"pharmacy"},"name":"São João","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/The Generics Pharmacy":{"tags":{"name":"The Generics Pharmacy","healthcare":"pharmacy","amenity":"pharmacy"},"name":"The Generics Pharmacy","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Uniprix":{"tags":{"name":"Uniprix","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Uniprix","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Walgreens":{"tags":{"name":"Walgreens","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Walgreens","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Walgreens Pharmacy":{"tags":{"name":"Walgreens Pharmacy","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Walgreens Pharmacy","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Walmart Pharmacy":{"tags":{"name":"Walmart Pharmacy","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Walmart Pharmacy","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Well Pharmacy":{"tags":{"name":"Well Pharmacy","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Well Pharmacy","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/centro naturista":{"tags":{"name":"centro naturista","healthcare":"pharmacy","amenity":"pharmacy"},"name":"centro naturista","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/А5":{"tags":{"name":"А5","healthcare":"pharmacy","amenity":"pharmacy"},"name":"А5","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Айболит":{"tags":{"name":"Айболит","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Айболит","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Аптека 36,6":{"tags":{"name":"Аптека 36,6","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Аптека 36,6","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Аптека низких цен":{"tags":{"name":"Аптека низких цен","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Аптека низких цен","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Аптека низьких цін":{"tags":{"name":"Аптека низьких цін","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Аптека низьких цін","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Аптека от склада":{"tags":{"name":"Аптека от склада","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Аптека от склада","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Аптека №1":{"tags":{"name":"Аптека №1","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Аптека №1","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Аптечный пункт":{"tags":{"name":"Аптечный пункт","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Аптечный пункт","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Арніка":{"tags":{"name":"Арніка","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Арніка","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Бережная аптека":{"tags":{"name":"Бережная аптека","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Бережная аптека","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Будь здоров":{"tags":{"name":"Будь здоров","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Будь здоров","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Вита":{"tags":{"name":"Вита","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Вита","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Горздрав":{"tags":{"name":"Горздрав","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Горздрав","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Живика":{"tags":{"name":"Живика","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Живика","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Здоровье":{"tags":{"name":"Здоровье","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Здоровье","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Имплозия":{"tags":{"name":"Имплозия","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Имплозия","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Классика":{"tags":{"name":"Классика","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Классика","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Ладушка":{"tags":{"name":"Ладушка","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Ладушка","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Мед-сервіс":{"tags":{"name":"Мед-сервіс","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Мед-сервіс","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Мелодия здоровья":{"tags":{"name":"Мелодия здоровья","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Мелодия здоровья","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Невис":{"tags":{"name":"Невис","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Невис","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Норма":{"tags":{"name":"Норма","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Норма","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Озерки":{"tags":{"name":"Озерки","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Озерки","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Панацея":{"tags":{"name":"Панацея","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Панацея","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Первая помощь":{"tags":{"name":"Первая помощь","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Первая помощь","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Планета здоровья":{"tags":{"name":"Планета здоровья","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Планета здоровья","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Ригла":{"tags":{"name":"Ригла","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Ригла","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Семейная":{"tags":{"name":"Семейная","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Семейная","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Социальная аптека":{"tags":{"name":"Социальная аптека","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Социальная аптека","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Столички":{"tags":{"name":"Столички","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Столички","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Фармакопейка":{"tags":{"name":"Фармакопейка","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Фармакопейка","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Фармакор":{"tags":{"name":"Фармакор","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Фармакор","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Фармация":{"tags":{"name":"Фармация","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Фармация","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Фармленд":{"tags":{"name":"Фармленд","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Фармленд","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/Центральная аптека":{"tags":{"name":"Центральная аптека","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Центральная аптека","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/סופר-פארם":{"tags":{"name":"סופר-פארם","healthcare":"pharmacy","amenity":"pharmacy"},"name":"סופר-פארם","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/داروخانه":{"tags":{"name":"داروخانه","healthcare":"pharmacy","amenity":"pharmacy"},"name":"داروخانه","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/داروخانه شبانه روزی":{"tags":{"name":"داروخانه شبانه روزی","healthcare":"pharmacy","amenity":"pharmacy"},"name":"داروخانه شبانه روزی","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/صيدلية":{"tags":{"name":"صيدلية","healthcare":"pharmacy","amenity":"pharmacy"},"name":"صيدلية","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/くすりの福太郎":{"tags":{"name":"くすりの福太郎","healthcare":"pharmacy","amenity":"pharmacy"},"name":"くすりの福太郎","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/さくら薬局":{"tags":{"name":"さくら薬局","healthcare":"pharmacy","amenity":"pharmacy"},"name":"さくら薬局","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/ウエルシア":{"tags":{"name":"ウエルシア","healthcare":"pharmacy","amenity":"pharmacy"},"name":"ウエルシア","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/カワチ薬品":{"tags":{"name":"カワチ薬品","healthcare":"pharmacy","amenity":"pharmacy"},"name":"カワチ薬品","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/クリエイト":{"tags":{"name":"クリエイト","healthcare":"pharmacy","amenity":"pharmacy"},"name":"クリエイト","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/サンドラッグ":{"tags":{"name":"サンドラッグ","healthcare":"pharmacy","amenity":"pharmacy"},"name":"サンドラッグ","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/スギ薬局":{"tags":{"name":"スギ薬局","healthcare":"pharmacy","amenity":"pharmacy"},"name":"スギ薬局","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/セイジョー":{"tags":{"name":"セイジョー","healthcare":"pharmacy","amenity":"pharmacy"},"name":"セイジョー","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/ツルハドラッグ":{"tags":{"name":"ツルハドラッグ","healthcare":"pharmacy","amenity":"pharmacy"},"name":"ツルハドラッグ","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/ドラッグてらしま (Drug Terashima)":{"tags":{"name":"ドラッグてらしま (Drug Terashima)","healthcare":"pharmacy","amenity":"pharmacy"},"name":"ドラッグてらしま (Drug Terashima)","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/マツモトキヨシ":{"tags":{"name":"マツモトキヨシ","healthcare":"pharmacy","amenity":"pharmacy"},"name":"マツモトキヨシ","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pharmacy/丁丁藥局":{"tags":{"name":"丁丁藥局","healthcare":"pharmacy","amenity":"pharmacy"},"name":"丁丁藥局","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","drive_through","opening_hours","payment_multi"],"suggestion":true},"amenity/pub/Black Bull":{"tags":{"name":"Black Bull","amenity":"pub"},"name":"Black Bull","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/Commercial Hotel":{"tags":{"name":"Commercial Hotel","amenity":"pub"},"name":"Commercial Hotel","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/Cross Keys":{"tags":{"name":"Cross Keys","amenity":"pub"},"name":"Cross Keys","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/Irish Pub":{"tags":{"name":"Irish Pub","amenity":"pub"},"name":"Irish Pub","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/Kings Arms":{"tags":{"name":"Kings Arms","amenity":"pub"},"name":"Kings Arms","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/Kings Head":{"tags":{"name":"Kings Head","amenity":"pub"},"name":"Kings Head","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/New Inn":{"tags":{"name":"New Inn","amenity":"pub"},"name":"New Inn","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/Prince of Wales":{"tags":{"name":"Prince of Wales","amenity":"pub"},"name":"Prince of Wales","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/Queens Head":{"tags":{"name":"Queens Head","amenity":"pub"},"name":"Queens Head","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/Red Lion":{"tags":{"name":"Red Lion","amenity":"pub"},"name":"Red Lion","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/Rose & Crown":{"tags":{"name":"Rose & Crown","amenity":"pub"},"name":"Rose & Crown","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/Rose and Crown":{"tags":{"name":"Rose and Crown","amenity":"pub"},"name":"Rose and Crown","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/Royal Oak":{"tags":{"name":"Royal Oak","amenity":"pub"},"name":"Royal Oak","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Albion":{"tags":{"name":"The Albion","amenity":"pub"},"name":"The Albion","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Anchor":{"tags":{"name":"The Anchor","amenity":"pub"},"name":"The Anchor","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Angel":{"tags":{"name":"The Angel","amenity":"pub"},"name":"The Angel","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Beehive":{"tags":{"name":"The Beehive","amenity":"pub"},"name":"The Beehive","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Bell":{"tags":{"name":"The Bell","amenity":"pub"},"name":"The Bell","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Bell Inn":{"tags":{"name":"The Bell Inn","amenity":"pub"},"name":"The Bell Inn","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Black Horse":{"tags":{"name":"The Black Horse","amenity":"pub"},"name":"The Black Horse","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Bull":{"tags":{"name":"The Bull","amenity":"pub"},"name":"The Bull","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Castle":{"tags":{"name":"The Castle","amenity":"pub"},"name":"The Castle","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Chequers":{"tags":{"name":"The Chequers","amenity":"pub"},"name":"The Chequers","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Cricketers":{"tags":{"name":"The Cricketers","amenity":"pub"},"name":"The Cricketers","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Cross Keys":{"tags":{"name":"The Cross Keys","amenity":"pub"},"name":"The Cross Keys","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Crown":{"tags":{"name":"The Crown","amenity":"pub"},"name":"The Crown","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Crown Inn":{"tags":{"name":"The Crown Inn","amenity":"pub"},"name":"The Crown Inn","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Fox":{"tags":{"name":"The Fox","amenity":"pub"},"name":"The Fox","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The George":{"tags":{"name":"The George","amenity":"pub"},"name":"The George","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Green Man":{"tags":{"name":"The Green Man","amenity":"pub"},"name":"The Green Man","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Greyhound":{"tags":{"name":"The Greyhound","amenity":"pub"},"name":"The Greyhound","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Kings Arms":{"tags":{"name":"The Kings Arms","amenity":"pub"},"name":"The Kings Arms","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Kings Head":{"tags":{"name":"The Kings Head","amenity":"pub"},"name":"The Kings Head","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The New Inn":{"tags":{"name":"The New Inn","amenity":"pub"},"name":"The New Inn","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Plough":{"tags":{"name":"The Plough","amenity":"pub"},"name":"The Plough","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Plough Inn":{"tags":{"name":"The Plough Inn","amenity":"pub"},"name":"The Plough Inn","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Queens Head":{"tags":{"name":"The Queens Head","amenity":"pub"},"name":"The Queens Head","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Railway":{"tags":{"name":"The Railway","amenity":"pub"},"name":"The Railway","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Red Lion":{"tags":{"name":"The Red Lion","amenity":"pub"},"name":"The Red Lion","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Rising Sun":{"tags":{"name":"The Rising Sun","amenity":"pub"},"name":"The Rising Sun","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Royal Oak":{"tags":{"name":"The Royal Oak","amenity":"pub"},"name":"The Royal Oak","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Ship":{"tags":{"name":"The Ship","amenity":"pub"},"name":"The Ship","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Ship Inn":{"tags":{"name":"The Ship Inn","amenity":"pub"},"name":"The Ship Inn","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Star":{"tags":{"name":"The Star","amenity":"pub"},"name":"The Star","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Star Inn":{"tags":{"name":"The Star Inn","amenity":"pub"},"name":"The Star Inn","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Sun Inn":{"tags":{"name":"The Sun Inn","amenity":"pub"},"name":"The Sun Inn","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Swan":{"tags":{"name":"The Swan","amenity":"pub"},"name":"The Swan","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Swan Inn":{"tags":{"name":"The Swan Inn","amenity":"pub"},"name":"The Swan Inn","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Victoria":{"tags":{"name":"The Victoria","amenity":"pub"},"name":"The Victoria","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The Wheatsheaf":{"tags":{"name":"The Wheatsheaf","amenity":"pub"},"name":"The Wheatsheaf","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The White Hart":{"tags":{"name":"The White Hart","amenity":"pub"},"name":"The White Hart","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The White Horse":{"tags":{"name":"The White Horse","amenity":"pub"},"name":"The White Horse","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The White Lion":{"tags":{"name":"The White Lion","amenity":"pub"},"name":"The White Lion","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/The White Swan":{"tags":{"name":"The White Swan","amenity":"pub"},"name":"The White Swan","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/魚民":{"tags":{"name":"魚民","amenity":"pub"},"name":"魚民","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/pub/鳥貴族":{"tags":{"name":"鳥貴族","amenity":"pub"},"name":"鳥貴族","icon":"beer","geometry":["point","area"],"fields":["name","address","building_area","opening_hours","smoking","outdoor_seating","brewery"],"suggestion":true},"amenity/restaurant/Adler":{"tags":{"name":"Adler","amenity":"restaurant"},"name":"Adler","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Adyar Ananda Bhavan":{"tags":{"name":"Adyar Ananda Bhavan","amenity":"restaurant"},"name":"Adyar Ananda Bhavan","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Athos":{"tags":{"name":"Athos","amenity":"restaurant"},"name":"Athos","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Autogrill":{"tags":{"name":"Autogrill","amenity":"restaurant"},"name":"Autogrill","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Bahnhof":{"tags":{"name":"Bahnhof","amenity":"restaurant"},"name":"Bahnhof","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Big Boy":{"tags":{"name":"Big Boy","amenity":"restaurant"},"name":"Big Boy","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Bonefish Grill":{"tags":{"name":"Bonefish Grill","amenity":"restaurant"},"name":"Bonefish Grill","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Canteen":{"tags":{"name":"Canteen","amenity":"restaurant"},"name":"Canteen","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Capri":{"tags":{"name":"Capri","amenity":"restaurant"},"name":"Capri","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Carluccio's":{"tags":{"name":"Carluccio's","amenity":"restaurant"},"name":"Carluccio's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Carpe Diem":{"tags":{"name":"Carpe Diem","amenity":"restaurant"},"name":"Carpe Diem","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Carrabba's Italian Grill":{"tags":{"name":"Carrabba's Italian Grill","amenity":"restaurant"},"name":"Carrabba's Italian Grill","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Casa Mia":{"tags":{"name":"Casa Mia","amenity":"restaurant"},"name":"Casa Mia","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Casablanca":{"tags":{"name":"Casablanca","amenity":"restaurant"},"name":"Casablanca","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Cheesecake Factory":{"tags":{"name":"Cheesecake Factory","amenity":"restaurant"},"name":"Cheesecake Factory","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Chifa":{"tags":{"name":"Chifa","amenity":"restaurant"},"name":"Chifa","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/China Buffet":{"tags":{"name":"China Buffet","amenity":"restaurant"},"name":"China Buffet","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/China House":{"tags":{"name":"China House","amenity":"restaurant"},"name":"China House","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/China Wok":{"tags":{"name":"China Wok","amenity":"restaurant"},"name":"China Wok","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Chiquito":{"tags":{"name":"Chiquito","amenity":"restaurant"},"name":"Chiquito","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Chuck E. Cheese's":{"tags":{"name":"Chuck E. Cheese's","amenity":"restaurant"},"name":"Chuck E. Cheese's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Cici's Pizza":{"tags":{"name":"Cici's Pizza","amenity":"restaurant"},"name":"Cici's Pizza","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Comedor":{"tags":{"name":"Comedor","amenity":"restaurant"},"name":"Comedor","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Comida China":{"tags":{"name":"Comida China","amenity":"restaurant"},"name":"Comida China","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Da Grasso":{"tags":{"name":"Da Grasso","amenity":"restaurant"},"name":"Da Grasso","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Dorfkrug":{"tags":{"name":"Dorfkrug","amenity":"restaurant"},"name":"Dorfkrug","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/East Side Mario's":{"tags":{"name":"East Side Mario's","amenity":"restaurant"},"name":"East Side Mario's","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/El Paso":{"tags":{"name":"El Paso","amenity":"restaurant"},"name":"El Paso","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/El Rancho":{"tags":{"name":"El Rancho","amenity":"restaurant"},"name":"El Rancho","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Europa":{"tags":{"name":"Europa","amenity":"restaurant"},"name":"Europa","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Famous Dave's":{"tags":{"name":"Famous Dave's","amenity":"restaurant"},"name":"Famous Dave's","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Gasthaus zur Linde":{"tags":{"name":"Gasthaus zur Linde","amenity":"restaurant"},"name":"Gasthaus zur Linde","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Golden Dragon":{"tags":{"name":"Golden Dragon","amenity":"restaurant"},"name":"Golden Dragon","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Great Wall":{"tags":{"name":"Great Wall","amenity":"restaurant"},"name":"Great Wall","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Gusto":{"tags":{"name":"Gusto","amenity":"restaurant"},"name":"Gusto","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Harvester":{"tags":{"name":"Harvester","amenity":"restaurant"},"name":"Harvester","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/IL Патио":{"tags":{"name":"IL Патио","amenity":"restaurant"},"name":"IL Патио","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Jason's Deli":{"tags":{"name":"Jason's Deli","amenity":"restaurant"},"name":"Jason's Deli","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Joe's Crab Shack":{"tags":{"name":"Joe's Crab Shack","amenity":"restaurant"},"name":"Joe's Crab Shack","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Jägerhof":{"tags":{"name":"Jägerhof","amenity":"restaurant"},"name":"Jägerhof","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Kreta":{"tags":{"name":"Kreta","amenity":"restaurant"},"name":"Kreta","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Kudu":{"tags":{"name":"Kudu","amenity":"restaurant"},"name":"Kudu","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/L'Escale":{"tags":{"name":"L'Escale","amenity":"restaurant"},"name":"L'Escale","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/L'Osteria":{"tags":{"name":"L'Osteria","amenity":"restaurant"},"name":"L'Osteria","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Bodega":{"tags":{"name":"La Bodega","amenity":"restaurant"},"name":"La Bodega","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Boucherie":{"tags":{"name":"La Boucherie","amenity":"restaurant"},"name":"La Boucherie","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Casa":{"tags":{"name":"La Casa","amenity":"restaurant"},"name":"La Casa","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Casona":{"tags":{"name":"La Casona","amenity":"restaurant"},"name":"La Casona","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Fontana":{"tags":{"name":"La Fontana","amenity":"restaurant"},"name":"La Fontana","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Gondola":{"tags":{"name":"La Gondola","amenity":"restaurant"},"name":"La Gondola","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Hacienda":{"tags":{"name":"La Hacienda","amenity":"restaurant"},"name":"La Hacienda","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Pergola":{"tags":{"name":"La Pergola","amenity":"restaurant"},"name":"La Pergola","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Piazzetta":{"tags":{"name":"La Piazzetta","amenity":"restaurant"},"name":"La Piazzetta","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Place":{"tags":{"name":"La Place","amenity":"restaurant"},"name":"La Place","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Scala":{"tags":{"name":"La Scala","amenity":"restaurant"},"name":"La Scala","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Tagliatella":{"tags":{"name":"La Tagliatella","amenity":"restaurant"},"name":"La Tagliatella","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Tasca":{"tags":{"name":"La Tasca","amenity":"restaurant"},"name":"La Tasca","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Taverna":{"tags":{"name":"La Taverna","amenity":"restaurant"},"name":"La Taverna","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Terrasse":{"tags":{"name":"La Terrasse","amenity":"restaurant"},"name":"La Terrasse","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Terraza":{"tags":{"name":"La Terraza","amenity":"restaurant"},"name":"La Terraza","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Terrazza":{"tags":{"name":"La Terrazza","amenity":"restaurant"},"name":"La Terrazza","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Trattoria":{"tags":{"name":"La Trattoria","amenity":"restaurant"},"name":"La Trattoria","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Little Italy":{"tags":{"name":"Little Italy","amenity":"restaurant"},"name":"Little Italy","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Logan's Roadhouse":{"tags":{"name":"Logan's Roadhouse","amenity":"restaurant"},"name":"Logan's Roadhouse","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Léon de Bruxelles":{"tags":{"name":"Léon de Bruxelles","amenity":"restaurant"},"name":"Léon de Bruxelles","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/MK Restaurants":{"tags":{"name":"MK Restaurants","amenity":"restaurant"},"name":"MK Restaurants","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Maharaja":{"tags":{"name":"Maharaja","amenity":"restaurant"},"name":"Maharaja","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Marco Polo":{"tags":{"name":"Marco Polo","amenity":"restaurant"},"name":"Marco Polo","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Marco's Pizza":{"tags":{"name":"Marco's Pizza","amenity":"restaurant"},"name":"Marco's Pizza","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/McAlister's Deli":{"tags":{"name":"McAlister's Deli","amenity":"restaurant"},"name":"McAlister's Deli","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Mediterraneo":{"tags":{"name":"Mediterraneo","amenity":"restaurant"},"name":"Mediterraneo","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Mellow Mushroom":{"tags":{"name":"Mellow Mushroom","amenity":"restaurant"},"name":"Mellow Mushroom","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Mimi's Cafe":{"tags":{"name":"Mimi's Cafe","amenity":"restaurant"},"name":"Mimi's Cafe","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Moe's Southwest Grill":{"tags":{"name":"Moe's Southwest Grill","amenity":"restaurant"},"name":"Moe's Southwest Grill","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Mythos":{"tags":{"name":"Mythos","amenity":"restaurant"},"name":"Mythos","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Noodles & Company":{"tags":{"name":"Noodles & Company","amenity":"restaurant"},"name":"Noodles & Company","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/O'Charley's":{"tags":{"name":"O'Charley's","amenity":"restaurant"},"name":"O'Charley's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Oasis":{"tags":{"name":"Oasis","amenity":"restaurant"},"name":"Oasis","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Ocean Basket":{"tags":{"name":"Ocean Basket","amenity":"restaurant"},"name":"Ocean Basket","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Old Chicago":{"tags":{"name":"Old Chicago","amenity":"restaurant"},"name":"Old Chicago","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Osaka":{"tags":{"name":"Osaka","amenity":"restaurant"},"name":"Osaka","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/P.F. Chang's":{"tags":{"name":"P.F. Chang's","amenity":"restaurant"},"name":"P.F. Chang's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pancake House":{"tags":{"name":"Pancake House","amenity":"restaurant"},"name":"Pancake House","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Panda":{"tags":{"name":"Panda","amenity":"restaurant"},"name":"Panda","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Parrilla":{"tags":{"name":"Parrilla","amenity":"restaurant"},"name":"Parrilla","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pinocchio":{"tags":{"name":"Pinocchio","amenity":"restaurant"},"name":"Pinocchio","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pizza Factory":{"tags":{"name":"Pizza Factory","amenity":"restaurant"},"name":"Pizza Factory","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pizza House":{"tags":{"name":"Pizza House","amenity":"restaurant"},"name":"Pizza House","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pizza Ranch":{"tags":{"name":"Pizza Ranch","amenity":"restaurant"},"name":"Pizza Ranch","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pizzeria Italia":{"tags":{"name":"Pizzeria Italia","amenity":"restaurant"},"name":"Pizzeria Italia","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pizzeria Milano":{"tags":{"name":"Pizzeria Milano","amenity":"restaurant"},"name":"Pizzeria Milano","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pizzeria Napoli":{"tags":{"name":"Pizzeria Napoli","amenity":"restaurant"},"name":"Pizzeria Napoli","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pizzeria Venezia":{"tags":{"name":"Pizzeria Venezia","amenity":"restaurant"},"name":"Pizzeria Venezia","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Poivre Rouge":{"tags":{"name":"Poivre Rouge","amenity":"restaurant"},"name":"Poivre Rouge","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pomodoro":{"tags":{"name":"Pomodoro","amenity":"restaurant"},"name":"Pomodoro","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Portofino":{"tags":{"name":"Portofino","amenity":"restaurant"},"name":"Portofino","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Qdoba Mexican Grill":{"tags":{"name":"Qdoba Mexican Grill","amenity":"restaurant"},"name":"Qdoba Mexican Grill","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Restaurante Universitário":{"tags":{"name":"Restaurante Universitário","amenity":"restaurant"},"name":"Restaurante Universitário","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Ristorante Del Arte":{"tags":{"name":"Ristorante Del Arte","amenity":"restaurant"},"name":"Ristorante Del Arte","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Rose":{"tags":{"name":"Rose","amenity":"restaurant"},"name":"Rose","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Rössle":{"tags":{"name":"Rössle","amenity":"restaurant"},"name":"Rössle","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Saigon":{"tags":{"name":"Saigon","amenity":"restaurant"},"name":"Saigon","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Santorini":{"tags":{"name":"Santorini","amenity":"restaurant"},"name":"Santorini","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Shakey's":{"tags":{"name":"Shakey's","amenity":"restaurant"},"name":"Shakey's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Shalimar":{"tags":{"name":"Shalimar","amenity":"restaurant"},"name":"Shalimar","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Shoney's":{"tags":{"name":"Shoney's","amenity":"restaurant"},"name":"Shoney's","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Sphinx":{"tags":{"name":"Sphinx","amenity":"restaurant"},"name":"Sphinx","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Steak 'n Shake":{"tags":{"name":"Steak 'n Shake","cuisine":"burger","amenity":"restaurant"},"name":"Steak 'n Shake","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Steak House":{"tags":{"name":"Steak House","amenity":"restaurant"},"name":"Steak House","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Sunset Grill":{"tags":{"name":"Sunset Grill","amenity":"restaurant"},"name":"Sunset Grill","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Sushi":{"tags":{"name":"Sushi","amenity":"restaurant"},"name":"Sushi","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Sushi Bar":{"tags":{"name":"Sushi Bar","amenity":"restaurant"},"name":"Sushi Bar","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Syrtaki":{"tags":{"name":"Syrtaki","amenity":"restaurant"},"name":"Syrtaki","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Taste of India":{"tags":{"name":"Taste of India","amenity":"restaurant"},"name":"Taste of India","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Taverna":{"tags":{"name":"Taverna","amenity":"restaurant"},"name":"Taverna","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/The Cheesecake Factory":{"tags":{"name":"The Cheesecake Factory","amenity":"restaurant"},"name":"The Cheesecake Factory","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Toby Carvery":{"tags":{"name":"Toby Carvery","amenity":"restaurant"},"name":"Toby Carvery","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Tony Roma's":{"tags":{"name":"Tony Roma's","amenity":"restaurant"},"name":"Tony Roma's","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Toscana":{"tags":{"name":"Toscana","amenity":"restaurant"},"name":"Toscana","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Trattoria":{"tags":{"name":"Trattoria","amenity":"restaurant"},"name":"Trattoria","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Venezia":{"tags":{"name":"Venezia","amenity":"restaurant"},"name":"Venezia","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Warung":{"tags":{"name":"Warung","amenity":"restaurant"},"name":"Warung","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Wasabi":{"tags":{"name":"Wasabi","amenity":"restaurant"},"name":"Wasabi","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Zorbas":{"tags":{"name":"Zorbas","amenity":"restaurant"},"name":"Zorbas","icon":"restaurant","geometry":["point","area"],"fields":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Zum Hirschen":{"tags":{"name":"Zum Hirschen","amenity":"restaurant"},"name":"Zum Hirschen","icon":"restaurant","geometry":["point","area"],"fields":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","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":["name","cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/school/Adolfo Lopez Mateos":{"tags":{"name":"Adolfo Lopez Mateos","amenity":"school"},"name":"Adolfo Lopez Mateos","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Agustin Ya�ez":{"tags":{"name":"Agustin Ya�ez","amenity":"school"},"name":"Agustin Ya�ez","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Albert-Schweitzer-Schule":{"tags":{"name":"Albert-Schweitzer-Schule","amenity":"school"},"name":"Albert-Schweitzer-Schule","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Amado Nervo":{"tags":{"name":"Amado Nervo","amenity":"school"},"name":"Amado Nervo","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Astrid-Lindgren-Schule":{"tags":{"name":"Astrid-Lindgren-Schule","amenity":"school"},"name":"Astrid-Lindgren-Schule","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Benito Juarez":{"tags":{"name":"Benito Juarez","amenity":"school"},"name":"Benito Juarez","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Brown School":{"tags":{"name":"Brown School","amenity":"school"},"name":"Brown School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/CEM":{"tags":{"name":"CEM","amenity":"school"},"name":"CEM","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Center School":{"tags":{"name":"Center School","amenity":"school"},"name":"Center School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Central Elementary School":{"tags":{"name":"Central Elementary School","amenity":"school"},"name":"Central Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Central High School":{"tags":{"name":"Central High School","amenity":"school"},"name":"Central High School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Central School":{"tags":{"name":"Central School","amenity":"school"},"name":"Central School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Colegio San José":{"tags":{"name":"Colegio San José","amenity":"school"},"name":"Colegio San José","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Collège Jean Moulin":{"tags":{"name":"Collège Jean Moulin","amenity":"school"},"name":"Collège Jean Moulin","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Collège privé Saint-Joseph":{"tags":{"name":"Collège privé Saint-Joseph","amenity":"school"},"name":"Collège privé Saint-Joseph","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Cuauhtemoc":{"tags":{"name":"Cuauhtemoc","amenity":"school"},"name":"Cuauhtemoc","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Curso Comunitario":{"tags":{"name":"Curso Comunitario","amenity":"school"},"name":"Curso Comunitario","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Cursos Comunitarios":{"tags":{"name":"Cursos Comunitarios","amenity":"school"},"name":"Cursos Comunitarios","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/EPP":{"tags":{"name":"EPP","amenity":"school"},"name":"EPP","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Emiliano Zapata":{"tags":{"name":"Emiliano Zapata","amenity":"school"},"name":"Emiliano Zapata","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Fairview Elementary School":{"tags":{"name":"Fairview Elementary School","amenity":"school"},"name":"Fairview Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Fairview School":{"tags":{"name":"Fairview School","amenity":"school"},"name":"Fairview School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Francisco I Madero":{"tags":{"name":"Francisco I Madero","amenity":"school"},"name":"Francisco I Madero","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Francisco I. Madero":{"tags":{"name":"Francisco I. Madero","amenity":"school"},"name":"Francisco I. Madero","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Francisco Villa":{"tags":{"name":"Francisco Villa","amenity":"school"},"name":"Francisco Villa","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Franklin Elementary School":{"tags":{"name":"Franklin Elementary School","amenity":"school"},"name":"Franklin Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Franklin School":{"tags":{"name":"Franklin School","amenity":"school"},"name":"Franklin School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Garfield Elementary School":{"tags":{"name":"Garfield Elementary School","amenity":"school"},"name":"Garfield Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Garfield School":{"tags":{"name":"Garfield School","amenity":"school"},"name":"Garfield School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Gimnazjum nr 1":{"tags":{"name":"Gimnazjum nr 1","amenity":"school"},"name":"Gimnazjum nr 1","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Government School":{"tags":{"name":"Government School","amenity":"school"},"name":"Government School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Gregorio Torres Quintero":{"tags":{"name":"Gregorio Torres Quintero","amenity":"school"},"name":"Gregorio Torres Quintero","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Groupe Scolaire":{"tags":{"name":"Groupe Scolaire","amenity":"school"},"name":"Groupe Scolaire","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Guadalupe Victoria":{"tags":{"name":"Guadalupe Victoria","amenity":"school"},"name":"Guadalupe Victoria","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Highland School":{"tags":{"name":"Highland School","amenity":"school"},"name":"Highland School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Hillcrest Elementary School":{"tags":{"name":"Hillcrest Elementary School","amenity":"school"},"name":"Hillcrest Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Holy Cross School":{"tags":{"name":"Holy Cross School","amenity":"school"},"name":"Holy Cross School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Holy Family School":{"tags":{"name":"Holy Family School","amenity":"school"},"name":"Holy Family School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Holy Trinity School":{"tags":{"name":"Holy Trinity School","amenity":"school"},"name":"Holy Trinity School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Ignacio Allende":{"tags":{"name":"Ignacio Allende","amenity":"school"},"name":"Ignacio Allende","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Ignacio Zaragoza":{"tags":{"name":"Ignacio Zaragoza","amenity":"school"},"name":"Ignacio Zaragoza","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Immaculate Conception School":{"tags":{"name":"Immaculate Conception School","amenity":"school"},"name":"Immaculate Conception School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Jackson Elementary School":{"tags":{"name":"Jackson Elementary School","amenity":"school"},"name":"Jackson Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Jackson School":{"tags":{"name":"Jackson School","amenity":"school"},"name":"Jackson School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Jefferson Elementary School":{"tags":{"name":"Jefferson Elementary School","amenity":"school"},"name":"Jefferson Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Jefferson School":{"tags":{"name":"Jefferson School","amenity":"school"},"name":"Jefferson School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Jose Clemente Orozco":{"tags":{"name":"Jose Clemente Orozco","amenity":"school"},"name":"Jose Clemente Orozco","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Jose Ma Morelos Y Pavon":{"tags":{"name":"Jose Ma Morelos Y Pavon","amenity":"school"},"name":"Jose Ma Morelos Y Pavon","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Jose Vasconcelos":{"tags":{"name":"Jose Vasconcelos","amenity":"school"},"name":"Jose Vasconcelos","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Josefa Ortiz De Dominguez":{"tags":{"name":"Josefa Ortiz De Dominguez","amenity":"school"},"name":"Josefa Ortiz De Dominguez","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Juan Escutia":{"tags":{"name":"Juan Escutia","amenity":"school"},"name":"Juan Escutia","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Justo Sierra":{"tags":{"name":"Justo Sierra","amenity":"school"},"name":"Justo Sierra","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Kumon":{"tags":{"name":"Kumon","amenity":"school"},"name":"Kumon","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Lazaro Cardenas":{"tags":{"name":"Lazaro Cardenas","amenity":"school"},"name":"Lazaro Cardenas","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Lazaro Cardenas Del Rio":{"tags":{"name":"Lazaro Cardenas Del Rio","amenity":"school"},"name":"Lazaro Cardenas Del Rio","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Leona Vicario":{"tags":{"name":"Leona Vicario","amenity":"school"},"name":"Leona Vicario","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Liberty Elementary School":{"tags":{"name":"Liberty Elementary School","amenity":"school"},"name":"Liberty Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Liberty School":{"tags":{"name":"Liberty School","amenity":"school"},"name":"Liberty School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Lincoln Elementary School":{"tags":{"name":"Lincoln Elementary School","amenity":"school"},"name":"Lincoln Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Lincoln School":{"tags":{"name":"Lincoln School","amenity":"school"},"name":"Lincoln School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Longfellow Elementary School":{"tags":{"name":"Longfellow Elementary School","amenity":"school"},"name":"Longfellow Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Longfellow School":{"tags":{"name":"Longfellow School","amenity":"school"},"name":"Longfellow School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Madison Elementary School":{"tags":{"name":"Madison Elementary School","amenity":"school"},"name":"Madison Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Manuel Lopez Cotilla":{"tags":{"name":"Manuel Lopez Cotilla","amenity":"school"},"name":"Manuel Lopez Cotilla","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Maple Grove School":{"tags":{"name":"Maple Grove School","amenity":"school"},"name":"Maple Grove School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/McKinley Elementary School":{"tags":{"name":"McKinley Elementary School","amenity":"school"},"name":"McKinley Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/McKinley School":{"tags":{"name":"McKinley School","amenity":"school"},"name":"McKinley School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Miguel Hidalgo":{"tags":{"name":"Miguel Hidalgo","amenity":"school"},"name":"Miguel Hidalgo","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Miguel Hidalgo Y Costilla":{"tags":{"name":"Miguel Hidalgo Y Costilla","amenity":"school"},"name":"Miguel Hidalgo Y Costilla","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Miller School":{"tags":{"name":"Miller School","amenity":"school"},"name":"Miller School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Mount Pleasant School":{"tags":{"name":"Mount Pleasant School","amenity":"school"},"name":"Mount Pleasant School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Mount Zion School":{"tags":{"name":"Mount Zion School","amenity":"school"},"name":"Mount Zion School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Mountain View Elementary School":{"tags":{"name":"Mountain View Elementary School","amenity":"school"},"name":"Mountain View Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/New Hope School":{"tags":{"name":"New Hope School","amenity":"school"},"name":"New Hope School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Nicolas Bravo":{"tags":{"name":"Nicolas Bravo","amenity":"school"},"name":"Nicolas Bravo","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Ni�os Heroes":{"tags":{"name":"Ni�os Heroes","amenity":"school"},"name":"Ni�os Heroes","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Nombre En Tramite":{"tags":{"name":"Nombre En Tramite","amenity":"school"},"name":"Nombre En Tramite","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/North Elementary School":{"tags":{"name":"North Elementary School","amenity":"school"},"name":"North Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Oak Grove School":{"tags":{"name":"Oak Grove School","amenity":"school"},"name":"Oak Grove School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Pedro Moreno":{"tags":{"name":"Pedro Moreno","amenity":"school"},"name":"Pedro Moreno","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Pestalozzischule":{"tags":{"name":"Pestalozzischule","amenity":"school"},"name":"Pestalozzischule","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Pine Grove School":{"tags":{"name":"Pine Grove School","amenity":"school"},"name":"Pine Grove School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Pleasant Hill School":{"tags":{"name":"Pleasant Hill School","amenity":"school"},"name":"Pleasant Hill School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Pleasant Valley School":{"tags":{"name":"Pleasant Valley School","amenity":"school"},"name":"Pleasant Valley School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Pleasant View School":{"tags":{"name":"Pleasant View School","amenity":"school"},"name":"Pleasant View School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Primaria Comunitaria":{"tags":{"name":"Primaria Comunitaria","amenity":"school"},"name":"Primaria Comunitaria","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Ramon Corona":{"tags":{"name":"Ramon Corona","amenity":"school"},"name":"Ramon Corona","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Ricardo Flores Magon":{"tags":{"name":"Ricardo Flores Magon","amenity":"school"},"name":"Ricardo Flores Magon","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Riverside School":{"tags":{"name":"Riverside School","amenity":"school"},"name":"Riverside School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Roosevelt Elementary School":{"tags":{"name":"Roosevelt Elementary School","amenity":"school"},"name":"Roosevelt Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Roosevelt School":{"tags":{"name":"Roosevelt School","amenity":"school"},"name":"Roosevelt School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/SD":{"tags":{"name":"SD","amenity":"school"},"name":"SD","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/SDN":{"tags":{"name":"SDN","amenity":"school"},"name":"SDN","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Sacred Heart School":{"tags":{"name":"Sacred Heart School","amenity":"school"},"name":"Sacred Heart School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Saint Francis School":{"tags":{"name":"Saint Francis School","amenity":"school"},"name":"Saint Francis School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Saint James School":{"tags":{"name":"Saint James School","amenity":"school"},"name":"Saint James School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Saint Johns School":{"tags":{"name":"Saint Johns School","amenity":"school"},"name":"Saint Johns School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Saint Joseph School":{"tags":{"name":"Saint Joseph School","amenity":"school"},"name":"Saint Joseph School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Saint Josephs School":{"tags":{"name":"Saint Josephs School","amenity":"school"},"name":"Saint Josephs School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Saint Kizito Primary School":{"tags":{"name":"Saint Kizito Primary School","amenity":"school"},"name":"Saint Kizito Primary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Saint Mary School":{"tags":{"name":"Saint Mary School","amenity":"school"},"name":"Saint Mary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Saint Marys School":{"tags":{"name":"Saint Marys School","amenity":"school"},"name":"Saint Marys School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Saint Patricks School":{"tags":{"name":"Saint Patricks School","amenity":"school"},"name":"Saint Patricks School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Saint Paul School":{"tags":{"name":"Saint Paul School","amenity":"school"},"name":"Saint Paul School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Saint Pauls School":{"tags":{"name":"Saint Pauls School","amenity":"school"},"name":"Saint Pauls School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Saint Peters School":{"tags":{"name":"Saint Peters School","amenity":"school"},"name":"Saint Peters School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Schillerschule":{"tags":{"name":"Schillerschule","amenity":"school"},"name":"Schillerschule","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/School Number 1":{"tags":{"name":"School Number 1","amenity":"school"},"name":"School Number 1","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/School Number 2":{"tags":{"name":"School Number 2","amenity":"school"},"name":"School Number 2","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/School Number 3":{"tags":{"name":"School Number 3","amenity":"school"},"name":"School Number 3","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/School Number 4":{"tags":{"name":"School Number 4","amenity":"school"},"name":"School Number 4","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Smith School":{"tags":{"name":"Smith School","amenity":"school"},"name":"Smith School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/South Elementary School":{"tags":{"name":"South Elementary School","amenity":"school"},"name":"South Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Sunnyside School":{"tags":{"name":"Sunnyside School","amenity":"school"},"name":"Sunnyside School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Szkoła Podstawowa nr 1":{"tags":{"name":"Szkoła Podstawowa nr 1","amenity":"school"},"name":"Szkoła Podstawowa nr 1","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Szkoła Podstawowa nr 2":{"tags":{"name":"Szkoła Podstawowa nr 2","amenity":"school"},"name":"Szkoła Podstawowa nr 2","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Szkoła Podstawowa nr 3":{"tags":{"name":"Szkoła Podstawowa nr 3","amenity":"school"},"name":"Szkoła Podstawowa nr 3","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Trinity School":{"tags":{"name":"Trinity School","amenity":"school"},"name":"Trinity School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/UNIDAD EDUCATIVA":{"tags":{"name":"UNIDAD EDUCATIVA","amenity":"school"},"name":"UNIDAD EDUCATIVA","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Union School":{"tags":{"name":"Union School","amenity":"school"},"name":"Union School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Valentin Gomez Farias":{"tags":{"name":"Valentin Gomez Farias","amenity":"school"},"name":"Valentin Gomez Farias","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Venustiano Carranza":{"tags":{"name":"Venustiano Carranza","amenity":"school"},"name":"Venustiano Carranza","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Vicente Guerrero":{"tags":{"name":"Vicente Guerrero","amenity":"school"},"name":"Vicente Guerrero","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Volkshochschule":{"tags":{"name":"Volkshochschule","amenity":"school"},"name":"Volkshochschule","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Volksschule":{"tags":{"name":"Volksschule","amenity":"school"},"name":"Volksschule","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Washington Elementary School":{"tags":{"name":"Washington Elementary School","amenity":"school"},"name":"Washington Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Washington School":{"tags":{"name":"Washington School","amenity":"school"},"name":"Washington School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/West Elementary School":{"tags":{"name":"West Elementary School","amenity":"school"},"name":"West Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/White School":{"tags":{"name":"White School","amenity":"school"},"name":"White School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Wilson Elementary School":{"tags":{"name":"Wilson Elementary School","amenity":"school"},"name":"Wilson Elementary School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Wilson School":{"tags":{"name":"Wilson School","amenity":"school"},"name":"Wilson School","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Általános iskola":{"tags":{"name":"Általános iskola","amenity":"school"},"name":"Általános iskola","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/École Jules Ferry":{"tags":{"name":"École Jules Ferry","amenity":"school"},"name":"École Jules Ferry","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/École Notre-Dame":{"tags":{"name":"École Notre-Dame","amenity":"school"},"name":"École Notre-Dame","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/École Saint-Joseph":{"tags":{"name":"École Saint-Joseph","amenity":"school"},"name":"École Saint-Joseph","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/École primaire Jean Jaurès":{"tags":{"name":"École primaire Jean Jaurès","amenity":"school"},"name":"École primaire Jean Jaurès","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/École primaire Jules Ferry":{"tags":{"name":"École primaire Jules Ferry","amenity":"school"},"name":"École primaire Jules Ferry","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/École primaire privée Notre-Dame":{"tags":{"name":"École primaire privée Notre-Dame","amenity":"school"},"name":"École primaire privée Notre-Dame","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/École primaire privée Saint-Joseph":{"tags":{"name":"École primaire privée Saint-Joseph","amenity":"school"},"name":"École primaire privée Saint-Joseph","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/École primaire privée Sainte-Marie":{"tags":{"name":"École primaire privée Sainte-Marie","amenity":"school"},"name":"École primaire privée Sainte-Marie","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/École élémentaire Jules Ferry":{"tags":{"name":"École élémentaire Jules Ferry","amenity":"school"},"name":"École élémentaire Jules Ferry","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Școala Generală":{"tags":{"name":"Școala Generală","amenity":"school"},"name":"Școala Generală","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Școală":{"tags":{"name":"Școală","amenity":"school"},"name":"Școală","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Вечерняя школа":{"tags":{"name":"Вечерняя школа","amenity":"school"},"name":"Вечерняя школа","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Гимназия №1":{"tags":{"name":"Гимназия №1","amenity":"school"},"name":"Гимназия №1","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Средняя школа №1":{"tags":{"name":"Средняя школа №1","amenity":"school"},"name":"Средняя школа №1","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Средняя школа №2":{"tags":{"name":"Средняя школа №2","amenity":"school"},"name":"Средняя школа №2","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Средняя школа №3":{"tags":{"name":"Средняя школа №3","amenity":"school"},"name":"Средняя школа №3","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа № 1":{"tags":{"name":"Школа № 1","amenity":"school"},"name":"Школа № 1","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа № 2":{"tags":{"name":"Школа № 2","amenity":"school"},"name":"Школа № 2","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа № 3":{"tags":{"name":"Школа № 3","amenity":"school"},"name":"Школа № 3","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа № 4":{"tags":{"name":"Школа № 4","amenity":"school"},"name":"Школа № 4","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа № 5":{"tags":{"name":"Школа № 5","amenity":"school"},"name":"Школа № 5","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №1":{"tags":{"name":"Школа №1","amenity":"school"},"name":"Школа №1","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №10":{"tags":{"name":"Школа №10","amenity":"school"},"name":"Школа №10","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №11":{"tags":{"name":"Школа №11","amenity":"school"},"name":"Школа №11","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №12":{"tags":{"name":"Школа №12","amenity":"school"},"name":"Школа №12","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №13":{"tags":{"name":"Школа №13","amenity":"school"},"name":"Школа №13","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №14":{"tags":{"name":"Школа №14","amenity":"school"},"name":"Школа №14","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №15":{"tags":{"name":"Школа №15","amenity":"school"},"name":"Школа №15","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №16":{"tags":{"name":"Школа №16","amenity":"school"},"name":"Школа №16","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №17":{"tags":{"name":"Школа №17","amenity":"school"},"name":"Школа №17","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №18":{"tags":{"name":"Школа №18","amenity":"school"},"name":"Школа №18","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №19":{"tags":{"name":"Школа №19","amenity":"school"},"name":"Школа №19","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №2":{"tags":{"name":"Школа №2","amenity":"school"},"name":"Школа №2","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №20":{"tags":{"name":"Школа №20","amenity":"school"},"name":"Школа №20","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №21":{"tags":{"name":"Школа №21","amenity":"school"},"name":"Школа №21","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №22":{"tags":{"name":"Школа №22","amenity":"school"},"name":"Школа №22","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №23":{"tags":{"name":"Школа №23","amenity":"school"},"name":"Школа №23","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №24":{"tags":{"name":"Школа №24","amenity":"school"},"name":"Школа №24","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №25":{"tags":{"name":"Школа №25","amenity":"school"},"name":"Школа №25","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №26":{"tags":{"name":"Школа №26","amenity":"school"},"name":"Школа №26","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №27":{"tags":{"name":"Школа №27","amenity":"school"},"name":"Школа №27","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №28":{"tags":{"name":"Школа №28","amenity":"school"},"name":"Школа №28","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №3":{"tags":{"name":"Школа №3","amenity":"school"},"name":"Школа №3","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №31":{"tags":{"name":"Школа №31","amenity":"school"},"name":"Школа №31","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №35":{"tags":{"name":"Школа №35","amenity":"school"},"name":"Школа №35","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №4":{"tags":{"name":"Школа №4","amenity":"school"},"name":"Школа №4","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №5":{"tags":{"name":"Школа №5","amenity":"school"},"name":"Школа №5","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №6":{"tags":{"name":"Школа №6","amenity":"school"},"name":"Школа №6","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №7":{"tags":{"name":"Школа №7","amenity":"school"},"name":"Школа №7","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №8":{"tags":{"name":"Школа №8","amenity":"school"},"name":"Школа №8","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/Школа №9":{"tags":{"name":"Школа №9","amenity":"school"},"name":"Школа №9","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/مدرسة":{"tags":{"name":"مدرسة","amenity":"school"},"name":"مدرسة","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/مدرسه":{"tags":{"name":"مدرسه","amenity":"school"},"name":"مدرسه","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/市立南中学校":{"tags":{"name":"市立南中学校","amenity":"school"},"name":"市立南中学校","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/市立南小学校":{"tags":{"name":"市立南小学校","amenity":"school"},"name":"市立南小学校","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/school/市立東中学校":{"tags":{"name":"市立東中学校","amenity":"school"},"name":"市立東中学校","icon":"school","geometry":["point","area"],"fields":["name","operator","address","religion","denomination"],"suggestion":true},"amenity/social_facility/Safe Haven":{"tags":{"name":"Safe Haven","amenity":"social_facility"},"name":"Safe Haven","icon":"poi-social-facility","geometry":["point","area"],"fields":["name","operator","address","building_area","social_facility","social_facility_for","opening_hours","wheelchair"],"suggestion":true},"amenity/social_facility/Детский дом":{"tags":{"name":"Детский дом","amenity":"social_facility"},"name":"Детский дом","icon":"poi-social-facility","geometry":["point","area"],"fields":["name","operator","address","building_area","social_facility","social_facility_for","opening_hours","wheelchair"],"suggestion":true},"amenity/social_facility/Социальный участковый":{"tags":{"name":"Социальный участковый","amenity":"social_facility"},"name":"Социальный участковый","icon":"poi-social-facility","geometry":["point","area"],"fields":["name","operator","address","building_area","social_facility","social_facility_for","opening_hours","wheelchair"],"suggestion":true},"amenity/theatre/Amfiteatr":{"tags":{"name":"Amfiteatr","amenity":"theatre"},"name":"Amfiteatr","icon":"theatre","geometry":["point","area"],"fields":["name","operator","address","building_area"],"suggestion":true},"amenity/theatre/Amphitheater":{"tags":{"name":"Amphitheater","amenity":"theatre"},"name":"Amphitheater","icon":"theatre","geometry":["point","area"],"fields":["name","operator","address","building_area"],"suggestion":true},"amenity/theatre/Amphitheatre":{"tags":{"name":"Amphitheatre","amenity":"theatre"},"name":"Amphitheatre","icon":"theatre","geometry":["point","area"],"fields":["name","operator","address","building_area"],"suggestion":true},"amenity/theatre/Freilichtbühne":{"tags":{"name":"Freilichtbühne","amenity":"theatre"},"name":"Freilichtbühne","icon":"theatre","geometry":["point","area"],"fields":["name","operator","address","building_area"],"suggestion":true},"amenity/theatre/Teatro Comunale":{"tags":{"name":"Teatro Comunale","amenity":"theatre"},"name":"Teatro Comunale","icon":"theatre","geometry":["point","area"],"fields":["name","operator","address","building_area"],"suggestion":true},"leisure/fitness_centre/LA Fitness":{"tags":{"name":"LA Fitness","leisure":"fitness_centre"},"name":"LA Fitness","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/fitness_centre/Planet Fitness":{"tags":{"name":"Planet Fitness","leisure":"fitness_centre"},"name":"Planet Fitness","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/fitness_centre/Snap Fitness":{"tags":{"name":"Snap Fitness","leisure":"fitness_centre"},"name":"Snap Fitness","icon":"pitch","geometry":["point","area"],"fields":["name","sport","address","building_area","opening_hours"],"suggestion":true},"leisure/playground/Çocuk Parkı":{"tags":{"name":"Çocuk Parkı","leisure":"playground"},"name":"Çocuk Parkı","icon":"playground","geometry":["point","area"],"fields":["name","operator","surface","playground/max_age","playground/min_age","access_simple"],"suggestion":true},"leisure/playground/놀이터":{"tags":{"name":"놀이터","leisure":"playground"},"name":"놀이터","icon":"playground","geometry":["point","area"],"fields":["name","operator","surface","playground/max_age","playground/min_age","access_simple"],"suggestion":true},"leisure/sports_centre/Anytime Fitness":{"tags":{"name":"Anytime Fitness","leisure":"sports_centre"},"name":"Anytime Fitness","icon":"pitch","geometry":["point","area"],"fields":["name","sport","building","address","opening_hours"],"suggestion":true},"leisure/sports_centre/Complejo Municipal de Deportes":{"tags":{"name":"Complejo Municipal de Deportes","leisure":"sports_centre"},"name":"Complejo Municipal de Deportes","icon":"pitch","geometry":["point","area"],"fields":["name","sport","building","address","opening_hours"],"suggestion":true},"leisure/sports_centre/Complexe Sportif":{"tags":{"name":"Complexe Sportif","leisure":"sports_centre"},"name":"Complexe Sportif","icon":"pitch","geometry":["point","area"],"fields":["name","sport","building","address","opening_hours"],"suggestion":true},"leisure/sports_centre/Curves":{"tags":{"name":"Curves","leisure":"sports_centre"},"name":"Curves","icon":"pitch","geometry":["point","area"],"fields":["name","sport","building","address","opening_hours"],"suggestion":true},"leisure/sports_centre/Fitness First":{"tags":{"name":"Fitness First","leisure":"sports_centre"},"name":"Fitness First","icon":"pitch","geometry":["point","area"],"fields":["name","sport","building","address","opening_hours"],"suggestion":true},"leisure/sports_centre/Gold's Gym":{"tags":{"name":"Gold's Gym","leisure":"sports_centre"},"name":"Gold's Gym","icon":"pitch","geometry":["point","area"],"fields":["name","sport","building","address","opening_hours"],"suggestion":true},"leisure/sports_centre/Kieser Training":{"tags":{"name":"Kieser Training","leisure":"sports_centre"},"name":"Kieser Training","icon":"pitch","geometry":["point","area"],"fields":["name","sport","building","address","opening_hours"],"suggestion":true},"leisure/sports_centre/Life Time Fitness":{"tags":{"name":"Life Time Fitness","leisure":"sports_centre"},"name":"Life Time Fitness","icon":"pitch","geometry":["point","area"],"fields":["name","sport","building","address","opening_hours"],"suggestion":true},"leisure/sports_centre/McFit":{"tags":{"name":"McFit","leisure":"sports_centre"},"name":"McFit","icon":"pitch","geometry":["point","area"],"fields":["name","sport","building","address","opening_hours"],"suggestion":true},"leisure/sports_centre/Mrs. Sporty":{"tags":{"name":"Mrs. Sporty","leisure":"sports_centre"},"name":"Mrs. Sporty","icon":"pitch","geometry":["point","area"],"fields":["name","sport","building","address","opening_hours"],"suggestion":true},"leisure/sports_centre/Orlik":{"tags":{"name":"Orlik","leisure":"sports_centre"},"name":"Orlik","icon":"pitch","geometry":["point","area"],"fields":["name","sport","building","address","opening_hours"],"suggestion":true},"leisure/sports_centre/Pabellón Municipal de Deportes":{"tags":{"name":"Pabellón Municipal de Deportes","leisure":"sports_centre"},"name":"Pabellón Municipal de Deportes","icon":"pitch","geometry":["point","area"],"fields":["name","sport","building","address","opening_hours"],"suggestion":true},"leisure/sports_centre/Palestra Comunale":{"tags":{"name":"Palestra Comunale","leisure":"sports_centre"},"name":"Palestra Comunale","icon":"pitch","geometry":["point","area"],"fields":["name","sport","building","address","opening_hours"],"suggestion":true},"leisure/sports_centre/Salle Omnisport":{"tags":{"name":"Salle Omnisport","leisure":"sports_centre"},"name":"Salle Omnisport","icon":"pitch","geometry":["point","area"],"fields":["name","sport","building","address","opening_hours"],"suggestion":true},"leisure/sports_centre/Virgin Active":{"tags":{"name":"Virgin Active","leisure":"sports_centre"},"name":"Virgin Active","icon":"pitch","geometry":["point","area"],"fields":["name","sport","building","address","opening_hours"],"suggestion":true},"leisure/sports_centre/YMCA":{"tags":{"name":"YMCA","leisure":"sports_centre"},"name":"YMCA","icon":"pitch","geometry":["point","area"],"fields":["name","sport","building","address","opening_hours"],"suggestion":true},"leisure/sports_centre/ДЮСШ":{"tags":{"name":"ДЮСШ","leisure":"sports_centre"},"name":"ДЮСШ","icon":"pitch","geometry":["point","area"],"fields":["name","sport","building","address","opening_hours"],"suggestion":true},"leisure/sports_centre/Ледовый дворец":{"tags":{"name":"Ледовый дворец","leisure":"sports_centre"},"name":"Ледовый дворец","icon":"pitch","geometry":["point","area"],"fields":["name","sport","building","address","opening_hours"],"suggestion":true},"leisure/sports_centre/体育館":{"tags":{"name":"体育館","leisure":"sports_centre"},"name":"体育館","icon":"pitch","geometry":["point","area"],"fields":["name","sport","building","address","opening_hours"],"suggestion":true},"leisure/swimming_pool/Schwimmerbecken":{"tags":{"name":"Schwimmerbecken","leisure":"swimming_pool"},"name":"Schwimmerbecken","icon":"swimming","geometry":["point","area"],"fields":["name","access_simple","operator","address"],"suggestion":true},"leisure/swimming_pool/Yüzme Havuzu":{"tags":{"name":"Yüzme Havuzu","leisure":"swimming_pool"},"name":"Yüzme Havuzu","icon":"swimming","geometry":["point","area"],"fields":["name","access_simple","operator","address"],"suggestion":true},"leisure/swimming_pool/プール":{"tags":{"name":"プール","leisure":"swimming_pool"},"name":"プール","icon":"swimming","geometry":["point","area"],"fields":["name","access_simple","operator","address"],"suggestion":true},"leisure/swimming_pool/游泳池":{"tags":{"name":"游泳池","leisure":"swimming_pool"},"name":"游泳池","icon":"swimming","geometry":["point","area"],"fields":["name","access_simple","operator","address"],"suggestion":true},"man_made/windmill/De Hoop":{"tags":{"name":"De Hoop","man_made":"windmill"},"name":"De Hoop","icon":"poi-windmill","geometry":["point","area"],"fields":["building_area"],"suggestion":true},"shop/alcohol/Alko":{"tags":{"name":"Alko","shop":"alcohol"},"name":"Alko","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/BC Liquor Store":{"tags":{"name":"BC Liquor Store","shop":"alcohol"},"name":"BC Liquor Store","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/BWS":{"tags":{"name":"BWS","shop":"alcohol"},"name":"BWS","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/Bargain Booze":{"tags":{"name":"Bargain Booze","shop":"alcohol"},"name":"Bargain Booze","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/Beer Store":{"tags":{"name":"Beer Store","shop":"alcohol"},"name":"Beer Store","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/Botilleria":{"tags":{"name":"Botilleria","shop":"alcohol"},"name":"Botilleria","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/Dan Murphy's":{"tags":{"name":"Dan Murphy's","shop":"alcohol"},"name":"Dan Murphy's","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/Gall & Gall":{"tags":{"name":"Gall & Gall","shop":"alcohol"},"name":"Gall & Gall","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/LCBO":{"tags":{"name":"LCBO","shop":"alcohol"},"name":"LCBO","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/Liquor Depot":{"tags":{"name":"Liquor Depot","shop":"alcohol"},"name":"Liquor Depot","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/Liquor Store":{"tags":{"name":"Liquor Store","shop":"alcohol"},"name":"Liquor Store","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/Liquorland":{"tags":{"name":"Liquorland","shop":"alcohol"},"name":"Liquorland","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/Mitra":{"tags":{"name":"Mitra","shop":"alcohol"},"name":"Mitra","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/Nicolas":{"tags":{"name":"Nicolas","shop":"alcohol"},"name":"Nicolas","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/SAQ":{"tags":{"name":"SAQ","shop":"alcohol"},"name":"SAQ","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/Systembolaget":{"tags":{"name":"Systembolaget","shop":"alcohol"},"name":"Systembolaget","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","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":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/Vinmonopolet":{"tags":{"name":"Vinmonopolet","shop":"alcohol"},"name":"Vinmonopolet","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/Алкомаркет":{"tags":{"name":"Алкомаркет","shop":"alcohol"},"name":"Алкомаркет","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/Ароматный мир":{"tags":{"name":"Ароматный мир","shop":"alcohol"},"name":"Ароматный мир","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/Бристоль":{"tags":{"name":"Бристоль","shop":"alcohol"},"name":"Бристоль","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/Градус":{"tags":{"name":"Градус","shop":"alcohol"},"name":"Градус","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/Живое пиво":{"tags":{"name":"Живое пиво","shop":"alcohol"},"name":"Живое пиво","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/Красное & Белое":{"tags":{"name":"Красное & Белое","shop":"alcohol"},"name":"Красное & Белое","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/Норман":{"tags":{"name":"Норман","shop":"alcohol"},"name":"Норман","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/Отдохни":{"tags":{"name":"Отдохни","shop":"alcohol"},"name":"Отдохни","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/Пиво":{"tags":{"name":"Пиво","shop":"alcohol"},"name":"Пиво","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/alcohol/Разливное пиво":{"tags":{"name":"Разливное пиво","shop":"alcohol"},"name":"Разливное пиво","icon":"alcohol-shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi","drive_through"],"suggestion":true},"shop/baby_goods/Aubert":{"tags":{"name":"Aubert","shop":"baby_goods"},"name":"Aubert","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/baby_goods/Babies R Us":{"tags":{"name":"Babies R Us","shop":"baby_goods"},"name":"Babies R Us","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/baby_goods/BabyOne":{"tags":{"name":"BabyOne","shop":"baby_goods"},"name":"BabyOne","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/AILI":{"tags":{"name":"AILI","shop":"bakery"},"name":"AILI","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Anker":{"tags":{"name":"Anker","shop":"bakery"},"name":"Anker","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Awiteks":{"tags":{"name":"Awiteks","shop":"bakery"},"name":"Awiteks","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Backshop":{"tags":{"name":"Backshop","shop":"bakery"},"name":"Backshop","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Backwerk":{"tags":{"name":"Backwerk","shop":"bakery"},"name":"Backwerk","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Baguette":{"tags":{"name":"Baguette","shop":"bakery"},"name":"Baguette","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Bakers Delight":{"tags":{"name":"Bakers Delight","shop":"bakery"},"name":"Bakers Delight","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Bakker Bart":{"tags":{"name":"Bakker Bart","shop":"bakery"},"name":"Bakker Bart","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Banette":{"tags":{"name":"Banette","shop":"bakery"},"name":"Banette","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Bäckerei Fuchs":{"tags":{"name":"Bäckerei Fuchs","shop":"bakery"},"name":"Bäckerei Fuchs","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Bäckerei Grimminger":{"tags":{"name":"Bäckerei Grimminger","shop":"bakery"},"name":"Bäckerei Grimminger","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Bäckerei Müller":{"tags":{"name":"Bäckerei Müller","shop":"bakery"},"name":"Bäckerei Müller","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Bäckerei Schmidt":{"tags":{"name":"Bäckerei Schmidt","shop":"bakery"},"name":"Bäckerei Schmidt","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Bäckerei Schneider":{"tags":{"name":"Bäckerei Schneider","shop":"bakery"},"name":"Bäckerei Schneider","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Cooplands":{"tags":{"name":"Cooplands","shop":"bakery"},"name":"Cooplands","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Dat Backhus":{"tags":{"name":"Dat Backhus","shop":"bakery"},"name":"Dat Backhus","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Der Beck":{"tags":{"name":"Der Beck","shop":"bakery"},"name":"Der Beck","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Der Mann":{"tags":{"name":"Der Mann","shop":"bakery"},"name":"Der Mann","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Ditsch":{"tags":{"name":"Ditsch","shop":"bakery"},"name":"Ditsch","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Fornetti":{"tags":{"name":"Fornetti","shop":"bakery"},"name":"Fornetti","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Goeken backen":{"tags":{"name":"Goeken backen","shop":"bakery"},"name":"Goeken backen","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Goldilocks":{"tags":{"name":"Goldilocks","shop":"bakery"},"name":"Goldilocks","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Greggs":{"tags":{"name":"Greggs","shop":"bakery"},"name":"Greggs","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Hofpfisterei":{"tags":{"name":"Hofpfisterei","shop":"bakery"},"name":"Hofpfisterei","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Ihle":{"tags":{"name":"Ihle","shop":"bakery"},"name":"Ihle","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Julie's Bakeshop":{"tags":{"name":"Julie's Bakeshop","shop":"bakery"},"name":"Julie's Bakeshop","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/K&U":{"tags":{"name":"K&U","shop":"bakery"},"name":"K&U","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/K&U Bäckerei":{"tags":{"name":"K&U Bäckerei","shop":"bakery"},"name":"K&U Bäckerei","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Kamps":{"tags":{"name":"Kamps","shop":"bakery"},"name":"Kamps","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/La Mie Câline":{"tags":{"name":"La Mie Câline","shop":"bakery"},"name":"La Mie Câline","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Le Crobag":{"tags":{"name":"Le Crobag","shop":"bakery"},"name":"Le Crobag","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Le Fournil":{"tags":{"name":"Le Fournil","shop":"bakery"},"name":"Le Fournil","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Lila Bäcker":{"tags":{"name":"Lila Bäcker","shop":"bakery"},"name":"Lila Bäcker","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Lipóti Pékség":{"tags":{"name":"Lipóti Pékség","shop":"bakery"},"name":"Lipóti Pékség","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Marie Blachère":{"tags":{"name":"Marie Blachère","shop":"bakery"},"name":"Marie Blachère","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Mlinar":{"tags":{"name":"Mlinar","shop":"bakery"},"name":"Mlinar","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Musmanni":{"tags":{"name":"Musmanni","shop":"bakery"},"name":"Musmanni","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Oebel":{"tags":{"name":"Oebel","shop":"bakery"},"name":"Oebel","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Paul":{"tags":{"name":"Paul","shop":"bakery"},"name":"Paul","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Red Ribbon":{"tags":{"name":"Red Ribbon","shop":"bakery"},"name":"Red Ribbon","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Schäfer's":{"tags":{"name":"Schäfer's","shop":"bakery"},"name":"Schäfer's","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Sehne":{"tags":{"name":"Sehne","shop":"bakery"},"name":"Sehne","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Stadtbäckerei":{"tags":{"name":"Stadtbäckerei","shop":"bakery"},"name":"Stadtbäckerei","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Steinecke":{"tags":{"name":"Steinecke","shop":"bakery"},"name":"Steinecke","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Sternenbäck":{"tags":{"name":"Sternenbäck","shop":"bakery"},"name":"Sternenbäck","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Ströck":{"tags":{"name":"Ströck","shop":"bakery"},"name":"Ströck","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Wiener Feinbäcker":{"tags":{"name":"Wiener Feinbäcker","shop":"bakery"},"name":"Wiener Feinbäcker","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/von Allwörden":{"tags":{"name":"von Allwörden","shop":"bakery"},"name":"von Allwörden","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Булочная":{"tags":{"name":"Булочная","shop":"bakery"},"name":"Булочная","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Горячий хлеб":{"tags":{"name":"Горячий хлеб","shop":"bakery"},"name":"Горячий хлеб","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Каравай":{"tags":{"name":"Каравай","shop":"bakery"},"name":"Каравай","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Кулиничи":{"tags":{"name":"Кулиничи","shop":"bakery"},"name":"Кулиничи","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Кулиничі":{"tags":{"name":"Кулиничі","shop":"bakery"},"name":"Кулиничі","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Свежий хлеб":{"tags":{"name":"Свежий хлеб","shop":"bakery"},"name":"Свежий хлеб","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/Хлеб":{"tags":{"name":"Хлеб","shop":"bakery"},"name":"Хлеб","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/مخبز":{"tags":{"name":"مخبز","shop":"bakery"},"name":"مخبز","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/مخبزة":{"tags":{"name":"مخبزة","shop":"bakery"},"name":"مخبزة","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/نان لواش":{"tags":{"name":"نان لواش","shop":"bakery"},"name":"نان لواش","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/نانوایی":{"tags":{"name":"نانوایی","shop":"bakery"},"name":"نانوایی","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/نانوایی بربری":{"tags":{"name":"نانوایی بربری","shop":"bakery"},"name":"نانوایی بربری","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/نانوایی سنگک":{"tags":{"name":"نانوایی سنگک","shop":"bakery"},"name":"نانوایی سنگک","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/نانوایی سنگکی":{"tags":{"name":"نانوایی سنگکی","shop":"bakery"},"name":"نانوایی سنگکی","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bakery/نانوایی لواش":{"tags":{"name":"نانوایی لواش","shop":"bakery"},"name":"نانوایی لواش","icon":"bakery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/beauty/Sally Beauty Supply":{"tags":{"name":"Sally Beauty Supply","shop":"beauty"},"name":"Sally Beauty Supply","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","opening_hours","payment_multi"],"suggestion":true},"shop/beauty/Yves Rocher":{"tags":{"name":"Yves Rocher","shop":"beauty"},"name":"Yves Rocher","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","opening_hours","payment_multi"],"suggestion":true},"shop/bed/Matratzen Concord":{"tags":{"name":"Matratzen Concord","shop":"bed"},"name":"Matratzen Concord","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bed/Mattress Firm":{"tags":{"name":"Mattress Firm","shop":"bed"},"name":"Mattress Firm","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bed/Sleepy's":{"tags":{"name":"Sleepy's","shop":"bed"},"name":"Sleepy's","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/beverages/50嵐":{"tags":{"name":"50嵐","shop":"beverages"},"name":"50嵐","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/beverages/Dursty":{"tags":{"name":"Dursty","shop":"beverages"},"name":"Dursty","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/beverages/Edeka Getränkemarkt":{"tags":{"name":"Edeka Getränkemarkt","shop":"beverages"},"name":"Edeka Getränkemarkt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/beverages/Fristo":{"tags":{"name":"Fristo","shop":"beverages"},"name":"Fristo","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/beverages/Getränke Hoffmann":{"tags":{"name":"Getränke Hoffmann","shop":"beverages"},"name":"Getränke Hoffmann","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/beverages/Getränkeland":{"tags":{"name":"Getränkeland","shop":"beverages"},"name":"Getränkeland","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/beverages/Getränkemarkt":{"tags":{"name":"Getränkemarkt","shop":"beverages"},"name":"Getränkemarkt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/beverages/Orterer Getränkemarkt":{"tags":{"name":"Orterer Getränkemarkt","shop":"beverages"},"name":"Orterer Getränkemarkt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/beverages/Rewe Getränkemarkt":{"tags":{"name":"Rewe Getränkemarkt","shop":"beverages"},"name":"Rewe Getränkemarkt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/beverages/Trinkgut":{"tags":{"name":"Trinkgut","shop":"beverages"},"name":"Trinkgut","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/beverages/茶湯會":{"tags":{"name":"茶湯會","shop":"beverages"},"name":"茶湯會","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bicycle/Halfords":{"tags":{"name":"Halfords","shop":"bicycle"},"name":"Halfords","icon":"bicycle","geometry":["point","area"],"fields":["name","operator","address","building_area","service/bicycle","opening_hours","payment_multi"],"suggestion":true},"shop/bicycle/Веломарка":{"tags":{"name":"Веломарка","shop":"bicycle"},"name":"Веломарка","icon":"bicycle","geometry":["point","area"],"fields":["name","operator","address","building_area","service/bicycle","opening_hours","payment_multi"],"suggestion":true},"shop/bicycle/サイクルベースあさひ":{"tags":{"name":"サイクルベースあさひ","shop":"bicycle"},"name":"サイクルベースあさひ","icon":"bicycle","geometry":["point","area"],"fields":["name","operator","address","building_area","service/bicycle","opening_hours","payment_multi"],"suggestion":true},"shop/bookmaker/Betfred":{"tags":{"name":"Betfred","shop":"bookmaker"},"name":"Betfred","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bookmaker/Coral":{"tags":{"name":"Coral","shop":"bookmaker"},"name":"Coral","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bookmaker/Ladbrokes":{"tags":{"name":"Ladbrokes","shop":"bookmaker"},"name":"Ladbrokes","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bookmaker/Paddy Power":{"tags":{"name":"Paddy Power","shop":"bookmaker"},"name":"Paddy Power","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bookmaker/William Hill":{"tags":{"name":"William Hill","shop":"bookmaker"},"name":"William Hill","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/bookmaker/ΟΠΑΠ":{"tags":{"name":"ΟΠΑΠ","shop":"bookmaker"},"name":"ΟΠΑΠ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/butcher/Boucherie Charcuterie":{"tags":{"name":"Boucherie Charcuterie","shop":"butcher"},"name":"Boucherie Charcuterie","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/butcher/Carnicería":{"tags":{"name":"Carnicería","shop":"butcher"},"name":"Carnicería","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/butcher/Fleischerei Richter":{"tags":{"name":"Fleischerei Richter","shop":"butcher"},"name":"Fleischerei Richter","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/butcher/Húsbolt":{"tags":{"name":"Húsbolt","shop":"butcher"},"name":"Húsbolt","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/butcher/Macelleria":{"tags":{"name":"Macelleria","shop":"butcher"},"name":"Macelleria","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/butcher/Vinzenzmurr":{"tags":{"name":"Vinzenzmurr","shop":"butcher"},"name":"Vinzenzmurr","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/butcher/Ариант":{"tags":{"name":"Ариант","shop":"butcher"},"name":"Ариант","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/butcher/Великолукский мясокомбинат":{"tags":{"name":"Великолукский мясокомбинат","shop":"butcher"},"name":"Великолукский мясокомбинат","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/butcher/Мясная лавка":{"tags":{"name":"Мясная лавка","shop":"butcher"},"name":"Мясная лавка","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/butcher/Мясницкий ряд":{"tags":{"name":"Мясницкий ряд","shop":"butcher"},"name":"Мясницкий ряд","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/butcher/Мясной":{"tags":{"name":"Мясной","shop":"butcher"},"name":"Мясной","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/butcher/Мясо":{"tags":{"name":"Мясо","shop":"butcher"},"name":"Мясо","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/butcher/Наша Ряба":{"tags":{"name":"Наша Ряба","shop":"butcher"},"name":"Наша Ряба","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/butcher/Свежее мясо":{"tags":{"name":"Свежее мясо","shop":"butcher"},"name":"Свежее мясо","icon":"slaughterhouse","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/car/Audi":{"tags":{"name":"Audi","shop":"car"},"name":"Audi","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/BMW":{"tags":{"name":"BMW","shop":"car"},"name":"BMW","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Chevrolet":{"tags":{"name":"Chevrolet","shop":"car"},"name":"Chevrolet","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Citroën":{"tags":{"name":"Citroën","shop":"car"},"name":"Citroën","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Dacia":{"tags":{"name":"Dacia","shop":"car"},"name":"Dacia","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Fiat":{"tags":{"name":"Fiat","shop":"car"},"name":"Fiat","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Ford":{"tags":{"name":"Ford","shop":"car"},"name":"Ford","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Honda":{"tags":{"name":"Honda","shop":"car"},"name":"Honda","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Hyundai":{"tags":{"name":"Hyundai","shop":"car"},"name":"Hyundai","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Isuzu":{"tags":{"name":"Isuzu","shop":"car"},"name":"Isuzu","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Kia":{"tags":{"name":"Kia","shop":"car"},"name":"Kia","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Land Rover":{"tags":{"name":"Land Rover","shop":"car"},"name":"Land Rover","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Lexus":{"tags":{"name":"Lexus","shop":"car"},"name":"Lexus","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Mazda":{"tags":{"name":"Mazda","shop":"car"},"name":"Mazda","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Mercedes-Benz":{"tags":{"name":"Mercedes-Benz","shop":"car"},"name":"Mercedes-Benz","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Mitsubishi":{"tags":{"name":"Mitsubishi","shop":"car"},"name":"Mitsubishi","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Mitsubishi Motors":{"tags":{"name":"Mitsubishi Motors","shop":"car"},"name":"Mitsubishi Motors","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/NISSAN":{"tags":{"name":"NISSAN","shop":"car"},"name":"NISSAN","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Nissan":{"tags":{"name":"Nissan","shop":"car"},"name":"Nissan","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Opel":{"tags":{"name":"Opel","shop":"car"},"name":"Opel","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Peugeot":{"tags":{"name":"Peugeot","shop":"car"},"name":"Peugeot","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Porsche":{"tags":{"name":"Porsche","shop":"car"},"name":"Porsche","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Renault":{"tags":{"name":"Renault","shop":"car"},"name":"Renault","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Seat":{"tags":{"name":"Seat","shop":"car"},"name":"Seat","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Skoda":{"tags":{"name":"Skoda","shop":"car"},"name":"Skoda","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Subaru":{"tags":{"name":"Subaru","shop":"car"},"name":"Subaru","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Suzuki":{"tags":{"name":"Suzuki","shop":"car"},"name":"Suzuki","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Toyota":{"tags":{"name":"Toyota","shop":"car"},"name":"Toyota","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Volkswagen":{"tags":{"name":"Volkswagen","shop":"car"},"name":"Volkswagen","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car/Volvo":{"tags":{"name":"Volvo","shop":"car"},"name":"Volvo","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_parts/Advance Auto Parts":{"tags":{"name":"Advance Auto Parts","shop":"car_parts"},"name":"Advance Auto Parts","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/car_parts/AutoZone":{"tags":{"name":"AutoZone","shop":"car_parts"},"name":"AutoZone","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/car_parts/Brezan":{"tags":{"name":"Brezan","shop":"car_parts"},"name":"Brezan","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/car_parts/NAPA Auto Parts":{"tags":{"name":"NAPA Auto Parts","shop":"car_parts"},"name":"NAPA Auto Parts","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/car_parts/Napa Auto Parts":{"tags":{"name":"Napa Auto Parts","shop":"car_parts"},"name":"Napa Auto Parts","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/car_parts/O'Reilly Auto Parts":{"tags":{"name":"O'Reilly Auto Parts","shop":"car_parts"},"name":"O'Reilly Auto Parts","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/car_parts/Repco":{"tags":{"name":"Repco","shop":"car_parts"},"name":"Repco","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/car_parts/Tokić":{"tags":{"name":"Tokić","shop":"car_parts"},"name":"Tokić","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/car_parts/repuestos automotrices":{"tags":{"name":"repuestos automotrices","shop":"car_parts"},"name":"repuestos automotrices","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/car_parts/Автозапчастини":{"tags":{"name":"Автозапчастини","shop":"car_parts"},"name":"Автозапчастини","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/car_parts/Автомир":{"tags":{"name":"Автомир","shop":"car_parts"},"name":"Автомир","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/car_parts/イエローハット":{"tags":{"name":"イエローハット","shop":"car_parts"},"name":"イエローハット","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/car_parts/オートバックス":{"tags":{"name":"オートバックス","shop":"car_parts"},"name":"オートバックス","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/car_parts/タイヤ館":{"tags":{"name":"タイヤ館","shop":"car_parts"},"name":"タイヤ館","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/A.T.U":{"tags":{"name":"A.T.U","shop":"car_repair"},"name":"A.T.U","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Bosch Car Service":{"tags":{"name":"Bosch Car Service","shop":"car_repair"},"name":"Bosch Car Service","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Carglass":{"tags":{"name":"Carglass","shop":"car_repair"},"name":"Carglass","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Euromaster":{"tags":{"name":"Euromaster","shop":"car_repair"},"name":"Euromaster","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Feu Vert":{"tags":{"name":"Feu Vert","shop":"car_repair"},"name":"Feu Vert","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Firestone":{"tags":{"name":"Firestone","shop":"car_repair"},"name":"Firestone","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Firestone Complete Auto Care":{"tags":{"name":"Firestone Complete Auto Care","shop":"car_repair"},"name":"Firestone Complete Auto Care","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Garage Renault":{"tags":{"name":"Garage Renault","shop":"car_repair"},"name":"Garage Renault","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Gomeria":{"tags":{"name":"Gomeria","shop":"car_repair"},"name":"Gomeria","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Gomería":{"tags":{"name":"Gomería","shop":"car_repair"},"name":"Gomería","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Goodyear":{"tags":{"name":"Goodyear","shop":"car_repair"},"name":"Goodyear","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Grease Monkey":{"tags":{"name":"Grease Monkey","shop":"car_repair"},"name":"Grease Monkey","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Jiffy Lube":{"tags":{"name":"Jiffy Lube","shop":"car_repair"},"name":"Jiffy Lube","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Kwik Fit":{"tags":{"name":"Kwik Fit","shop":"car_repair"},"name":"Kwik Fit","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Lubricentro":{"tags":{"name":"Lubricentro","shop":"car_repair"},"name":"Lubricentro","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Meineke":{"tags":{"name":"Meineke","shop":"car_repair"},"name":"Meineke","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Mekonomen":{"tags":{"name":"Mekonomen","shop":"car_repair"},"name":"Mekonomen","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Midas":{"tags":{"name":"Midas","shop":"car_repair"},"name":"Midas","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Mr. Lube":{"tags":{"name":"Mr. Lube","shop":"car_repair"},"name":"Mr. Lube","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Norauto":{"tags":{"name":"Norauto","shop":"car_repair"},"name":"Norauto","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Pep Boys":{"tags":{"name":"Pep Boys","shop":"car_repair"},"name":"Pep Boys","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Pit Stop":{"tags":{"name":"Pit Stop","shop":"car_repair"},"name":"Pit Stop","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Point S":{"tags":{"name":"Point S","shop":"car_repair"},"name":"Point S","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Roady":{"tags":{"name":"Roady","shop":"car_repair"},"name":"Roady","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Sears Auto Center":{"tags":{"name":"Sears Auto Center","shop":"car_repair"},"name":"Sears Auto Center","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Speedy":{"tags":{"name":"Speedy","shop":"car_repair"},"name":"Speedy","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Stacja Kontroli Pojazdów":{"tags":{"name":"Stacja Kontroli Pojazdów","shop":"car_repair"},"name":"Stacja Kontroli Pojazdów","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Taller":{"tags":{"name":"Taller","shop":"car_repair"},"name":"Taller","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Valvoline":{"tags":{"name":"Valvoline","shop":"car_repair"},"name":"Valvoline","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Valvoline Instant Oil Change":{"tags":{"name":"Valvoline Instant Oil Change","shop":"car_repair"},"name":"Valvoline Instant Oil Change","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Wulkanizacja":{"tags":{"name":"Wulkanizacja","shop":"car_repair"},"name":"Wulkanizacja","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/ÖAMTC":{"tags":{"name":"ÖAMTC","shop":"car_repair"},"name":"ÖAMTC","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Автомастерская":{"tags":{"name":"Автомастерская","shop":"car_repair"},"name":"Автомастерская","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Авторемонт":{"tags":{"name":"Авторемонт","shop":"car_repair"},"name":"Авторемонт","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Автосервис":{"tags":{"name":"Автосервис","shop":"car_repair"},"name":"Автосервис","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Автосервис+шиномонтаж":{"tags":{"name":"Автосервис+шиномонтаж","shop":"car_repair"},"name":"Автосервис+шиномонтаж","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Замена масла":{"tags":{"name":"Замена масла","shop":"car_repair"},"name":"Замена масла","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/СТО":{"tags":{"name":"СТО","shop":"car_repair"},"name":"СТО","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/Шиномонтаж":{"tags":{"name":"Шиномонтаж","shop":"car_repair"},"name":"Шиномонтаж","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/car_repair/шиномонтаж":{"tags":{"name":"шиномонтаж","shop":"car_repair"},"name":"шиномонтаж","icon":"car","geometry":["point","area"],"fields":["name","operator","address","building_area","service/vehicle","opening_hours","payment_multi"],"suggestion":true},"shop/carpet/Carpet Right":{"tags":{"name":"Carpet Right","shop":"carpet"},"name":"Carpet Right","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/carpet/Carpetright":{"tags":{"name":"Carpetright","shop":"carpet"},"name":"Carpetright","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/charity/Age UK":{"tags":{"name":"Age UK","shop":"charity"},"name":"Age UK","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","opening_hours","payment_multi"],"suggestion":true},"shop/charity/Barnardo's":{"tags":{"name":"Barnardo's","shop":"charity"},"name":"Barnardo's","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","opening_hours","payment_multi"],"suggestion":true},"shop/charity/British Heart Foundation":{"tags":{"name":"British Heart Foundation","shop":"charity"},"name":"British Heart Foundation","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","opening_hours","payment_multi"],"suggestion":true},"shop/charity/Cancer Research UK":{"tags":{"name":"Cancer Research UK","shop":"charity"},"name":"Cancer Research UK","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","opening_hours","payment_multi"],"suggestion":true},"shop/charity/Oxfam":{"tags":{"name":"Oxfam","shop":"charity"},"name":"Oxfam","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","opening_hours","payment_multi"],"suggestion":true},"shop/charity/Salvation Army":{"tags":{"name":"Salvation Army","shop":"charity"},"name":"Salvation Army","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","opening_hours","payment_multi"],"suggestion":true},"shop/charity/Scope":{"tags":{"name":"Scope","shop":"charity"},"name":"Scope","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","opening_hours","payment_multi"],"suggestion":true},"shop/charity/Sue Ryder":{"tags":{"name":"Sue Ryder","shop":"charity"},"name":"Sue Ryder","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","opening_hours","payment_multi"],"suggestion":true},"shop/chemist/7 Дней":{"tags":{"name":"7 Дней","shop":"chemist"},"name":"7 Дней","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/chemist/Bipa":{"tags":{"name":"Bipa","shop":"chemist"},"name":"Bipa","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/chemist/Budnikowsky":{"tags":{"name":"Budnikowsky","shop":"chemist"},"name":"Budnikowsky","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/chemist/Etos":{"tags":{"name":"Etos","shop":"chemist"},"name":"Etos","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/chemist/Kruidvat":{"tags":{"name":"Kruidvat","shop":"chemist"},"name":"Kruidvat","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/chemist/Matas":{"tags":{"name":"Matas","shop":"chemist"},"name":"Matas","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/chemist/Müller":{"tags":{"name":"Müller","shop":"chemist"},"name":"Müller","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/chemist/Rossmann":{"tags":{"name":"Rossmann","shop":"chemist"},"name":"Rossmann","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/chemist/Schlecker":{"tags":{"name":"Schlecker","shop":"chemist"},"name":"Schlecker","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/chemist/Teta":{"tags":{"name":"Teta","shop":"chemist"},"name":"Teta","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/chemist/Trekpleister":{"tags":{"name":"Trekpleister","shop":"chemist"},"name":"Trekpleister","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/chemist/Watsons":{"tags":{"name":"Watsons","shop":"chemist"},"name":"Watsons","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/chemist/dm":{"tags":{"name":"dm","shop":"chemist"},"name":"dm","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/chemist/Бытовая химия":{"tags":{"name":"Бытовая химия","shop":"chemist"},"name":"Бытовая химия","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/chemist/Магнит Косметик":{"tags":{"name":"Магнит Косметик","shop":"chemist"},"name":"Магнит Косметик","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/chemist/Мила":{"tags":{"name":"Мила","shop":"chemist"},"name":"Мила","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/chemist/Остров чистоты":{"tags":{"name":"Остров чистоты","shop":"chemist"},"name":"Остров чистоты","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/chemist/Рубль Бум":{"tags":{"name":"Рубль Бум","shop":"chemist"},"name":"Рубль Бум","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/chemist/Улыбка радуги":{"tags":{"name":"Улыбка радуги","shop":"chemist"},"name":"Улыбка радуги","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/chemist/屈臣氏":{"tags":{"name":"屈臣氏","shop":"chemist"},"name":"屈臣氏","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/chemist/康是美":{"tags":{"name":"康是美","shop":"chemist"},"name":"康是美","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/AOKI":{"tags":{"name":"AOKI","shop":"clothes"},"name":"AOKI","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/AWG":{"tags":{"name":"AWG","shop":"clothes"},"name":"AWG","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Ackermans":{"tags":{"name":"Ackermans","shop":"clothes"},"name":"Ackermans","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Adidas":{"tags":{"name":"Adidas","shop":"clothes"},"name":"Adidas","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/American Apparel":{"tags":{"name":"American Apparel","shop":"clothes"},"name":"American Apparel","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/American Eagle Outfitters":{"tags":{"name":"American Eagle Outfitters","shop":"clothes"},"name":"American Eagle Outfitters","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Anthropologie":{"tags":{"name":"Anthropologie","shop":"clothes"},"name":"Anthropologie","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Ardene":{"tags":{"name":"Ardene","shop":"clothes"},"name":"Ardene","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Armand Thiery":{"tags":{"name":"Armand Thiery","shop":"clothes"},"name":"Armand Thiery","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Banana Republic":{"tags":{"name":"Banana Republic","shop":"clothes"},"name":"Banana Republic","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Benetton":{"tags":{"name":"Benetton","shop":"clothes"},"name":"Benetton","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Bershka":{"tags":{"name":"Bershka","shop":"clothes"},"name":"Bershka","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Bonita":{"tags":{"name":"Bonita","shop":"clothes"},"name":"Bonita","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Bonobo":{"tags":{"name":"Bonobo","shop":"clothes"},"name":"Bonobo","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Brooks Brothers":{"tags":{"name":"Brooks Brothers","shop":"clothes"},"name":"Brooks Brothers","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Burberry":{"tags":{"name":"Burberry","shop":"clothes"},"name":"Burberry","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Burlington Coat Factory":{"tags":{"name":"Burlington Coat Factory","shop":"clothes"},"name":"Burlington Coat Factory","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Burton":{"tags":{"name":"Burton","shop":"clothes"},"name":"Burton","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/C&A":{"tags":{"name":"C&A","shop":"clothes"},"name":"C&A","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Cache Cache":{"tags":{"name":"Cache Cache","shop":"clothes"},"name":"Cache Cache","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Calvin Klein":{"tags":{"name":"Calvin Klein","shop":"clothes"},"name":"Calvin Klein","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Calzedonia":{"tags":{"name":"Calzedonia","shop":"clothes"},"name":"Calzedonia","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Camaïeu":{"tags":{"name":"Camaïeu","shop":"clothes"},"name":"Camaïeu","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Caroll":{"tags":{"name":"Caroll","shop":"clothes"},"name":"Caroll","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Carter's":{"tags":{"name":"Carter's","shop":"clothes"},"name":"Carter's","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Cecil":{"tags":{"name":"Cecil","shop":"clothes"},"name":"Cecil","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Celio":{"tags":{"name":"Celio","shop":"clothes"},"name":"Celio","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"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":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Chico's":{"tags":{"name":"Chico's","shop":"clothes"},"name":"Chico's","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Cropp":{"tags":{"name":"Cropp","shop":"clothes"},"name":"Cropp","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Cubus":{"tags":{"name":"Cubus","shop":"clothes"},"name":"Cubus","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Desigual":{"tags":{"name":"Desigual","shop":"clothes"},"name":"Desigual","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Devred":{"tags":{"name":"Devred","shop":"clothes"},"name":"Devred","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Didi":{"tags":{"name":"Didi","shop":"clothes"},"name":"Didi","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Diesel":{"tags":{"name":"Diesel","shop":"clothes"},"name":"Diesel","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Dorothy Perkins":{"tags":{"name":"Dorothy Perkins","shop":"clothes"},"name":"Dorothy Perkins","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Dress Barn":{"tags":{"name":"Dress Barn","shop":"clothes"},"name":"Dress Barn","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Dressmann":{"tags":{"name":"Dressmann","shop":"clothes"},"name":"Dressmann","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Eddie Bauer":{"tags":{"name":"Eddie Bauer","shop":"clothes"},"name":"Eddie Bauer","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Edgars":{"tags":{"name":"Edgars","shop":"clothes"},"name":"Edgars","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Engbers":{"tags":{"name":"Engbers","shop":"clothes"},"name":"Engbers","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"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":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Esprit":{"tags":{"name":"Esprit","shop":"clothes"},"name":"Esprit","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Etam":{"tags":{"name":"Etam","shop":"clothes"},"name":"Etam","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Express":{"tags":{"name":"Express","shop":"clothes"},"name":"Express","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Fat Face":{"tags":{"name":"Fat Face","shop":"clothes"},"name":"Fat Face","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Forever 21":{"tags":{"name":"Forever 21","shop":"clothes"},"name":"Forever 21","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Gant":{"tags":{"name":"Gant","shop":"clothes"},"name":"Gant","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Gap":{"tags":{"name":"Gap","shop":"clothes"},"name":"Gap","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Gerry Weber":{"tags":{"name":"Gerry Weber","shop":"clothes"},"name":"Gerry Weber","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Gina Laura":{"tags":{"name":"Gina Laura","shop":"clothes"},"name":"Gina Laura","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Guess":{"tags":{"name":"Guess","shop":"clothes"},"name":"Guess","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Gymboree":{"tags":{"name":"Gymboree","shop":"clothes"},"name":"Gymboree","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Gémo":{"tags":{"name":"Gémo","shop":"clothes"},"name":"Gémo","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/H&M":{"tags":{"name":"H&M","shop":"clothes"},"name":"H&M","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Hallhuber":{"tags":{"name":"Hallhuber","shop":"clothes"},"name":"Hallhuber","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/House":{"tags":{"name":"House","shop":"clothes"},"name":"House","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Hugo Boss":{"tags":{"name":"Hugo Boss","shop":"clothes"},"name":"Hugo Boss","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Humana":{"tags":{"name":"Humana","shop":"clothes"},"name":"Humana","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Hunkemöller":{"tags":{"name":"Hunkemöller","shop":"clothes"},"name":"Hunkemöller","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Intimissimi":{"tags":{"name":"Intimissimi","shop":"clothes"},"name":"Intimissimi","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/JBC":{"tags":{"name":"JBC","shop":"clothes"},"name":"JBC","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Jack & Jones":{"tags":{"name":"Jack & Jones","shop":"clothes"},"name":"Jack & Jones","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Jack Wolfskin":{"tags":{"name":"Jack Wolfskin","shop":"clothes"},"name":"Jack Wolfskin","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Jeans Fritz":{"tags":{"name":"Jeans Fritz","shop":"clothes"},"name":"Jeans Fritz","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Jennyfer":{"tags":{"name":"Jennyfer","shop":"clothes"},"name":"Jennyfer","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Jigsaw":{"tags":{"name":"Jigsaw","shop":"clothes"},"name":"Jigsaw","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Jules":{"tags":{"name":"Jules","shop":"clothes"},"name":"Jules","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Justice":{"tags":{"name":"Justice","shop":"clothes"},"name":"Justice","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/KappAhl":{"tags":{"name":"KappAhl","shop":"clothes"},"name":"KappAhl","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/KiK":{"tags":{"name":"KiK","shop":"clothes"},"name":"KiK","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Kiabi":{"tags":{"name":"Kiabi","shop":"clothes"},"name":"Kiabi","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/La Halle":{"tags":{"name":"La Halle","shop":"clothes"},"name":"La Halle","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Lacoste":{"tags":{"name":"Lacoste","shop":"clothes"},"name":"Lacoste","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Lane Bryant":{"tags":{"name":"Lane Bryant","shop":"clothes"},"name":"Lane Bryant","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Levi's":{"tags":{"name":"Levi's","shop":"clothes"},"name":"Levi's","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Lindex":{"tags":{"name":"Lindex","shop":"clothes"},"name":"Lindex","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Loft":{"tags":{"name":"Loft","shop":"clothes"},"name":"Loft","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Mango":{"tags":{"name":"Mango","shop":"clothes"},"name":"Mango","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Marc O'Polo":{"tags":{"name":"Marc O'Polo","shop":"clothes"},"name":"Marc O'Polo","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Mark's":{"tags":{"name":"Mark's","shop":"clothes"},"name":"Mark's","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Marshalls":{"tags":{"name":"Marshalls","shop":"clothes"},"name":"Marshalls","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Massimo Dutti":{"tags":{"name":"Massimo Dutti","shop":"clothes"},"name":"Massimo Dutti","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Matalan":{"tags":{"name":"Matalan","shop":"clothes"},"name":"Matalan","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Maurices":{"tags":{"name":"Maurices","shop":"clothes"},"name":"Maurices","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Max Mara":{"tags":{"name":"Max Mara","shop":"clothes"},"name":"Max Mara","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"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":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Mexx":{"tags":{"name":"Mexx","shop":"clothes"},"name":"Mexx","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Michael Kors":{"tags":{"name":"Michael Kors","shop":"clothes"},"name":"Michael Kors","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Mim":{"tags":{"name":"Mim","shop":"clothes"},"name":"Mim","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Monsoon":{"tags":{"name":"Monsoon","shop":"clothes"},"name":"Monsoon","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Mr Price":{"tags":{"name":"Mr Price","shop":"clothes"},"name":"Mr Price","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/NKD":{"tags":{"name":"NKD","shop":"clothes"},"name":"NKD","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/New Look":{"tags":{"name":"New Look","shop":"clothes"},"name":"New Look","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/New Yorker":{"tags":{"name":"New Yorker","shop":"clothes"},"name":"New Yorker","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/NewYorker":{"tags":{"name":"NewYorker","shop":"clothes"},"name":"NewYorker","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Next":{"tags":{"name":"Next","shop":"clothes"},"name":"Next","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Nike":{"tags":{"name":"Nike","shop":"clothes"},"name":"Nike","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Nordstrom Rack":{"tags":{"name":"Nordstrom Rack","shop":"clothes"},"name":"Nordstrom Rack","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/OVS":{"tags":{"name":"OVS","shop":"clothes"},"name":"OVS","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Okaïdi":{"tags":{"name":"Okaïdi","shop":"clothes"},"name":"Okaïdi","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Old Navy":{"tags":{"name":"Old Navy","shop":"clothes"},"name":"Old Navy","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Only":{"tags":{"name":"Only","shop":"clothes"},"name":"Only","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Orchestra":{"tags":{"name":"Orchestra","shop":"clothes"},"name":"Orchestra","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Original Marines":{"tags":{"name":"Original Marines","shop":"clothes"},"name":"Original Marines","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Orsay":{"tags":{"name":"Orsay","shop":"clothes"},"name":"Orsay","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Outfit":{"tags":{"name":"Outfit","shop":"clothes"},"name":"Outfit","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Outlet":{"tags":{"name":"Outlet","shop":"clothes"},"name":"Outlet","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Palmers":{"tags":{"name":"Palmers","shop":"clothes"},"name":"Palmers","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Peacocks":{"tags":{"name":"Peacocks","shop":"clothes"},"name":"Peacocks","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Peek & Cloppenburg":{"tags":{"name":"Peek & Cloppenburg","shop":"clothes"},"name":"Peek & Cloppenburg","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Pep":{"tags":{"name":"Pep","shop":"clothes"},"name":"Pep","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Pepco":{"tags":{"name":"Pepco","shop":"clothes"},"name":"Pepco","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Petit Bateau":{"tags":{"name":"Petit Bateau","shop":"clothes"},"name":"Petit Bateau","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Pimkie":{"tags":{"name":"Pimkie","shop":"clothes"},"name":"Pimkie","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Plato's Closet":{"tags":{"name":"Plato's Closet","shop":"clothes"},"name":"Plato's Closet","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Primark":{"tags":{"name":"Primark","shop":"clothes"},"name":"Primark","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Promod":{"tags":{"name":"Promod","shop":"clothes"},"name":"Promod","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Pull & Bear":{"tags":{"name":"Pull & Bear","shop":"clothes"},"name":"Pull & Bear","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Reitmans":{"tags":{"name":"Reitmans","shop":"clothes"},"name":"Reitmans","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Reserved":{"tags":{"name":"Reserved","shop":"clothes"},"name":"Reserved","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/River Island":{"tags":{"name":"River Island","shop":"clothes"},"name":"River Island","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Ross":{"tags":{"name":"Ross","shop":"clothes"},"name":"Ross","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Sela":{"tags":{"name":"Sela","shop":"clothes"},"name":"Sela","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Sergent Major":{"tags":{"name":"Sergent Major","shop":"clothes"},"name":"Sergent Major","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Shoeby":{"tags":{"name":"Shoeby","shop":"clothes"},"name":"Shoeby","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Sisley":{"tags":{"name":"Sisley","shop":"clothes"},"name":"Sisley","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Springfield":{"tags":{"name":"Springfield","shop":"clothes"},"name":"Springfield","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Stefanel":{"tags":{"name":"Stefanel","shop":"clothes"},"name":"Stefanel","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Steps":{"tags":{"name":"Steps","shop":"clothes"},"name":"Steps","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Stradivarius":{"tags":{"name":"Stradivarius","shop":"clothes"},"name":"Stradivarius","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Street One":{"tags":{"name":"Street One","shop":"clothes"},"name":"Street One","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Superdry":{"tags":{"name":"Superdry","shop":"clothes"},"name":"Superdry","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/TJ Maxx":{"tags":{"name":"TJ Maxx","shop":"clothes"},"name":"TJ Maxx","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/TK Maxx":{"tags":{"name":"TK Maxx","shop":"clothes"},"name":"TK Maxx","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Takko":{"tags":{"name":"Takko","shop":"clothes"},"name":"Takko","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Talbots":{"tags":{"name":"Talbots","shop":"clothes"},"name":"Talbots","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Tally Weijl":{"tags":{"name":"Tally Weijl","shop":"clothes"},"name":"Tally Weijl","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Tati":{"tags":{"name":"Tati","shop":"clothes"},"name":"Tati","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Terranova":{"tags":{"name":"Terranova","shop":"clothes"},"name":"Terranova","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Tesha":{"tags":{"name":"Tesha","shop":"clothes"},"name":"Tesha","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Tezenis":{"tags":{"name":"Tezenis","shop":"clothes"},"name":"Tezenis","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/The Children's Place":{"tags":{"name":"The Children's Place","shop":"clothes"},"name":"The Children's Place","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/The North Face":{"tags":{"name":"The North Face","shop":"clothes"},"name":"The North Face","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/The Sting":{"tags":{"name":"The Sting","shop":"clothes"},"name":"The Sting","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Timberland":{"tags":{"name":"Timberland","shop":"clothes"},"name":"Timberland","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Toko Pakaian":{"tags":{"name":"Toko Pakaian","shop":"clothes"},"name":"Toko Pakaian","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Tom Tailor":{"tags":{"name":"Tom Tailor","shop":"clothes"},"name":"Tom Tailor","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Tommy Hilfiger":{"tags":{"name":"Tommy Hilfiger","shop":"clothes"},"name":"Tommy Hilfiger","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Topshop":{"tags":{"name":"Topshop","shop":"clothes"},"name":"Topshop","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Triumph":{"tags":{"name":"Triumph","shop":"clothes"},"name":"Triumph","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Truworths":{"tags":{"name":"Truworths","shop":"clothes"},"name":"Truworths","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Ulla Popken":{"tags":{"name":"Ulla Popken","shop":"clothes"},"name":"Ulla Popken","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Uniqlo":{"tags":{"name":"Uniqlo","shop":"clothes"},"name":"Uniqlo","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"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":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Urban Outfitters":{"tags":{"name":"Urban Outfitters","shop":"clothes"},"name":"Urban Outfitters","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Vero Moda":{"tags":{"name":"Vero Moda","shop":"clothes"},"name":"Vero Moda","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Victoria's Secret":{"tags":{"name":"Victoria's Secret","shop":"clothes"},"name":"Victoria's Secret","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Vögele":{"tags":{"name":"Vögele","shop":"clothes"},"name":"Vögele","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/WE":{"tags":{"name":"WE","shop":"clothes"},"name":"WE","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Wibra":{"tags":{"name":"Wibra","shop":"clothes"},"name":"Wibra","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Winners":{"tags":{"name":"Winners","shop":"clothes"},"name":"Winners","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Yamamay":{"tags":{"name":"Yamamay","shop":"clothes"},"name":"Yamamay","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Zara":{"tags":{"name":"Zara","shop":"clothes"},"name":"Zara","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Zeeman":{"tags":{"name":"Zeeman","shop":"clothes"},"name":"Zeeman","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/mister*lady":{"tags":{"name":"mister*lady","shop":"clothes"},"name":"mister*lady","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/s.Oliver":{"tags":{"name":"s.Oliver","shop":"clothes"},"name":"s.Oliver","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Детская одежда":{"tags":{"name":"Детская одежда","shop":"clothes"},"name":"Детская одежда","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Женская одежда":{"tags":{"name":"Женская одежда","shop":"clothes"},"name":"Женская одежда","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Липненски":{"tags":{"name":"Липненски","shop":"clothes"},"name":"Липненски","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Московская ярмарка":{"tags":{"name":"Московская ярмарка","shop":"clothes"},"name":"Московская ярмарка","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Одежда":{"tags":{"name":"Одежда","shop":"clothes"},"name":"Одежда","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Смешные цены":{"tags":{"name":"Смешные цены","shop":"clothes"},"name":"Смешные цены","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/Спецодежда":{"tags":{"name":"Спецодежда","shop":"clothes"},"name":"Спецодежда","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/しまむら":{"tags":{"name":"しまむら","shop":"clothes"},"name":"しまむら","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/ユニクロ":{"tags":{"name":"ユニクロ","shop":"clothes"},"name":"ユニクロ","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/ワークマン":{"tags":{"name":"ワークマン","shop":"clothes"},"name":"ワークマン","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/洋服の青山":{"tags":{"name":"洋服の青山","shop":"clothes"},"name":"洋服の青山","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/clothes/西松屋":{"tags":{"name":"西松屋","shop":"clothes"},"name":"西松屋","icon":"clothing-store","geometry":["point","area"],"fields":["name","clothes","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/coffee/Nespresso":{"tags":{"name":"Nespresso","shop":"coffee"},"name":"Nespresso","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/coffee/Tchibo":{"tags":{"name":"Tchibo","shop":"coffee"},"name":"Tchibo","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/computer/Apple Store":{"tags":{"name":"Apple Store","shop":"computer"},"name":"Apple Store","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/computer/DNS":{"tags":{"name":"DNS","shop":"computer"},"name":"DNS","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/computer/PC World":{"tags":{"name":"PC World","shop":"computer"},"name":"PC World","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/computer/ДНС":{"tags":{"name":"ДНС","shop":"computer"},"name":"ДНС","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/confectionery/Fagyizó":{"tags":{"name":"Fagyizó","shop":"confectionery"},"name":"Fagyizó","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/confectionery/Hussel":{"tags":{"name":"Hussel","shop":"confectionery"},"name":"Hussel","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/confectionery/Leonidas":{"tags":{"name":"Leonidas","shop":"confectionery"},"name":"Leonidas","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/confectionery/T. SN":{"tags":{"name":"T. SN","shop":"confectionery"},"name":"T. SN","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/confectionery/Thorntons":{"tags":{"name":"Thorntons","shop":"confectionery"},"name":"Thorntons","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/711":{"tags":{"name":"711","shop":"convenience"},"name":"711","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/777":{"tags":{"name":"777","shop":"convenience"},"name":"777","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/24 часа":{"tags":{"name":"24 часа","shop":"convenience"},"name":"24 часа","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/7-Eleven":{"tags":{"name":"7-Eleven","shop":"convenience"},"name":"7-Eleven","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/8 à Huit":{"tags":{"name":"8 à Huit","shop":"convenience"},"name":"8 à Huit","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/99 Speedmart":{"tags":{"name":"99 Speedmart","shop":"convenience"},"name":"99 Speedmart","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/ABC":{"tags":{"name":"ABC","shop":"convenience"},"name":"ABC","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/AMPM":{"tags":{"name":"AMPM","shop":"convenience"},"name":"AMPM","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Aibė":{"tags":{"name":"Aibė","shop":"convenience"},"name":"Aibė","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Alepa":{"tags":{"name":"Alepa","shop":"convenience"},"name":"Alepa","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Alfamart":{"tags":{"name":"Alfamart","shop":"convenience"},"name":"Alfamart","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Alimentara":{"tags":{"name":"Alimentara","shop":"convenience"},"name":"Alimentara","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Almacen":{"tags":{"name":"Almacen","shop":"convenience"},"name":"Almacen","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Almacén":{"tags":{"name":"Almacén","shop":"convenience"},"name":"Almacén","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/BP Shop":{"tags":{"name":"BP Shop","shop":"convenience"},"name":"BP Shop","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Baqala":{"tags":{"name":"Baqala","shop":"convenience"},"name":"Baqala","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Best One":{"tags":{"name":"Best One","shop":"convenience"},"name":"Best One","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Best-One":{"tags":{"name":"Best-One","shop":"convenience"},"name":"Best-One","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Bodega":{"tags":{"name":"Bodega","shop":"convenience"},"name":"Bodega","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Bonjour":{"tags":{"name":"Bonjour","shop":"convenience"},"name":"Bonjour","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/CBA":{"tags":{"name":"CBA","shop":"convenience"},"name":"CBA","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/COOP":{"tags":{"name":"COOP","shop":"convenience"},"name":"COOP","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/COOP Jednota":{"tags":{"name":"COOP Jednota","shop":"convenience"},"name":"COOP Jednota","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/CU":{"tags":{"name":"CU","shop":"convenience"},"name":"CU","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Casino Shop":{"tags":{"name":"Casino Shop","shop":"convenience"},"name":"Casino Shop","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Centra":{"tags":{"name":"Centra","shop":"convenience"},"name":"Centra","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Central Convenience Store":{"tags":{"name":"Central Convenience Store","shop":"convenience"},"name":"Central Convenience Store","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Circle K":{"tags":{"name":"Circle K","shop":"convenience"},"name":"Circle K","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Coop Jednota":{"tags":{"name":"Coop Jednota","shop":"convenience"},"name":"Coop Jednota","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Corner Store":{"tags":{"name":"Corner Store","shop":"convenience"},"name":"Corner Store","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Costcutter":{"tags":{"name":"Costcutter","shop":"convenience"},"name":"Costcutter","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Couche-Tard":{"tags":{"name":"Couche-Tard","shop":"convenience"},"name":"Couche-Tard","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Cumberland Farms":{"tags":{"name":"Cumberland Farms","shop":"convenience"},"name":"Cumberland Farms","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Daisy Mart":{"tags":{"name":"Daisy Mart","shop":"convenience"},"name":"Daisy Mart","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Delikatesy":{"tags":{"name":"Delikatesy","shop":"convenience"},"name":"Delikatesy","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Dollar General":{"tags":{"name":"Dollar General","shop":"convenience"},"name":"Dollar General","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Dépanneur":{"tags":{"name":"Dépanneur","shop":"convenience"},"name":"Dépanneur","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/FamilyMart":{"tags":{"name":"FamilyMart","shop":"convenience"},"name":"FamilyMart","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Food Mart":{"tags":{"name":"Food Mart","shop":"convenience"},"name":"Food Mart","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Four Square":{"tags":{"name":"Four Square","shop":"convenience"},"name":"Four Square","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Fresh":{"tags":{"name":"Fresh","shop":"convenience"},"name":"Fresh","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Freshmarket":{"tags":{"name":"Freshmarket","shop":"convenience"},"name":"Freshmarket","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/GS25":{"tags":{"name":"GS25","shop":"convenience"},"name":"GS25","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Groszek":{"tags":{"name":"Groszek","shop":"convenience"},"name":"Groszek","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Hasty Market":{"tags":{"name":"Hasty Market","shop":"convenience"},"name":"Hasty Market","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Hruška":{"tags":{"name":"Hruška","shop":"convenience"},"name":"Hruška","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Indomaret":{"tags":{"name":"Indomaret","shop":"convenience"},"name":"Indomaret","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Jednota":{"tags":{"name":"Jednota","shop":"convenience"},"name":"Jednota","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Joker":{"tags":{"name":"Joker","shop":"convenience"},"name":"Joker","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/K-Market":{"tags":{"name":"K-Market","shop":"convenience"},"name":"K-Market","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Kangaroo Express":{"tags":{"name":"Kangaroo Express","shop":"convenience"},"name":"Kangaroo Express","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Kisbolt":{"tags":{"name":"Kisbolt","shop":"convenience"},"name":"Kisbolt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Lawson":{"tags":{"name":"Lawson","shop":"convenience"},"name":"Lawson","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Lewiatan":{"tags":{"name":"Lewiatan","shop":"convenience"},"name":"Lewiatan","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Lifestyle Express":{"tags":{"name":"Lifestyle Express","shop":"convenience"},"name":"Lifestyle Express","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Londis":{"tags":{"name":"Londis","shop":"convenience"},"name":"Londis","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/M&S Simply Food":{"tags":{"name":"M&S Simply Food","shop":"convenience"},"name":"M&S Simply Food","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Mac's":{"tags":{"name":"Mac's","shop":"convenience"},"name":"Mac's","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Mace":{"tags":{"name":"Mace","shop":"convenience"},"name":"Mace","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Magazin":{"tags":{"name":"Magazin","shop":"convenience"},"name":"Magazin","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Magazin Mixt":{"tags":{"name":"Magazin Mixt","shop":"convenience"},"name":"Magazin Mixt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Magazin Non-Stop":{"tags":{"name":"Magazin Non-Stop","shop":"convenience"},"name":"Magazin Non-Stop","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Magazin mixt":{"tags":{"name":"Magazin mixt","shop":"convenience"},"name":"Magazin mixt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Maxikiosco":{"tags":{"name":"Maxikiosco","shop":"convenience"},"name":"Maxikiosco","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Małpka Express":{"tags":{"name":"Małpka Express","shop":"convenience"},"name":"Małpka Express","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/McColl's":{"tags":{"name":"McColl's","shop":"convenience"},"name":"McColl's","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Migrolino":{"tags":{"name":"Migrolino","shop":"convenience"},"name":"Migrolino","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Mini ABC":{"tags":{"name":"Mini ABC","shop":"convenience"},"name":"Mini ABC","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Mini Market":{"tags":{"name":"Mini Market","shop":"convenience"},"name":"Mini Market","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"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":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Mini Mart":{"tags":{"name":"Mini Mart","shop":"convenience"},"name":"Mini Mart","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Mini Stop":{"tags":{"name":"Mini Stop","shop":"convenience"},"name":"Mini Stop","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Minimercado":{"tags":{"name":"Minimercado","shop":"convenience"},"name":"Minimercado","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Mlin i pekare":{"tags":{"name":"Mlin i pekare","shop":"convenience"},"name":"Mlin i pekare","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Nasz Sklep":{"tags":{"name":"Nasz Sklep","shop":"convenience"},"name":"Nasz Sklep","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Nisa":{"tags":{"name":"Nisa","shop":"convenience"},"name":"Nisa","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Nisa Local":{"tags":{"name":"Nisa Local","shop":"convenience"},"name":"Nisa Local","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/OK-Mart":{"tags":{"name":"OK-Mart","shop":"convenience"},"name":"OK-Mart","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/OK便利商店":{"tags":{"name":"OK便利商店","shop":"convenience"},"name":"OK便利商店","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/OK便利店 Circle K":{"tags":{"name":"OK便利店 Circle K","shop":"convenience"},"name":"OK便利店 Circle K","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Odido":{"tags":{"name":"Odido","shop":"convenience"},"name":"Odido","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/On The Run":{"tags":{"name":"On The Run","shop":"convenience"},"name":"On The Run","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/On the Run":{"tags":{"name":"On the Run","shop":"convenience"},"name":"On the Run","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/One Stop":{"tags":{"name":"One Stop","shop":"convenience"},"name":"One Stop","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Oxxo":{"tags":{"name":"Oxxo","shop":"convenience"},"name":"Oxxo","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Parduotuvė":{"tags":{"name":"Parduotuvė","shop":"convenience"},"name":"Parduotuvė","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Petit Casino":{"tags":{"name":"Petit Casino","shop":"convenience"},"name":"Petit Casino","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Plaid Pantry":{"tags":{"name":"Plaid Pantry","shop":"convenience"},"name":"Plaid Pantry","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Potraviny":{"tags":{"name":"Potraviny","shop":"convenience"},"name":"Potraviny","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Prehrana":{"tags":{"name":"Prehrana","shop":"convenience"},"name":"Prehrana","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Premier":{"tags":{"name":"Premier","shop":"convenience"},"name":"Premier","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Proxi":{"tags":{"name":"Proxi","shop":"convenience"},"name":"Proxi","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Proxy":{"tags":{"name":"Proxy","shop":"convenience"},"name":"Proxy","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Pulperia":{"tags":{"name":"Pulperia","shop":"convenience"},"name":"Pulperia","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Royal Farms":{"tags":{"name":"Royal Farms","shop":"convenience"},"name":"Royal Farms","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Sale":{"tags":{"name":"Sale","shop":"convenience"},"name":"Sale","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Sari-sari Store":{"tags":{"name":"Sari-sari Store","shop":"convenience"},"name":"Sari-sari Store","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Select":{"tags":{"name":"Select","shop":"convenience"},"name":"Select","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Shell Select":{"tags":{"name":"Shell Select","shop":"convenience"},"name":"Shell Select","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Shop & Go":{"tags":{"name":"Shop & Go","shop":"convenience"},"name":"Shop & Go","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Siwa":{"tags":{"name":"Siwa","shop":"convenience"},"name":"Siwa","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Sklep spożywczy":{"tags":{"name":"Sklep spożywczy","shop":"convenience"},"name":"Sklep spożywczy","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Smíšené zboží":{"tags":{"name":"Smíšené zboží","shop":"convenience"},"name":"Smíšené zboží","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Społem":{"tags":{"name":"Społem","shop":"convenience"},"name":"Społem","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Spätkauf":{"tags":{"name":"Spätkauf","shop":"convenience"},"name":"Spätkauf","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Stewart's":{"tags":{"name":"Stewart's","shop":"convenience"},"name":"Stewart's","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Stores":{"tags":{"name":"Stores","shop":"convenience"},"name":"Stores","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Stripes":{"tags":{"name":"Stripes","shop":"convenience"},"name":"Stripes","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Studenac":{"tags":{"name":"Studenac","shop":"convenience"},"name":"Studenac","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Sunkus":{"tags":{"name":"Sunkus","shop":"convenience"},"name":"Sunkus","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Słoneczko":{"tags":{"name":"Słoneczko","shop":"convenience"},"name":"Słoneczko","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/TESCO Lotus Express":{"tags":{"name":"TESCO Lotus Express","shop":"convenience"},"name":"TESCO Lotus Express","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Tesco Express":{"tags":{"name":"Tesco Express","shop":"convenience"},"name":"Tesco Express","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Tesco Lotus Express":{"tags":{"name":"Tesco Lotus Express","shop":"convenience"},"name":"Tesco Lotus Express","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Tom Market 89":{"tags":{"name":"Tom Market 89","shop":"convenience"},"name":"Tom Market 89","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/United Dairy Farmers":{"tags":{"name":"United Dairy Farmers","shop":"convenience"},"name":"United Dairy Farmers","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Vegyesbolt":{"tags":{"name":"Vegyesbolt","shop":"convenience"},"name":"Vegyesbolt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Večerka":{"tags":{"name":"Večerka","shop":"convenience"},"name":"Večerka","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Vival":{"tags":{"name":"Vival","shop":"convenience"},"name":"Vival","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Wawa":{"tags":{"name":"Wawa","shop":"convenience"},"name":"Wawa","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Weltladen":{"tags":{"name":"Weltladen","shop":"convenience"},"name":"Weltladen","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/abc":{"tags":{"name":"abc","shop":"convenience"},"name":"abc","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/ampm":{"tags":{"name":"ampm","shop":"convenience"},"name":"ampm","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/best-one":{"tags":{"name":"best-one","shop":"convenience"},"name":"best-one","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/odido":{"tags":{"name":"odido","shop":"convenience"},"name":"odido","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Élelmiszer":{"tags":{"name":"Élelmiszer","shop":"convenience"},"name":"Élelmiszer","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Élelmiszerbolt":{"tags":{"name":"Élelmiszerbolt","shop":"convenience"},"name":"Élelmiszerbolt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Żabka":{"tags":{"name":"Żabka","shop":"convenience"},"name":"Żabka","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Žabka":{"tags":{"name":"Žabka","shop":"convenience"},"name":"Žabka","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Августина":{"tags":{"name":"Августина","shop":"convenience"},"name":"Августина","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Авоська":{"tags":{"name":"Авоська","shop":"convenience"},"name":"Авоська","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Агрокомплекс":{"tags":{"name":"Агрокомплекс","shop":"convenience"},"name":"Агрокомплекс","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Альянс":{"tags":{"name":"Альянс","shop":"convenience"},"name":"Альянс","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Апельсин":{"tags":{"name":"Апельсин","shop":"convenience"},"name":"Апельсин","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Ассорти":{"tags":{"name":"Ассорти","shop":"convenience"},"name":"Ассорти","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Белорусские продукты":{"tags":{"name":"Белорусские продукты","shop":"convenience"},"name":"Белорусские продукты","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Берёзка":{"tags":{"name":"Берёзка","shop":"convenience"},"name":"Берёзка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Везунчик":{"tags":{"name":"Везунчик","shop":"convenience"},"name":"Везунчик","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Весна":{"tags":{"name":"Весна","shop":"convenience"},"name":"Весна","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Ветеран":{"tags":{"name":"Ветеран","shop":"convenience"},"name":"Ветеран","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Визит":{"tags":{"name":"Визит","shop":"convenience"},"name":"Визит","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Виктория":{"tags":{"name":"Виктория","shop":"convenience"},"name":"Виктория","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/ВкусВилл":{"tags":{"name":"ВкусВилл","shop":"convenience"},"name":"ВкусВилл","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Гастроном":{"tags":{"name":"Гастроном","shop":"convenience"},"name":"Гастроном","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Гермес":{"tags":{"name":"Гермес","shop":"convenience"},"name":"Гермес","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Гурман":{"tags":{"name":"Гурман","shop":"convenience"},"name":"Гурман","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Домашний":{"tags":{"name":"Домашний","shop":"convenience"},"name":"Домашний","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Елена":{"tags":{"name":"Елена","shop":"convenience"},"name":"Елена","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Ермолино":{"tags":{"name":"Ермолино","shop":"convenience"},"name":"Ермолино","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Калинка":{"tags":{"name":"Калинка","shop":"convenience"},"name":"Калинка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Кировский":{"tags":{"name":"Кировский","shop":"convenience"},"name":"Кировский","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Колобок":{"tags":{"name":"Колобок","shop":"convenience"},"name":"Колобок","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Колосок":{"tags":{"name":"Колосок","shop":"convenience"},"name":"Колосок","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Копеечка":{"tags":{"name":"Копеечка","shop":"convenience"},"name":"Копеечка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Копейка":{"tags":{"name":"Копейка","shop":"convenience"},"name":"Копейка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Корзинка":{"tags":{"name":"Корзинка","shop":"convenience"},"name":"Корзинка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Крамниця":{"tags":{"name":"Крамниця","shop":"convenience"},"name":"Крамниця","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Кристалл":{"tags":{"name":"Кристалл","shop":"convenience"},"name":"Кристалл","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Кулинария":{"tags":{"name":"Кулинария","shop":"convenience"},"name":"Кулинария","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Купец":{"tags":{"name":"Купец","shop":"convenience"},"name":"Купец","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Ласточка":{"tags":{"name":"Ласточка","shop":"convenience"},"name":"Ласточка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Лидер":{"tags":{"name":"Лидер","shop":"convenience"},"name":"Лидер","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Любимый":{"tags":{"name":"Любимый","shop":"convenience"},"name":"Любимый","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Люкс":{"tags":{"name":"Люкс","shop":"convenience"},"name":"Люкс","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Магазин при АЗС":{"tags":{"name":"Магазин при АЗС","shop":"convenience"},"name":"Магазин при АЗС","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Мария-Ра":{"tags":{"name":"Мария-Ра","shop":"convenience"},"name":"Мария-Ра","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Маяк":{"tags":{"name":"Маяк","shop":"convenience"},"name":"Маяк","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Меркурий":{"tags":{"name":"Меркурий","shop":"convenience"},"name":"Меркурий","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Мечта":{"tags":{"name":"Мечта","shop":"convenience"},"name":"Мечта","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Минимаркет":{"tags":{"name":"Минимаркет","shop":"convenience"},"name":"Минимаркет","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Мираж":{"tags":{"name":"Мираж","shop":"convenience"},"name":"Мираж","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Надежда":{"tags":{"name":"Надежда","shop":"convenience"},"name":"Надежда","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Ника":{"tags":{"name":"Ника","shop":"convenience"},"name":"Ника","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Оазис":{"tags":{"name":"Оазис","shop":"convenience"},"name":"Оазис","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Олимп":{"tags":{"name":"Олимп","shop":"convenience"},"name":"Олимп","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Подсолнух":{"tags":{"name":"Подсолнух","shop":"convenience"},"name":"Подсолнух","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Престиж":{"tags":{"name":"Престиж","shop":"convenience"},"name":"Престиж","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Продукти":{"tags":{"name":"Продукти","shop":"convenience"},"name":"Продукти","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Продуктовый":{"tags":{"name":"Продуктовый","shop":"convenience"},"name":"Продуктовый","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Продуктовый магазин":{"tags":{"name":"Продуктовый магазин","shop":"convenience"},"name":"Продуктовый магазин","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Продукты":{"tags":{"name":"Продукты","shop":"convenience"},"name":"Продукты","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Продукты 24":{"tags":{"name":"Продукты 24","shop":"convenience"},"name":"Продукты 24","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Радуга":{"tags":{"name":"Радуга","shop":"convenience"},"name":"Радуга","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Родны кут":{"tags":{"name":"Родны кут","shop":"convenience"},"name":"Родны кут","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Ромашка":{"tags":{"name":"Ромашка","shop":"convenience"},"name":"Ромашка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Русь":{"tags":{"name":"Русь","shop":"convenience"},"name":"Русь","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Светлана":{"tags":{"name":"Светлана","shop":"convenience"},"name":"Светлана","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Смак":{"tags":{"name":"Смак","shop":"convenience"},"name":"Смак","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Солнечный":{"tags":{"name":"Солнечный","shop":"convenience"},"name":"Солнечный","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Татьяна":{"tags":{"name":"Татьяна","shop":"convenience"},"name":"Татьяна","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Тройка":{"tags":{"name":"Тройка","shop":"convenience"},"name":"Тройка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/У Палыча":{"tags":{"name":"У Палыча","shop":"convenience"},"name":"У Палыча","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Универсам":{"tags":{"name":"Универсам","shop":"convenience"},"name":"Универсам","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Фортуна":{"tags":{"name":"Фортуна","shop":"convenience"},"name":"Фортуна","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Хороший":{"tags":{"name":"Хороший","shop":"convenience"},"name":"Хороший","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Центральный":{"tags":{"name":"Центральный","shop":"convenience"},"name":"Центральный","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Чайка":{"tags":{"name":"Чайка","shop":"convenience"},"name":"Чайка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Шанс":{"tags":{"name":"Шанс","shop":"convenience"},"name":"Шанс","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Эконом":{"tags":{"name":"Эконом","shop":"convenience"},"name":"Эконом","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Юбилейный":{"tags":{"name":"Юбилейный","shop":"convenience"},"name":"Юбилейный","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/Юлия":{"tags":{"name":"Юлия","shop":"convenience"},"name":"Юлия","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/продукты":{"tags":{"name":"продукты","shop":"convenience"},"name":"продукты","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/მარკეტი":{"tags":{"name":"მარკეტი","shop":"convenience"},"name":"მარკეტი","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/サンクス":{"tags":{"name":"サンクス","name:en":"sunkus","shop":"convenience"},"name":"サンクス","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/サークルK":{"tags":{"name":"サークルK","name:en":"Circle K","shop":"convenience"},"name":"サークルK","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/スリーエフ":{"tags":{"name":"スリーエフ","shop":"convenience"},"name":"スリーエフ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/セイコーマート":{"tags":{"name":"セイコーマート","shop":"convenience"},"name":"セイコーマート","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/セブンイレブン":{"tags":{"name":"セブンイレブン","name:en":"7-Eleven","shop":"convenience"},"name":"セブンイレブン","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/セブンイレブン(Seven-Eleven)":{"tags":{"name":"セブンイレブン(Seven-Eleven)","shop":"convenience"},"name":"セブンイレブン(Seven-Eleven)","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/セーブオン":{"tags":{"name":"セーブオン","shop":"convenience"},"name":"セーブオン","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/デイリーヤマザキ":{"tags":{"name":"デイリーヤマザキ","shop":"convenience"},"name":"デイリーヤマザキ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/ファミリーマート":{"tags":{"name":"ファミリーマート","name:en":"FamilyMart","shop":"convenience"},"name":"ファミリーマート","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/ポプラ":{"tags":{"name":"ポプラ","shop":"convenience"},"name":"ポプラ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/ミニストップ":{"tags":{"name":"ミニストップ","name:en":"MINISTOP","shop":"convenience"},"name":"ミニストップ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/ヤマザキショップ":{"tags":{"name":"ヤマザキショップ","shop":"convenience"},"name":"ヤマザキショップ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/ローソン":{"tags":{"name":"ローソン","name:en":"LAWSON","shop":"convenience"},"name":"ローソン","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/ローソンストア100":{"tags":{"name":"ローソンストア100","shop":"convenience"},"name":"ローソンストア100","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/全家":{"tags":{"name":"全家","shop":"convenience"},"name":"全家","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/全家便利商店":{"tags":{"name":"全家便利商店","shop":"convenience"},"name":"全家便利商店","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/萊爾富":{"tags":{"name":"萊爾富","shop":"convenience"},"name":"萊爾富","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/convenience/세븐일레븐":{"tags":{"name":"세븐일레븐","shop":"convenience"},"name":"세븐일레븐","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/copyshop/FedEx Office":{"tags":{"name":"FedEx Office","shop":"copyshop"},"name":"FedEx Office","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/copyshop/FedEx Office Print and Ship Center":{"tags":{"name":"FedEx Office Print and Ship Center","shop":"copyshop"},"name":"FedEx Office Print and Ship Center","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/cosmetics/Douglas":{"tags":{"name":"Douglas","shop":"cosmetics"},"name":"Douglas","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/cosmetics/Lush":{"tags":{"name":"Lush","shop":"cosmetics"},"name":"Lush","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/cosmetics/Marionnaud":{"tags":{"name":"Marionnaud","shop":"cosmetics"},"name":"Marionnaud","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/cosmetics/Sephora":{"tags":{"name":"Sephora","shop":"cosmetics"},"name":"Sephora","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/cosmetics/The Body Shop":{"tags":{"name":"The Body Shop","shop":"cosmetics"},"name":"The Body Shop","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/cosmetics/Л'Этуаль":{"tags":{"name":"Л'Этуаль","shop":"cosmetics"},"name":"Л'Этуаль","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/cosmetics/Магнит косметик":{"tags":{"name":"Магнит косметик","shop":"cosmetics"},"name":"Магнит косметик","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/cosmetics/Магнит-Косметик":{"tags":{"name":"Магнит-Косметик","shop":"cosmetics"},"name":"Магнит-Косметик","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/cosmetics/Подружка":{"tags":{"name":"Подружка","shop":"cosmetics"},"name":"Подружка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/craft/Hobby Lobby":{"tags":{"name":"Hobby Lobby","shop":"craft"},"name":"Hobby Lobby","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/craft/Michaels":{"tags":{"name":"Michaels","shop":"craft"},"name":"Michaels","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Argos":{"tags":{"name":"Argos","shop":"department_store"},"name":"Argos","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Bed Bath & Beyond":{"tags":{"name":"Bed Bath & Beyond","shop":"department_store"},"name":"Bed Bath & Beyond","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Big Lots":{"tags":{"name":"Big Lots","shop":"department_store"},"name":"Big Lots","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Big W":{"tags":{"name":"Big W","shop":"department_store"},"name":"Big W","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Canadian Tire":{"tags":{"name":"Canadian Tire","shop":"department_store"},"name":"Canadian Tire","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Coppel":{"tags":{"name":"Coppel","shop":"department_store"},"name":"Coppel","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Debenhams":{"tags":{"name":"Debenhams","shop":"department_store"},"name":"Debenhams","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Dillard's":{"tags":{"name":"Dillard's","shop":"department_store"},"name":"Dillard's","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/El Corte Inglés":{"tags":{"name":"El Corte Inglés","shop":"department_store"},"name":"El Corte Inglés","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Galeria Kaufhof":{"tags":{"name":"Galeria Kaufhof","shop":"department_store"},"name":"Galeria Kaufhof","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/HEMA":{"tags":{"name":"HEMA","shop":"department_store"},"name":"HEMA","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Harvey Norman":{"tags":{"name":"Harvey Norman","shop":"department_store"},"name":"Harvey Norman","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/JCPenney":{"tags":{"name":"JCPenney","shop":"department_store"},"name":"JCPenney","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Karstadt":{"tags":{"name":"Karstadt","shop":"department_store"},"name":"Karstadt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Kmart":{"tags":{"name":"Kmart","shop":"department_store"},"name":"Kmart","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Kohl's":{"tags":{"name":"Kohl's","shop":"department_store"},"name":"Kohl's","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Lojas Americanas":{"tags":{"name":"Lojas Americanas","shop":"department_store"},"name":"Lojas Americanas","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Macy's":{"tags":{"name":"Macy's","shop":"department_store"},"name":"Macy's","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Marks & Spencer":{"tags":{"name":"Marks & Spencer","shop":"department_store"},"name":"Marks & Spencer","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Myer":{"tags":{"name":"Myer","shop":"department_store"},"name":"Myer","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Nordstrom":{"tags":{"name":"Nordstrom","shop":"department_store"},"name":"Nordstrom","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Sears":{"tags":{"name":"Sears","shop":"department_store"},"name":"Sears","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Shopko":{"tags":{"name":"Shopko","shop":"department_store"},"name":"Shopko","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Target":{"tags":{"name":"Target","shop":"department_store"},"name":"Target","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/The Warehouse":{"tags":{"name":"The Warehouse","shop":"department_store"},"name":"The Warehouse","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Woolworth":{"tags":{"name":"Woolworth","shop":"department_store"},"name":"Woolworth","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/department_store/Универмаг":{"tags":{"name":"Универмаг","shop":"department_store"},"name":"Универмаг","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Ace Hardware":{"tags":{"name":"Ace Hardware","shop":"doityourself"},"name":"Ace Hardware","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/B&Q":{"tags":{"name":"B&Q","shop":"doityourself"},"name":"B&Q","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Bauhaus":{"tags":{"name":"Bauhaus","shop":"doityourself"},"name":"Bauhaus","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Biltema":{"tags":{"name":"Biltema","shop":"doityourself"},"name":"Biltema","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Brico":{"tags":{"name":"Brico","shop":"doityourself"},"name":"Brico","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Bricomarché":{"tags":{"name":"Bricomarché","shop":"doityourself"},"name":"Bricomarché","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Bricorama":{"tags":{"name":"Bricorama","shop":"doityourself"},"name":"Bricorama","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Bunnings Warehouse":{"tags":{"name":"Bunnings Warehouse","shop":"doityourself"},"name":"Bunnings Warehouse","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Castorama":{"tags":{"name":"Castorama","shop":"doityourself"},"name":"Castorama","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Easy":{"tags":{"name":"Easy","shop":"doityourself"},"name":"Easy","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Gamma":{"tags":{"name":"Gamma","shop":"doityourself"},"name":"Gamma","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Globus Baumarkt":{"tags":{"name":"Globus Baumarkt","shop":"doityourself"},"name":"Globus Baumarkt","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Hagebaumarkt":{"tags":{"name":"Hagebaumarkt","shop":"doityourself"},"name":"Hagebaumarkt","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Hellweg":{"tags":{"name":"Hellweg","shop":"doityourself"},"name":"Hellweg","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Home Depot":{"tags":{"name":"Home Depot","shop":"doityourself"},"name":"Home Depot","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Home Hardware":{"tags":{"name":"Home Hardware","shop":"doityourself"},"name":"Home Hardware","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Homebase":{"tags":{"name":"Homebase","shop":"doityourself"},"name":"Homebase","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Hornbach":{"tags":{"name":"Hornbach","shop":"doityourself"},"name":"Hornbach","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Hubo":{"tags":{"name":"Hubo","shop":"doityourself"},"name":"Hubo","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Karwei":{"tags":{"name":"Karwei","shop":"doityourself"},"name":"Karwei","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Lagerhaus":{"tags":{"name":"Lagerhaus","shop":"doityourself"},"name":"Lagerhaus","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Leroy Merlin":{"tags":{"name":"Leroy Merlin","shop":"doityourself"},"name":"Leroy Merlin","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Lowe's":{"tags":{"name":"Lowe's","shop":"doityourself"},"name":"Lowe's","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Lowes":{"tags":{"name":"Lowes","shop":"doityourself"},"name":"Lowes","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Menards":{"tags":{"name":"Menards","shop":"doityourself"},"name":"Menards","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Mr Bricolage":{"tags":{"name":"Mr Bricolage","shop":"doityourself"},"name":"Mr Bricolage","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Mr.Bricolage":{"tags":{"name":"Mr.Bricolage","shop":"doityourself"},"name":"Mr.Bricolage","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/OBI":{"tags":{"name":"OBI","shop":"doityourself"},"name":"OBI","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Point P":{"tags":{"name":"Point P","shop":"doityourself"},"name":"Point P","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Praktiker":{"tags":{"name":"Praktiker","shop":"doityourself"},"name":"Praktiker","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Praxis":{"tags":{"name":"Praxis","shop":"doityourself"},"name":"Praxis","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Rona":{"tags":{"name":"Rona","shop":"doityourself"},"name":"Rona","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Screwfix":{"tags":{"name":"Screwfix","shop":"doityourself"},"name":"Screwfix","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Sonderpreis Baumarkt":{"tags":{"name":"Sonderpreis Baumarkt","shop":"doityourself"},"name":"Sonderpreis Baumarkt","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Tekzen":{"tags":{"name":"Tekzen","shop":"doityourself"},"name":"Tekzen","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Toom Baumarkt":{"tags":{"name":"Toom Baumarkt","shop":"doityourself"},"name":"Toom Baumarkt","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Weldom":{"tags":{"name":"Weldom","shop":"doityourself"},"name":"Weldom","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Wickes":{"tags":{"name":"Wickes","shop":"doityourself"},"name":"Wickes","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Леруа Мерлен":{"tags":{"name":"Леруа Мерлен","shop":"doityourself"},"name":"Леруа Мерлен","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Мастер":{"tags":{"name":"Мастер","shop":"doityourself"},"name":"Мастер","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Строитель":{"tags":{"name":"Строитель","shop":"doityourself"},"name":"Строитель","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/Стройматериалы":{"tags":{"name":"Стройматериалы","shop":"doityourself"},"name":"Стройматериалы","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/カインズホーム":{"tags":{"name":"カインズホーム","shop":"doityourself"},"name":"カインズホーム","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/コメリ":{"tags":{"name":"コメリ","shop":"doityourself"},"name":"コメリ","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/doityourself/コーナン":{"tags":{"name":"コーナン","shop":"doityourself"},"name":"コーナン","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/dry_cleaning/Cleaners":{"tags":{"name":"Cleaners","shop":"dry_cleaning"},"name":"Cleaners","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/dry_cleaning/Pressing":{"tags":{"name":"Pressing","shop":"dry_cleaning"},"name":"Pressing","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/dry_cleaning/Диана":{"tags":{"name":"Диана","shop":"dry_cleaning"},"name":"Диана","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/dry_cleaning/Химчистка":{"tags":{"name":"Химчистка","shop":"dry_cleaning"},"name":"Химчистка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/dry_cleaning/ホワイト急便":{"tags":{"name":"ホワイト急便","shop":"dry_cleaning"},"name":"ホワイト急便","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/BCC":{"tags":{"name":"BCC","shop":"electronics"},"name":"BCC","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Batteries Plus Bulbs":{"tags":{"name":"Batteries Plus Bulbs","shop":"electronics"},"name":"Batteries Plus Bulbs","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Best Buy":{"tags":{"name":"Best Buy","shop":"electronics"},"name":"Best Buy","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Boulanger":{"tags":{"name":"Boulanger","shop":"electronics"},"name":"Boulanger","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Currys":{"tags":{"name":"Currys","shop":"electronics"},"name":"Currys","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Currys PC World":{"tags":{"name":"Currys PC World","shop":"electronics"},"name":"Currys PC World","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Darty":{"tags":{"name":"Darty","shop":"electronics"},"name":"Darty","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Elektra":{"tags":{"name":"Elektra","shop":"electronics"},"name":"Elektra","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Elgiganten":{"tags":{"name":"Elgiganten","shop":"electronics"},"name":"Elgiganten","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Euronics":{"tags":{"name":"Euronics","shop":"electronics"},"name":"Euronics","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Expert":{"tags":{"name":"Expert","shop":"electronics"},"name":"Expert","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Hartlauer":{"tags":{"name":"Hartlauer","shop":"electronics"},"name":"Hartlauer","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Interdiscount":{"tags":{"name":"Interdiscount","shop":"electronics"},"name":"Interdiscount","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/La Curacao":{"tags":{"name":"La Curacao","shop":"electronics"},"name":"La Curacao","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Maplin":{"tags":{"name":"Maplin","shop":"electronics"},"name":"Maplin","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Media Expert":{"tags":{"name":"Media Expert","shop":"electronics"},"name":"Media Expert","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Media Markt":{"tags":{"name":"Media Markt","shop":"electronics"},"name":"Media Markt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Musimundo":{"tags":{"name":"Musimundo","shop":"electronics"},"name":"Musimundo","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Neonet":{"tags":{"name":"Neonet","shop":"electronics"},"name":"Neonet","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/RTV Euro AGD":{"tags":{"name":"RTV Euro AGD","shop":"electronics"},"name":"RTV Euro AGD","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Radio Shack":{"tags":{"name":"Radio Shack","shop":"electronics"},"name":"Radio Shack","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Rogers":{"tags":{"name":"Rogers","shop":"electronics"},"name":"Rogers","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Samsung":{"tags":{"name":"Samsung","shop":"electronics"},"name":"Samsung","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Saturn":{"tags":{"name":"Saturn","shop":"electronics"},"name":"Saturn","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Sony":{"tags":{"name":"Sony","shop":"electronics"},"name":"Sony","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/The Source":{"tags":{"name":"The Source","shop":"electronics"},"name":"The Source","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Unieuro":{"tags":{"name":"Unieuro","shop":"electronics"},"name":"Unieuro","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/М.Видео":{"tags":{"name":"М.Видео","shop":"electronics"},"name":"М.Видео","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Фокстрот":{"tags":{"name":"Фокстрот","shop":"electronics"},"name":"Фокстрот","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Эксперт":{"tags":{"name":"Эксперт","shop":"electronics"},"name":"Эксперт","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/Эльдорадо":{"tags":{"name":"Эльдорадо","shop":"electronics"},"name":"Эльдорадо","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/エディオン":{"tags":{"name":"エディオン","shop":"electronics"},"name":"エディオン","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/ケーズデンキ":{"tags":{"name":"ケーズデンキ","shop":"electronics"},"name":"ケーズデンキ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/コジマ":{"tags":{"name":"コジマ","shop":"electronics"},"name":"コジマ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/ヤマダ電機":{"tags":{"name":"ヤマダ電機","shop":"electronics"},"name":"ヤマダ電機","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/全國電子":{"tags":{"name":"全國電子","shop":"electronics"},"name":"全國電子","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/electronics/燦坤3C":{"tags":{"name":"燦坤3C","shop":"electronics"},"name":"燦坤3C","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/erotic/Orion":{"tags":{"name":"Orion","shop":"erotic"},"name":"Orion","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/fabric/Ткани":{"tags":{"name":"Ткани","shop":"fabric"},"name":"Ткани","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/farm/Hofladen":{"tags":{"name":"Hofladen","shop":"farm"},"name":"Hofladen","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/florist/Blume 2000":{"tags":{"name":"Blume 2000","shop":"florist"},"name":"Blume 2000","icon":"florist","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/florist/Blumen Risse":{"tags":{"name":"Blumen Risse","shop":"florist"},"name":"Blumen Risse","icon":"florist","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/florist/Fleuriste":{"tags":{"name":"Fleuriste","shop":"florist"},"name":"Fleuriste","icon":"florist","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/florist/Interflora":{"tags":{"name":"Interflora","shop":"florist"},"name":"Interflora","icon":"florist","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/florist/Monceau Fleurs":{"tags":{"name":"Monceau Fleurs","shop":"florist"},"name":"Monceau Fleurs","icon":"florist","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/florist/Virágbolt":{"tags":{"name":"Virágbolt","shop":"florist"},"name":"Virágbolt","icon":"florist","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/florist/Квіти":{"tags":{"name":"Квіти","shop":"florist"},"name":"Квіти","icon":"florist","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/florist/Цветочный магазин":{"tags":{"name":"Цветочный магазин","shop":"florist"},"name":"Цветочный магазин","icon":"florist","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/florist/Цветы":{"tags":{"name":"Цветы","shop":"florist"},"name":"Цветы","icon":"florist","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/frame/rumah penduduk":{"tags":{"name":"rumah penduduk","shop":"frame"},"name":"rumah penduduk","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/funeral_directors/The Co-operative Funeralcare":{"tags":{"name":"The Co-operative Funeralcare","shop":"funeral_directors"},"name":"The Co-operative Funeralcare","icon":"cemetery","geometry":["point","area"],"fields":["name","operator","address","building_area","religion","denomination"],"suggestion":true},"shop/funeral_directors/Ритуальные услуги":{"tags":{"name":"Ритуальные услуги","shop":"funeral_directors"},"name":"Ритуальные услуги","icon":"cemetery","geometry":["point","area"],"fields":["name","operator","address","building_area","religion","denomination"],"suggestion":true},"shop/furniture/Aaron's":{"tags":{"name":"Aaron's","shop":"furniture"},"name":"Aaron's","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/furniture/Black Red White":{"tags":{"name":"Black Red White","shop":"furniture"},"name":"Black Red White","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/furniture/Bodzio":{"tags":{"name":"Bodzio","shop":"furniture"},"name":"Bodzio","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/furniture/But":{"tags":{"name":"But","shop":"furniture"},"name":"But","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/furniture/Conforama":{"tags":{"name":"Conforama","shop":"furniture"},"name":"Conforama","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/furniture/DFS":{"tags":{"name":"DFS","shop":"furniture"},"name":"DFS","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/furniture/Dänisches Bettenlager":{"tags":{"name":"Dänisches Bettenlager","shop":"furniture"},"name":"Dänisches Bettenlager","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/furniture/Fly":{"tags":{"name":"Fly","shop":"furniture"},"name":"Fly","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/furniture/Harveys":{"tags":{"name":"Harveys","shop":"furniture"},"name":"Harveys","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/furniture/IKEA":{"tags":{"name":"IKEA","shop":"furniture"},"name":"IKEA","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/furniture/JYSK":{"tags":{"name":"JYSK","shop":"furniture"},"name":"JYSK","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/furniture/Kwantum":{"tags":{"name":"Kwantum","shop":"furniture"},"name":"Kwantum","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/furniture/Leen Bakker":{"tags":{"name":"Leen Bakker","shop":"furniture"},"name":"Leen Bakker","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/furniture/Pier 1 Imports":{"tags":{"name":"Pier 1 Imports","shop":"furniture"},"name":"Pier 1 Imports","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/furniture/Roller":{"tags":{"name":"Roller","shop":"furniture"},"name":"Roller","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/furniture/The Brick":{"tags":{"name":"The Brick","shop":"furniture"},"name":"The Brick","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/furniture/Меблі":{"tags":{"name":"Меблі","shop":"furniture"},"name":"Меблі","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/furniture/ニトリ":{"tags":{"name":"ニトリ","shop":"furniture"},"name":"ニトリ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/garden_centre/Dehner":{"tags":{"name":"Dehner","shop":"garden_centre"},"name":"Dehner","icon":"garden-center","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/garden_centre/Gamm Vert":{"tags":{"name":"Gamm Vert","shop":"garden_centre"},"name":"Gamm Vert","icon":"garden-center","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/garden_centre/Jardiland":{"tags":{"name":"Jardiland","shop":"garden_centre"},"name":"Jardiland","icon":"garden-center","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/garden_centre/Point Vert":{"tags":{"name":"Point Vert","shop":"garden_centre"},"name":"Point Vert","icon":"garden-center","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/garden_centre/Welkoop":{"tags":{"name":"Welkoop","shop":"garden_centre"},"name":"Welkoop","icon":"garden-center","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/garden_centre/Семена":{"tags":{"name":"Семена","shop":"garden_centre"},"name":"Семена","icon":"garden-center","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/gift/Card Factory":{"tags":{"name":"Card Factory","shop":"gift"},"name":"Card Factory","icon":"gift","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/gift/Hallmark":{"tags":{"name":"Hallmark","shop":"gift"},"name":"Hallmark","icon":"gift","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/gift/Подарки":{"tags":{"name":"Подарки","shop":"gift"},"name":"Подарки","icon":"gift","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/greengrocer/Frutería":{"tags":{"name":"Frutería","shop":"greengrocer"},"name":"Frutería","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/greengrocer/Овощи и фрукты":{"tags":{"name":"Овощи и фрукты","shop":"greengrocer"},"name":"Овощи и фрукты","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Berber":{"tags":{"name":"Berber","shop":"hairdresser"},"name":"Berber","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Cost Cutters":{"tags":{"name":"Cost Cutters","shop":"hairdresser"},"name":"Cost Cutters","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Fantastic Sams":{"tags":{"name":"Fantastic Sams","shop":"hairdresser"},"name":"Fantastic Sams","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Figaro":{"tags":{"name":"Figaro","shop":"hairdresser"},"name":"Figaro","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/First Choice Haircutters":{"tags":{"name":"First Choice Haircutters","shop":"hairdresser"},"name":"First Choice Haircutters","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Franck Provost":{"tags":{"name":"Franck Provost","shop":"hairdresser"},"name":"Franck Provost","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Frizerie":{"tags":{"name":"Frizerie","shop":"hairdresser"},"name":"Frizerie","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Great Clips":{"tags":{"name":"Great Clips","shop":"hairdresser"},"name":"Great Clips","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Haarmonie":{"tags":{"name":"Haarmonie","shop":"hairdresser"},"name":"Haarmonie","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Haarscharf":{"tags":{"name":"Haarscharf","shop":"hairdresser"},"name":"Haarscharf","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Hair Cuttery":{"tags":{"name":"Hair Cuttery","shop":"hairdresser"},"name":"Hair Cuttery","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Hairkiller":{"tags":{"name":"Hairkiller","shop":"hairdresser"},"name":"Hairkiller","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Jean Louis David":{"tags":{"name":"Jean Louis David","shop":"hairdresser"},"name":"Jean Louis David","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Jean-Louis David":{"tags":{"name":"Jean-Louis David","shop":"hairdresser"},"name":"Jean-Louis David","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Klier":{"tags":{"name":"Klier","shop":"hairdresser"},"name":"Klier","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Klipp":{"tags":{"name":"Klipp","shop":"hairdresser"},"name":"Klipp","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Le Salon":{"tags":{"name":"Le Salon","shop":"hairdresser"},"name":"Le Salon","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Marco Aldany":{"tags":{"name":"Marco Aldany","shop":"hairdresser"},"name":"Marco Aldany","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Peluquería":{"tags":{"name":"Peluquería","shop":"hairdresser"},"name":"Peluquería","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Salon fryzjerski":{"tags":{"name":"Salon fryzjerski","shop":"hairdresser"},"name":"Salon fryzjerski","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Sport Clips":{"tags":{"name":"Sport Clips","shop":"hairdresser"},"name":"Sport Clips","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Super Cuts":{"tags":{"name":"Super Cuts","shop":"hairdresser"},"name":"Super Cuts","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Supercuts":{"tags":{"name":"Supercuts","shop":"hairdresser"},"name":"Supercuts","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Tchip":{"tags":{"name":"Tchip","shop":"hairdresser"},"name":"Tchip","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/The Barber Shop":{"tags":{"name":"The Barber Shop","shop":"hairdresser"},"name":"The Barber Shop","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Toni & Guy":{"tags":{"name":"Toni & Guy","shop":"hairdresser"},"name":"Toni & Guy","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Top Hair":{"tags":{"name":"Top Hair","shop":"hairdresser"},"name":"Top Hair","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Локон":{"tags":{"name":"Локон","shop":"hairdresser"},"name":"Локон","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Парикмахерская":{"tags":{"name":"Парикмахерская","shop":"hairdresser"},"name":"Парикмахерская","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Перукарня":{"tags":{"name":"Перукарня","shop":"hairdresser"},"name":"Перукарня","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Салон красоты":{"tags":{"name":"Салон красоты","shop":"hairdresser"},"name":"Салон красоты","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Стиль":{"tags":{"name":"Стиль","shop":"hairdresser"},"name":"Стиль","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/Шарм":{"tags":{"name":"Шарм","shop":"hairdresser"},"name":"Шарм","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hairdresser/حلاق":{"tags":{"name":"حلاق","shop":"hairdresser"},"name":"حلاق","icon":"hairdresser","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hardware/1000 мелочей":{"tags":{"name":"1000 мелочей","shop":"hardware"},"name":"1000 мелочей","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hardware/Ferretería":{"tags":{"name":"Ferretería","shop":"hardware"},"name":"Ferretería","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hardware/Harbor Freight Tools":{"tags":{"name":"Harbor Freight Tools","shop":"hardware"},"name":"Harbor Freight Tools","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hardware/Quincaillerie":{"tags":{"name":"Quincaillerie","shop":"hardware"},"name":"Quincaillerie","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hardware/True Value":{"tags":{"name":"True Value","shop":"hardware"},"name":"True Value","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hardware/Würth":{"tags":{"name":"Würth","shop":"hardware"},"name":"Würth","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hardware/Промтовары":{"tags":{"name":"Промтовары","shop":"hardware"},"name":"Промтовары","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hardware/Сантехника":{"tags":{"name":"Сантехника","shop":"hardware"},"name":"Сантехника","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hardware/Товары для дома":{"tags":{"name":"Товары для дома","shop":"hardware"},"name":"Товары для дома","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hardware/Хозтовары":{"tags":{"name":"Хозтовары","shop":"hardware"},"name":"Хозтовары","icon":"poi-tool","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hearing_aids/Amplifon":{"tags":{"name":"Amplifon","shop":"hearing_aids"},"name":"Amplifon","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hearing_aids/Geers":{"tags":{"name":"Geers","shop":"hearing_aids"},"name":"Geers","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hearing_aids/Kind Hörgeräte":{"tags":{"name":"Kind Hörgeräte","shop":"hearing_aids"},"name":"Kind Hörgeräte","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hearing_aids/amplifon":{"tags":{"name":"amplifon","shop":"hearing_aids"},"name":"amplifon","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/hifi/Bang & Olufsen":{"tags":{"name":"Bang & Olufsen","shop":"hifi"},"name":"Bang & Olufsen","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/houseware/Blokker":{"tags":{"name":"Blokker","shop":"houseware"},"name":"Blokker","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/houseware/Marskramer":{"tags":{"name":"Marskramer","shop":"houseware"},"name":"Marskramer","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/houseware/Xenos":{"tags":{"name":"Xenos","shop":"houseware"},"name":"Xenos","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/interior_decoration/Casa":{"tags":{"name":"Casa","shop":"interior_decoration"},"name":"Casa","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/interior_decoration/Depot":{"tags":{"name":"Depot","shop":"interior_decoration"},"name":"Depot","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/jewelry/585":{"tags":{"name":"585","shop":"jewelry"},"name":"585","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/jewelry/Apart":{"tags":{"name":"Apart","shop":"jewelry"},"name":"Apart","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/jewelry/Bijou Brigitte":{"tags":{"name":"Bijou Brigitte","shop":"jewelry"},"name":"Bijou Brigitte","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/jewelry/Christ":{"tags":{"name":"Christ","shop":"jewelry"},"name":"Christ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/jewelry/Claire's":{"tags":{"name":"Claire's","shop":"jewelry"},"name":"Claire's","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/jewelry/Ernest Jones":{"tags":{"name":"Ernest Jones","shop":"jewelry"},"name":"Ernest Jones","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/jewelry/H Samuel":{"tags":{"name":"H Samuel","shop":"jewelry"},"name":"H Samuel","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/jewelry/James Avery Jewelry":{"tags":{"name":"James Avery Jewelry","shop":"jewelry"},"name":"James Avery Jewelry","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/jewelry/Julien d'Orcel":{"tags":{"name":"Julien d'Orcel","shop":"jewelry"},"name":"Julien d'Orcel","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/jewelry/Kay Jewelers":{"tags":{"name":"Kay Jewelers","shop":"jewelry"},"name":"Kay Jewelers","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/jewelry/Pandora":{"tags":{"name":"Pandora","shop":"jewelry"},"name":"Pandora","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/jewelry/Swarovski":{"tags":{"name":"Swarovski","shop":"jewelry"},"name":"Swarovski","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/jewelry/Адамас":{"tags":{"name":"Адамас","shop":"jewelry"},"name":"Адамас","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/jewelry/Золото":{"tags":{"name":"Золото","shop":"jewelry"},"name":"Золото","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/kiosk/KIOS":{"tags":{"name":"KIOS","shop":"kiosk"},"name":"KIOS","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/kiosk/Kiosko":{"tags":{"name":"Kiosko","shop":"kiosk"},"name":"Kiosko","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/kiosk/Kiosque":{"tags":{"name":"Kiosque","shop":"kiosk"},"name":"Kiosque","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/kiosk/Kolporter":{"tags":{"name":"Kolporter","shop":"kiosk"},"name":"Kolporter","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/kiosk/Lietuvos spauda":{"tags":{"name":"Lietuvos spauda","shop":"kiosk"},"name":"Lietuvos spauda","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/kiosk/Narvesen":{"tags":{"name":"Narvesen","shop":"kiosk"},"name":"Narvesen","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/kiosk/Pressbyrån":{"tags":{"name":"Pressbyrån","shop":"kiosk"},"name":"Pressbyrån","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/kiosk/Pulpería":{"tags":{"name":"Pulpería","shop":"kiosk"},"name":"Pulpería","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/kiosk/R-Kioski":{"tags":{"name":"R-Kioski","shop":"kiosk"},"name":"R-Kioski","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/kiosk/Ruch":{"tags":{"name":"Ruch","shop":"kiosk"},"name":"Ruch","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/kiosk/Tabak Trafik":{"tags":{"name":"Tabak Trafik","shop":"kiosk"},"name":"Tabak Trafik","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/kiosk/Tisak":{"tags":{"name":"Tisak","shop":"kiosk"},"name":"Tisak","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/kiosk/Trafik":{"tags":{"name":"Trafik","shop":"kiosk"},"name":"Trafik","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/kiosk/Trafika":{"tags":{"name":"Trafika","shop":"kiosk"},"name":"Trafika","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/kiosk/Trinkhalle":{"tags":{"name":"Trinkhalle","shop":"kiosk"},"name":"Trinkhalle","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/kiosk/Белсоюзпечать":{"tags":{"name":"Белсоюзпечать","shop":"kiosk"},"name":"Белсоюзпечать","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/kiosk/Киоск":{"tags":{"name":"Киоск","shop":"kiosk"},"name":"Киоск","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/kiosk/Мороженое":{"tags":{"name":"Мороженое","shop":"kiosk"},"name":"Мороженое","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/kiosk/მარკეტი (Market)":{"tags":{"name":"მარკეტი (Market)","shop":"kiosk"},"name":"მარკეტი (Market)","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/kitchen/Cuisinella":{"tags":{"name":"Cuisinella","shop":"kitchen"},"name":"Cuisinella","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/kitchen/Home Utensils":{"tags":{"name":"Home Utensils","shop":"kitchen"},"name":"Home Utensils","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/laundry/Launderette":{"tags":{"name":"Launderette","shop":"laundry"},"name":"Launderette","icon":"laundry","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/laundry/Lavandería":{"tags":{"name":"Lavandería","shop":"laundry"},"name":"Lavandería","icon":"laundry","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/laundry/コインランドリー":{"tags":{"name":"コインランドリー","shop":"laundry"},"name":"コインランドリー","icon":"laundry","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/lottery/Loteria de la Provincia":{"tags":{"name":"Loteria de la Provincia","shop":"lottery"},"name":"Loteria de la Provincia","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/lottery/Lotería Nacional":{"tags":{"name":"Lotería Nacional","shop":"lottery"},"name":"Lotería Nacional","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/lottery/Lotería de la Provincia":{"tags":{"name":"Lotería de la Provincia","shop":"lottery"},"name":"Lotería de la Provincia","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/lottery/Lotto":{"tags":{"name":"Lotto","shop":"lottery"},"name":"Lotto","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/lottery/Lottózó":{"tags":{"name":"Lottózó","shop":"lottery"},"name":"Lottózó","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/lottery/ONCE":{"tags":{"name":"ONCE","shop":"lottery"},"name":"ONCE","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mall/Торговый центр":{"tags":{"name":"Торговый центр","shop":"mall"},"name":"Торговый центр","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"shop/massage/Massage Envy":{"tags":{"name":"Massage Envy","shop":"massage"},"name":"Massage Envy","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/medical_supply/Pofam-Poznań":{"tags":{"name":"Pofam-Poznań","shop":"medical_supply"},"name":"Pofam-Poznań","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/3 Store":{"tags":{"name":"3 Store","shop":"mobile_phone"},"name":"3 Store","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/AT&T":{"tags":{"name":"AT&T","shop":"mobile_phone"},"name":"AT&T","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Bell":{"tags":{"name":"Bell","shop":"mobile_phone"},"name":"Bell","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Bitė":{"tags":{"name":"Bitė","shop":"mobile_phone"},"name":"Bitė","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Boost Mobile":{"tags":{"name":"Boost Mobile","shop":"mobile_phone"},"name":"Boost Mobile","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Carphone Warehouse":{"tags":{"name":"Carphone Warehouse","shop":"mobile_phone"},"name":"Carphone Warehouse","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Claro":{"tags":{"name":"Claro","shop":"mobile_phone"},"name":"Claro","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Cricket Wireless":{"tags":{"name":"Cricket Wireless","shop":"mobile_phone"},"name":"Cricket Wireless","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Digicel":{"tags":{"name":"Digicel","shop":"mobile_phone"},"name":"Digicel","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/EE":{"tags":{"name":"EE","shop":"mobile_phone"},"name":"EE","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/MetroPCS":{"tags":{"name":"MetroPCS","shop":"mobile_phone"},"name":"MetroPCS","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Movistar":{"tags":{"name":"Movistar","shop":"mobile_phone"},"name":"Movistar","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/O2":{"tags":{"name":"O2","shop":"mobile_phone"},"name":"O2","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Orange":{"tags":{"name":"Orange","shop":"mobile_phone"},"name":"Orange","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Personal":{"tags":{"name":"Personal","shop":"mobile_phone"},"name":"Personal","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Play":{"tags":{"name":"Play","shop":"mobile_phone"},"name":"Play","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Plus":{"tags":{"name":"Plus","shop":"mobile_phone"},"name":"Plus","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/SFR":{"tags":{"name":"SFR","shop":"mobile_phone"},"name":"SFR","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Sprint":{"tags":{"name":"Sprint","shop":"mobile_phone"},"name":"Sprint","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/T-Mobile":{"tags":{"name":"T-Mobile","shop":"mobile_phone"},"name":"T-Mobile","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/TIM":{"tags":{"name":"TIM","shop":"mobile_phone"},"name":"TIM","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Telcel":{"tags":{"name":"Telcel","shop":"mobile_phone"},"name":"Telcel","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Tele2":{"tags":{"name":"Tele2","shop":"mobile_phone"},"name":"Tele2","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Telekom":{"tags":{"name":"Telekom","shop":"mobile_phone"},"name":"Telekom","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Telekom Shop":{"tags":{"name":"Telekom Shop","shop":"mobile_phone"},"name":"Telekom Shop","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Telenor":{"tags":{"name":"Telenor","shop":"mobile_phone"},"name":"Telenor","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Telus":{"tags":{"name":"Telus","shop":"mobile_phone"},"name":"Telus","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"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":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Three":{"tags":{"name":"Three","shop":"mobile_phone"},"name":"Three","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Tim":{"tags":{"name":"Tim","shop":"mobile_phone"},"name":"Tim","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Télécentre":{"tags":{"name":"Télécentre","shop":"mobile_phone"},"name":"Télécentre","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Verizon":{"tags":{"name":"Verizon","shop":"mobile_phone"},"name":"Verizon","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Verizon Wireless":{"tags":{"name":"Verizon Wireless","shop":"mobile_phone"},"name":"Verizon Wireless","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Vodafone":{"tags":{"name":"Vodafone","shop":"mobile_phone"},"name":"Vodafone","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Vodafone Shop":{"tags":{"name":"Vodafone Shop","shop":"mobile_phone"},"name":"Vodafone Shop","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Wind":{"tags":{"name":"Wind","shop":"mobile_phone"},"name":"Wind","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Yoigo":{"tags":{"name":"Yoigo","shop":"mobile_phone"},"name":"Yoigo","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/au":{"tags":{"name":"au","shop":"mobile_phone"},"name":"au","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/auショップ":{"tags":{"name":"auショップ","shop":"mobile_phone"},"name":"auショップ","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/mobilcom debitel":{"tags":{"name":"mobilcom debitel","shop":"mobile_phone"},"name":"mobilcom debitel","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Алло":{"tags":{"name":"Алло","shop":"mobile_phone"},"name":"Алло","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Билайн":{"tags":{"name":"Билайн","shop":"mobile_phone"},"name":"Билайн","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Евросеть":{"tags":{"name":"Евросеть","shop":"mobile_phone"},"name":"Евросеть","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Київстар":{"tags":{"name":"Київстар","shop":"mobile_phone"},"name":"Київстар","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/МТС":{"tags":{"name":"МТС","shop":"mobile_phone"},"name":"МТС","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Мегафон":{"tags":{"name":"Мегафон","shop":"mobile_phone"},"name":"Мегафон","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Связной":{"tags":{"name":"Связной","shop":"mobile_phone"},"name":"Связной","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/Теле2":{"tags":{"name":"Теле2","shop":"mobile_phone"},"name":"Теле2","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/ソフトバンクショップ":{"tags":{"name":"ソフトバンクショップ","shop":"mobile_phone"},"name":"ソフトバンクショップ","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/mobile_phone/ドコモショップ":{"tags":{"name":"ドコモショップ","shop":"mobile_phone"},"name":"ドコモショップ","icon":"mobile-phone","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/money_lender/Money Mart":{"tags":{"name":"Money Mart","shop":"money_lender"},"name":"Money Mart","icon":"bank","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","currency_multi"],"suggestion":true},"shop/motorcycle/Harley Davidson":{"tags":{"name":"Harley Davidson","shop":"motorcycle"},"name":"Harley Davidson","icon":"scooter","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/motorcycle/Yamaha":{"tags":{"name":"Yamaha","shop":"motorcycle"},"name":"Yamaha","icon":"scooter","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/music/HMV":{"tags":{"name":"HMV","shop":"music"},"name":"HMV","icon":"music","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/musical_instrument/Guitar Center":{"tags":{"name":"Guitar Center","shop":"musical_instrument"},"name":"Guitar Center","icon":"music","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/newsagent/Edicola":{"tags":{"name":"Edicola","shop":"newsagent"},"name":"Edicola","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/newsagent/Maison de la Presse":{"tags":{"name":"Maison de la Presse","shop":"newsagent"},"name":"Maison de la Presse","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/newsagent/Relay":{"tags":{"name":"Relay","shop":"newsagent"},"name":"Relay","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/newsagent/Tabac Presse":{"tags":{"name":"Tabac Presse","shop":"newsagent"},"name":"Tabac Presse","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/newsagent/WHSmith":{"tags":{"name":"WHSmith","shop":"newsagent"},"name":"WHSmith","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/newsagent/Витебскоблсоюзпечать":{"tags":{"name":"Витебскоблсоюзпечать","shop":"newsagent"},"name":"Витебскоблсоюзпечать","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/newsagent/Первая полоса":{"tags":{"name":"Первая полоса","shop":"newsagent"},"name":"Первая полоса","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/newsagent/Печать":{"tags":{"name":"Печать","shop":"newsagent"},"name":"Печать","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/newsagent/Роспечать":{"tags":{"name":"Роспечать","shop":"newsagent"},"name":"Роспечать","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/newsagent/Союзпечать":{"tags":{"name":"Союзпечать","shop":"newsagent"},"name":"Союзпечать","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/Alain Afflelou":{"tags":{"name":"Alain Afflelou","shop":"optician"},"name":"Alain Afflelou","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/Apollo":{"tags":{"name":"Apollo","shop":"optician"},"name":"Apollo","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/Atol":{"tags":{"name":"Atol","shop":"optician"},"name":"Atol","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/Boots Opticians":{"tags":{"name":"Boots Opticians","shop":"optician"},"name":"Boots Opticians","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/Fielmann":{"tags":{"name":"Fielmann","shop":"optician"},"name":"Fielmann","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/General Óptica":{"tags":{"name":"General Óptica","shop":"optician"},"name":"General Óptica","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/Grand Optical":{"tags":{"name":"Grand Optical","shop":"optician"},"name":"Grand Optical","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/Générale d'Optique":{"tags":{"name":"Générale d'Optique","shop":"optician"},"name":"Générale d'Optique","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/Hakim Optical":{"tags":{"name":"Hakim Optical","shop":"optician"},"name":"Hakim Optical","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/Hans Anders":{"tags":{"name":"Hans Anders","shop":"optician"},"name":"Hans Anders","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/Krys":{"tags":{"name":"Krys","shop":"optician"},"name":"Krys","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/Les Opticiens Mutualistes":{"tags":{"name":"Les Opticiens Mutualistes","shop":"optician"},"name":"Les Opticiens Mutualistes","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/Optic 2000":{"tags":{"name":"Optic 2000","shop":"optician"},"name":"Optic 2000","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/Optical Center":{"tags":{"name":"Optical Center","shop":"optician"},"name":"Optical Center","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/Pearle":{"tags":{"name":"Pearle","shop":"optician"},"name":"Pearle","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/Pearle Vision":{"tags":{"name":"Pearle Vision","shop":"optician"},"name":"Pearle Vision","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/Specsavers":{"tags":{"name":"Specsavers","shop":"optician"},"name":"Specsavers","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/Sunglass Hut":{"tags":{"name":"Sunglass Hut","shop":"optician"},"name":"Sunglass Hut","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/Synoptik":{"tags":{"name":"Synoptik","shop":"optician"},"name":"Synoptik","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/Vision Express":{"tags":{"name":"Vision Express","shop":"optician"},"name":"Vision Express","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/แว่นท็อปเจริญ":{"tags":{"name":"แว่นท็อปเจริญ","shop":"optician"},"name":"แว่นท็อปเจริญ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/メガネスーパー":{"tags":{"name":"メガネスーパー","shop":"optician"},"name":"メガネスーパー","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/optician/眼鏡市場":{"tags":{"name":"眼鏡市場","shop":"optician"},"name":"眼鏡市場","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/outdoor/Mountain Warehouse":{"tags":{"name":"Mountain Warehouse","shop":"outdoor"},"name":"Mountain Warehouse","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/outdoor/REI":{"tags":{"name":"REI","shop":"outdoor"},"name":"REI","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/outdoor/Рыболов":{"tags":{"name":"Рыболов","shop":"outdoor"},"name":"Рыболов","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/paint/Benjamin Moore":{"tags":{"name":"Benjamin Moore","shop":"paint"},"name":"Benjamin Moore","icon":"water","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/paint/Comex":{"tags":{"name":"Comex","shop":"paint"},"name":"Comex","icon":"water","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/paint/Jotun":{"tags":{"name":"Jotun","shop":"paint"},"name":"Jotun","icon":"water","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/paint/National Paints":{"tags":{"name":"National Paints","shop":"paint"},"name":"National Paints","icon":"water","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/paint/Sherwin Williams":{"tags":{"name":"Sherwin Williams","shop":"paint"},"name":"Sherwin Williams","icon":"water","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/paint/Sherwin-Williams Paints":{"tags":{"name":"Sherwin-Williams Paints","shop":"paint"},"name":"Sherwin-Williams Paints","icon":"water","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/pawnbroker/Cash Converters":{"tags":{"name":"Cash Converters","shop":"pawnbroker"},"name":"Cash Converters","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/pawnbroker/Lombard":{"tags":{"name":"Lombard","shop":"pawnbroker"},"name":"Lombard","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/pawnbroker/Palawan Pawnshop":{"tags":{"name":"Palawan Pawnshop","shop":"pawnbroker"},"name":"Palawan Pawnshop","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/pet/Das Futterhaus":{"tags":{"name":"Das Futterhaus","shop":"pet"},"name":"Das Futterhaus","icon":"dog-park","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/pet/Fressnapf":{"tags":{"name":"Fressnapf","shop":"pet"},"name":"Fressnapf","icon":"dog-park","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/pet/Global Pet Foods":{"tags":{"name":"Global Pet Foods","shop":"pet"},"name":"Global Pet Foods","icon":"dog-park","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/pet/Maxi Zoo":{"tags":{"name":"Maxi Zoo","shop":"pet"},"name":"Maxi Zoo","icon":"dog-park","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/pet/Pet Valu":{"tags":{"name":"Pet Valu","shop":"pet"},"name":"Pet Valu","icon":"dog-park","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/pet/PetSmart":{"tags":{"name":"PetSmart","shop":"pet"},"name":"PetSmart","icon":"dog-park","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/pet/Petco":{"tags":{"name":"Petco","shop":"pet"},"name":"Petco","icon":"dog-park","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"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":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/pet/Бетховен":{"tags":{"name":"Бетховен","shop":"pet"},"name":"Бетховен","icon":"dog-park","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/pet/Зоотовары":{"tags":{"name":"Зоотовары","shop":"pet"},"name":"Зоотовары","icon":"dog-park","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/pet/Четыре лапы":{"tags":{"name":"Четыре лапы","shop":"pet"},"name":"Четыре лапы","icon":"dog-park","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/second_hand/Goodwill":{"tags":{"name":"Goodwill","shop":"second_hand"},"name":"Goodwill","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","opening_hours","payment_multi"],"suggestion":true},"shop/second_hand/Value Village":{"tags":{"name":"Value Village","shop":"second_hand"},"name":"Value Village","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","second_hand","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Aldo":{"tags":{"name":"Aldo","shop":"shoes"},"name":"Aldo","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Bata":{"tags":{"name":"Bata","shop":"shoes"},"name":"Bata","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Besson Chaussures":{"tags":{"name":"Besson Chaussures","shop":"shoes"},"name":"Besson Chaussures","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Brantano":{"tags":{"name":"Brantano","shop":"shoes"},"name":"Brantano","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/CCC":{"tags":{"name":"CCC","shop":"shoes"},"name":"CCC","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Camper":{"tags":{"name":"Camper","shop":"shoes"},"name":"Camper","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Chaussea":{"tags":{"name":"Chaussea","shop":"shoes"},"name":"Chaussea","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Clarks":{"tags":{"name":"Clarks","shop":"shoes"},"name":"Clarks","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Converse":{"tags":{"name":"Converse","shop":"shoes"},"name":"Converse","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Crocs":{"tags":{"name":"Crocs","shop":"shoes"},"name":"Crocs","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/DSW":{"tags":{"name":"DSW","shop":"shoes"},"name":"DSW","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Deichmann":{"tags":{"name":"Deichmann","shop":"shoes"},"name":"Deichmann","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Dosenbach":{"tags":{"name":"Dosenbach","shop":"shoes"},"name":"Dosenbach","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Ecco":{"tags":{"name":"Ecco","shop":"shoes"},"name":"Ecco","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Famous Footwear":{"tags":{"name":"Famous Footwear","shop":"shoes"},"name":"Famous Footwear","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Foot Locker":{"tags":{"name":"Foot Locker","shop":"shoes"},"name":"Foot Locker","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Geox":{"tags":{"name":"Geox","shop":"shoes"},"name":"Geox","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Kari":{"tags":{"name":"Kari","shop":"shoes"},"name":"Kari","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"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":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Mephisto":{"tags":{"name":"Mephisto","shop":"shoes"},"name":"Mephisto","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Minelli":{"tags":{"name":"Minelli","shop":"shoes"},"name":"Minelli","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/New Balance":{"tags":{"name":"New Balance","shop":"shoes"},"name":"New Balance","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Payless":{"tags":{"name":"Payless","shop":"shoes"},"name":"Payless","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Payless Shoe Source":{"tags":{"name":"Payless Shoe Source","shop":"shoes"},"name":"Payless Shoe Source","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Payless ShoeSource":{"tags":{"name":"Payless ShoeSource","shop":"shoes"},"name":"Payless ShoeSource","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Quick Schuh":{"tags":{"name":"Quick Schuh","shop":"shoes"},"name":"Quick Schuh","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Rack Room Shoes":{"tags":{"name":"Rack Room Shoes","shop":"shoes"},"name":"Rack Room Shoes","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Reno":{"tags":{"name":"Reno","shop":"shoes"},"name":"Reno","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Rieker":{"tags":{"name":"Rieker","shop":"shoes"},"name":"Rieker","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Salamander":{"tags":{"name":"Salamander","shop":"shoes"},"name":"Salamander","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/San Marina":{"tags":{"name":"San Marina","shop":"shoes"},"name":"San Marina","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Scapino":{"tags":{"name":"Scapino","shop":"shoes"},"name":"Scapino","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Shoe Carnival":{"tags":{"name":"Shoe Carnival","shop":"shoes"},"name":"Shoe Carnival","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Shoe Zone":{"tags":{"name":"Shoe Zone","shop":"shoes"},"name":"Shoe Zone","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Siemes Schuhcenter":{"tags":{"name":"Siemes Schuhcenter","shop":"shoes"},"name":"Siemes Schuhcenter","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Skechers":{"tags":{"name":"Skechers","shop":"shoes"},"name":"Skechers","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Tamaris":{"tags":{"name":"Tamaris","shop":"shoes"},"name":"Tamaris","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/vanHaren":{"tags":{"name":"vanHaren","shop":"shoes"},"name":"vanHaren","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Éram":{"tags":{"name":"Éram","shop":"shoes"},"name":"Éram","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Ремонт обуви":{"tags":{"name":"Ремонт обуви","shop":"shoes"},"name":"Ремонт обуви","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/ЦентрОбувь":{"tags":{"name":"ЦентрОбувь","shop":"shoes"},"name":"ЦентрОбувь","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/Юничел":{"tags":{"name":"Юничел","shop":"shoes"},"name":"Юничел","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/shoes/東京靴流通センター":{"tags":{"name":"東京靴流通センター","shop":"shoes"},"name":"東京靴流通センター","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/sports/Aktiesport":{"tags":{"name":"Aktiesport","shop":"sports"},"name":"Aktiesport","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/sports/Big 5 Sporting Goods":{"tags":{"name":"Big 5 Sporting Goods","shop":"sports"},"name":"Big 5 Sporting Goods","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/sports/Decathlon":{"tags":{"name":"Decathlon","shop":"sports"},"name":"Decathlon","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"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":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/sports/Hervis":{"tags":{"name":"Hervis","shop":"sports"},"name":"Hervis","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/sports/Intersport":{"tags":{"name":"Intersport","shop":"sports"},"name":"Intersport","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/sports/JD Sports":{"tags":{"name":"JD Sports","shop":"sports"},"name":"JD Sports","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/sports/Sport 2000":{"tags":{"name":"Sport 2000","shop":"sports"},"name":"Sport 2000","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/sports/Sports Authority":{"tags":{"name":"Sports Authority","shop":"sports"},"name":"Sports Authority","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/sports/Sports Direct":{"tags":{"name":"Sports Direct","shop":"sports"},"name":"Sports Direct","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/sports/Спортмастер":{"tags":{"name":"Спортмастер","shop":"sports"},"name":"Спортмастер","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/sports/Спорттовары":{"tags":{"name":"Спорттовары","shop":"sports"},"name":"Спорттовары","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/stationery/Bureau Vallée":{"tags":{"name":"Bureau Vallée","shop":"stationery"},"name":"Bureau Vallée","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/stationery/Libro":{"tags":{"name":"Libro","shop":"stationery"},"name":"Libro","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/stationery/McPaper":{"tags":{"name":"McPaper","shop":"stationery"},"name":"McPaper","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/stationery/Office Depot":{"tags":{"name":"Office Depot","shop":"stationery"},"name":"Office Depot","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/stationery/Office Max":{"tags":{"name":"Office Max","shop":"stationery"},"name":"Office Max","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/stationery/Officeworks":{"tags":{"name":"Officeworks","shop":"stationery"},"name":"Officeworks","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/stationery/Pagro":{"tags":{"name":"Pagro","shop":"stationery"},"name":"Pagro","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/stationery/Paperchase":{"tags":{"name":"Paperchase","shop":"stationery"},"name":"Paperchase","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/stationery/Ryman":{"tags":{"name":"Ryman","shop":"stationery"},"name":"Ryman","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/stationery/Staples":{"tags":{"name":"Staples","shop":"stationery"},"name":"Staples","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/stationery/Канцтовары":{"tags":{"name":"Канцтовары","shop":"stationery"},"name":"Канцтовары","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/A&O":{"tags":{"name":"A&O","shop":"supermarket"},"name":"A&O","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/A101":{"tags":{"name":"A101","shop":"supermarket"},"name":"A101","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/AD Delhaize":{"tags":{"name":"AD Delhaize","shop":"supermarket"},"name":"AD Delhaize","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/ADEG":{"tags":{"name":"ADEG","shop":"supermarket"},"name":"ADEG","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Ahorramás":{"tags":{"name":"Ahorramás","shop":"supermarket"},"name":"Ahorramás","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Albert":{"tags":{"name":"Albert","shop":"supermarket"},"name":"Albert","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Albert Heijn":{"tags":{"name":"Albert Heijn","shop":"supermarket"},"name":"Albert Heijn","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Albertsons":{"tags":{"name":"Albertsons","shop":"supermarket"},"name":"Albertsons","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Aldi":{"tags":{"name":"Aldi","shop":"supermarket"},"name":"Aldi","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Aldi Nord":{"tags":{"name":"Aldi Nord","shop":"supermarket"},"name":"Aldi Nord","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Aldi Süd":{"tags":{"name":"Aldi Süd","shop":"supermarket"},"name":"Aldi Süd","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Alimerka":{"tags":{"name":"Alimerka","shop":"supermarket"},"name":"Alimerka","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Alnatura":{"tags":{"name":"Alnatura","shop":"supermarket"},"name":"Alnatura","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Asda":{"tags":{"name":"Asda","shop":"supermarket"},"name":"Asda","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Atac":{"tags":{"name":"Atac","shop":"supermarket"},"name":"Atac","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Atacadão":{"tags":{"name":"Atacadão","shop":"supermarket"},"name":"Atacadão","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Auchan":{"tags":{"name":"Auchan","shop":"supermarket"},"name":"Auchan","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/BM":{"tags":{"name":"BM","shop":"supermarket"},"name":"BM","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Biedronka":{"tags":{"name":"Biedronka","shop":"supermarket"},"name":"Biedronka","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Big C":{"tags":{"name":"Big C","shop":"supermarket"},"name":"Big C","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Billa":{"tags":{"name":"Billa","shop":"supermarket"},"name":"Billa","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Bim":{"tags":{"name":"Bim","shop":"supermarket"},"name":"Bim","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Biocoop":{"tags":{"name":"Biocoop","shop":"supermarket"},"name":"Biocoop","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Bodega Aurrera":{"tags":{"name":"Bodega Aurrera","shop":"supermarket"},"name":"Bodega Aurrera","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Budgens":{"tags":{"name":"Budgens","shop":"supermarket"},"name":"Budgens","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Bulk Barn":{"tags":{"name":"Bulk Barn","shop":"supermarket"},"name":"Bulk Barn","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Bunnpris":{"tags":{"name":"Bunnpris","shop":"supermarket"},"name":"Bunnpris","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/CONAD":{"tags":{"name":"CONAD","shop":"supermarket"},"name":"CONAD","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/CRAI":{"tags":{"name":"CRAI","shop":"supermarket"},"name":"CRAI","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Caprabo":{"tags":{"name":"Caprabo","shop":"supermarket"},"name":"Caprabo","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Cargills Food City":{"tags":{"name":"Cargills Food City","shop":"supermarket"},"name":"Cargills Food City","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Carrefour":{"tags":{"name":"Carrefour","shop":"supermarket"},"name":"Carrefour","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Carrefour City":{"tags":{"name":"Carrefour City","shop":"supermarket"},"name":"Carrefour City","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Carrefour Contact":{"tags":{"name":"Carrefour Contact","shop":"supermarket"},"name":"Carrefour Contact","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Carrefour Express":{"tags":{"name":"Carrefour Express","shop":"supermarket"},"name":"Carrefour Express","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"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":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Checkers":{"tags":{"name":"Checkers","shop":"supermarket"},"name":"Checkers","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Chedraui":{"tags":{"name":"Chedraui","shop":"supermarket"},"name":"Chedraui","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Co-Op":{"tags":{"name":"Co-Op","shop":"supermarket"},"name":"Co-Op","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Co-op":{"tags":{"name":"Co-op","shop":"supermarket"},"name":"Co-op","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Co-operative":{"tags":{"name":"Co-operative","shop":"supermarket"},"name":"Co-operative","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Coles":{"tags":{"name":"Coles","shop":"supermarket"},"name":"Coles","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Colmado":{"tags":{"name":"Colmado","shop":"supermarket"},"name":"Colmado","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Colruyt":{"tags":{"name":"Colruyt","shop":"supermarket"},"name":"Colruyt","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Combi":{"tags":{"name":"Combi","shop":"supermarket"},"name":"Combi","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Comercial Mexicana":{"tags":{"name":"Comercial Mexicana","shop":"supermarket"},"name":"Comercial Mexicana","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Conad":{"tags":{"name":"Conad","shop":"supermarket"},"name":"Conad","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Conad City":{"tags":{"name":"Conad City","shop":"supermarket"},"name":"Conad City","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Condis":{"tags":{"name":"Condis","shop":"supermarket"},"name":"Condis","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Consum":{"tags":{"name":"Consum","shop":"supermarket"},"name":"Consum","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Continente":{"tags":{"name":"Continente","shop":"supermarket"},"name":"Continente","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Coop":{"tags":{"name":"Coop","shop":"supermarket"},"name":"Coop","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Coop Extra":{"tags":{"name":"Coop Extra","shop":"supermarket"},"name":"Coop Extra","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Coop Konsum":{"tags":{"name":"Coop Konsum","shop":"supermarket"},"name":"Coop Konsum","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Costco":{"tags":{"name":"Costco","shop":"supermarket"},"name":"Costco","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Coto":{"tags":{"name":"Coto","shop":"supermarket"},"name":"Coto","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Countdown":{"tags":{"name":"Countdown","shop":"supermarket"},"name":"Countdown","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Coviran":{"tags":{"name":"Coviran","shop":"supermarket"},"name":"Coviran","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Covirán":{"tags":{"name":"Covirán","shop":"supermarket"},"name":"Covirán","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Crai":{"tags":{"name":"Crai","shop":"supermarket"},"name":"Crai","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Cub Foods":{"tags":{"name":"Cub Foods","shop":"supermarket"},"name":"Cub Foods","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Dagli'Brugsen":{"tags":{"name":"Dagli'Brugsen","shop":"supermarket"},"name":"Dagli'Brugsen","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Deen":{"tags":{"name":"Deen","shop":"supermarket"},"name":"Deen","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Delhaize":{"tags":{"name":"Delhaize","shop":"supermarket"},"name":"Delhaize","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Delikatesy Centrum":{"tags":{"name":"Delikatesy Centrum","shop":"supermarket"},"name":"Delikatesy Centrum","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Denner":{"tags":{"name":"Denner","shop":"supermarket"},"name":"Denner","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Despar":{"tags":{"name":"Despar","shop":"supermarket"},"name":"Despar","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Despensa Familiar":{"tags":{"name":"Despensa Familiar","shop":"supermarket"},"name":"Despensa Familiar","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Dia":{"tags":{"name":"Dia","shop":"supermarket"},"name":"Dia","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Dia %":{"tags":{"name":"Dia %","shop":"supermarket"},"name":"Dia %","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Dia Market":{"tags":{"name":"Dia Market","shop":"supermarket"},"name":"Dia Market","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Dino":{"tags":{"name":"Dino","shop":"supermarket"},"name":"Dino","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Dirk van den Broek":{"tags":{"name":"Dirk van den Broek","shop":"supermarket"},"name":"Dirk van den Broek","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Disco":{"tags":{"name":"Disco","shop":"supermarket"},"name":"Disco","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Diska":{"tags":{"name":"Diska","shop":"supermarket"},"name":"Diska","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Dunnes Stores":{"tags":{"name":"Dunnes Stores","shop":"supermarket"},"name":"Dunnes Stores","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/E-Center":{"tags":{"name":"E-Center","shop":"supermarket"},"name":"E-Center","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/E. Leclerc":{"tags":{"name":"E. Leclerc","shop":"supermarket"},"name":"E. Leclerc","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/E. Leclerc Drive":{"tags":{"name":"E. Leclerc Drive","shop":"supermarket"},"name":"E. Leclerc Drive","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/EMTÉ":{"tags":{"name":"EMTÉ","shop":"supermarket"},"name":"EMTÉ","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Edeka":{"tags":{"name":"Edeka","shop":"supermarket"},"name":"Edeka","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Ekom":{"tags":{"name":"Ekom","shop":"supermarket"},"name":"Ekom","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Ekono":{"tags":{"name":"Ekono","shop":"supermarket"},"name":"Ekono","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/El Árbol":{"tags":{"name":"El Árbol","shop":"supermarket"},"name":"El Árbol","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Eroski":{"tags":{"name":"Eroski","shop":"supermarket"},"name":"Eroski","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Esselunga":{"tags":{"name":"Esselunga","shop":"supermarket"},"name":"Esselunga","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/EuroSpin":{"tags":{"name":"EuroSpin","shop":"supermarket"},"name":"EuroSpin","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Eurospar":{"tags":{"name":"Eurospar","shop":"supermarket"},"name":"Eurospar","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Eurospin":{"tags":{"name":"Eurospin","shop":"supermarket"},"name":"Eurospin","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Extra":{"tags":{"name":"Extra","shop":"supermarket"},"name":"Extra","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Famiglia Cooperativa":{"tags":{"name":"Famiglia Cooperativa","shop":"supermarket"},"name":"Famiglia Cooperativa","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Famila":{"tags":{"name":"Famila","shop":"supermarket"},"name":"Famila","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Fareway":{"tags":{"name":"Fareway","shop":"supermarket"},"name":"Fareway","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Farmfoods":{"tags":{"name":"Farmfoods","shop":"supermarket"},"name":"Farmfoods","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Feneberg":{"tags":{"name":"Feneberg","shop":"supermarket"},"name":"Feneberg","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Food Basics":{"tags":{"name":"Food Basics","shop":"supermarket"},"name":"Food Basics","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Food Lion":{"tags":{"name":"Food Lion","shop":"supermarket"},"name":"Food Lion","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Foodland":{"tags":{"name":"Foodland","shop":"supermarket"},"name":"Foodland","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Foodworks":{"tags":{"name":"Foodworks","shop":"supermarket"},"name":"Foodworks","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Franprix":{"tags":{"name":"Franprix","shop":"supermarket"},"name":"Franprix","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Fred Meyer":{"tags":{"name":"Fred Meyer","shop":"supermarket"},"name":"Fred Meyer","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Froiz":{"tags":{"name":"Froiz","shop":"supermarket"},"name":"Froiz","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Føtex":{"tags":{"name":"Føtex","shop":"supermarket"},"name":"Føtex","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/G20":{"tags":{"name":"G20","shop":"supermarket"},"name":"G20","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Gadis":{"tags":{"name":"Gadis","shop":"supermarket"},"name":"Gadis","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Giant":{"tags":{"name":"Giant","shop":"supermarket"},"name":"Giant","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Giant Eagle":{"tags":{"name":"Giant Eagle","shop":"supermarket"},"name":"Giant Eagle","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Grand Frais":{"tags":{"name":"Grand Frais","shop":"supermarket"},"name":"Grand Frais","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Grocery Outlet":{"tags":{"name":"Grocery Outlet","shop":"supermarket"},"name":"Grocery Outlet","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Géant Casino":{"tags":{"name":"Géant Casino","shop":"supermarket"},"name":"Géant Casino","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/H-E-B":{"tags":{"name":"H-E-B","shop":"supermarket"},"name":"H-E-B","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/HIT":{"tags":{"name":"HIT","shop":"supermarket"},"name":"HIT","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Hannaford":{"tags":{"name":"Hannaford","shop":"supermarket"},"name":"Hannaford","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Harris Teeter":{"tags":{"name":"Harris Teeter","shop":"supermarket"},"name":"Harris Teeter","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Hemköp":{"tags":{"name":"Hemköp","shop":"supermarket"},"name":"Hemköp","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Heron Foods":{"tags":{"name":"Heron Foods","shop":"supermarket"},"name":"Heron Foods","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Hofer":{"tags":{"name":"Hofer","shop":"supermarket"},"name":"Hofer","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Hoogvliet":{"tags":{"name":"Hoogvliet","shop":"supermarket"},"name":"Hoogvliet","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Hy-Vee":{"tags":{"name":"Hy-Vee","shop":"supermarket"},"name":"Hy-Vee","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/ICA":{"tags":{"name":"ICA","shop":"supermarket"},"name":"ICA","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/ICA Kvantum":{"tags":{"name":"ICA Kvantum","shop":"supermarket"},"name":"ICA Kvantum","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/IDEA":{"tags":{"name":"IDEA","shop":"supermarket"},"name":"IDEA","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/IGA":{"tags":{"name":"IGA","shop":"supermarket"},"name":"IGA","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Iceland":{"tags":{"name":"Iceland","shop":"supermarket"},"name":"Iceland","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Intermarché":{"tags":{"name":"Intermarché","shop":"supermarket"},"name":"Intermarché","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Intermarché Contact":{"tags":{"name":"Intermarché Contact","shop":"supermarket"},"name":"Intermarché Contact","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Intermarché Super":{"tags":{"name":"Intermarché Super","shop":"supermarket"},"name":"Intermarché Super","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Interspar":{"tags":{"name":"Interspar","shop":"supermarket"},"name":"Interspar","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Irma":{"tags":{"name":"Irma","shop":"supermarket"},"name":"Irma","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Jewel-Osco":{"tags":{"name":"Jewel-Osco","shop":"supermarket"},"name":"Jewel-Osco","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Jumbo":{"tags":{"name":"Jumbo","shop":"supermarket"},"name":"Jumbo","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/K+K":{"tags":{"name":"K+K","shop":"supermarket"},"name":"K+K","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Kaufland":{"tags":{"name":"Kaufland","shop":"supermarket"},"name":"Kaufland","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/King Soopers":{"tags":{"name":"King Soopers","shop":"supermarket"},"name":"King Soopers","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Kiwi":{"tags":{"name":"Kiwi","shop":"supermarket"},"name":"Kiwi","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Konsum":{"tags":{"name":"Konsum","shop":"supermarket"},"name":"Konsum","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Konzum":{"tags":{"name":"Konzum","shop":"supermarket"},"name":"Konzum","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Kroger":{"tags":{"name":"Kroger","shop":"supermarket"},"name":"Kroger","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Kvickly":{"tags":{"name":"Kvickly","shop":"supermarket"},"name":"Kvickly","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/La Vie Claire":{"tags":{"name":"La Vie Claire","shop":"supermarket"},"name":"La Vie Claire","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Landi":{"tags":{"name":"Landi","shop":"supermarket"},"name":"Landi","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Leader Price":{"tags":{"name":"Leader Price","shop":"supermarket"},"name":"Leader Price","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Leclerc Drive":{"tags":{"name":"Leclerc Drive","shop":"supermarket"},"name":"Leclerc Drive","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Lider":{"tags":{"name":"Lider","shop":"supermarket"},"name":"Lider","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Lidl":{"tags":{"name":"Lidl","shop":"supermarket"},"name":"Lidl","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Lupa":{"tags":{"name":"Lupa","shop":"supermarket"},"name":"Lupa","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/MPREIS":{"tags":{"name":"MPREIS","shop":"supermarket"},"name":"MPREIS","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Makro":{"tags":{"name":"Makro","shop":"supermarket"},"name":"Makro","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Markant":{"tags":{"name":"Markant","shop":"supermarket"},"name":"Markant","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Market Basket":{"tags":{"name":"Market Basket","shop":"supermarket"},"name":"Market Basket","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Marktkauf":{"tags":{"name":"Marktkauf","shop":"supermarket"},"name":"Marktkauf","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Match":{"tags":{"name":"Match","shop":"supermarket"},"name":"Match","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Maxi":{"tags":{"name":"Maxi","shop":"supermarket"},"name":"Maxi","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Maxi Dia":{"tags":{"name":"Maxi Dia","shop":"supermarket"},"name":"Maxi Dia","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Maxima":{"tags":{"name":"Maxima","shop":"supermarket"},"name":"Maxima","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Maxima X":{"tags":{"name":"Maxima X","shop":"supermarket"},"name":"Maxima X","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Maxima XX":{"tags":{"name":"Maxima XX","shop":"supermarket"},"name":"Maxima XX","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Mega Image":{"tags":{"name":"Mega Image","shop":"supermarket"},"name":"Mega Image","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Mego":{"tags":{"name":"Mego","shop":"supermarket"},"name":"Mego","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Meijer":{"tags":{"name":"Meijer","shop":"supermarket"},"name":"Meijer","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Meny":{"tags":{"name":"Meny","shop":"supermarket"},"name":"Meny","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Mercado Municipal":{"tags":{"name":"Mercado Municipal","shop":"supermarket"},"name":"Mercado Municipal","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Mercado de Abastos":{"tags":{"name":"Mercado de Abastos","shop":"supermarket"},"name":"Mercado de Abastos","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Mercadona":{"tags":{"name":"Mercadona","shop":"supermarket"},"name":"Mercadona","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Mercator":{"tags":{"name":"Mercator","shop":"supermarket"},"name":"Mercator","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Merkur":{"tags":{"name":"Merkur","shop":"supermarket"},"name":"Merkur","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Metro":{"tags":{"name":"Metro","shop":"supermarket"},"name":"Metro","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Migros":{"tags":{"name":"Migros","shop":"supermarket"},"name":"Migros","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Mila":{"tags":{"name":"Mila","shop":"supermarket"},"name":"Mila","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Minipreço":{"tags":{"name":"Minipreço","shop":"supermarket"},"name":"Minipreço","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Mix Markt":{"tags":{"name":"Mix Markt","shop":"supermarket"},"name":"Mix Markt","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Monoprix":{"tags":{"name":"Monoprix","shop":"supermarket"},"name":"Monoprix","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/More":{"tags":{"name":"More","shop":"supermarket"},"name":"More","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Morrisons":{"tags":{"name":"Morrisons","shop":"supermarket"},"name":"Morrisons","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/NORMA":{"tags":{"name":"NORMA","shop":"supermarket"},"name":"NORMA","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/NP":{"tags":{"name":"NP","shop":"supermarket"},"name":"NP","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Nah & Frisch":{"tags":{"name":"Nah & Frisch","shop":"supermarket"},"name":"Nah & Frisch","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Nahkauf":{"tags":{"name":"Nahkauf","shop":"supermarket"},"name":"Nahkauf","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Netto":{"tags":{"name":"Netto","shop":"supermarket"},"name":"Netto","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Netto Marken-Discount":{"tags":{"name":"Netto Marken-Discount","shop":"supermarket"},"name":"Netto Marken-Discount","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/New World":{"tags":{"name":"New World","shop":"supermarket"},"name":"New World","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/No Frills":{"tags":{"name":"No Frills","shop":"supermarket"},"name":"No Frills","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Norfa XL":{"tags":{"name":"Norfa XL","shop":"supermarket"},"name":"Norfa XL","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Norma":{"tags":{"name":"Norma","shop":"supermarket"},"name":"Norma","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/PENNY":{"tags":{"name":"PENNY","shop":"supermarket"},"name":"PENNY","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/PLUS":{"tags":{"name":"PLUS","shop":"supermarket"},"name":"PLUS","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/POLOmarket":{"tags":{"name":"POLOmarket","shop":"supermarket"},"name":"POLOmarket","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Palí":{"tags":{"name":"Palí","shop":"supermarket"},"name":"Palí","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Pam":{"tags":{"name":"Pam","shop":"supermarket"},"name":"Pam","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Penny":{"tags":{"name":"Penny","shop":"supermarket"},"name":"Penny","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Penny Markt":{"tags":{"name":"Penny Markt","shop":"supermarket"},"name":"Penny Markt","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Pick n Pay":{"tags":{"name":"Pick n Pay","shop":"supermarket"},"name":"Pick n Pay","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Piggly Wiggly":{"tags":{"name":"Piggly Wiggly","shop":"supermarket"},"name":"Piggly Wiggly","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Pingo Doce":{"tags":{"name":"Pingo Doce","shop":"supermarket"},"name":"Pingo Doce","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Piotr i Paweł":{"tags":{"name":"Piotr i Paweł","shop":"supermarket"},"name":"Piotr i Paweł","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Plaza Vea":{"tags":{"name":"Plaza Vea","shop":"supermarket"},"name":"Plaza Vea","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Plodine":{"tags":{"name":"Plodine","shop":"supermarket"},"name":"Plodine","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Poiesz":{"tags":{"name":"Poiesz","shop":"supermarket"},"name":"Poiesz","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Price Chopper":{"tags":{"name":"Price Chopper","shop":"supermarket"},"name":"Price Chopper","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Prix":{"tags":{"name":"Prix","shop":"supermarket"},"name":"Prix","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Profi":{"tags":{"name":"Profi","shop":"supermarket"},"name":"Profi","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Proxy Delhaize":{"tags":{"name":"Proxy Delhaize","shop":"supermarket"},"name":"Proxy Delhaize","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Publix":{"tags":{"name":"Publix","shop":"supermarket"},"name":"Publix","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Punto Simply":{"tags":{"name":"Punto Simply","shop":"supermarket"},"name":"Punto Simply","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Puregold":{"tags":{"name":"Puregold","shop":"supermarket"},"name":"Puregold","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Pão de Açúcar":{"tags":{"name":"Pão de Açúcar","shop":"supermarket"},"name":"Pão de Açúcar","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/QFC":{"tags":{"name":"QFC","shop":"supermarket"},"name":"QFC","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/REMA 1000":{"tags":{"name":"REMA 1000","shop":"supermarket"},"name":"REMA 1000","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Ralphs":{"tags":{"name":"Ralphs","shop":"supermarket"},"name":"Ralphs","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Real":{"tags":{"name":"Real","shop":"supermarket"},"name":"Real","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Real Canadian Superstore":{"tags":{"name":"Real Canadian Superstore","shop":"supermarket"},"name":"Real Canadian Superstore","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Reliance Fresh":{"tags":{"name":"Reliance Fresh","shop":"supermarket"},"name":"Reliance Fresh","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Rema 1000":{"tags":{"name":"Rema 1000","shop":"supermarket"},"name":"Rema 1000","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Rewe":{"tags":{"name":"Rewe","shop":"supermarket"},"name":"Rewe","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Rewe City":{"tags":{"name":"Rewe City","shop":"supermarket"},"name":"Rewe City","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Rimi":{"tags":{"name":"Rimi","shop":"supermarket"},"name":"Rimi","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/S-Market":{"tags":{"name":"S-Market","shop":"supermarket"},"name":"S-Market","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Safeway":{"tags":{"name":"Safeway","shop":"supermarket"},"name":"Safeway","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Sainsbury's":{"tags":{"name":"Sainsbury's","shop":"supermarket"},"name":"Sainsbury's","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Sainsbury's Local":{"tags":{"name":"Sainsbury's Local","shop":"supermarket"},"name":"Sainsbury's Local","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Sam's Club":{"tags":{"name":"Sam's Club","shop":"supermarket"},"name":"Sam's Club","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Santa Isabel":{"tags":{"name":"Santa Isabel","shop":"supermarket"},"name":"Santa Isabel","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Save-A-Lot":{"tags":{"name":"Save-A-Lot","shop":"supermarket"},"name":"Save-A-Lot","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/ShopRite":{"tags":{"name":"ShopRite","shop":"supermarket"},"name":"ShopRite","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Shoprite":{"tags":{"name":"Shoprite","shop":"supermarket"},"name":"Shoprite","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Sigma":{"tags":{"name":"Sigma","shop":"supermarket"},"name":"Sigma","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Simply Market":{"tags":{"name":"Simply Market","shop":"supermarket"},"name":"Simply Market","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Sky":{"tags":{"name":"Sky","shop":"supermarket"},"name":"Sky","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Smith's":{"tags":{"name":"Smith's","shop":"supermarket"},"name":"Smith's","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Sobeys":{"tags":{"name":"Sobeys","shop":"supermarket"},"name":"Sobeys","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Soriana":{"tags":{"name":"Soriana","shop":"supermarket"},"name":"Soriana","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Spar":{"tags":{"name":"Spar","shop":"supermarket"},"name":"Spar","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Sprouts Farmers Market":{"tags":{"name":"Sprouts Farmers Market","shop":"supermarket"},"name":"Sprouts Farmers Market","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Stokrotka":{"tags":{"name":"Stokrotka","shop":"supermarket"},"name":"Stokrotka","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Stop & Shop":{"tags":{"name":"Stop & Shop","shop":"supermarket"},"name":"Stop & Shop","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Super C":{"tags":{"name":"Super C","shop":"supermarket"},"name":"Super C","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Super U":{"tags":{"name":"Super U","shop":"supermarket"},"name":"Super U","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/SuperBrugsen":{"tags":{"name":"SuperBrugsen","shop":"supermarket"},"name":"SuperBrugsen","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/SuperValu":{"tags":{"name":"SuperValu","shop":"supermarket"},"name":"SuperValu","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Superama":{"tags":{"name":"Superama","shop":"supermarket"},"name":"Superama","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Supersol":{"tags":{"name":"Supersol","shop":"supermarket"},"name":"Supersol","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Superspar":{"tags":{"name":"Superspar","shop":"supermarket"},"name":"Superspar","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Tegut":{"tags":{"name":"Tegut","shop":"supermarket"},"name":"Tegut","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Tengelmann":{"tags":{"name":"Tengelmann","shop":"supermarket"},"name":"Tengelmann","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Tesco":{"tags":{"name":"Tesco","shop":"supermarket"},"name":"Tesco","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Tesco Extra":{"tags":{"name":"Tesco Extra","shop":"supermarket"},"name":"Tesco Extra","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Tesco Lotus":{"tags":{"name":"Tesco Lotus","shop":"supermarket"},"name":"Tesco Lotus","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Tesco Metro":{"tags":{"name":"Tesco Metro","shop":"supermarket"},"name":"Tesco Metro","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/The Co-operative":{"tags":{"name":"The Co-operative","shop":"supermarket"},"name":"The Co-operative","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"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":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Tommy":{"tags":{"name":"Tommy","shop":"supermarket"},"name":"Tommy","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Tottus":{"tags":{"name":"Tottus","shop":"supermarket"},"name":"Tottus","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Trader Joe's":{"tags":{"name":"Trader Joe's","shop":"supermarket"},"name":"Trader Joe's","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Treff 3000":{"tags":{"name":"Treff 3000","shop":"supermarket"},"name":"Treff 3000","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/U Express":{"tags":{"name":"U Express","shop":"supermarket"},"name":"U Express","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Unimarc":{"tags":{"name":"Unimarc","shop":"supermarket"},"name":"Unimarc","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Unimarkt":{"tags":{"name":"Unimarkt","shop":"supermarket"},"name":"Unimarkt","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Utile":{"tags":{"name":"Utile","shop":"supermarket"},"name":"Utile","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Vea":{"tags":{"name":"Vea","shop":"supermarket"},"name":"Vea","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Volg":{"tags":{"name":"Volg","shop":"supermarket"},"name":"Volg","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Waitrose":{"tags":{"name":"Waitrose","shop":"supermarket"},"name":"Waitrose","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Walmart":{"tags":{"name":"Walmart","shop":"supermarket"},"name":"Walmart","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Walmart Neighborhood Market":{"tags":{"name":"Walmart Neighborhood Market","shop":"supermarket"},"name":"Walmart Neighborhood Market","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Walmart Supercenter":{"tags":{"name":"Walmart Supercenter","shop":"supermarket"},"name":"Walmart Supercenter","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Wasgau":{"tags":{"name":"Wasgau","shop":"supermarket"},"name":"Wasgau","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Wegmans":{"tags":{"name":"Wegmans","shop":"supermarket"},"name":"Wegmans","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Wellcome":{"tags":{"name":"Wellcome","shop":"supermarket"},"name":"Wellcome","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Whole Foods Market":{"tags":{"name":"Whole Foods Market","shop":"supermarket"},"name":"Whole Foods Market","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Willys":{"tags":{"name":"Willys","shop":"supermarket"},"name":"Willys","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/WinCo Foods":{"tags":{"name":"WinCo Foods","shop":"supermarket"},"name":"WinCo Foods","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Winn Dixie":{"tags":{"name":"Winn Dixie","shop":"supermarket"},"name":"Winn Dixie","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Woolworths":{"tags":{"name":"Woolworths","shop":"supermarket"},"name":"Woolworths","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/denn's Biomarkt":{"tags":{"name":"denn's Biomarkt","shop":"supermarket"},"name":"denn's Biomarkt","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/fakta":{"tags":{"name":"fakta","shop":"supermarket"},"name":"fakta","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/real":{"tags":{"name":"real","shop":"supermarket"},"name":"real","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/tegut":{"tags":{"name":"tegut","shop":"supermarket"},"name":"tegut","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Şok":{"tags":{"name":"Şok","shop":"supermarket"},"name":"Şok","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/ΑΒ Βασιλόπουλος":{"tags":{"name":"ΑΒ Βασιλόπουλος","shop":"supermarket"},"name":"ΑΒ Βασιλόπουλος","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Γαλαξίας":{"tags":{"name":"Γαλαξίας","shop":"supermarket"},"name":"Γαλαξίας","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Μασούτης":{"tags":{"name":"Μασούτης","shop":"supermarket"},"name":"Μασούτης","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Σκλαβενίτης":{"tags":{"name":"Σκλαβενίτης","shop":"supermarket"},"name":"Σκλαβενίτης","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/АТБ":{"tags":{"name":"АТБ","shop":"supermarket"},"name":"АТБ","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Абсолют":{"tags":{"name":"Абсолют","shop":"supermarket"},"name":"Абсолют","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Азбука Вкуса":{"tags":{"name":"Азбука Вкуса","shop":"supermarket"},"name":"Азбука Вкуса","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Атак":{"tags":{"name":"Атак","shop":"supermarket"},"name":"Атак","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Ашан":{"tags":{"name":"Ашан","shop":"supermarket"},"name":"Ашан","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Верный":{"tags":{"name":"Верный","shop":"supermarket"},"name":"Верный","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Вопак":{"tags":{"name":"Вопак","shop":"supermarket"},"name":"Вопак","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Гроздь":{"tags":{"name":"Гроздь","shop":"supermarket"},"name":"Гроздь","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Десяточка":{"tags":{"name":"Десяточка","shop":"supermarket"},"name":"Десяточка","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Дикси":{"tags":{"name":"Дикси","shop":"supermarket"},"name":"Дикси","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Евроопт":{"tags":{"name":"Евроопт","shop":"supermarket"},"name":"Евроопт","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Карусель":{"tags":{"name":"Карусель","shop":"supermarket"},"name":"Карусель","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Квартал":{"tags":{"name":"Квартал","shop":"supermarket"},"name":"Квартал","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Командор":{"tags":{"name":"Командор","shop":"supermarket"},"name":"Командор","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Красный Яр":{"tags":{"name":"Красный Яр","shop":"supermarket"},"name":"Красный Яр","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Лента":{"tags":{"name":"Лента","shop":"supermarket"},"name":"Лента","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Магнит":{"tags":{"name":"Магнит","shop":"supermarket"},"name":"Магнит","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Магнолия":{"tags":{"name":"Магнолия","shop":"supermarket"},"name":"Магнолия","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Монетка":{"tags":{"name":"Монетка","shop":"supermarket"},"name":"Монетка","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Народная 7Я семьЯ":{"tags":{"name":"Народная 7Я семьЯ","shop":"supermarket"},"name":"Народная 7Я семьЯ","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Перекресток":{"tags":{"name":"Перекресток","shop":"supermarket"},"name":"Перекресток","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Покупочка":{"tags":{"name":"Покупочка","shop":"supermarket"},"name":"Покупочка","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Полушка":{"tags":{"name":"Полушка","shop":"supermarket"},"name":"Полушка","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Пятёрочка":{"tags":{"name":"Пятёрочка","shop":"supermarket"},"name":"Пятёрочка","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Радеж":{"tags":{"name":"Радеж","shop":"supermarket"},"name":"Радеж","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Рукавичка":{"tags":{"name":"Рукавичка","shop":"supermarket"},"name":"Рукавичка","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Светофор":{"tags":{"name":"Светофор","shop":"supermarket"},"name":"Светофор","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Седьмой континент":{"tags":{"name":"Седьмой континент","shop":"supermarket"},"name":"Седьмой континент","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Семейный":{"tags":{"name":"Семейный","shop":"supermarket"},"name":"Семейный","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Семья":{"tags":{"name":"Семья","shop":"supermarket"},"name":"Семья","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Супермаркет":{"tags":{"name":"Супермаркет","shop":"supermarket"},"name":"Супермаркет","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Сільпо":{"tags":{"name":"Сільпо","shop":"supermarket"},"name":"Сільпо","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Таврія‑В":{"tags":{"name":"Таврія‑В","shop":"supermarket"},"name":"Таврія‑В","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Фора":{"tags":{"name":"Фора","shop":"supermarket"},"name":"Фора","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Фуршет":{"tags":{"name":"Фуршет","shop":"supermarket"},"name":"Фуршет","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Хүнсний дэлгүүр":{"tags":{"name":"Хүнсний дэлгүүр","shop":"supermarket"},"name":"Хүнсний дэлгүүр","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/Эдельвейс":{"tags":{"name":"Эдельвейс","shop":"supermarket"},"name":"Эдельвейс","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/хүнсний дэлгүүр":{"tags":{"name":"хүнсний дэлгүүр","shop":"supermarket"},"name":"хүнсний дэлгүүр","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/بقالة":{"tags":{"name":"بقالة","shop":"supermarket"},"name":"بقالة","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/سوپر مارکت":{"tags":{"name":"سوپر مارکت","shop":"supermarket"},"name":"سوپر مارکت","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/سوپرمارکت":{"tags":{"name":"سوپرمارکت","shop":"supermarket"},"name":"سوپرمارکت","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/いなげや":{"tags":{"name":"いなげや","shop":"supermarket"},"name":"いなげや","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/まいばすけっと":{"tags":{"name":"まいばすけっと","shop":"supermarket"},"name":"まいばすけっと","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/イオン":{"tags":{"name":"イオン","shop":"supermarket"},"name":"イオン","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/イトーヨーカドー":{"tags":{"name":"イトーヨーカドー","shop":"supermarket"},"name":"イトーヨーカドー","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/カスミ":{"tags":{"name":"カスミ","shop":"supermarket"},"name":"カスミ","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/マックスバリュ":{"tags":{"name":"マックスバリュ","shop":"supermarket"},"name":"マックスバリュ","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/マルエツ":{"tags":{"name":"マルエツ","shop":"supermarket"},"name":"マルエツ","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/ライフ":{"tags":{"name":"ライフ","shop":"supermarket"},"name":"ライフ","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/全聯":{"tags":{"name":"全聯","shop":"supermarket"},"name":"全聯","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/全聯福利中心":{"tags":{"name":"全聯福利中心","shop":"supermarket"},"name":"全聯福利中心","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/惠康 Wellcome":{"tags":{"name":"惠康 Wellcome","shop":"supermarket"},"name":"惠康 Wellcome","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/業務スーパー":{"tags":{"name":"業務スーパー","shop":"supermarket"},"name":"業務スーパー","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/美廉社":{"tags":{"name":"美廉社","shop":"supermarket"},"name":"美廉社","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/supermarket/西友":{"tags":{"name":"西友","shop":"supermarket"},"name":"西友","icon":"grocery","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/tailor/Atelier de couture":{"tags":{"name":"Atelier de couture","shop":"tailor"},"name":"Atelier de couture","icon":"clothing-store","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/ticket/Boutique Grandes Lignes":{"tags":{"name":"Boutique Grandes Lignes","shop":"ticket"},"name":"Boutique Grandes Lignes","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/ticket/Guichet Transilien":{"tags":{"name":"Guichet Transilien","shop":"ticket"},"name":"Guichet Transilien","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/ticket/Касса":{"tags":{"name":"Касса","shop":"ticket"},"name":"Касса","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/ticket/Проездные билеты":{"tags":{"name":"Проездные билеты","shop":"ticket"},"name":"Проездные билеты","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/tobacco/Dohánybolt":{"tags":{"name":"Dohánybolt","shop":"tobacco"},"name":"Dohánybolt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/tobacco/Estanco":{"tags":{"name":"Estanco","shop":"tobacco"},"name":"Estanco","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/tobacco/Nemzeti Dohánybolt":{"tags":{"name":"Nemzeti Dohánybolt","shop":"tobacco"},"name":"Nemzeti Dohánybolt","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/tobacco/Tabacos":{"tags":{"name":"Tabacos","shop":"tobacco"},"name":"Tabacos","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/tobacco/Табакерка":{"tags":{"name":"Табакерка","shop":"tobacco"},"name":"Табакерка","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/toys/Dráčik":{"tags":{"name":"Dráčik","shop":"toys"},"name":"Dráčik","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/toys/Intertoys":{"tags":{"name":"Intertoys","shop":"toys"},"name":"Intertoys","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/toys/King Jouet":{"tags":{"name":"King Jouet","shop":"toys"},"name":"King Jouet","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"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":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/toys/Maxi Toys":{"tags":{"name":"Maxi Toys","shop":"toys"},"name":"Maxi Toys","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/toys/Toys R Us":{"tags":{"name":"Toys R Us","shop":"toys"},"name":"Toys R Us","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/toys/Детский мир":{"tags":{"name":"Детский мир","shop":"toys"},"name":"Детский мир","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/toys/Игрушки":{"tags":{"name":"Игрушки","shop":"toys"},"name":"Игрушки","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/travel_agency/D-reizen":{"tags":{"name":"D-reizen","shop":"travel_agency"},"name":"D-reizen","icon":"suitcase","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/travel_agency/DER Reisebüro":{"tags":{"name":"DER Reisebüro","shop":"travel_agency"},"name":"DER Reisebüro","icon":"suitcase","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/travel_agency/First Reisebüro":{"tags":{"name":"First Reisebüro","shop":"travel_agency"},"name":"First Reisebüro","icon":"suitcase","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/travel_agency/Flight Centre":{"tags":{"name":"Flight Centre","shop":"travel_agency"},"name":"Flight Centre","icon":"suitcase","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/travel_agency/Reiseland":{"tags":{"name":"Reiseland","shop":"travel_agency"},"name":"Reiseland","icon":"suitcase","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/travel_agency/TUI":{"tags":{"name":"TUI","shop":"travel_agency"},"name":"TUI","icon":"suitcase","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/travel_agency/The Co-operative Travel":{"tags":{"name":"The Co-operative Travel","shop":"travel_agency"},"name":"The Co-operative Travel","icon":"suitcase","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/travel_agency/Thomas Cook":{"tags":{"name":"Thomas Cook","shop":"travel_agency"},"name":"Thomas Cook","icon":"suitcase","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/travel_agency/Thomson":{"tags":{"name":"Thomson","shop":"travel_agency"},"name":"Thomson","icon":"suitcase","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/tyres/Borracharia":{"tags":{"name":"Borracharia","shop":"tyres"},"name":"Borracharia","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/tyres/Bridgestone":{"tags":{"name":"Bridgestone","shop":"tyres"},"name":"Bridgestone","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/tyres/Discount Tire":{"tags":{"name":"Discount Tire","shop":"tyres"},"name":"Discount Tire","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/tyres/Les Schwab Tire Center":{"tags":{"name":"Les Schwab Tire Center","shop":"tyres"},"name":"Les Schwab Tire Center","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/tyres/Vianor":{"tags":{"name":"Vianor","shop":"tyres"},"name":"Vianor","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/tyres/Вулканизация":{"tags":{"name":"Вулканизация","shop":"tyres"},"name":"Вулканизация","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/variety_store/Action":{"tags":{"name":"Action","shop":"variety_store"},"name":"Action","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/variety_store/Bazar":{"tags":{"name":"Bazar","shop":"variety_store"},"name":"Bazar","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/variety_store/Big Bazar":{"tags":{"name":"Big Bazar","shop":"variety_store"},"name":"Big Bazar","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/variety_store/Dollar Tree":{"tags":{"name":"Dollar Tree","shop":"variety_store"},"name":"Dollar Tree","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/variety_store/Dollarama":{"tags":{"name":"Dollarama","shop":"variety_store"},"name":"Dollarama","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/variety_store/EuroShop":{"tags":{"name":"EuroShop","shop":"variety_store"},"name":"EuroShop","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/variety_store/Family Dollar":{"tags":{"name":"Family Dollar","shop":"variety_store"},"name":"Family Dollar","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/variety_store/Fix Price":{"tags":{"name":"Fix Price","shop":"variety_store"},"name":"Fix Price","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/variety_store/Fix price":{"tags":{"name":"Fix price","shop":"variety_store"},"name":"Fix price","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/variety_store/FixPrice":{"tags":{"name":"FixPrice","shop":"variety_store"},"name":"FixPrice","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/variety_store/GiFi":{"tags":{"name":"GiFi","shop":"variety_store"},"name":"GiFi","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/variety_store/Home Bargains":{"tags":{"name":"Home Bargains","shop":"variety_store"},"name":"Home Bargains","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/variety_store/Mäc-Geiz":{"tags":{"name":"Mäc-Geiz","shop":"variety_store"},"name":"Mäc-Geiz","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/variety_store/NOZ":{"tags":{"name":"NOZ","shop":"variety_store"},"name":"NOZ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/variety_store/Poundland":{"tags":{"name":"Poundland","shop":"variety_store"},"name":"Poundland","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/variety_store/Poundworld":{"tags":{"name":"Poundworld","shop":"variety_store"},"name":"Poundworld","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/variety_store/Tedi":{"tags":{"name":"Tedi","shop":"variety_store"},"name":"Tedi","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/variety_store/ダイソー":{"tags":{"name":"ダイソー","shop":"variety_store"},"name":"ダイソー","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/video/Blockbuster":{"tags":{"name":"Blockbuster","shop":"video"},"name":"Blockbuster","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/video/Family Video":{"tags":{"name":"Family Video","shop":"video"},"name":"Family Video","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/video/TSUTAYA":{"tags":{"name":"TSUTAYA","shop":"video"},"name":"TSUTAYA","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/video/World of Video":{"tags":{"name":"World of Video","shop":"video"},"name":"World of Video","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/video/ゲオ":{"tags":{"name":"ゲオ","shop":"video"},"name":"ゲオ","icon":"shop","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/video_games/EB Games":{"tags":{"name":"EB Games","shop":"video_games"},"name":"EB Games","icon":"gaming","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/video_games/Game":{"tags":{"name":"Game","shop":"video_games"},"name":"Game","icon":"gaming","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/video_games/GameStop":{"tags":{"name":"GameStop","shop":"video_games"},"name":"GameStop","icon":"gaming","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"shop/video_games/Micromania":{"tags":{"name":"Micromania","shop":"video_games"},"name":"Micromania","icon":"gaming","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","payment_multi"],"suggestion":true},"tourism/alpine_hut/КОШ":{"tags":{"name":"КОШ","tourism":"alpine_hut"},"name":"КОШ","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/apartment/Двухкомнатная квартира на сутки":{"tags":{"name":"Двухкомнатная квартира на сутки","tourism":"apartment"},"name":"Двухкомнатная квартира на сутки","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/attraction/Arch":{"tags":{"name":"Arch","tourism":"attraction"},"name":"Arch","icon":"star","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Kursächsische Postmeilensäule":{"tags":{"name":"Kursächsische Postmeilensäule","tourism":"attraction"},"name":"Kursächsische Postmeilensäule","icon":"star","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Maibaum":{"tags":{"name":"Maibaum","tourism":"attraction"},"name":"Maibaum","icon":"star","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Moab trail":{"tags":{"name":"Moab trail","tourism":"attraction"},"name":"Moab trail","icon":"star","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Moai":{"tags":{"name":"Moai","tourism":"attraction"},"name":"Moai","icon":"star","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/OWŚ":{"tags":{"name":"OWŚ","tourism":"attraction"},"name":"OWŚ","icon":"star","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Sommerrodelbahn":{"tags":{"name":"Sommerrodelbahn","tourism":"attraction"},"name":"Sommerrodelbahn","icon":"star","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/path contiunes":{"tags":{"name":"path contiunes","tourism":"attraction"},"name":"path contiunes","icon":"star","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/white blaze":{"tags":{"name":"white blaze","tourism":"attraction"},"name":"white blaze","icon":"star","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Кладбище еврейское":{"tags":{"name":"Кладбище еврейское","tourism":"attraction"},"name":"Кладбище еврейское","icon":"star","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Колесо обозрения":{"tags":{"name":"Колесо обозрения","tourism":"attraction"},"name":"Колесо обозрения","icon":"star","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Приусадебный парк":{"tags":{"name":"Приусадебный парк","tourism":"attraction"},"name":"Приусадебный парк","icon":"star","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Усадьба":{"tags":{"name":"Усадьба","tourism":"attraction"},"name":"Усадьба","icon":"star","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Хозяйственный двор":{"tags":{"name":"Хозяйственный двор","tourism":"attraction"},"name":"Хозяйственный двор","icon":"star","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/Часовня":{"tags":{"name":"Часовня","tourism":"attraction"},"name":"Часовня","icon":"star","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/attraction/дольмен":{"tags":{"name":"дольмен","tourism":"attraction"},"name":"дольмен","icon":"star","geometry":["point","vertex","area"],"fields":["name","operator","address"],"suggestion":true},"tourism/camp_site/Camping Municipal":{"tags":{"name":"Camping Municipal","tourism":"camp_site"},"name":"Camping Municipal","icon":"campsite","geometry":["point","vertex","area"],"fields":["name","operator","address","capacity","fee","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/camp_site/Camping municipal":{"tags":{"name":"Camping municipal","tourism":"camp_site"},"name":"Camping municipal","icon":"campsite","geometry":["point","vertex","area"],"fields":["name","operator","address","capacity","fee","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/guest_house/Home":{"tags":{"name":"Home","tourism":"guest_house"},"name":"Home","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/guest_house/OW Bielanka":{"tags":{"name":"OW Bielanka","tourism":"guest_house"},"name":"OW Bielanka","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hostel/Albergue de Peregrinos":{"tags":{"name":"Albergue de Peregrinos","tourism":"hostel"},"name":"Albergue de Peregrinos","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hostel/Hospedaje":{"tags":{"name":"Hospedaje","tourism":"hostel"},"name":"Hospedaje","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hostel/Hostal":{"tags":{"name":"Hostal","tourism":"hostel"},"name":"Hostal","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/B&B Hôtel":{"tags":{"name":"B&B Hôtel","tourism":"hotel"},"name":"B&B Hôtel","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/B&b Hôtel":{"tags":{"name":"B&b Hôtel","tourism":"hotel"},"name":"B&b Hôtel","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Best Western":{"tags":{"name":"Best Western","tourism":"hotel"},"name":"Best Western","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Campanile":{"tags":{"name":"Campanile","tourism":"hotel"},"name":"Campanile","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Central Hotel":{"tags":{"name":"Central Hotel","tourism":"hotel"},"name":"Central Hotel","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/City Hotel":{"tags":{"name":"City Hotel","tourism":"hotel"},"name":"City Hotel","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Comfort Inn":{"tags":{"name":"Comfort Inn","tourism":"hotel"},"name":"Comfort Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Comfort Inn & Suites":{"tags":{"name":"Comfort Inn & Suites","tourism":"hotel"},"name":"Comfort Inn & Suites","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Comfort Suites":{"tags":{"name":"Comfort Suites","tourism":"hotel"},"name":"Comfort Suites","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Country Inn & Suites":{"tags":{"name":"Country Inn & Suites","tourism":"hotel"},"name":"Country Inn & Suites","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Courtyard by Marriott":{"tags":{"name":"Courtyard by Marriott","tourism":"hotel"},"name":"Courtyard by Marriott","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Crowne Plaza":{"tags":{"name":"Crowne Plaza","tourism":"hotel"},"name":"Crowne Plaza","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Days Inn":{"tags":{"name":"Days Inn","tourism":"hotel"},"name":"Days Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Embassy Suites":{"tags":{"name":"Embassy Suites","tourism":"hotel"},"name":"Embassy Suites","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Extended Stay America":{"tags":{"name":"Extended Stay America","tourism":"hotel"},"name":"Extended Stay America","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Fairfield Inn":{"tags":{"name":"Fairfield Inn","tourism":"hotel"},"name":"Fairfield Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Fairfield Inn & Suites":{"tags":{"name":"Fairfield Inn & Suites","tourism":"hotel"},"name":"Fairfield Inn & Suites","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Formule 1":{"tags":{"name":"Formule 1","tourism":"hotel"},"name":"Formule 1","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Grand Hotel":{"tags":{"name":"Grand Hotel","tourism":"hotel"},"name":"Grand Hotel","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hampton Inn":{"tags":{"name":"Hampton Inn","tourism":"hotel"},"name":"Hampton Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hampton Inn & Suites":{"tags":{"name":"Hampton Inn & Suites","tourism":"hotel"},"name":"Hampton Inn & Suites","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hilton Garden Inn":{"tags":{"name":"Hilton Garden Inn","tourism":"hotel"},"name":"Hilton Garden Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Holiday Inn":{"tags":{"name":"Holiday Inn","tourism":"hotel"},"name":"Holiday Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Holiday Inn Express":{"tags":{"name":"Holiday Inn Express","tourism":"hotel"},"name":"Holiday Inn Express","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Holiday Inn Express & Suites":{"tags":{"name":"Holiday Inn Express & Suites","tourism":"hotel"},"name":"Holiday Inn Express & Suites","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Homewood Suites":{"tags":{"name":"Homewood Suites","tourism":"hotel"},"name":"Homewood Suites","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hotel Central":{"tags":{"name":"Hotel Central","tourism":"hotel"},"name":"Hotel Central","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hotel Europa":{"tags":{"name":"Hotel Europa","tourism":"hotel"},"name":"Hotel Europa","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hotel Ibis":{"tags":{"name":"Hotel Ibis","tourism":"hotel"},"name":"Hotel Ibis","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hotel Krone":{"tags":{"name":"Hotel Krone","tourism":"hotel"},"name":"Hotel Krone","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hotel Panorama":{"tags":{"name":"Hotel Panorama","tourism":"hotel"},"name":"Hotel Panorama","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hotel Plaza":{"tags":{"name":"Hotel Plaza","tourism":"hotel"},"name":"Hotel Plaza","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hotel Post":{"tags":{"name":"Hotel Post","tourism":"hotel"},"name":"Hotel Post","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hotel Royal":{"tags":{"name":"Hotel Royal","tourism":"hotel"},"name":"Hotel Royal","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hotel Victoria":{"tags":{"name":"Hotel Victoria","tourism":"hotel"},"name":"Hotel Victoria","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hotel zur Post":{"tags":{"name":"Hotel zur Post","tourism":"hotel"},"name":"Hotel zur Post","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hôtel Ibis":{"tags":{"name":"Hôtel Ibis","tourism":"hotel"},"name":"Hôtel Ibis","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Hôtel de France":{"tags":{"name":"Hôtel de France","tourism":"hotel"},"name":"Hôtel de France","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Ibis":{"tags":{"name":"Ibis","tourism":"hotel"},"name":"Ibis","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Ibis Budget":{"tags":{"name":"Ibis Budget","tourism":"hotel"},"name":"Ibis Budget","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Ibis Styles":{"tags":{"name":"Ibis Styles","tourism":"hotel"},"name":"Ibis Styles","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Kyriad":{"tags":{"name":"Kyriad","tourism":"hotel"},"name":"Kyriad","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/La Quinta":{"tags":{"name":"La Quinta","tourism":"hotel"},"name":"La Quinta","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Marriott":{"tags":{"name":"Marriott","tourism":"hotel"},"name":"Marriott","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Mercure":{"tags":{"name":"Mercure","tourism":"hotel"},"name":"Mercure","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Novotel":{"tags":{"name":"Novotel","tourism":"hotel"},"name":"Novotel","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Palace Hotel":{"tags":{"name":"Palace Hotel","tourism":"hotel"},"name":"Palace Hotel","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Park Hotel":{"tags":{"name":"Park Hotel","tourism":"hotel"},"name":"Park Hotel","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Parkhotel":{"tags":{"name":"Parkhotel","tourism":"hotel"},"name":"Parkhotel","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Premier Inn":{"tags":{"name":"Premier Inn","tourism":"hotel"},"name":"Premier Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Première Classe":{"tags":{"name":"Première Classe","tourism":"hotel"},"name":"Première Classe","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Quality Inn":{"tags":{"name":"Quality Inn","tourism":"hotel"},"name":"Quality Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Quality Inn & Suites":{"tags":{"name":"Quality Inn & Suites","tourism":"hotel"},"name":"Quality Inn & Suites","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Ramada":{"tags":{"name":"Ramada","tourism":"hotel"},"name":"Ramada","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Residence Inn":{"tags":{"name":"Residence Inn","tourism":"hotel"},"name":"Residence Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Royal Hotel":{"tags":{"name":"Royal Hotel","tourism":"hotel"},"name":"Royal Hotel","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Sheraton":{"tags":{"name":"Sheraton","tourism":"hotel"},"name":"Sheraton","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Sleep Inn":{"tags":{"name":"Sleep Inn","tourism":"hotel"},"name":"Sleep Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Staybridge Suites":{"tags":{"name":"Staybridge Suites","tourism":"hotel"},"name":"Staybridge Suites","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Super 8":{"tags":{"name":"Super 8","tourism":"hotel"},"name":"Super 8","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Travelodge":{"tags":{"name":"Travelodge","tourism":"hotel"},"name":"Travelodge","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/Гостиница":{"tags":{"name":"Гостиница","tourism":"hotel"},"name":"Гостиница","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/hotel/東横イン":{"tags":{"name":"東横イン","tourism":"hotel"},"name":"東横イン","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/motel/Budget Inn":{"tags":{"name":"Budget Inn","tourism":"motel"},"name":"Budget Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/motel/Econo Lodge":{"tags":{"name":"Econo Lodge","tourism":"motel"},"name":"Econo Lodge","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/motel/Motel 6":{"tags":{"name":"Motel 6","tourism":"motel"},"name":"Motel 6","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/motel/Rodeway Inn":{"tags":{"name":"Rodeway Inn","tourism":"motel"},"name":"Rodeway Inn","icon":"lodging","geometry":["point","area"],"fields":["name","operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"tourism/museum/Heimatmuseum":{"tags":{"name":"Heimatmuseum","tourism":"museum"},"name":"Heimatmuseum","icon":"museum","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"tourism/museum/Stadtmuseum":{"tags":{"name":"Stadtmuseum","tourism":"museum"},"name":"Stadtmuseum","icon":"museum","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"tourism/museum/Tájház":{"tags":{"name":"Tájház","tourism":"museum"},"name":"Tájház","icon":"museum","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"tourism/museum/Краеведческий музей":{"tags":{"name":"Краеведческий музей","tourism":"museum"},"name":"Краеведческий музей","icon":"museum","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true},"tourism/museum/Музей":{"tags":{"name":"Музей","tourism":"museum"},"name":"Музей","icon":"museum","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours"],"suggestion":true}};
23673
23674 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","highway/turning_loop","traffic_calming","highway/mini_roundabout","highway/motorway_junction","vertex"],"relation":["category-route","category-restriction","public_transport/stop_area","type/boundary","type/waterway","type/multipolygon","type/site","relation"]};
23675
23676 var categories = {"category-barrier":{"icon":"roadblock","geometry":"line","name":"Barrier Features","members":["barrier/fence","barrier/wall","barrier/ditch","barrier/gate","barrier/hedge","barrier/kerb","barrier"]},"category-building":{"icon":"building","geometry":"area","name":"Building Features","members":["building","building/house","building/apartments","building/retail","building/commercial","building/industrial","building/residential"]},"category-golf":{"icon":"golf","geometry":"area","name":"Golf Features","members":["golf/fairway","golf/green","golf/lateral_water_hazard_area","golf/rough","golf/bunker","golf/tee","golf/water_hazard_area"]},"category-landuse":{"icon":"landuse","geometry":"area","name":"Land Use Features","members":["landuse/residential","landuse/industrial","landuse/commercial","landuse/retail","landuse/farmland","landuse/farmyard","landuse/forest","landuse/meadow","landuse/aquaculture","landuse/cemetery","landuse/military","landuse/religious"]},"category-natural-area":{"icon":"natural","geometry":"area","name":"Natural Features","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":{"icon":"natural","geometry":"line","name":"Natural Features","members":["natural/coastline","natural/tree_row"]},"category-natural-point":{"icon":"natural","geometry":"point","name":"Natural Features","members":["natural/peak","natural/cliff","natural/beach","natural/cave_entrance"]},"category-path":{"icon":"category-path","geometry":"line","name":"Path Features","members":["footway/crosswalk","footway/sidewalk","highway/steps","highway/path","highway/footway","highway/cycleway","highway/bridleway","highway/pedestrian_line"]},"category-rail":{"icon":"category-rail","geometry":"line","name":"Rail Features","members":["railway/rail","railway/subway","railway/tram","railway/monorail","railway/disused","railway/abandoned"]},"category-restriction":{"icon":"restriction","geometry":"relation","name":"Restriction Features","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":{"icon":"category-roads","geometry":"line","name":"Road Features","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":{"icon":"route","geometry":"relation","name":"Route Features","members":["type/route/road","type/route/bicycle","type/route/foot","type/route/hiking","type/route/horse","type/route/piste","type/route/bus","type/route/train","type/route/light_rail","type/route/tram","type/route/subway","type/route/ferry","type/route/power","type/route/pipeline","type/route/detour","type/route_master","type/route"]},"category-water-area":{"icon":"water","geometry":"area","name":"Water Features","members":["natural/water/lake","natural/water/pond","natural/water/reservoir","natural/water"]},"category-water-line":{"icon":"category-water","geometry":"line","name":"Water Features","members":["waterway/river","waterway/stream","waterway/canal","waterway/ditch","waterway/drain"]}};
23677
23678 var fields = {"access_simple":{"key":"access","type":"combo","label":"Allowed Access","options":["yes","permissive","private","customers","no"]},"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","addr:unit"],"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","unit":"Unit"}}},"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"},"agrarian":{"key":"agrarian","type":"semiCombo","label":"Products"},"amenity":{"key":"amenity","type":"typeCombo","label":"Type"},"animal_boarding":{"key":"animal_boarding","type":"semiCombo","label":"For Animals"},"animal_breeding":{"key":"animal_breeding","type":"semiCombo","label":"For Animals"},"animal_shelter":{"key":"animal_shelter","type":"semiCombo","label":"For Animals"},"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"},"boules":{"key":"boules","type":"typeCombo","label":"Type"},"boundary":{"key":"boundary","type":"combo","label":"Type"},"brand":{"key":"brand","type":"text","label":"Brand"},"brewery":{"key":"brewery","type":"semiCombo","label":"Draft Beers"},"bridge":{"key":"bridge","type":"typeCombo","label":"Type","placeholder":"Default"},"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"},"cables":{"key":"cables","type":"number","label":"Cables","placeholder":"1, 2, 3..."},"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..."},"castle_type":{"key":"castle_type","type":"combo","label":"Type"},"clothes":{"key":"clothes","type":"semiCombo","label":"Clothes"},"club":{"key":"club","type":"typeCombo","label":"Type"},"collection_times":{"key":"collection_times","type":"text","label":"Collection Times"},"comment":{"key":"comment","type":"textarea","label":"Changeset Comment","placeholder":"Brief description of your contributions (required)"},"communication_multi":{"key":"communication:","type":"multiCombo","label":"Communication Types"},"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":"Content"},"country":{"key":"country","type":"combo","label":"Country"},"covered":{"key":"covered","type":"check","label":"Covered"},"craft":{"key":"craft","type":"typeCombo","label":"Type"},"crane/type":{"key":"crane:type","type":"combo","label":"Crane Type","strings":{"options":{"portal_crane":"Portal Crane","floor-mounted_crane":"Floor-mounted Crane","travel_lift":"Travel Lift"}}},"crop":{"key":"crop","type":"semiCombo","label":"Crops"},"crossing":{"key":"crossing","type":"combo","label":"Type"},"cuisine":{"key":"cuisine","type":"semiCombo","label":"Cuisines"},"currency_multi":{"key":"currency:","type":"multiCombo","label":"Currency Types"},"cutting":{"key":"cutting","type":"typeCombo","label":"Type","placeholder":"Default"},"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},"devices":{"key":"devices","type":"number","label":"Devices","placeholder":"1, 2, 3..."},"diaper":{"key":"diaper","type":"combo","label":"Diaper Changing Available","options":["yes","no","room","1","2","3","4","5"]},"direction_cardinal":{"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"}}},"direction_clock":{"key":"direction","type":"combo","label":"Direction","strings":{"options":{"clockwise":"Clockwise","anticlockwise":"Counterclockwise"}}},"direction_vertex":{"key":"direction","type":"combo","label":"Direction","strings":{"options":{"forward":"Forward","backward":"Backward","both":"Both / All"}}},"direction":{"key":"direction","type":"number","label":"Direction (Degrees Clockwise)","placeholder":"45, 90, 180, 270"},"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"},"duration":{"key":"duration","type":"text","label":"Duration","placeholder":"00:00"},"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"},"embankment":{"key":"embankment","type":"typeCombo","label":"Type","placeholder":"Default"},"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"}}},"fitness_station":{"key":"fitness_station","type":"typeCombo","label":"Equipment Type"},"fixme":{"key":"fixme","type":"textarea","label":"Fix Me","universal":true},"ford":{"key":"ford","type":"typeCombo","label":"Type","placeholder":"Default"},"frequency":{"key":"frequency","type":"combo","label":"Operating Frequency"},"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/output/electricity":{"key":"generator:output:electricity","type":"text","label":"Power Output","placeholder":"50 MW, 100 MW, 200 MW..."},"generator/source":{"key":"generator:source","type":"combo","label":"Source"},"generator/type":{"key":"generator:type","type":"combo","label":"Type"},"government":{"key":"government","type":"typeCombo","label":"Type"},"grape_variety":{"key":"grape_variety","type":"semiCombo","label":"Grape Varieties"},"handicap":{"key":"handicap","type":"number","label":"Handicap","placeholder":"1-18"},"handrail":{"key":"handrail","type":"check","label":"Handrail"},"hashtags":{"key":"hashtags","type":"semiCombo","label":"Suggested Hashtags","placeholder":"#example"},"healthcare":{"key":"healthcare","type":"typeCombo","label":"Type"},"healthcare/speciality":{"key":"healthcare:speciality","type":"semiCombo","reference":{"key":"healthcare"},"label":"Specialties"},"height":{"key":"height","type":"number","label":"Height (Meters)"},"highway":{"key":"highway","type":"typeCombo","label":"Type"},"historic":{"key":"historic","type":"typeCombo","label":"Type"},"historic/civilization":{"key":"historic:civilization","type":"combo","label":"Historic Civilization"},"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"},"inscription":{"key":"inscription","type":"textarea","label":"Inscription"},"intermittent":{"key":"intermittent","type":"check","label":"Intermittent"},"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"},"label":{"key":"label","type":"textarea","label":"Label"},"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":"number","label":"Layer","placeholder":"0"},"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"},"manhole":{"key":"manhole","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},"maxweight":{"key":"maxweight","type":"combo","label":"Max Weight","snake_case":false},"memorial":{"key":"memorial","type":"typeCombo","label":"Type"},"monitoring_multi":{"key":"monitoring:","type":"multiCombo","label":"Monitoring"},"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","universal":true,"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":"onewayCheck","label":"One Way","strings":{"options":{"undefined":"Assumed to be Yes","yes":"Yes","no":"No","reversible":"Reversible","alternating":"Alternating"}}},"oneway":{"key":"oneway","type":"onewayCheck","label":"One Way","strings":{"options":{"undefined":"Assumed to be No","yes":"Yes","no":"No","reversible":"Reversible","alternating":"Alternating"}}},"opening_hours":{"key":"opening_hours","type":"combo","label":"Hours","snake_case":false},"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..."},"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","universal":true},"phases":{"key":"phases","type":"number","label":"Phases","placeholder":"1, 2, 3..."},"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"},"plant/output/electricity":{"key":"plant:output:electricity","type":"text","label":"Power Output","placeholder":"500 MW, 1000 MW, 2000 MW..."},"playground/baby":{"key":"baby","type":"check","label":"Baby Seat"},"playground/max_age":{"key":"max_age","type":"number","label":"Maximum Age"},"playground/min_age":{"key":"min_age","type":"number","label":"Minimum Age"},"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":"semiCombo","label":"Produce"},"product":{"key":"product","type":"semiCombo","label":"Products"},"railway":{"key":"railway","type":"typeCombo","label":"Type"},"railway/position":{"key":"railway:position","type":"text","placeholder":"Distance to one decimal (123.4)","label":"Milestone Position"},"railway/signal/direction":{"key":"railway:signal:direction","type":"combo","label":"Direction","strings":{"options":{"forward":"Forward","backward":"Backward","both":"Both / All"}}},"rating":{"key":"rating","type":"combo","label":"Power Rating","snake_case":false},"recycling_accepts":{"key":"recycling:","type":"multiCombo","label":"Accepts"},"ref_aeroway_gate":{"key":"ref","type":"text","label":"Gate Number"},"ref_golf_hole":{"key":"ref","type":"text","label":"Hole Number","placeholder":"1-18"},"ref_highway_junction":{"key":"ref","type":"text","label":"Junction Number"},"ref_platform":{"key":"ref","type":"text","label":"Platform Number"},"ref_road_number":{"key":"ref","type":"text","label":"Road Number"},"ref_route":{"key":"ref","type":"text","label":"Route Number"},"ref_runway":{"key":"ref","type":"text","label":"Runway Number","placeholder":"e.g. 01L/19R"},"ref_stop_position":{"key":"ref","type":"text","label":"Stop Number"},"ref_taxiway":{"key":"ref","type":"text","label":"Taxiway Name","placeholder":"e.g. A5"},"ref":{"key":"ref","type":"text","label":"Reference Code"},"ref/isil":{"key":"ref:isil","type":"text","label":"ISIL Code"},"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_times":{"key":"service_times","type":"text","label":"Service Times"},"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"},"service/vehicle":{"key":"service:vehicle:","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":"semiCombo","icon":"source","universal":true,"label":"Sources","snake_case":false,"caseSensitive":true,"options":["survey","local knowledge","gps","aerial imagery","streetlevel imagery"]},"sport_ice":{"key":"sport","type":"semiCombo","label":"Sports","options":["skating","hockey","multi","curling","ice_stock"]},"sport_racing_motor":{"key":"sport","type":"semiCombo","label":"Sports","options":["motor","karting","motocross"]},"sport_racing_nonmotor":{"key":"sport","type":"semiCombo","label":"Sports","options":["bmx","cycling","dog_racing","horse_racing","running"]},"sport":{"key":"sport","type":"semiCombo","label":"Sports"},"stars":{"key":"stars","type":"number","label":"Stars"},"start_date":{"key":"start_date","type":"text","universal":true,"label":"Start Date"},"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_waterway":{"type":"structureRadio","keys":["tunnel"],"label":"Structure","placeholder":"Unknown","strings":{"options":{"tunnel":"Tunnel"}}},"structure":{"type":"structureRadio","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"},"substance":{"key":"substance","type":"combo","label":"Substance"},"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"},"switch":{"key":"switch","type":"combo","label":"Type","strings":{"options":{"mechanical":"Mechanical","circuit_breaker":"Circuit Breaker","disconnector":"Disconnector","earthing":"Earthing"}}},"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"},"tomb":{"key":"tomb","type":"typeCombo","label":"Type"},"tourism_attraction":{"key":"tourism","default":"attraction","type":"typeCombo","universal":true,"label":"Tourism"},"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"}}},"trade":{"key":"trade","type":"typeCombo","label":"Type"},"traffic_calming":{"key":"traffic_calming","type":"typeCombo","label":"Type"},"traffic_signals":{"key":"traffic_signals","type":"combo","label":"Type","default":"signal"},"traffic_signals/direction":{"key":"traffic_signals:direction","type":"combo","label":"Direction","strings":{"options":{"forward":"Forward","backward":"Backward","both":"Both / All"}}},"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"}}},"transformer":{"key":"transformer","type":"combo","label":"Type","strings":{"options":{"distribution":"Distribution","generator":"Generator","converter":"Converter","traction":"Traction","auto":"Autotransformer","phase_angle_regulator":"Phase Angle Regulator","auxiliary":"Auxiliary","yes":"Unknown"}}},"trees":{"key":"trees","type":"semiCombo","label":"Trees"},"tunnel":{"key":"tunnel","type":"typeCombo","label":"Type","placeholder":"Default"},"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)"}}},"volcano/status":{"key":"volcano:status","type":"combo","label":"Volcano Status","strings":{"options":{"active":"Active","dormant":"Dormant","extinct":"Extinct"}}},"volcano/type":{"key":"volcano:type","type":"combo","label":"Volcano Type","strings":{"options":{"stratovolcano":"Stratovolcano","shield":"Shield","scoria":"Scoria"}}},"voltage":{"key":"voltage","type":"combo","label":"Voltage"},"voltage/primary":{"key":"voltage:primary","type":"combo","label":"Primary Voltage"},"voltage/secondary":{"key":"voltage:secondary","type":"combo","label":"Secondary Voltage"},"voltage/tertiary":{"key":"voltage:tertiary","type":"combo","label":"Tertiary Voltage"},"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"},"windings":{"key":"windings","type":"number","label":"Windings","placeholder":"1, 2, 3..."},"windings/configuration":{"key":"windings:configuration","type":"combo","label":"Windings Configuration","strings":{"options":{"star":"Star / Wye","delta":"Delta","open-delta":"Open Delta","zigzag":"Zig Zag","open":"Open","scott":"Scott","leblanc":"Leblanc"}}}};
23679
23680 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"];
23681 var all$1 = {
23682         all: all
23683 };
23684
23685 var all$2 = Object.freeze({
23686         all: all,
23687         default: all$1
23688 });
23689
23690 var Airport = ["airfield","airport","heliport","rocket"];
23691 var Dining = ["bakery","bar","beer","cafe","fast-food","ice-cream","restaurant"];
23692 var Education = ["college","school"];
23693 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"];
23694 var Health = ["dentist","doctor","hospital","pharmacy"];
23695 var Outdoors = ["campsite","cemetery","dog-park","garden","golf","park","picnic-site","playground","zoo"];
23696 var Transit = ["bus","ferry"];
23697 var streets = {
23698         Airport: Airport,
23699         Dining: Dining,
23700         Education: Education,
23701         General: General,
23702         Health: Health,
23703         Outdoors: Outdoors,
23704         Transit: Transit,
23705         "Mountain peak": ["mountain","volcano"],
23706         "Rail station": ["entrance","rail","rail-light","rail-metro"]
23707 };
23708
23709 var streets$1 = Object.freeze({
23710         Airport: Airport,
23711         Dining: Dining,
23712         Education: Education,
23713         General: General,
23714         Health: Health,
23715         Outdoors: Outdoors,
23716         Transit: Transit,
23717         default: streets
23718 });
23719
23720 var require$$0$1 = ( all$2 && all$1 ) || all$2;
23721
23722 var require$$1$1 = ( streets$1 && streets ) || streets$1;
23723
23724 var maki = {
23725   layouts: {
23726     all: require$$0$1,
23727     streets: require$$1$1
23728   }
23729 };
23730
23731 var dataFeatureIcons = maki.layouts.all.all;
23732
23733 var data = {
23734     imagery: dataImagery,
23735     presets: {
23736         presets: presets,
23737         defaults: defaults,
23738         categories: categories,
23739         fields: fields
23740     }
23741 };
23742
23743 function osmEntity(attrs) {
23744     // For prototypal inheritance.
23745     if (this instanceof osmEntity) return;
23746
23747     // Create the appropriate subtype.
23748     if (attrs && attrs.type) {
23749         return osmEntity[attrs.type].apply(this, arguments);
23750     } else if (attrs && attrs.id) {
23751         return osmEntity[osmEntity.id.type(attrs.id)].apply(this, arguments);
23752     }
23753
23754     // Initialize a generic Entity (used only in tests).
23755     return (new osmEntity()).initialize(arguments);
23756 }
23757
23758
23759 osmEntity.id = function(type) {
23760     return osmEntity.id.fromOSM(type, osmEntity.id.next[type]--);
23761 };
23762
23763
23764 osmEntity.id.next = {
23765     changeset: -1, node: -1, way: -1, relation: -1
23766 };
23767
23768
23769 osmEntity.id.fromOSM = function(type, id) {
23770     return type[0] + id;
23771 };
23772
23773
23774 osmEntity.id.toOSM = function(id) {
23775     return id.slice(1);
23776 };
23777
23778
23779 osmEntity.id.type = function(id) {
23780     return { 'c': 'changeset', 'n': 'node', 'w': 'way', 'r': 'relation' }[id[0]];
23781 };
23782
23783
23784 // A function suitable for use as the second argument to d3.selection#data().
23785 osmEntity.key = function(entity) {
23786     return entity.id + 'v' + (entity.v || 0);
23787 };
23788
23789
23790 osmEntity.prototype = {
23791
23792     tags: {},
23793
23794
23795     initialize: function(sources) {
23796         for (var i = 0; i < sources.length; ++i) {
23797             var source = sources[i];
23798             for (var prop in source) {
23799                 if (Object.prototype.hasOwnProperty.call(source, prop)) {
23800                     if (source[prop] === undefined) {
23801                         delete this[prop];
23802                     } else {
23803                         this[prop] = source[prop];
23804                     }
23805                 }
23806             }
23807         }
23808
23809         if (!this.id && this.type) {
23810             this.id = osmEntity.id(this.type);
23811         }
23812         if (!this.hasOwnProperty('visible')) {
23813             this.visible = true;
23814         }
23815
23816         if (debug) {
23817             Object.freeze(this);
23818             Object.freeze(this.tags);
23819
23820             if (this.loc) Object.freeze(this.loc);
23821             if (this.nodes) Object.freeze(this.nodes);
23822             if (this.members) Object.freeze(this.members);
23823         }
23824
23825         return this;
23826     },
23827
23828
23829     copy: function(resolver, copies) {
23830         if (copies[this.id])
23831             return copies[this.id];
23832
23833         var copy = osmEntity(this, {id: undefined, user: undefined, version: undefined});
23834         copies[this.id] = copy;
23835
23836         return copy;
23837     },
23838
23839
23840     osmId: function() {
23841         return osmEntity.id.toOSM(this.id);
23842     },
23843
23844
23845     isNew: function() {
23846         return this.osmId() < 0;
23847     },
23848
23849
23850     update: function(attrs) {
23851         return osmEntity(this, attrs, {v: 1 + (this.v || 0)});
23852     },
23853
23854
23855     mergeTags: function(tags) {
23856         var merged = clone(this.tags), changed = false;
23857         for (var k in tags) {
23858             var t1 = merged[k],
23859                 t2 = tags[k];
23860             if (!t1) {
23861                 changed = true;
23862                 merged[k] = t2;
23863             } else if (t1 !== t2) {
23864                 changed = true;
23865                 merged[k] = union(t1.split(/;\s*/), t2.split(/;\s*/)).join(';');
23866             }
23867         }
23868         return changed ? this.update({tags: merged}) : this;
23869     },
23870
23871
23872     intersects: function(extent, resolver) {
23873         return this.extent(resolver).intersects(extent);
23874     },
23875
23876
23877     isUsed: function(resolver) {
23878         return without(Object.keys(this.tags), 'area').length > 0 ||
23879             resolver.parentRelations(this).length > 0;
23880     },
23881
23882
23883     hasInterestingTags: function() {
23884         return keys$1(this.tags).some(osmIsInterestingTag);
23885     },
23886
23887
23888     isHighwayIntersection: function() {
23889         return false;
23890     },
23891
23892     isDegenerate: function() {
23893         return true;
23894     },
23895
23896     deprecatedTags: function() {
23897         var tags = toPairs(this.tags);
23898         var deprecated = {};
23899
23900         dataDeprecated.forEach(function(d) {
23901             var match = toPairs(d.old)[0];
23902             tags.forEach(function(t) {
23903                 if (t[0] === match[0] &&
23904                     (t[1] === match[1] || match[1] === '*')) {
23905                     deprecated[t[0]] = t[1];
23906                 }
23907             });
23908         });
23909
23910         return deprecated;
23911     }
23912 };
23913
23914 function geoExtent(min, max) {
23915     if (!(this instanceof geoExtent)) return new geoExtent(min, max);
23916     if (min instanceof geoExtent) {
23917         return min;
23918     } else if (min && min.length === 2 && min[0].length === 2 && min[1].length === 2) {
23919         this[0] = min[0];
23920         this[1] = min[1];
23921     } else {
23922         this[0] = min        || [ Infinity,  Infinity];
23923         this[1] = max || min || [-Infinity, -Infinity];
23924     }
23925 }
23926
23927 geoExtent.prototype = new Array(2);
23928
23929 assignIn(geoExtent.prototype, {
23930
23931     equals: function (obj) {
23932         return this[0][0] === obj[0][0] &&
23933             this[0][1] === obj[0][1] &&
23934             this[1][0] === obj[1][0] &&
23935             this[1][1] === obj[1][1];
23936     },
23937
23938
23939     extend: function(obj) {
23940         if (!(obj instanceof geoExtent)) obj = new geoExtent(obj);
23941         return geoExtent(
23942             [Math.min(obj[0][0], this[0][0]), Math.min(obj[0][1], this[0][1])],
23943             [Math.max(obj[1][0], this[1][0]), Math.max(obj[1][1], this[1][1])]
23944         );
23945     },
23946
23947
23948     _extend: function(extent) {
23949         this[0][0] = Math.min(extent[0][0], this[0][0]);
23950         this[0][1] = Math.min(extent[0][1], this[0][1]);
23951         this[1][0] = Math.max(extent[1][0], this[1][0]);
23952         this[1][1] = Math.max(extent[1][1], this[1][1]);
23953     },
23954
23955
23956     area: function() {
23957         return Math.abs((this[1][0] - this[0][0]) * (this[1][1] - this[0][1]));
23958     },
23959
23960
23961     center: function() {
23962         return [(this[0][0] + this[1][0]) / 2,
23963                 (this[0][1] + this[1][1]) / 2];
23964     },
23965
23966
23967     rectangle: function() {
23968         return [this[0][0], this[0][1], this[1][0], this[1][1]];
23969     },
23970
23971
23972     bbox: function() {
23973         return { minX: this[0][0], minY: this[0][1], maxX: this[1][0], maxY: this[1][1] };
23974     },
23975
23976
23977     polygon: function() {
23978         return [
23979             [this[0][0], this[0][1]],
23980             [this[0][0], this[1][1]],
23981             [this[1][0], this[1][1]],
23982             [this[1][0], this[0][1]],
23983             [this[0][0], this[0][1]]
23984         ];
23985     },
23986
23987
23988     contains: function(obj) {
23989         if (!(obj instanceof geoExtent)) obj = new geoExtent(obj);
23990         return obj[0][0] >= this[0][0] &&
23991                obj[0][1] >= this[0][1] &&
23992                obj[1][0] <= this[1][0] &&
23993                obj[1][1] <= this[1][1];
23994     },
23995
23996
23997     intersects: function(obj) {
23998         if (!(obj instanceof geoExtent)) obj = new geoExtent(obj);
23999         return obj[0][0] <= this[1][0] &&
24000                obj[0][1] <= this[1][1] &&
24001                obj[1][0] >= this[0][0] &&
24002                obj[1][1] >= this[0][1];
24003     },
24004
24005
24006     intersection: function(obj) {
24007         if (!this.intersects(obj)) return new geoExtent();
24008         return new geoExtent(
24009             [Math.max(obj[0][0], this[0][0]), Math.max(obj[0][1], this[0][1])],
24010             [Math.min(obj[1][0], this[1][0]), Math.min(obj[1][1], this[1][1])]
24011         );
24012     },
24013
24014
24015     percentContainedIn: function(obj) {
24016         if (!(obj instanceof geoExtent)) obj = new geoExtent(obj);
24017         var a1 = this.intersection(obj).area(),
24018             a2 = this.area();
24019
24020         if (a1 === Infinity || a2 === Infinity || a1 === 0 || a2 === 0) {
24021             return 0;
24022         } else {
24023             return a1 / a2;
24024         }
24025     },
24026
24027
24028     padByMeters: function(meters) {
24029         var dLat = geoMetersToLat(meters),
24030             dLon = geoMetersToLon(meters, this.center()[1]);
24031         return geoExtent(
24032             [this[0][0] - dLon, this[0][1] - dLat],
24033             [this[1][0] + dLon, this[1][1] + dLat]
24034         );
24035     },
24036
24037
24038     toParam: function() {
24039         return this.rectangle().join(',');
24040     }
24041
24042 });
24043
24044 // constants
24045 var TAU = 2 * Math.PI;
24046 var EQUATORIAL_RADIUS = 6356752.314245179;
24047 var POLAR_RADIUS = 6378137.0;
24048
24049
24050 function geoLatToMeters(dLat) {
24051     return dLat * (TAU * POLAR_RADIUS / 360);
24052 }
24053
24054
24055 function geoLonToMeters(dLon, atLat) {
24056     return Math.abs(atLat) >= 90 ? 0 :
24057         dLon * (TAU * EQUATORIAL_RADIUS / 360) * Math.abs(Math.cos(atLat * (Math.PI / 180)));
24058 }
24059
24060
24061 function geoMetersToLat(m) {
24062     return m / (TAU * POLAR_RADIUS / 360);
24063 }
24064
24065
24066 function geoMetersToLon(m, atLat) {
24067     return Math.abs(atLat) >= 90 ? 0 :
24068         m / (TAU * EQUATORIAL_RADIUS / 360) / Math.abs(Math.cos(atLat * (Math.PI / 180)));
24069 }
24070
24071
24072 function geoMetersToOffset(meters, tileSize) {
24073     tileSize = tileSize || 256;
24074     return [
24075         meters[0] * tileSize / (TAU * EQUATORIAL_RADIUS),
24076         -meters[1] * tileSize / (TAU * POLAR_RADIUS)
24077     ];
24078 }
24079
24080
24081 function geoOffsetToMeters(offset, tileSize) {
24082     tileSize = tileSize || 256;
24083     return [
24084         offset[0] * TAU * EQUATORIAL_RADIUS / tileSize,
24085         -offset[1] * TAU * POLAR_RADIUS / tileSize
24086     ];
24087 }
24088
24089
24090 // Equirectangular approximation of spherical distances on Earth
24091 function geoSphericalDistance(a, b) {
24092     var x = geoLonToMeters(a[0] - b[0], (a[1] + b[1]) / 2);
24093     var y = geoLatToMeters(a[1] - b[1]);
24094     return Math.sqrt((x * x) + (y * y));
24095 }
24096
24097
24098 // scale to zoom
24099 function geoScaleToZoom(k, tileSize) {
24100     tileSize = tileSize || 256;
24101     var log2ts = Math.log(tileSize) * Math.LOG2E;
24102     return Math.log(k * TAU) / Math.LN2 - log2ts;
24103 }
24104
24105
24106 // zoom to scale
24107 function geoZoomToScale(z, tileSize) {
24108     tileSize = tileSize || 256;
24109     return tileSize * Math.pow(2, z) / TAU;
24110 }
24111
24112 /**
24113  * A specialized version of `_.every` for arrays without support for
24114  * iteratee shorthands.
24115  *
24116  * @private
24117  * @param {Array} [array] The array to iterate over.
24118  * @param {Function} predicate The function invoked per iteration.
24119  * @returns {boolean} Returns `true` if all elements pass the predicate check,
24120  *  else `false`.
24121  */
24122 function arrayEvery(array, predicate) {
24123   var index = -1,
24124       length = array == null ? 0 : array.length;
24125
24126   while (++index < length) {
24127     if (!predicate(array[index], index, array)) {
24128       return false;
24129     }
24130   }
24131   return true;
24132 }
24133
24134 /**
24135  * The base implementation of `_.every` without support for iteratee shorthands.
24136  *
24137  * @private
24138  * @param {Array|Object} collection The collection to iterate over.
24139  * @param {Function} predicate The function invoked per iteration.
24140  * @returns {boolean} Returns `true` if all elements pass the predicate check,
24141  *  else `false`
24142  */
24143 function baseEvery(collection, predicate) {
24144   var result = true;
24145   baseEach(collection, function(value, index, collection) {
24146     result = !!predicate(value, index, collection);
24147     return result;
24148   });
24149   return result;
24150 }
24151
24152 /**
24153  * Checks if `predicate` returns truthy for **all** elements of `collection`.
24154  * Iteration is stopped once `predicate` returns falsey. The predicate is
24155  * invoked with three arguments: (value, index|key, collection).
24156  *
24157  * **Note:** This method returns `true` for
24158  * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
24159  * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
24160  * elements of empty collections.
24161  *
24162  * @static
24163  * @memberOf _
24164  * @since 0.1.0
24165  * @category Collection
24166  * @param {Array|Object} collection The collection to iterate over.
24167  * @param {Function} [predicate=_.identity] The function invoked per iteration.
24168  * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
24169  * @returns {boolean} Returns `true` if all elements pass the predicate check,
24170  *  else `false`.
24171  * @example
24172  *
24173  * _.every([true, 1, null, 'yes'], Boolean);
24174  * // => false
24175  *
24176  * var users = [
24177  *   { 'user': 'barney', 'age': 36, 'active': false },
24178  *   { 'user': 'fred',   'age': 40, 'active': false }
24179  * ];
24180  *
24181  * // The `_.matches` iteratee shorthand.
24182  * _.every(users, { 'user': 'barney', 'active': false });
24183  * // => false
24184  *
24185  * // The `_.matchesProperty` iteratee shorthand.
24186  * _.every(users, ['active', false]);
24187  * // => true
24188  *
24189  * // The `_.property` iteratee shorthand.
24190  * _.every(users, 'active');
24191  * // => false
24192  */
24193 function every(collection, predicate, guard) {
24194   var func = isArray(collection) ? arrayEvery : baseEvery;
24195   if (guard && isIterateeCall(collection, predicate, guard)) {
24196     predicate = undefined;
24197   }
24198   return func(collection, baseIteratee(predicate, 3));
24199 }
24200
24201 /**
24202  * The base implementation of `_.some` without support for iteratee shorthands.
24203  *
24204  * @private
24205  * @param {Array|Object} collection The collection to iterate over.
24206  * @param {Function} predicate The function invoked per iteration.
24207  * @returns {boolean} Returns `true` if any element passes the predicate check,
24208  *  else `false`.
24209  */
24210 function baseSome(collection, predicate) {
24211   var result;
24212
24213   baseEach(collection, function(value, index, collection) {
24214     result = predicate(value, index, collection);
24215     return !result;
24216   });
24217   return !!result;
24218 }
24219
24220 /**
24221  * Checks if `predicate` returns truthy for **any** element of `collection`.
24222  * Iteration is stopped once `predicate` returns truthy. The predicate is
24223  * invoked with three arguments: (value, index|key, collection).
24224  *
24225  * @static
24226  * @memberOf _
24227  * @since 0.1.0
24228  * @category Collection
24229  * @param {Array|Object} collection The collection to iterate over.
24230  * @param {Function} [predicate=_.identity] The function invoked per iteration.
24231  * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
24232  * @returns {boolean} Returns `true` if any element passes the predicate check,
24233  *  else `false`.
24234  * @example
24235  *
24236  * _.some([null, 0, 'yes', false], Boolean);
24237  * // => true
24238  *
24239  * var users = [
24240  *   { 'user': 'barney', 'active': true },
24241  *   { 'user': 'fred',   'active': false }
24242  * ];
24243  *
24244  * // The `_.matches` iteratee shorthand.
24245  * _.some(users, { 'user': 'barney', 'active': false });
24246  * // => false
24247  *
24248  * // The `_.matchesProperty` iteratee shorthand.
24249  * _.some(users, ['active', false]);
24250  * // => true
24251  *
24252  * // The `_.property` iteratee shorthand.
24253  * _.some(users, 'active');
24254  * // => true
24255  */
24256 function some(collection, predicate, guard) {
24257   var func = isArray(collection) ? arraySome : baseSome;
24258   if (guard && isIterateeCall(collection, predicate, guard)) {
24259     predicate = undefined;
24260   }
24261   return func(collection, baseIteratee(predicate, 3));
24262 }
24263
24264 // vector equals
24265 function geoVecEqual(a, b, epsilon) {
24266     if (epsilon) {
24267         return (Math.abs(a[0] - b[0]) <= epsilon) && (Math.abs(a[1] - b[1]) <= epsilon);
24268     } else {
24269         return (a[0] === b[0]) && (a[1] === b[1]);
24270     }
24271 }
24272
24273 // vector addition
24274 function geoVecAdd(a, b) {
24275     return [ a[0] + b[0], a[1] + b[1] ];
24276 }
24277
24278 // vector subtraction
24279 function geoVecSubtract(a, b) {
24280     return [ a[0] - b[0], a[1] - b[1] ];
24281 }
24282
24283 // vector scaling
24284 function geoVecScale(a, mag) {
24285     return [ a[0] * mag, a[1] * mag ];
24286 }
24287
24288 // vector rounding (was: geoRoundCoordinates)
24289 function geoVecFloor(a) {
24290     return [ Math.floor(a[0]), Math.floor(a[1]) ];
24291 }
24292
24293 // linear interpolation
24294 function geoVecInterp(a, b, t) {
24295     return [
24296         a[0] + (b[0] - a[0]) * t,
24297         a[1] + (b[1] - a[1]) * t
24298     ];
24299 }
24300
24301 // http://jsperf.com/id-dist-optimization
24302 function geoVecLength(a, b) {
24303     var x = a[0] - b[0];
24304     var y = a[1] - b[1];
24305     return Math.sqrt((x * x) + (y * y));
24306 }
24307
24308 // Return the counterclockwise angle in the range (-pi, pi)
24309 // between the positive X axis and the line intersecting a and b.
24310 function geoVecAngle(a, b) {
24311     return Math.atan2(b[1] - a[1], b[0] - a[0]);
24312 }
24313
24314 // dot product
24315 function geoVecDot(a, b, origin) {
24316     origin = origin || [0, 0];
24317     return (a[0] - origin[0]) * (b[0] - origin[0]) +
24318         (a[1] - origin[1]) * (b[1] - origin[1]);
24319 }
24320
24321 // 2D cross product of OA and OB vectors, returns magnitude of Z vector
24322 // Returns a positive value, if OAB makes a counter-clockwise turn,
24323 // negative for clockwise turn, and zero if the points are collinear.
24324 function geoVecCross(a, b, origin) {
24325     origin = origin || [0, 0];
24326     return (a[0] - origin[0]) * (b[1] - origin[1]) -
24327         (a[1] - origin[1]) * (b[0] - origin[0]);
24328 }
24329
24330 // Return the counterclockwise angle in the range (-pi, pi)
24331 // between the positive X axis and the line intersecting a and b.
24332 function geoAngle(a, b, projection) {
24333     return geoVecAngle(projection(a.loc), projection(b.loc));
24334 }
24335
24336 function geoEdgeEqual(a, b) {
24337     return (a[0] === b[0] && a[1] === b[1]) ||
24338         (a[0] === b[1] && a[1] === b[0]);
24339 }
24340
24341 // Rotate all points counterclockwise around a pivot point by given angle
24342 function geoRotate(points, angle, around) {
24343     return points.map(function(point) {
24344         var radial = geoVecSubtract(point, around);
24345         return [
24346             radial[0] * Math.cos(angle) - radial[1] * Math.sin(angle) + around[0],
24347             radial[0] * Math.sin(angle) + radial[1] * Math.cos(angle) + around[1]
24348         ];
24349     });
24350 }
24351
24352
24353 // Choose the edge with the minimal distance from `point` to its orthogonal
24354 // projection onto that edge, if such a projection exists, or the distance to
24355 // the closest vertex on that edge. Returns an object with the `index` of the
24356 // chosen edge, the chosen `loc` on that edge, and the `distance` to to it.
24357 function geoChooseEdge(nodes, point, projection, activeID) {
24358     var dist = geoVecLength;
24359     var points = nodes.map(function(n) { return projection(n.loc); });
24360     var ids = nodes.map(function(n) { return n.id; });
24361     var min = Infinity;
24362     var idx;
24363     var loc;
24364
24365     for (var i = 0; i < points.length - 1; i++) {
24366         if (ids[i] === activeID || ids[i + 1] === activeID) continue;
24367
24368         var o = points[i];
24369         var s = geoVecSubtract(points[i + 1], o);
24370         var v = geoVecSubtract(point, o);
24371         var proj = geoVecDot(v, s) / geoVecDot(s, s);
24372         var p;
24373
24374         if (proj < 0) {
24375             p = o;
24376         } else if (proj > 1) {
24377             p = points[i + 1];
24378         } else {
24379             p = [o[0] + proj * s[0], o[1] + proj * s[1]];
24380         }
24381
24382         var d = dist(p, point);
24383         if (d < min) {
24384             min = d;
24385             idx = i + 1;
24386             loc = projection.invert(p);
24387         }
24388     }
24389
24390     if (idx !== undefined) {
24391         return { index: idx, distance: min, loc: loc };
24392     } else {
24393         return null;
24394     }
24395 }
24396
24397
24398 // Test active (dragged or drawing) segments against inactive segments
24399 // This is used to test e.g. multipolygon rings that cross
24400 // `activeNodes` is the ring containing the activeID being dragged.
24401 // `inactiveNodes` is the other ring to test against
24402 function geoHasLineIntersections(activeNodes, inactiveNodes, activeID) {
24403     var actives = [];
24404     var inactives = [];
24405     var j, k, n1, n2, segment;
24406
24407     // gather active segments (only segments in activeNodes that contain the activeID)
24408     for (j = 0; j < activeNodes.length - 1; j++) {
24409         n1 = activeNodes[j];
24410         n2 = activeNodes[j+1];
24411         segment = [n1.loc, n2.loc];
24412         if (n1.id === activeID || n2.id === activeID) {
24413             actives.push(segment);
24414         }
24415     }
24416
24417     // gather inactive segments
24418     for (j = 0; j < inactiveNodes.length - 1; j++) {
24419         n1 = inactiveNodes[j];
24420         n2 = inactiveNodes[j+1];
24421         segment = [n1.loc, n2.loc];
24422         inactives.push(segment);
24423     }
24424
24425     // test
24426     for (j = 0; j < actives.length; j++) {
24427         for (k = 0; k < inactives.length; k++) {
24428             var p = actives[j];
24429             var q = inactives[k];
24430             var hit = geoLineIntersection(p, q);
24431             if (hit) {
24432                 return true;
24433             }
24434         }
24435     }
24436
24437     return false;
24438 }
24439
24440
24441 // Test active (dragged or drawing) segments against inactive segments
24442 // This is used to test whether a way intersects with itself.
24443 function geoHasSelfIntersections(nodes, activeID) {
24444     var actives = [];
24445     var inactives = [];
24446     var j, k;
24447
24448     // group active and passive segments along the nodes
24449     for (j = 0; j < nodes.length - 1; j++) {
24450         var n1 = nodes[j];
24451         var n2 = nodes[j+1];
24452         var segment = [n1.loc, n2.loc];
24453         if (n1.id === activeID || n2.id === activeID) {
24454             actives.push(segment);
24455         } else {
24456             inactives.push(segment);
24457         }
24458     }
24459
24460     // test
24461     for (j = 0; j < actives.length; j++) {
24462         for (k = 0; k < inactives.length; k++) {
24463             var p = actives[j];
24464             var q = inactives[k];
24465             // skip if segments share an endpoint
24466             if (geoVecEqual(p[1], q[0]) || geoVecEqual(p[0], q[1]) ||
24467                 geoVecEqual(p[0], q[0]) || geoVecEqual(p[1], q[1]) ) {
24468                 continue;
24469             }
24470
24471             var hit = geoLineIntersection(p, q);
24472             if (hit) {
24473                 var epsilon = 1e-8;
24474                 // skip if the hit is at the segment's endpoint
24475                 if (geoVecEqual(p[1], hit, epsilon) || geoVecEqual(p[0], hit, epsilon) ||
24476                     geoVecEqual(q[1], hit, epsilon) || geoVecEqual(q[0], hit, epsilon) ) {
24477                     continue;
24478                 } else {
24479                     return true;
24480                 }
24481             }
24482         }
24483     }
24484
24485     return false;
24486 }
24487
24488
24489 // Return the intersection point of 2 line segments.
24490 // From https://github.com/pgkelley4/line-segments-intersect
24491 // This uses the vector cross product approach described below:
24492 //  http://stackoverflow.com/a/565282/786339
24493 function geoLineIntersection(a, b) {
24494     var p = [a[0][0], a[0][1]];
24495     var p2 = [a[1][0], a[1][1]];
24496     var q = [b[0][0], b[0][1]];
24497     var q2 = [b[1][0], b[1][1]];
24498     var r = geoVecSubtract(p2, p);
24499     var s = geoVecSubtract(q2, q);
24500     var uNumerator = geoVecCross(geoVecSubtract(q, p), r);
24501     var denominator = geoVecCross(r, s);
24502
24503     if (uNumerator && denominator) {
24504         var u = uNumerator / denominator;
24505         var t = geoVecCross(geoVecSubtract(q, p), s) / denominator;
24506
24507         if ((t >= 0) && (t <= 1) && (u >= 0) && (u <= 1)) {
24508             return geoVecInterp(p, p2, t);
24509         }
24510     }
24511
24512     return null;
24513 }
24514
24515
24516 function geoPathIntersections(path1, path2) {
24517     var intersections = [];
24518     for (var i = 0; i < path1.length - 1; i++) {
24519         for (var j = 0; j < path2.length - 1; j++) {
24520             var a = [ path1[i], path1[i+1] ];
24521             var b = [ path2[j], path2[j+1] ];
24522             var hit = geoLineIntersection(a, b);
24523             if (hit) {
24524                 intersections.push(hit);
24525             }
24526         }
24527     }
24528     return intersections;
24529 }
24530
24531 function geoPathHasIntersections(path1, path2) {
24532     for (var i = 0; i < path1.length - 1; i++) {
24533         for (var j = 0; j < path2.length - 1; j++) {
24534             var a = [ path1[i], path1[i+1] ];
24535             var b = [ path2[j], path2[j+1] ];
24536             var hit = geoLineIntersection(a, b);
24537             if (hit) {
24538                 return true;
24539             }
24540         }
24541     }
24542     return false;
24543 }
24544
24545
24546 // Return whether point is contained in polygon.
24547 //
24548 // `point` should be a 2-item array of coordinates.
24549 // `polygon` should be an array of 2-item arrays of coordinates.
24550 //
24551 // From https://github.com/substack/point-in-polygon.
24552 // ray-casting algorithm based on
24553 // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
24554 //
24555 function geoPointInPolygon(point, polygon) {
24556     var x = point[0];
24557     var y = point[1];
24558     var inside = false;
24559
24560     for (var i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
24561         var xi = polygon[i][0];
24562         var yi = polygon[i][1];
24563         var xj = polygon[j][0];
24564         var yj = polygon[j][1];
24565
24566         var intersect = ((yi > y) !== (yj > y)) &&
24567             (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
24568         if (intersect) inside = !inside;
24569     }
24570
24571     return inside;
24572 }
24573
24574
24575 function geoPolygonContainsPolygon(outer, inner) {
24576     return every(inner, function(point) {
24577         return geoPointInPolygon(point, outer);
24578     });
24579 }
24580
24581
24582 function geoPolygonIntersectsPolygon(outer, inner, checkSegments) {
24583     function testPoints(outer, inner) {
24584         return some(inner, function(point) {
24585             return geoPointInPolygon(point, outer);
24586         });
24587     }
24588
24589    return testPoints(outer, inner) || (!!checkSegments && geoPathHasIntersections(outer, inner));
24590 }
24591
24592
24593 function geoPathLength(path) {
24594     var length = 0;
24595     for (var i = 0; i < path.length - 1; i++) {
24596         length += geoVecLength(path[i], path[i + 1]);
24597     }
24598     return length;
24599 }
24600
24601
24602 // If the given point is at the edge of the padded viewport,
24603 // return a vector that will nudge the viewport in that direction
24604 function geoViewportEdge(point, dimensions) {
24605     var pad = [80, 20, 50, 20];   // top, right, bottom, left
24606     var x = 0;
24607     var y = 0;
24608
24609     if (point[0] > dimensions[0] - pad[1])
24610         x = -10;
24611     if (point[0] < pad[3])
24612         x = 10;
24613     if (point[1] > dimensions[1] - pad[2])
24614         y = -10;
24615     if (point[1] < pad[0])
24616         y = 10;
24617
24618     if (x || y) {
24619         return [x, y];
24620     } else {
24621         return null;
24622     }
24623 }
24624
24625 /*
24626     Bypasses features of D3's default projection stream pipeline that are unnecessary:
24627     * Antimeridian clipping
24628     * Spherical rotation
24629     * Resampling
24630 */
24631 function geoRawMercator() {
24632     var project = mercatorRaw,
24633         k = 512 / Math.PI, // scale
24634         x = 0, y = 0, // translate
24635         clipExtent = [[0, 0], [0, 0]];
24636
24637
24638     function projection(point) {
24639         point = project(point[0] * Math.PI / 180, point[1] * Math.PI / 180);
24640         return [point[0] * k + x, y - point[1] * k];
24641     }
24642
24643
24644     projection.invert = function(point) {
24645         point = project.invert((point[0] - x) / k, (y - point[1]) / k);
24646         return point && [point[0] * 180 / Math.PI, point[1] * 180 / Math.PI];
24647     };
24648
24649
24650     projection.scale = function(_) {
24651         if (!arguments.length) return k;
24652         k = +_;
24653         return projection;
24654     };
24655
24656
24657     projection.translate = function(_) {
24658         if (!arguments.length) return [x, y];
24659         x = +_[0];
24660         y = +_[1];
24661         return projection;
24662     };
24663
24664
24665     projection.clipExtent = function(_) {
24666         if (!arguments.length) return clipExtent;
24667         clipExtent = _;
24668         return projection;
24669     };
24670
24671
24672     projection.transform = function(_) {
24673         if (!arguments.length) return identity$7.translate(x, y).scale(k);
24674         x = +_.x;
24675         y = +_.y;
24676         k = +_.k;
24677         return projection;
24678     };
24679
24680
24681     projection.stream = d3_geoTransform({
24682         point: function(x, y) {
24683             x = projection([x, y]);
24684             this.stream.point(x[0], x[1]);
24685         }
24686     }).stream;
24687
24688
24689     return projection;
24690 }
24691
24692 function osmChangeset() {
24693     if (!(this instanceof osmChangeset)) {
24694         return (new osmChangeset()).initialize(arguments);
24695     } else if (arguments.length) {
24696         this.initialize(arguments);
24697     }
24698 }
24699
24700
24701 osmEntity.changeset = osmChangeset;
24702
24703 osmChangeset.prototype = Object.create(osmEntity.prototype);
24704
24705 assignIn(osmChangeset.prototype, {
24706
24707     type: 'changeset',
24708
24709
24710     extent: function() {
24711         return new geoExtent();
24712     },
24713
24714
24715     geometry: function() {
24716         return 'changeset';
24717     },
24718
24719
24720     asJXON: function() {
24721         return {
24722             osm: {
24723                 changeset: {
24724                     tag: map$4(this.tags, function(value, key) {
24725                         return { '@k': key, '@v': value };
24726                     }),
24727                     '@version': 0.6,
24728                     '@generator': 'iD'
24729                 }
24730             }
24731         };
24732     },
24733
24734
24735     // Generate [osmChange](http://wiki.openstreetmap.org/wiki/OsmChange)
24736     // XML. Returns a string.
24737     osmChangeJXON: function(changes) {
24738         var changeset_id = this.id;
24739
24740         function nest(x, order) {
24741             var groups = {};
24742             for (var i = 0; i < x.length; i++) {
24743                 var tagName = Object.keys(x[i])[0];
24744                 if (!groups[tagName]) groups[tagName] = [];
24745                 groups[tagName].push(x[i][tagName]);
24746             }
24747             var ordered = {};
24748             order.forEach(function(o) {
24749                 if (groups[o]) ordered[o] = groups[o];
24750             });
24751             return ordered;
24752         }
24753
24754
24755         // sort relations in a changeset by dependencies
24756         function sort(changes) {
24757
24758             // find a referenced relation in the current changeset
24759             function resolve(item) {
24760                 return find$1(relations, function(relation) {
24761                     return item.keyAttributes.type === 'relation'
24762                         && item.keyAttributes.ref === relation['@id'];
24763                 });
24764             }
24765
24766             // a new item is an item that has not been already processed
24767             function isNew(item) {
24768                 return !sorted[ item['@id'] ] && !find$1(processing, function(proc) {
24769                     return proc['@id'] === item['@id'];
24770                 });
24771             }
24772
24773             var processing = [],
24774                 sorted = {},
24775                 relations = changes.relation;
24776
24777             if (!relations) return changes;
24778
24779             for (var i = 0; i < relations.length; i++) {
24780                 var relation = relations[i];
24781
24782                 // skip relation if already sorted
24783                 if (!sorted[relation['@id']]) {
24784                     processing.push(relation);
24785                 }
24786
24787                 while (processing.length > 0) {
24788                     var next = processing[0],
24789                     deps = filter(compact(next.member.map(resolve)), isNew);
24790                     if (deps.length === 0) {
24791                         sorted[next['@id']] = next;
24792                         processing.shift();
24793                     } else {
24794                         processing = deps.concat(processing);
24795                     }
24796                 }
24797             }
24798
24799             changes.relation = values$1(sorted);
24800             return changes;
24801         }
24802
24803         function rep(entity) {
24804             return entity.asJXON(changeset_id);
24805         }
24806
24807         return {
24808             osmChange: {
24809                 '@version': 0.6,
24810                 '@generator': 'iD',
24811                 'create': sort(nest(changes.created.map(rep), ['node', 'way', 'relation'])),
24812                 'modify': nest(changes.modified.map(rep), ['node', 'way', 'relation']),
24813                 'delete': assignIn(nest(changes.deleted.map(rep), ['relation', 'way', 'node']), { '@if-unused': true })
24814             }
24815         };
24816     },
24817
24818
24819     asGeoJSON: function() {
24820         return {};
24821     }
24822
24823 });
24824
24825 /**
24826  * Creates a duplicate-free version of an array, using
24827  * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
24828  * for equality comparisons, in which only the first occurrence of each element
24829  * is kept. The order of result values is determined by the order they occur
24830  * in the array.
24831  *
24832  * @static
24833  * @memberOf _
24834  * @since 0.1.0
24835  * @category Array
24836  * @param {Array} array The array to inspect.
24837  * @returns {Array} Returns the new duplicate free array.
24838  * @example
24839  *
24840  * _.uniq([2, 1, 2]);
24841  * // => [2, 1]
24842  */
24843 function uniq(array) {
24844   return (array && array.length) ? baseUniq(array) : [];
24845 }
24846
24847 function osmNode() {
24848     if (!(this instanceof osmNode)) {
24849         return (new osmNode()).initialize(arguments);
24850     } else if (arguments.length) {
24851         this.initialize(arguments);
24852     }
24853 }
24854
24855 osmEntity.node = osmNode;
24856
24857 osmNode.prototype = Object.create(osmEntity.prototype);
24858
24859 assignIn(osmNode.prototype, {
24860
24861     type: 'node',
24862
24863
24864     extent: function() {
24865         return new geoExtent(this.loc);
24866     },
24867
24868
24869     geometry: function(graph) {
24870         return graph.transient(this, 'geometry', function() {
24871             return graph.isPoi(this) ? 'point' : 'vertex';
24872         });
24873     },
24874
24875
24876     move: function(loc) {
24877         return this.update({loc: loc});
24878     },
24879
24880
24881     isDegenerate: function() {
24882         return !(
24883             Array.isArray(this.loc) && this.loc.length === 2 &&
24884             this.loc[0] >= -180 && this.loc[0] <= 180 &&
24885             this.loc[1] >= -90 && this.loc[1] <= 90
24886         );
24887     },
24888
24889
24890     // Inspect tags and geometry to determine which direction(s) this node/vertex points
24891     directions: function(resolver, projection) {
24892         var val;
24893         var i;
24894
24895         // which tag to use?
24896         if (this.isHighwayIntersection(resolver) && (this.tags.stop || '').toLowerCase() === 'all') {
24897             // all-way stop tag on a highway intersection
24898             val = 'all';
24899         } else {
24900             // generic direction tag
24901             val = (this.tags.direction || '').toLowerCase();
24902
24903             // better suffix-style direction tag
24904             var re = /:direction$/i;
24905             var keys = Object.keys(this.tags);
24906             for (i = 0; i < keys.length; i++) {
24907                 if (re.test(keys[i])) {
24908                     val = this.tags[keys[i]].toLowerCase();
24909                     break;
24910                 }
24911             }
24912         }
24913
24914         if (val === '') return [];
24915
24916         var cardinal = {
24917             north: 0,               n: 0,
24918             northnortheast: 22,     nne: 22,
24919             northeast: 45,          ne: 45,
24920             eastnortheast: 67,      ene: 67,
24921             east: 90,               e: 90,
24922             eastsoutheast: 112,     ese: 112,
24923             southeast: 135,         se: 135,
24924             southsoutheast: 157,    sse: 157,
24925             south: 180,             s: 180,
24926             southsouthwest: 202,    ssw: 202,
24927             southwest: 225,         sw: 225,
24928             westsouthwest: 247,     wsw: 247,
24929             west: 270,              w: 270,
24930             westnorthwest: 292,     wnw: 292,
24931             northwest: 315,         nw: 315,
24932             northnorthwest: 337,    nnw: 337
24933         };
24934
24935
24936         var values = val.split(';');
24937         var results = [];
24938
24939         values.forEach(function(v) {
24940             // swap cardinal for numeric directions
24941             if (cardinal[v] !== undefined) {
24942                 v = cardinal[v];
24943             }
24944
24945             // numeric direction - just add to results
24946             if (v !== '' && !isNaN(+v)) {
24947                 results.push(+v);
24948                 return;
24949             }
24950
24951             // string direction - inspect parent ways
24952             var lookBackward =
24953                 (this.tags['traffic_sign:backward'] || v === 'backward' || v === 'both' || v === 'all');
24954             var lookForward =
24955                 (this.tags['traffic_sign:forward'] || v === 'forward' || v === 'both' || v === 'all');
24956
24957             if (!lookForward && !lookBackward) return;
24958
24959             var nodeIds = {};
24960             resolver.parentWays(this).forEach(function(parent) {
24961                 var nodes = parent.nodes;
24962                 for (i = 0; i < nodes.length; i++) {
24963                     if (nodes[i] === this.id) {  // match current entity
24964                         if (lookForward && i > 0) {
24965                             nodeIds[nodes[i - 1]] = true;  // look back to prev node
24966                         }
24967                         if (lookBackward && i < nodes.length - 1) {
24968                             nodeIds[nodes[i + 1]] = true;  // look ahead to next node
24969                         }
24970                     }
24971                 }
24972             }, this);
24973
24974             Object.keys(nodeIds).forEach(function(nodeId) {
24975                 // +90 because geoAngle returns angle from X axis, not Y (north)
24976                 results.push(
24977                     (geoAngle(this, resolver.entity(nodeId), projection) * (180 / Math.PI)) + 90
24978                 );
24979             }, this);
24980
24981         }, this);
24982
24983         return uniq(results);
24984     },
24985
24986
24987     isEndpoint: function(resolver) {
24988         return resolver.transient(this, 'isEndpoint', function() {
24989             var id = this.id;
24990             return resolver.parentWays(this).filter(function(parent) {
24991                 return !parent.isClosed() && !!parent.affix(id);
24992             }).length > 0;
24993         });
24994     },
24995
24996
24997     isConnected: function(resolver) {
24998         return resolver.transient(this, 'isConnected', function() {
24999             var parents = resolver.parentWays(this);
25000
25001             function isLine(entity) {
25002                 return entity.geometry(resolver) === 'line' &&
25003                     entity.hasInterestingTags();
25004             }
25005
25006             // vertex is connected to multiple parent lines
25007             if (parents.length > 1 && some(parents, isLine)) {
25008                 return true;
25009
25010             } else if (parents.length === 1) {
25011                 var way = parents[0],
25012                     nodes = way.nodes.slice();
25013                 if (way.isClosed()) { nodes.pop(); }  // ignore connecting node if closed
25014
25015                 // return true if vertex appears multiple times (way is self intersecting)
25016                 return nodes.indexOf(this.id) !== nodes.lastIndexOf(this.id);
25017             }
25018
25019             return false;
25020         });
25021     },
25022
25023
25024     isIntersection: function(resolver) {
25025         return resolver.transient(this, 'isIntersection', function() {
25026             return resolver.parentWays(this).filter(function(parent) {
25027                 return (parent.tags.highway ||
25028                     parent.tags.waterway ||
25029                     parent.tags.railway ||
25030                     parent.tags.aeroway) &&
25031                     parent.geometry(resolver) === 'line';
25032             }).length > 1;
25033         });
25034     },
25035
25036
25037     isHighwayIntersection: function(resolver) {
25038         return resolver.transient(this, 'isHighwayIntersection', function() {
25039             return resolver.parentWays(this).filter(function(parent) {
25040                 return parent.tags.highway && parent.geometry(resolver) === 'line';
25041             }).length > 1;
25042         });
25043     },
25044
25045
25046     isOnAddressLine: function(resolver) {
25047         return resolver.transient(this, 'isOnAddressLine', function() {
25048             return resolver.parentWays(this).filter(function(parent) {
25049                 return parent.tags.hasOwnProperty('addr:interpolation') &&
25050                     parent.geometry(resolver) === 'line';
25051             }).length > 0;
25052         });
25053     },
25054
25055
25056     asJXON: function(changeset_id) {
25057         var r = {
25058             node: {
25059                 '@id': this.osmId(),
25060                 '@lon': this.loc[0],
25061                 '@lat': this.loc[1],
25062                 '@version': (this.version || 0),
25063                 tag: map$4(this.tags, function(v, k) {
25064                     return { keyAttributes: { k: k, v: v } };
25065                 })
25066             }
25067         };
25068         if (changeset_id) r.node['@changeset'] = changeset_id;
25069         return r;
25070     },
25071
25072
25073     asGeoJSON: function() {
25074         return {
25075             type: 'Point',
25076             coordinates: this.loc
25077         };
25078     }
25079 });
25080
25081 /** Error message constants. */
25082 var FUNC_ERROR_TEXT$1 = 'Expected a function';
25083
25084 /**
25085  * Creates a function that negates the result of the predicate `func`. The
25086  * `func` predicate is invoked with the `this` binding and arguments of the
25087  * created function.
25088  *
25089  * @static
25090  * @memberOf _
25091  * @since 3.0.0
25092  * @category Function
25093  * @param {Function} predicate The predicate to negate.
25094  * @returns {Function} Returns the new negated function.
25095  * @example
25096  *
25097  * function isEven(n) {
25098  *   return n % 2 == 0;
25099  * }
25100  *
25101  * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
25102  * // => [1, 3, 5]
25103  */
25104 function negate(predicate) {
25105   if (typeof predicate != 'function') {
25106     throw new TypeError(FUNC_ERROR_TEXT$1);
25107   }
25108   return function() {
25109     var args = arguments;
25110     switch (args.length) {
25111       case 0: return !predicate.call(this);
25112       case 1: return !predicate.call(this, args[0]);
25113       case 2: return !predicate.call(this, args[0], args[1]);
25114       case 3: return !predicate.call(this, args[0], args[1], args[2]);
25115     }
25116     return !predicate.apply(this, args);
25117   };
25118 }
25119
25120 /**
25121  * The opposite of `_.filter`; this method returns the elements of `collection`
25122  * that `predicate` does **not** return truthy for.
25123  *
25124  * @static
25125  * @memberOf _
25126  * @since 0.1.0
25127  * @category Collection
25128  * @param {Array|Object} collection The collection to iterate over.
25129  * @param {Function} [predicate=_.identity] The function invoked per iteration.
25130  * @returns {Array} Returns the new filtered array.
25131  * @see _.filter
25132  * @example
25133  *
25134  * var users = [
25135  *   { 'user': 'barney', 'age': 36, 'active': false },
25136  *   { 'user': 'fred',   'age': 40, 'active': true }
25137  * ];
25138  *
25139  * _.reject(users, function(o) { return !o.active; });
25140  * // => objects for ['fred']
25141  *
25142  * // The `_.matches` iteratee shorthand.
25143  * _.reject(users, { 'age': 40, 'active': true });
25144  * // => objects for ['barney']
25145  *
25146  * // The `_.matchesProperty` iteratee shorthand.
25147  * _.reject(users, ['active', false]);
25148  * // => objects for ['fred']
25149  *
25150  * // The `_.property` iteratee shorthand.
25151  * _.reject(users, 'active');
25152  * // => objects for ['barney']
25153  */
25154 function reject(collection, predicate) {
25155   var func = isArray(collection) ? arrayFilter : baseFilter;
25156   return func(collection, negate(baseIteratee(predicate, 3)));
25157 }
25158
25159 /**
25160  * An alternative to `_.reduce`; this method transforms `object` to a new
25161  * `accumulator` object which is the result of running each of its own
25162  * enumerable string keyed properties thru `iteratee`, with each invocation
25163  * potentially mutating the `accumulator` object. If `accumulator` is not
25164  * provided, a new object with the same `[[Prototype]]` will be used. The
25165  * iteratee is invoked with four arguments: (accumulator, value, key, object).
25166  * Iteratee functions may exit iteration early by explicitly returning `false`.
25167  *
25168  * @static
25169  * @memberOf _
25170  * @since 1.3.0
25171  * @category Object
25172  * @param {Object} object The object to iterate over.
25173  * @param {Function} [iteratee=_.identity] The function invoked per iteration.
25174  * @param {*} [accumulator] The custom accumulator value.
25175  * @returns {*} Returns the accumulated value.
25176  * @example
25177  *
25178  * _.transform([2, 3, 4], function(result, n) {
25179  *   result.push(n *= n);
25180  *   return n % 2 == 0;
25181  * }, []);
25182  * // => [4, 9]
25183  *
25184  * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
25185  *   (result[value] || (result[value] = [])).push(key);
25186  * }, {});
25187  * // => { '1': ['a', 'c'], '2': ['b'] }
25188  */
25189 function transform$1(object, iteratee, accumulator) {
25190   var isArr = isArray(object),
25191       isArrLike = isArr || isBuffer(object) || isTypedArray(object);
25192
25193   iteratee = baseIteratee(iteratee, 4);
25194   if (accumulator == null) {
25195     var Ctor = object && object.constructor;
25196     if (isArrLike) {
25197       accumulator = isArr ? new Ctor : [];
25198     }
25199     else if (isObject(object)) {
25200       accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
25201     }
25202     else {
25203       accumulator = {};
25204     }
25205   }
25206   (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
25207     return iteratee(accumulator, value, index, object);
25208   });
25209   return accumulator;
25210 }
25211
25212 /*
25213   Order the nodes of a way in reverse order and reverse any direction dependent tags
25214   other than `oneway`. (We assume that correcting a backwards oneway is the primary
25215   reason for reversing a way.)
25216
25217   The following transforms are performed:
25218
25219     Keys:
25220           *:right=* ⟺ *:left=*
25221         *:forward=* ⟺ *:backward=*
25222        direction=up ⟺ direction=down
25223          incline=up ⟺ incline=down
25224             *=right ⟺ *=left
25225
25226     Relation members:
25227        role=forward ⟺ role=backward
25228          role=north ⟺ role=south
25229           role=east ⟺ role=west
25230
25231    In addition, numeric-valued `incline` tags are negated.
25232
25233    The JOSM implementation was used as a guide, but transformations that were of unclear benefit
25234    or adjusted tags that don't seem to be used in practice were omitted.
25235
25236    Also, each node on the way is examined for its own tags and the following transformations are performed
25237    in order to ensure associated nodes (eg a Stop Sign) is also reversed
25238
25239     Node Keys:
25240         *direction=forward ⟺ *direction=backward
25241         *direction=left ⟺ *direction=right
25242         *:forward=* ⟺ *:backward=*
25243         *:left=* ⟺ *:right=*
25244
25245    References:
25246       http://wiki.openstreetmap.org/wiki/Forward_%26_backward,_left_%26_right
25247       http://wiki.openstreetmap.org/wiki/Key:direction#Steps
25248       http://wiki.openstreetmap.org/wiki/Key:incline
25249       http://wiki.openstreetmap.org/wiki/Route#Members
25250       http://josm.openstreetmap.de/browser/josm/trunk/src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java
25251       http://wiki.openstreetmap.org/wiki/Tag:highway%3Dstop
25252       http://wiki.openstreetmap.org/wiki/Key:traffic_sign#On_a_way_or_area
25253  */
25254 function actionReverse(wayId, options) {
25255     var replacements = [
25256             [/:right$/, ':left'], [/:left$/, ':right'],
25257             [/:forward$/, ':backward'], [/:backward$/, ':forward']
25258         ],
25259         numeric = /^([+\-]?)(?=[\d.])/,
25260         roleReversals = {
25261             forward: 'backward',
25262             backward: 'forward',
25263             north: 'south',
25264             south: 'north',
25265             east: 'west',
25266             west: 'east'
25267         };
25268
25269
25270     function reverseKey(key) {
25271         for (var i = 0; i < replacements.length; ++i) {
25272             var replacement = replacements[i];
25273             if (replacement[0].test(key)) {
25274                 return key.replace(replacement[0], replacement[1]);
25275             }
25276         }
25277         return key;
25278     }
25279
25280
25281     function reverseValue(key, value) {
25282         if (key === 'incline' && numeric.test(value)) {
25283             return value.replace(numeric, function(_, sign) { return sign === '-' ? '' : '-'; });
25284         } else if (key === 'incline' || key === 'direction') {
25285             return {up: 'down', down: 'up'}[value] || value;
25286         } else if (options && options.reverseOneway && key === 'oneway') {
25287             return {yes: '-1', '1': '-1', '-1': 'yes'}[value] || value;
25288         } else {
25289             return {left: 'right', right: 'left'}[value] || value;
25290         }
25291     }
25292
25293
25294     function reverseDirectionTags(node) {
25295         // Update the direction based tags as appropriate then return an updated node
25296         return node.update({tags: transform$1(node.tags, function(acc, tagValue, tagKey) {
25297             // See if this is a direction tag and reverse (or use existing value if not recognised)
25298             var re = /direction$/;
25299             if (re.test(tagKey)) {
25300                 acc[tagKey] = {forward: 'backward', backward: 'forward', left: 'right', right: 'left'}[tagValue] || tagValue;
25301             } else {
25302                 // Use the reverseKey method to cater for situations such as traffic_sign:forward=stop
25303                 // This will pass through other tags unchanged
25304                 acc[reverseKey(tagKey)] = tagValue;
25305             }
25306             return acc;
25307         }, {})});
25308     }
25309
25310
25311     function reverseTagsOnNodes(graph, nodeIds) {
25312         // Reverse the direction of appropriate tags attached to the nodes (#3076)
25313         return nodeIds
25314             // Get each node from the graph
25315             .map(function(nodeId) { return graph.entity(nodeId);})
25316             // Check tags on the node, if there aren't any, we can skip
25317             .filter(function(existingNode) { return existingNode.tags !== undefined;})
25318             // Get a new version of each node with the appropriate tags reversed
25319             .map(function(existingNode) { return reverseDirectionTags(existingNode);})
25320             // Chain together consecutive updates to the graph for each updated node and return
25321             .reduce(function (accGraph, value) { return accGraph.replace(value); }, graph);
25322     }
25323
25324
25325     return function(graph) {
25326         var way = graph.entity(wayId),
25327             nodes = way.nodes.slice().reverse(),
25328             tags = {}, key, role;
25329
25330         for (key in way.tags) {
25331             tags[reverseKey(key)] = reverseValue(key, way.tags[key]);
25332         }
25333
25334         graph.parentRelations(way).forEach(function(relation) {
25335             relation.members.forEach(function(member, index) {
25336                 if (member.id === way.id && (role = roleReversals[member.role])) {
25337                     relation = relation.updateMember({role: role}, index);
25338                     graph = graph.replace(relation);
25339                 }
25340             });
25341         });
25342
25343         // Reverse any associated directions on nodes on the way and then replace
25344         // the way itself with the reversed node ids and updated way tags
25345         return reverseTagsOnNodes(graph, nodes).replace(way.update({nodes: nodes, tags: tags}));
25346     };
25347 }
25348
25349 /** `Object#toString` result references. */
25350 var numberTag$4 = '[object Number]';
25351
25352 /**
25353  * Checks if `value` is classified as a `Number` primitive or object.
25354  *
25355  * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
25356  * classified as numbers, use the `_.isFinite` method.
25357  *
25358  * @static
25359  * @memberOf _
25360  * @since 0.1.0
25361  * @category Lang
25362  * @param {*} value The value to check.
25363  * @returns {boolean} Returns `true` if `value` is a number, else `false`.
25364  * @example
25365  *
25366  * _.isNumber(3);
25367  * // => true
25368  *
25369  * _.isNumber(Number.MIN_VALUE);
25370  * // => true
25371  *
25372  * _.isNumber(Infinity);
25373  * // => true
25374  *
25375  * _.isNumber('3');
25376  * // => false
25377  */
25378 function isNumber(value) {
25379   return typeof value == 'number' ||
25380     (isObjectLike(value) && baseGetTag(value) == numberTag$4);
25381 }
25382
25383 /** `Object#toString` result references. */
25384 var stringTag$4 = '[object String]';
25385
25386 /**
25387  * Checks if `value` is classified as a `String` primitive or object.
25388  *
25389  * @static
25390  * @since 0.1.0
25391  * @memberOf _
25392  * @category Lang
25393  * @param {*} value The value to check.
25394  * @returns {boolean} Returns `true` if `value` is a string, else `false`.
25395  * @example
25396  *
25397  * _.isString('abc');
25398  * // => true
25399  *
25400  * _.isString(1);
25401  * // => false
25402  */
25403 function isString(value) {
25404   return typeof value == 'string' ||
25405     (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag$4);
25406 }
25407
25408 /**
25409  * Checks if `value` is `NaN`.
25410  *
25411  * **Note:** This method is based on
25412  * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
25413  * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
25414  * `undefined` and other non-number values.
25415  *
25416  * @static
25417  * @memberOf _
25418  * @since 0.1.0
25419  * @category Lang
25420  * @param {*} value The value to check.
25421  * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
25422  * @example
25423  *
25424  * _.isNaN(NaN);
25425  * // => true
25426  *
25427  * _.isNaN(new Number(NaN));
25428  * // => true
25429  *
25430  * isNaN(undefined);
25431  * // => true
25432  *
25433  * _.isNaN(undefined);
25434  * // => false
25435  */
25436 function isNaN$1(value) {
25437   // An `NaN` primitive is the only value that is not equal to itself.
25438   // Perform the `toStringTag` check first to avoid errors with some
25439   // ActiveX objects in IE.
25440   return isNumber(value) && value != +value;
25441 }
25442
25443 function osmLanes(entity) {
25444     if (entity.type !== 'way') return null;
25445     if (!entity.tags.highway) return null;
25446
25447     var tags = entity.tags;
25448     var isOneWay = entity.isOneWay();
25449     var laneCount = getLaneCount(tags, isOneWay);
25450     var maxspeed = parseMaxspeed(tags);
25451
25452     var laneDirections = parseLaneDirections(tags, isOneWay, laneCount);
25453     var forward = laneDirections.forward;
25454     var backward = laneDirections.backward;
25455     var bothways = laneDirections.bothways;
25456
25457     // parse the piped string 'x|y|z' format
25458     var turnLanes = {};
25459     turnLanes.unspecified = parseTurnLanes(tags['turn:lanes']);
25460     turnLanes.forward = parseTurnLanes(tags['turn:lanes:forward']);
25461     turnLanes.backward = parseTurnLanes(tags['turn:lanes:backward']);
25462
25463     var maxspeedLanes = {};
25464     maxspeedLanes.unspecified = parseMaxspeedLanes(tags['maxspeed:lanes'], maxspeed);
25465     maxspeedLanes.forward = parseMaxspeedLanes(tags['maxspeed:lanes:forward'], maxspeed);
25466     maxspeedLanes.backward = parseMaxspeedLanes(tags['maxspeed:lanes:backward'], maxspeed);
25467
25468     var psvLanes = {};
25469     psvLanes.unspecified = parseMiscLanes(tags['psv:lanes']);
25470     psvLanes.forward = parseMiscLanes(tags['psv:lanes:forward']);
25471     psvLanes.backward = parseMiscLanes(tags['psv:lanes:backward']);
25472
25473     var busLanes = {};
25474     busLanes.unspecified = parseMiscLanes(tags['bus:lanes']);
25475     busLanes.forward = parseMiscLanes(tags['bus:lanes:forward']);
25476     busLanes.backward = parseMiscLanes(tags['bus:lanes:backward']);
25477
25478     var taxiLanes = {};
25479     taxiLanes.unspecified = parseMiscLanes(tags['taxi:lanes']);
25480     taxiLanes.forward = parseMiscLanes(tags['taxi:lanes:forward']);
25481     taxiLanes.backward = parseMiscLanes(tags['taxi:lanes:backward']);
25482
25483     var hovLanes = {};
25484     hovLanes.unspecified = parseMiscLanes(tags['hov:lanes']);
25485     hovLanes.forward = parseMiscLanes(tags['hov:lanes:forward']);
25486     hovLanes.backward = parseMiscLanes(tags['hov:lanes:backward']);
25487
25488     var hgvLanes = {};
25489     hgvLanes.unspecified = parseMiscLanes(tags['hgv:lanes']);
25490     hgvLanes.forward = parseMiscLanes(tags['hgv:lanes:forward']);
25491     hgvLanes.backward = parseMiscLanes(tags['hgv:lanes:backward']);
25492
25493     var bicyclewayLanes = {};
25494     bicyclewayLanes.unspecified = parseBicycleWay(tags['bicycleway:lanes']);
25495     bicyclewayLanes.forward = parseBicycleWay(tags['bicycleway:lanes:forward']);
25496     bicyclewayLanes.backward = parseBicycleWay(tags['bicycleway:lanes:backward']);
25497
25498     var lanesObj = {
25499         forward: [],
25500         backward: [],
25501         unspecified: []
25502     };
25503
25504     // map forward/backward/unspecified of each lane type to lanesObj
25505     mapToLanesObj(lanesObj, turnLanes, 'turnLane');
25506     mapToLanesObj(lanesObj, maxspeedLanes, 'maxspeed');
25507     mapToLanesObj(lanesObj, psvLanes, 'psv');
25508     mapToLanesObj(lanesObj, busLanes, 'bus');
25509     mapToLanesObj(lanesObj, taxiLanes, 'taxi');
25510     mapToLanesObj(lanesObj, hovLanes, 'hov');
25511     mapToLanesObj(lanesObj, hgvLanes, 'hgv');
25512     mapToLanesObj(lanesObj, bicyclewayLanes, 'bicycleway');
25513
25514     return {
25515         metadata: {
25516             count: laneCount,
25517             oneway: isOneWay,
25518             forward: forward,
25519             backward: backward,
25520             bothways: bothways,
25521             turnLanes: turnLanes,
25522             maxspeed: maxspeed,
25523             maxspeedLanes: maxspeedLanes,
25524             psvLanes: psvLanes,
25525             busLanes: busLanes,
25526             taxiLanes: taxiLanes,
25527             hovLanes: hovLanes,
25528             hgvLanes: hgvLanes,
25529             bicyclewayLanes: bicyclewayLanes
25530         },
25531         lanes: lanesObj
25532     };
25533 }
25534
25535
25536 function getLaneCount(tags, isOneWay) {
25537     var count;
25538     if (tags.lanes) {
25539         count = parseInt(tags.lanes, 10);
25540         if (count > 0) {
25541             return count;
25542         }
25543     }
25544
25545
25546     switch (tags.highway) {
25547         case 'trunk':
25548         case 'motorway':
25549             count = isOneWay ? 2 : 4;
25550             break;
25551         default:
25552             count = isOneWay ? 1 : 2;
25553             break;
25554     }
25555
25556     return count;
25557 }
25558
25559
25560 function parseMaxspeed(tags) {
25561     var maxspeed = tags.maxspeed;
25562     if (isNumber(maxspeed)) return maxspeed;
25563     if (isString(maxspeed)) {
25564         maxspeed = maxspeed.match(/^([0-9][\.0-9]+?)(?:[ ]?(?:km\/h|kmh|kph|mph|knots))?$/g);
25565         if (!maxspeed) return;
25566         return parseInt(maxspeed, 10);
25567     }
25568 }
25569
25570
25571 function parseLaneDirections(tags, isOneWay, laneCount) {
25572     var forward = parseInt(tags['lanes:forward'], 10);
25573     var backward = parseInt(tags['lanes:backward'], 10);
25574     var bothways = parseInt(tags['lanes:both_ways'], 10) > 0 ? 1 : 0;
25575
25576     if (parseInt(tags.oneway, 10) === -1) {
25577         forward = 0;
25578         bothways = 0;
25579         backward = laneCount;
25580     }
25581     else if (isOneWay) {
25582         forward = laneCount;
25583         bothways = 0;
25584         backward = 0;
25585     }
25586     else if (isNaN$1(forward) && isNaN$1(backward)) {
25587         backward = Math.floor((laneCount - bothways) / 2);
25588         forward = laneCount - bothways - backward;
25589     }
25590     else if (isNaN$1(forward)) {
25591         if (backward > laneCount - bothways) {
25592             backward = laneCount - bothways;
25593         }
25594         forward = laneCount - bothways - backward;
25595     }
25596     else if (isNaN$1(backward)) {
25597         if (forward > laneCount - bothways) {
25598             forward = laneCount - bothways;
25599         }
25600         backward = laneCount - bothways - forward;
25601     }
25602     return {
25603         forward: forward,
25604         backward: backward,
25605         bothways: bothways
25606     };
25607 }
25608
25609
25610 function parseTurnLanes(tag){
25611     if (!tag) return;
25612
25613     var validValues = [
25614         'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right',
25615         'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none'
25616     ];
25617
25618     return tag.split('|')
25619         .map(function (s) {
25620             if (s === '') s = 'none';
25621             return s.split(';')
25622                 .map(function (d) {
25623                     return validValues.indexOf(d) === -1 ? 'unknown': d;
25624                 });
25625         });
25626 }
25627
25628
25629 function parseMaxspeedLanes(tag, maxspeed) {
25630     if (!tag) return;
25631
25632     return tag.split('|')
25633         .map(function (s) {
25634             if (s === 'none') return s;
25635             var m = parseInt(s, 10);
25636             if (s === '' || m === maxspeed) return null;
25637             return isNaN$1(m) ? 'unknown': m;
25638         });
25639 }
25640
25641
25642 function parseMiscLanes(tag) {
25643     if (!tag) return;
25644
25645     var validValues = [
25646         'yes', 'no', 'designated'
25647     ];
25648
25649     return tag.split('|')
25650         .map(function (s) {
25651             if (s === '') s = 'no';
25652             return validValues.indexOf(s) === -1 ? 'unknown': s;
25653         });
25654 }
25655
25656
25657 function parseBicycleWay(tag) {
25658     if (!tag) return;
25659
25660     var validValues = [
25661         'yes', 'no', 'designated', 'lane'
25662     ];
25663
25664     return tag.split('|')
25665         .map(function (s) {
25666             if (s === '') s = 'no';
25667             return validValues.indexOf(s) === -1 ? 'unknown': s;
25668         });
25669 }
25670
25671
25672 function mapToLanesObj(lanesObj, data, key) {
25673     if (data.forward) data.forward.forEach(function(l, i) {
25674         if (!lanesObj.forward[i]) lanesObj.forward[i] = {};
25675         lanesObj.forward[i][key] = l;
25676     });
25677     if (data.backward) data.backward.forEach(function(l, i) {
25678         if (!lanesObj.backward[i]) lanesObj.backward[i] = {};
25679         lanesObj.backward[i][key] = l;
25680     });
25681     if (data.unspecified) data.unspecified.forEach(function(l, i) {
25682         if (!lanesObj.unspecified[i]) lanesObj.unspecified[i] = {};
25683         lanesObj.unspecified[i][key] = l;
25684     });
25685 }
25686
25687 /** Used to compose bitmasks for cloning. */
25688 var CLONE_DEEP_FLAG$4 = 1;
25689 var CLONE_SYMBOLS_FLAG$3 = 4;
25690
25691 /**
25692  * This method is like `_.clone` except that it recursively clones `value`.
25693  *
25694  * @static
25695  * @memberOf _
25696  * @since 1.0.0
25697  * @category Lang
25698  * @param {*} value The value to recursively clone.
25699  * @returns {*} Returns the deep cloned value.
25700  * @see _.clone
25701  * @example
25702  *
25703  * var objects = [{ 'a': 1 }, { 'b': 2 }];
25704  *
25705  * var deep = _.cloneDeep(objects);
25706  * console.log(deep[0] === objects[0]);
25707  * // => false
25708  */
25709 function cloneDeep(value) {
25710   return baseClone(value, CLONE_DEEP_FLAG$4 | CLONE_SYMBOLS_FLAG$3);
25711 }
25712
25713 /**
25714  * Gets the timestamp of the number of milliseconds that have elapsed since
25715  * the Unix epoch (1 January 1970 00:00:00 UTC).
25716  *
25717  * @static
25718  * @memberOf _
25719  * @since 2.4.0
25720  * @category Date
25721  * @returns {number} Returns the timestamp.
25722  * @example
25723  *
25724  * _.defer(function(stamp) {
25725  *   console.log(_.now() - stamp);
25726  * }, _.now());
25727  * // => Logs the number of milliseconds it took for the deferred invocation.
25728  */
25729 var now$1 = function() {
25730   return root$2.Date.now();
25731 };
25732
25733 /** Error message constants. */
25734 var FUNC_ERROR_TEXT$2 = 'Expected a function';
25735
25736 /* Built-in method references for those with the same name as other `lodash` methods. */
25737 var nativeMax$2 = Math.max;
25738 var nativeMin = Math.min;
25739
25740 /**
25741  * Creates a debounced function that delays invoking `func` until after `wait`
25742  * milliseconds have elapsed since the last time the debounced function was
25743  * invoked. The debounced function comes with a `cancel` method to cancel
25744  * delayed `func` invocations and a `flush` method to immediately invoke them.
25745  * Provide `options` to indicate whether `func` should be invoked on the
25746  * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
25747  * with the last arguments provided to the debounced function. Subsequent
25748  * calls to the debounced function return the result of the last `func`
25749  * invocation.
25750  *
25751  * **Note:** If `leading` and `trailing` options are `true`, `func` is
25752  * invoked on the trailing edge of the timeout only if the debounced function
25753  * is invoked more than once during the `wait` timeout.
25754  *
25755  * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
25756  * until to the next tick, similar to `setTimeout` with a timeout of `0`.
25757  *
25758  * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
25759  * for details over the differences between `_.debounce` and `_.throttle`.
25760  *
25761  * @static
25762  * @memberOf _
25763  * @since 0.1.0
25764  * @category Function
25765  * @param {Function} func The function to debounce.
25766  * @param {number} [wait=0] The number of milliseconds to delay.
25767  * @param {Object} [options={}] The options object.
25768  * @param {boolean} [options.leading=false]
25769  *  Specify invoking on the leading edge of the timeout.
25770  * @param {number} [options.maxWait]
25771  *  The maximum time `func` is allowed to be delayed before it's invoked.
25772  * @param {boolean} [options.trailing=true]
25773  *  Specify invoking on the trailing edge of the timeout.
25774  * @returns {Function} Returns the new debounced function.
25775  * @example
25776  *
25777  * // Avoid costly calculations while the window size is in flux.
25778  * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
25779  *
25780  * // Invoke `sendMail` when clicked, debouncing subsequent calls.
25781  * jQuery(element).on('click', _.debounce(sendMail, 300, {
25782  *   'leading': true,
25783  *   'trailing': false
25784  * }));
25785  *
25786  * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
25787  * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
25788  * var source = new EventSource('/stream');
25789  * jQuery(source).on('message', debounced);
25790  *
25791  * // Cancel the trailing debounced invocation.
25792  * jQuery(window).on('popstate', debounced.cancel);
25793  */
25794 function debounce(func, wait, options) {
25795   var lastArgs,
25796       lastThis,
25797       maxWait,
25798       result,
25799       timerId,
25800       lastCallTime,
25801       lastInvokeTime = 0,
25802       leading = false,
25803       maxing = false,
25804       trailing = true;
25805
25806   if (typeof func != 'function') {
25807     throw new TypeError(FUNC_ERROR_TEXT$2);
25808   }
25809   wait = toNumber(wait) || 0;
25810   if (isObject(options)) {
25811     leading = !!options.leading;
25812     maxing = 'maxWait' in options;
25813     maxWait = maxing ? nativeMax$2(toNumber(options.maxWait) || 0, wait) : maxWait;
25814     trailing = 'trailing' in options ? !!options.trailing : trailing;
25815   }
25816
25817   function invokeFunc(time) {
25818     var args = lastArgs,
25819         thisArg = lastThis;
25820
25821     lastArgs = lastThis = undefined;
25822     lastInvokeTime = time;
25823     result = func.apply(thisArg, args);
25824     return result;
25825   }
25826
25827   function leadingEdge(time) {
25828     // Reset any `maxWait` timer.
25829     lastInvokeTime = time;
25830     // Start the timer for the trailing edge.
25831     timerId = setTimeout(timerExpired, wait);
25832     // Invoke the leading edge.
25833     return leading ? invokeFunc(time) : result;
25834   }
25835
25836   function remainingWait(time) {
25837     var timeSinceLastCall = time - lastCallTime,
25838         timeSinceLastInvoke = time - lastInvokeTime,
25839         result = wait - timeSinceLastCall;
25840
25841     return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
25842   }
25843
25844   function shouldInvoke(time) {
25845     var timeSinceLastCall = time - lastCallTime,
25846         timeSinceLastInvoke = time - lastInvokeTime;
25847
25848     // Either this is the first call, activity has stopped and we're at the
25849     // trailing edge, the system time has gone backwards and we're treating
25850     // it as the trailing edge, or we've hit the `maxWait` limit.
25851     return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
25852       (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
25853   }
25854
25855   function timerExpired() {
25856     var time = now$1();
25857     if (shouldInvoke(time)) {
25858       return trailingEdge(time);
25859     }
25860     // Restart the timer.
25861     timerId = setTimeout(timerExpired, remainingWait(time));
25862   }
25863
25864   function trailingEdge(time) {
25865     timerId = undefined;
25866
25867     // Only invoke if we have `lastArgs` which means `func` has been
25868     // debounced at least once.
25869     if (trailing && lastArgs) {
25870       return invokeFunc(time);
25871     }
25872     lastArgs = lastThis = undefined;
25873     return result;
25874   }
25875
25876   function cancel() {
25877     if (timerId !== undefined) {
25878       clearTimeout(timerId);
25879     }
25880     lastInvokeTime = 0;
25881     lastArgs = lastCallTime = lastThis = timerId = undefined;
25882   }
25883
25884   function flush() {
25885     return timerId === undefined ? result : trailingEdge(now$1());
25886   }
25887
25888   function debounced() {
25889     var time = now$1(),
25890         isInvoking = shouldInvoke(time);
25891
25892     lastArgs = arguments;
25893     lastThis = this;
25894     lastCallTime = time;
25895
25896     if (isInvoking) {
25897       if (timerId === undefined) {
25898         return leadingEdge(lastCallTime);
25899       }
25900       if (maxing) {
25901         // Handle invocations in a tight loop.
25902         timerId = setTimeout(timerExpired, wait);
25903         return invokeFunc(lastCallTime);
25904       }
25905     }
25906     if (timerId === undefined) {
25907       timerId = setTimeout(timerExpired, wait);
25908     }
25909     return result;
25910   }
25911   debounced.cancel = cancel;
25912   debounced.flush = flush;
25913   return debounced;
25914 }
25915
25916 /**
25917  * Casts `value` to `identity` if it's not a function.
25918  *
25919  * @private
25920  * @param {*} value The value to inspect.
25921  * @returns {Function} Returns cast function.
25922  */
25923 function castFunction(value) {
25924   return typeof value == 'function' ? value : identity$8;
25925 }
25926
25927 /**
25928  * Iterates over elements of `collection` and invokes `iteratee` for each element.
25929  * The iteratee is invoked with three arguments: (value, index|key, collection).
25930  * Iteratee functions may exit iteration early by explicitly returning `false`.
25931  *
25932  * **Note:** As with other "Collections" methods, objects with a "length"
25933  * property are iterated like arrays. To avoid this behavior use `_.forIn`
25934  * or `_.forOwn` for object iteration.
25935  *
25936  * @static
25937  * @memberOf _
25938  * @since 0.1.0
25939  * @alias each
25940  * @category Collection
25941  * @param {Array|Object} collection The collection to iterate over.
25942  * @param {Function} [iteratee=_.identity] The function invoked per iteration.
25943  * @returns {Array|Object} Returns `collection`.
25944  * @see _.forEachRight
25945  * @example
25946  *
25947  * _.forEach([1, 2], function(value) {
25948  *   console.log(value);
25949  * });
25950  * // => Logs `1` then `2`.
25951  *
25952  * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
25953  *   console.log(key);
25954  * });
25955  * // => Logs 'a' then 'b' (iteration order is not guaranteed).
25956  */
25957 function forEach(collection, iteratee) {
25958   var func = isArray(collection) ? arrayEach : baseEach;
25959   return func(collection, castFunction(iteratee));
25960 }
25961
25962 /**
25963  * Iterates over own enumerable string keyed properties of an object and
25964  * invokes `iteratee` for each property. The iteratee is invoked with three
25965  * arguments: (value, key, object). Iteratee functions may exit iteration
25966  * early by explicitly returning `false`.
25967  *
25968  * @static
25969  * @memberOf _
25970  * @since 0.3.0
25971  * @category Object
25972  * @param {Object} object The object to iterate over.
25973  * @param {Function} [iteratee=_.identity] The function invoked per iteration.
25974  * @returns {Object} Returns `object`.
25975  * @see _.forOwnRight
25976  * @example
25977  *
25978  * function Foo() {
25979  *   this.a = 1;
25980  *   this.b = 2;
25981  * }
25982  *
25983  * Foo.prototype.c = 3;
25984  *
25985  * _.forOwn(new Foo, function(value, key) {
25986  *   console.log(key);
25987  * });
25988  * // => Logs 'a' then 'b' (iteration order is not guaranteed).
25989  */
25990 function forOwn(object, iteratee) {
25991   return object && baseForOwn(object, castFunction(iteratee));
25992 }
25993
25994 var translations = Object.create(null);
25995
25996 var currentLocale = 'en';
25997 var textDirection = 'ltr';
25998
25999 function setLocale(_) {
26000     if (translations[_] !== undefined) {
26001         currentLocale = _;
26002     } else if (translations[_.split('-')[0]]) {
26003         currentLocale = _.split('-')[0];
26004     }
26005 }
26006
26007 function addTranslation(id, value) {
26008     translations[id] = value;
26009 }
26010
26011 /**
26012  * Given a string identifier, try to find that string in the current
26013  * language, and return it.
26014  *
26015  * @param {string} s string identifier
26016  * @returns {string?} locale string
26017  */
26018 function t(s, o, loc) {
26019     loc = loc || currentLocale;
26020
26021     var path = s
26022         .split('.')
26023         .map(function(s) { return s.replace('<TX_DOT>', '.'); })
26024         .reverse();
26025
26026     var rep = translations[loc];
26027
26028     while (rep !== undefined && path.length) rep = rep[path.pop()];
26029
26030     if (rep !== undefined) {
26031         if (o) for (var k in o) rep = rep.replace('{' + k + '}', o[k]);
26032         return rep;
26033     }
26034
26035     if (loc !== 'en') {
26036         return t(s, o, 'en');
26037     }
26038
26039     if (o && 'default' in o) {
26040         return o.default;
26041     }
26042
26043     var missing = 'Missing ' + loc + ' translation: ' + s;
26044     if (typeof console !== 'undefined') console.error(missing); // eslint-disable-line
26045
26046     return missing;
26047 }
26048
26049 /**
26050  * Given string 'ltr' or 'rtl', save that setting
26051  *
26052  * @param {string} s ltr or rtl
26053  */
26054
26055 function setTextDirection(dir) {
26056     textDirection = dir;
26057 }
26058
26059 /** Used to compose bitmasks for cloning. */
26060 var CLONE_DEEP_FLAG$5 = 1;
26061 var CLONE_SYMBOLS_FLAG$4 = 4;
26062
26063 /**
26064  * This method is like `_.cloneWith` except that it recursively clones `value`.
26065  *
26066  * @static
26067  * @memberOf _
26068  * @since 4.0.0
26069  * @category Lang
26070  * @param {*} value The value to recursively clone.
26071  * @param {Function} [customizer] The function to customize cloning.
26072  * @returns {*} Returns the deep cloned value.
26073  * @see _.cloneWith
26074  * @example
26075  *
26076  * function customizer(value) {
26077  *   if (_.isElement(value)) {
26078  *     return value.cloneNode(true);
26079  *   }
26080  * }
26081  *
26082  * var el = _.cloneDeepWith(document.body, customizer);
26083  *
26084  * console.log(el === document.body);
26085  * // => false
26086  * console.log(el.nodeName);
26087  * // => 'BODY'
26088  * console.log(el.childNodes.length);
26089  * // => 20
26090  */
26091 function cloneDeepWith(value, customizer) {
26092   customizer = typeof customizer == 'function' ? customizer : undefined;
26093   return baseClone(value, CLONE_DEEP_FLAG$5 | CLONE_SYMBOLS_FLAG$4, customizer);
26094 }
26095
26096 /**
26097  * Creates an array of `array` values not included in the other given arrays
26098  * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
26099  * for equality comparisons. The order and references of result values are
26100  * determined by the first array.
26101  *
26102  * **Note:** Unlike `_.pullAll`, this method returns a new array.
26103  *
26104  * @static
26105  * @memberOf _
26106  * @since 0.1.0
26107  * @category Array
26108  * @param {Array} array The array to inspect.
26109  * @param {...Array} [values] The values to exclude.
26110  * @returns {Array} Returns the new array of filtered values.
26111  * @see _.without, _.xor
26112  * @example
26113  *
26114  * _.difference([2, 1], [2, 3]);
26115  * // => [1]
26116  */
26117 var difference = baseRest(function(array, values) {
26118   return isArrayLikeObject(array)
26119     ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
26120     : [];
26121 });
26122
26123 /** `Object#toString` result references. */
26124 var mapTag$6 = '[object Map]';
26125 var setTag$6 = '[object Set]';
26126
26127 /** Used for built-in method references. */
26128 var objectProto$17 = Object.prototype;
26129
26130 /** Used to check objects for own properties. */
26131 var hasOwnProperty$14 = objectProto$17.hasOwnProperty;
26132
26133 /**
26134  * Checks if `value` is an empty object, collection, map, or set.
26135  *
26136  * Objects are considered empty if they have no own enumerable string keyed
26137  * properties.
26138  *
26139  * Array-like values such as `arguments` objects, arrays, buffers, strings, or
26140  * jQuery-like collections are considered empty if they have a `length` of `0`.
26141  * Similarly, maps and sets are considered empty if they have a `size` of `0`.
26142  *
26143  * @static
26144  * @memberOf _
26145  * @since 0.1.0
26146  * @category Lang
26147  * @param {*} value The value to check.
26148  * @returns {boolean} Returns `true` if `value` is empty, else `false`.
26149  * @example
26150  *
26151  * _.isEmpty(null);
26152  * // => true
26153  *
26154  * _.isEmpty(true);
26155  * // => true
26156  *
26157  * _.isEmpty(1);
26158  * // => true
26159  *
26160  * _.isEmpty([1, 2, 3]);
26161  * // => false
26162  *
26163  * _.isEmpty({ 'a': 1 });
26164  * // => false
26165  */
26166 function isEmpty(value) {
26167   if (value == null) {
26168     return true;
26169   }
26170   if (isArrayLike(value) &&
26171       (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
26172         isBuffer(value) || isTypedArray(value) || isArguments(value))) {
26173     return !value.length;
26174   }
26175   var tag = getTag$1(value);
26176   if (tag == mapTag$6 || tag == setTag$6) {
26177     return !value.size;
26178   }
26179   if (isPrototype(value)) {
26180     return !baseKeys(value).length;
26181   }
26182   for (var key in value) {
26183     if (hasOwnProperty$14.call(value, key)) {
26184       return false;
26185     }
26186   }
26187   return true;
26188 }
26189
26190 var detected;
26191
26192 function utilDetect(force) {
26193     if (detected && !force) return detected;
26194     detected = {};
26195
26196     var ua = navigator.userAgent,
26197         m = null;
26198
26199     m = ua.match(/(edge)\/?\s*(\.?\d+(\.\d+)*)/i);   // Edge
26200     if (m !== null) {
26201         detected.browser = m[1];
26202         detected.version = m[2];
26203     }
26204     if (!detected.browser) {
26205         m = ua.match(/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/i);   // IE11
26206         if (m !== null) {
26207             detected.browser = 'msie';
26208             detected.version = m[1];
26209         }
26210     }
26211     if (!detected.browser) {
26212         m = ua.match(/(opr)\/?\s*(\.?\d+(\.\d+)*)/i);   // Opera 15+
26213         if (m !== null) {
26214             detected.browser = 'Opera';
26215             detected.version = m[2];
26216         }
26217     }
26218     if (!detected.browser) {
26219         m = ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
26220         if (m !== null) {
26221             detected.browser = m[1];
26222             detected.version = m[2];
26223             m = ua.match(/version\/([\.\d]+)/i);
26224             if (m !== null) detected.version = m[1];
26225         }
26226     }
26227     if (!detected.browser) {
26228         detected.browser = navigator.appName;
26229         detected.version = navigator.appVersion;
26230     }
26231
26232     // keep major.minor version only..
26233     detected.version = detected.version.split(/\W/).slice(0,2).join('.');
26234
26235     if (detected.browser.toLowerCase() === 'msie') {
26236         detected.ie = true;
26237         detected.browser = 'Internet Explorer';
26238         detected.support = parseFloat(detected.version) >= 11;
26239     } else {
26240         detected.ie = false;
26241         detected.support = true;
26242     }
26243
26244     // Added due to incomplete svg style support. See #715
26245     detected.opera = (detected.browser.toLowerCase() === 'opera' && parseFloat(detected.version) < 15 );
26246
26247     detected.locale = (navigator.language || navigator.userLanguage || 'en-US');
26248     detected.language = detected.locale.split('-')[0];
26249
26250     // Search `navigator.languages` for a better locale.. Prefer the first language,
26251     // unless the second language is a culture-specific version of the first one, see #3842
26252     if (navigator.languages && navigator.languages.length > 0) {
26253         var code0 = navigator.languages[0],
26254             parts0 = code0.split('-');
26255
26256         detected.locale = code0;
26257         detected.language = parts0[0];
26258
26259         if (navigator.languages.length > 1 && parts0.length === 1) {
26260             var code1 = navigator.languages[1],
26261                 parts1 = code1.split('-');
26262
26263             if (parts1[0] === parts0[0]) {
26264                 detected.locale = code1;
26265             }
26266         }
26267     }
26268
26269     // Loaded locale is stored in currentLocale
26270     // return that instead (except in the situation where 'en' might override 'en-US')
26271     var loadedLocale = currentLocale || 'en';
26272     if (loadedLocale !== 'en') {
26273         detected.locale = loadedLocale;
26274         detected.language = detected.locale.split('-')[0];
26275     }
26276
26277     // detect text direction
26278     var q = utilStringQs(window.location.hash.substring(1));
26279     var lang = dataLocales[detected.locale];
26280     if ((lang && lang.rtl) || (q.rtl === 'true')) {
26281         detected.textDirection = 'rtl';
26282     } else {
26283         detected.textDirection = 'ltr';
26284     }
26285     setTextDirection(detected.textDirection);
26286
26287     // detect host
26288     var loc = window.top.location;
26289     var origin = loc.origin;
26290     if (!origin) {  // for unpatched IE11
26291         origin = loc.protocol + '//' + loc.hostname + (loc.port ? ':' + loc.port: '');
26292     }
26293
26294     detected.host = origin + loc.pathname;
26295
26296     detected.filedrop = (window.FileReader && 'ondrop' in window);
26297
26298     detected.download = !(detected.ie || detected.browser.toLowerCase() === 'edge');
26299
26300     detected.cssfilters = !(detected.ie || detected.browser.toLowerCase() === 'edge');
26301
26302     function nav(x) {
26303         return navigator.userAgent.indexOf(x) !== -1;
26304     }
26305
26306     if (nav('Win')) {
26307         detected.os = 'win';
26308         detected.platform = 'Windows';
26309     }
26310     else if (nav('Mac')) {
26311         detected.os = 'mac';
26312         detected.platform = 'Macintosh';
26313     }
26314     else if (nav('X11') || nav('Linux')) {
26315         detected.os = 'linux';
26316         detected.platform = 'Linux';
26317     }
26318     else {
26319         detected.os = 'win';
26320         detected.platform = 'Unknown';
26321     }
26322
26323     return detected;
26324 }
26325
26326 var remove$1 = removeDiacritics;
26327
26328 var replacementList = [
26329   {
26330     base: ' ',
26331     chars: "\u00A0",
26332   }, {
26333     base: '0',
26334     chars: "\u07C0",
26335   }, {
26336     base: 'A',
26337     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",
26338   }, {
26339     base: 'AA',
26340     chars: "\uA732",
26341   }, {
26342     base: 'AE',
26343     chars: "\u00C6\u01FC\u01E2",
26344   }, {
26345     base: 'AO',
26346     chars: "\uA734",
26347   }, {
26348     base: 'AU',
26349     chars: "\uA736",
26350   }, {
26351     base: 'AV',
26352     chars: "\uA738\uA73A",
26353   }, {
26354     base: 'AY',
26355     chars: "\uA73C",
26356   }, {
26357     base: 'B',
26358     chars: "\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0181",
26359   }, {
26360     base: 'C',
26361     chars: "\u24b8\uff23\uA73E\u1E08\u0106\u0043\u0108\u010A\u010C\u00C7\u0187\u023B",
26362   }, {
26363     base: 'D',
26364     chars: "\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018A\u0189\u1D05\uA779",
26365   }, {
26366     base: 'Dh',
26367     chars: "\u00D0",
26368   }, {
26369     base: 'DZ',
26370     chars: "\u01F1\u01C4",
26371   }, {
26372     base: 'Dz',
26373     chars: "\u01F2\u01C5",
26374   }, {
26375     base: 'E',
26376     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",
26377   }, {
26378     base: 'F',
26379     chars: "\uA77C\u24BB\uFF26\u1E1E\u0191\uA77B",
26380   }, {
26381     base: 'G',
26382     chars: "\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E\u0262",
26383   }, {
26384     base: 'H',
26385     chars: "\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D",
26386   }, {
26387     base: 'I',
26388     chars: "\u24BE\uFF29\xCC\xCD\xCE\u0128\u012A\u012C\u0130\xCF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197",
26389   }, {
26390     base: 'J',
26391     chars: "\u24BF\uFF2A\u0134\u0248\u0237",
26392   }, {
26393     base: 'K',
26394     chars: "\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2",
26395   }, {
26396     base: 'L',
26397     chars: "\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780",
26398   }, {
26399     base: 'LJ',
26400     chars: "\u01C7",
26401   }, {
26402     base: 'Lj',
26403     chars: "\u01C8",
26404   }, {
26405     base: 'M',
26406     chars: "\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C\u03FB",
26407   }, {
26408     base: 'N',
26409     chars: "\uA7A4\u0220\u24C3\uFF2E\u01F8\u0143\xD1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u019D\uA790\u1D0E",
26410   }, {
26411     base: 'NJ',
26412     chars: "\u01CA",
26413   }, {
26414     base: 'Nj',
26415     chars: "\u01CB",
26416   }, {
26417     base: 'O',
26418     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",
26419   }, {
26420     base: 'OE',
26421     chars: "\u0152",
26422   }, {
26423     base: 'OI',
26424     chars: "\u01A2",
26425   }, {
26426     base: 'OO',
26427     chars: "\uA74E",
26428   }, {
26429     base: 'OU',
26430     chars: "\u0222",
26431   }, {
26432     base: 'P',
26433     chars: "\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754",
26434   }, {
26435     base: 'Q',
26436     chars: "\u24C6\uFF31\uA756\uA758\u024A",
26437   }, {
26438     base: 'R',
26439     chars: "\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782",
26440   }, {
26441     base: 'S',
26442     chars: "\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784",
26443   }, {
26444     base: 'T',
26445     chars: "\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786",
26446   }, {
26447     base: 'Th',
26448     chars: "\u00DE",
26449   }, {
26450     base: 'TZ',
26451     chars: "\uA728",
26452   }, {
26453     base: 'U',
26454     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",
26455   }, {
26456     base: 'V',
26457     chars: "\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245",
26458   }, {
26459     base: 'VY',
26460     chars: "\uA760",
26461   }, {
26462     base: 'W',
26463     chars: "\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72",
26464   }, {
26465     base: 'X',
26466     chars: "\u24CD\uFF38\u1E8A\u1E8C",
26467   }, {
26468     base: 'Y',
26469     chars: "\u24CE\uFF39\u1EF2\xDD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE",
26470   }, {
26471     base: 'Z',
26472     chars: "\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762",
26473   }, {
26474     base: 'a',
26475     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",
26476   }, {
26477     base: 'aa',
26478     chars: "\uA733",
26479   }, {
26480     base: 'ae',
26481     chars: "\u00E6\u01FD\u01E3",
26482   }, {
26483     base: 'ao',
26484     chars: "\uA735",
26485   }, {
26486     base: 'au',
26487     chars: "\uA737",
26488   }, {
26489     base: 'av',
26490     chars: "\uA739\uA73B",
26491   }, {
26492     base: 'ay',
26493     chars: "\uA73D",
26494   }, {
26495     base: 'b',
26496     chars: "\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253\u0182",
26497   }, {
26498     base: 'c',
26499     chars: "\uFF43\u24D2\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184",
26500   }, {
26501     base: 'd',
26502     chars: "\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\u018B\u13E7\u0501\uA7AA",
26503   }, {
26504     base: 'dh',
26505     chars: "\u00F0",
26506   }, {
26507     base: 'dz',
26508     chars: "\u01F3\u01C6",
26509   }, {
26510     base: 'e',
26511     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",
26512   }, {
26513     base: 'f',
26514     chars: "\u24D5\uFF46\u1E1F\u0192",
26515   }, {
26516     base: 'ff',
26517     chars: "\uFB00",
26518   }, {
26519     base: 'fi',
26520     chars: "\uFB01",
26521   }, {
26522     base: 'fl',
26523     chars: "\uFB02",
26524   }, {
26525     base: 'ffi',
26526     chars: "\uFB03",
26527   }, {
26528     base: 'ffl',
26529     chars: "\uFB04",
26530   }, {
26531     base: 'g',
26532     chars: "\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\uA77F\u1D79",
26533   }, {
26534     base: 'h',
26535     chars: "\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265",
26536   }, {
26537     base: 'hv',
26538     chars: "\u0195",
26539   }, {
26540     base: 'i',
26541     chars: "\u24D8\uFF49\xEC\xED\xEE\u0129\u012B\u012D\xEF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131",
26542   }, {
26543     base: 'j',
26544     chars: "\u24D9\uFF4A\u0135\u01F0\u0249",
26545   }, {
26546     base: 'k',
26547     chars: "\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3",
26548   }, {
26549     base: 'l',
26550     chars: "\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747\u026D",
26551   }, {
26552     base: 'lj',
26553     chars: "\u01C9",
26554   }, {
26555     base: 'm',
26556     chars: "\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F",
26557   }, {
26558     base: 'n',
26559     chars: "\u24DD\uFF4E\u01F9\u0144\xF1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5\u043B\u0509",
26560   }, {
26561     base: 'nj',
26562     chars: "\u01CC",
26563   }, {
26564     base: 'o',
26565     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",
26566   }, {
26567     base: 'oe',
26568     chars: "\u0153",
26569   }, {
26570     base: 'oi',
26571     chars: "\u01A3",
26572   }, {
26573     base: 'oo',
26574     chars: "\uA74F",
26575   }, {
26576     base: 'ou',
26577     chars: "\u0223",
26578   }, {
26579     base: 'p',
26580     chars: "\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755\u03C1",
26581   }, {
26582     base: 'q',
26583     chars: "\u24E0\uFF51\u024B\uA757\uA759",
26584   }, {
26585     base: 'r',
26586     chars: "\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783",
26587   }, {
26588     base: 's',
26589     chars: "\u24E2\uFF53\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B\u0282",
26590   }, {
26591     base: 'ss',
26592     chars: "\xDF",
26593   }, {
26594     base: 't',
26595     chars: "\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787",
26596   }, {
26597     base: 'th',
26598     chars: "\u00FE",
26599   }, {
26600     base: 'tz',
26601     chars: "\uA729",
26602   }, {
26603     base: 'u',
26604     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",
26605   }, {
26606     base: 'v',
26607     chars: "\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C",
26608   }, {
26609     base: 'vy',
26610     chars: "\uA761",
26611   }, {
26612     base: 'w',
26613     chars: "\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73",
26614   }, {
26615     base: 'x',
26616     chars: "\u24E7\uFF58\u1E8B\u1E8D",
26617   }, {
26618     base: 'y',
26619     chars: "\u24E8\uFF59\u1EF3\xFD\u0177\u1EF9\u0233\u1E8F\xFF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF",
26620   }, {
26621     base: 'z',
26622     chars: "\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763",
26623   }
26624 ];
26625
26626 var diacriticsMap = {};
26627 for (var i = 0; i < replacementList.length; i += 1) {
26628   var chars = replacementList[i].chars;
26629   for (var j = 0; j < chars.length; j += 1) {
26630     diacriticsMap[chars[j]] = replacementList[i].base;
26631   }
26632 }
26633
26634 function removeDiacritics(str) {
26635   return str.replace(/[^\u0000-\u007e]/g, function(c) {
26636     return diacriticsMap[c] || c;
26637   });
26638 }
26639
26640 // see https://github.com/openstreetmap/iD/pull/3707
26641 // https://gist.github.com/mapmeld/556b09ddec07a2044c76e1ef45f01c60
26642
26643 var chars$1 = {
26644     // madda above alef
26645     1570: { initial: 'آ‎', isolated: 'ﺁ', medial: 'ﺁ', final: 'ﺂ' },
26646
26647     // hamza above and below alef
26648     1571: { initial: 'أ', isolated: 'ﺃ', medial: '', final: 'ﺄ' },
26649     // 1572 is ؤ
26650     1573: { initial: 'إ', isolated: 'ﺇ', medial: '', final: 'ﺈ' },
26651     // 1574 is ئ
26652     1575: { initial: 'ا', isolated: 'ا', medial: '', final: 'ﺎ' },
26653     1576: { initial: 'ﺑ', isolated: 'ﺏ', medial: 'ﺒ', final: 'ﺐ' },
26654
26655     // 1577 ة
26656     1577: { initial: '', isolated: 'ة', medial: '', final: 'ﺔ' },
26657
26658     1578: { initial: 'ﺗ', isolated: 'ﺕ', medial: 'ﺘ', final: 'ﺖ' },
26659     1579: { initial: 'ﺛ', isolated: 'ﺙ', medial: 'ﺜ', final: 'ﺚ' },
26660     1580: { initial: 'ﺟ', isolated: 'ﺝ', medial: 'ﺠ', final: 'ﺞ' },
26661     1581: { initial: 'ﺣ', isolated: 'ﺡ', medial: 'ﺤ', final: 'ﺢ' },
26662     1582: { initial: 'ﺧ', isolated: 'ﺥ', medial: 'ﺨ', final: 'ﺦ' },
26663     1583: { initial: 'ﺩ', isolated: 'ﺩ', medial: '', final: 'ﺪ' },
26664     1584: { initial: 'ﺫ', isolated: 'ﺫ', medial: '', final: 'ﺬ' },
26665     1585: { initial: 'ﺭ', isolated: 'ﺭ', medial: '', final: 'ﺮ' },
26666     1586: { initial: 'ﺯ', isolated: 'ﺯ', medial: '', final: 'ﺰ' },
26667     1688: { initial: 'ﮊ', isolated: 'ﮊ', medial: '', final: 'ﮋ' },
26668     1587: { initial: 'ﺳ', isolated: 'ﺱ', medial: 'ﺴ', final: 'ﺲ' },
26669     1588: { initial: 'ﺷ', isolated: 'ﺵ', medial: 'ﺸ', final: 'ﺶ' },
26670     1589: { initial: 'ﺻ', isolated: 'ﺹ', medial: 'ﺼ', final: 'ﺺ' },
26671     1590: { initial: 'ﺿ', isolated: 'ﺽ', medial: 'ﻀ', final: 'ﺾ' },
26672     1591: { initial: 'ﻃ', isolated: 'ﻁ', medial: 'ﻄ', final: 'ﻂ' },
26673     1592: { initial: 'ﻇ', isolated: 'ﻅ', medial: 'ﻈ', final: 'ﻆ' },
26674     1593: { initial: 'ﻋ', isolated: 'ﻉ', medial: 'ﻌ', final: 'ﻊ' },
26675     1594: { initial: 'ﻏ', isolated: 'ﻍ', medial: 'ﻐ', final: 'ﻎ' },
26676
26677     // 1595 ػ - may be very rare
26678
26679     1601: { initial: 'ﻓ', isolated: 'ﻑ', medial: 'ﻔ', final: 'ﻒ' },
26680     1602: { initial: 'ﻗ', isolated: 'ﻕ', medial: 'ﻘ', final: 'ﻖ' },
26681     1604: { initial: 'ﻟ', isolated: 'ﻝ', medial: 'ﻠ', final: 'ﻞ' },
26682     1605: { initial: 'ﻣ', isolated: 'ﻡ', medial: 'ﻤ', final: 'ﻢ' },
26683     1606: { initial: 'ﻧ', isolated: 'ﻥ', medial: 'ﻨ', final: 'ﻦ' },
26684     1607: { initial: 'ﻫ', isolated: 'ﻩ', medial: 'ﻬ', final: 'ﻪ' },
26685     1608: { initial: 'ﻭ', isolated: 'ﻭ', medial: '', final: 'ﻮ' },
26686
26687     // 1609 ى
26688     1609: { initial: 'ﯨ', isolated: 'ﻯ', medial: 'ﯩ', final: 'ﻰ' },
26689     // 1610 ي
26690     1610: { initial: 'ﻳ', isolated: 'ﻱ', medial: 'ﻴ', final: 'ﻲ' },
26691
26692     // short vowel sounds / tashkil markings
26693
26694     1662: { initial: 'ﭘ', isolated: 'ﭖ', medial: 'ﭙ', final: 'ﭗ' },
26695
26696     1670: { initial: 'ﭼ', isolated: 'ﭺ', medial: 'ﭽ', final: 'ﭻ' },
26697     1603: { initial: 'ﻛ', isolated: 'ﻙ', medial: 'ﻜ', final: 'ﻚ' },
26698     1705: { initial: 'ﻛ', isolated: 'ﮎ', medial: 'ﻜ', final: 'ﮏ' },
26699     1711: { initial: 'ﮔ', isolated: 'ﮒ', medial: 'ﮕ', final: 'ﮓ' },
26700     1740: { initial: 'ﻳ', isolated: 'ﻯ', medial: 'ﻴ', final: 'ﻰ' },
26701     5000: { initial: 'ﻻ', isolated: 'ﻻ', medial: '', final: 'ﻼ' }
26702 };
26703
26704 var rtlRegex = /[\u0590-\u05FF\u0600-\u06FF\u0780-\u07BF]/;
26705
26706 function fixRTLTextForSvg(inputText) {
26707     var context = true;
26708     var ret = '';
26709     var rtlBuffer = [];
26710     var arabicRegex = /[\u0600-\u06FF]/g;
26711     var arabicTashkil = /[\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED]/;
26712     var thaanaVowel = /[\u07A6-\u07B0]/;
26713     var hebrewSign = /[\u0591-\u05bd\u05bf\u05c1-\u05c5\u05c7]/;
26714
26715     if (!arabicRegex.test(inputText)) {
26716         // Hebrew or Thaana RTL script
26717         for (var n = 0; n < inputText.length; n++) {
26718             var c = inputText[n];
26719             if ((thaanaVowel.test(c) || hebrewSign.test(c)) && rtlBuffer.length) {
26720                 rtlBuffer[rtlBuffer.length - 1] += c;
26721             } else if (rtlRegex.test(c)) {
26722                 rtlBuffer.push(c);
26723             } else if (c === ' ' && rtlBuffer.length) {
26724                 // whitespace within RTL text
26725                 rtlBuffer = [rtlBuffer.reverse().join('') + ' '];
26726             } else {
26727                 // non-RTL character
26728                 ret += rtlBuffer.reverse().join('') + c;
26729                 rtlBuffer = [];
26730             }
26731         }
26732     } else {
26733         for (var i = 0, l = inputText.length; i < l; i++) {
26734             var code = inputText[i].charCodeAt(0);
26735             var nextCode = inputText[i + 1] ? inputText[i + 1].charCodeAt(0) : 0;
26736
26737             if (!chars$1[code]) {
26738                 if (code === 32 && rtlBuffer.length) {
26739                     // whitespace
26740                     rtlBuffer = [rtlBuffer.reverse().join('') + ' '];
26741                 } else if (arabicTashkil.test(inputText[i]) && rtlBuffer.length) {
26742                     // tashkil mark
26743                     rtlBuffer[rtlBuffer.length - 1] += inputText[i];
26744                 } else {
26745                     // non-RTL character
26746                     ret += rtlBuffer.reverse().join('') + inputText[i];
26747                     rtlBuffer = [];
26748                 }
26749                 continue;
26750             }
26751             if (context) {
26752                 if (i === l - 1 || nextCode === 32) {
26753                     rtlBuffer.push(chars$1[code].isolated);
26754                 } else {
26755                     // special case for لا
26756                     if (code === 1604 && nextCode === 1575) {
26757                         rtlBuffer.push(chars$1[5000].initial);
26758                         i++;
26759                         context = true;
26760                         continue;
26761                     }
26762                     rtlBuffer.push(chars$1[code].initial);
26763                 }
26764             } else {
26765                 if (i === l - 1 || nextCode === 32){
26766                     rtlBuffer.push(chars$1[code].final);
26767                 } else {
26768                     // special case for ﻼ
26769                     if (code === 1604 && nextCode === 1575){
26770                         rtlBuffer.push(chars$1[5000].final);
26771                         i++;
26772                         context = true;
26773                         continue;
26774                     }
26775                     if (chars$1[code].medial === ''){
26776                         rtlBuffer.push(chars$1[code].final);
26777                     } else {
26778                         rtlBuffer.push(chars$1[code].medial);
26779                     }
26780                 }
26781             }
26782             context = (chars$1[code].medial === '') || nextCode === 32;
26783         }
26784     }
26785     ret += rtlBuffer.reverse().join('');
26786     return ret;
26787 }
26788
26789 function utilTagText(entity) {
26790     return map$4(entity.tags, function(v, k) {
26791         return k + '=' + v;
26792     }).join(', ');
26793 }
26794
26795
26796 function utilEntitySelector(ids) {
26797     return ids.length ? '.' + ids.join(',.') : 'nothing';
26798 }
26799
26800
26801 function utilEntityOrMemberSelector(ids, graph) {
26802     var s = utilEntitySelector(ids);
26803
26804     ids.forEach(function(id) {
26805         var entity = graph.hasEntity(id);
26806         if (entity && entity.type === 'relation') {
26807             entity.members.forEach(function(member) {
26808                 s += ',.' + member.id;
26809             });
26810         }
26811     });
26812
26813     return s;
26814 }
26815
26816
26817 function utilGetAllNodes(ids, graph) {
26818     var seen = {};
26819     var nodes = [];
26820     ids.forEach(getNodes);
26821     return nodes;
26822
26823     function getNodes(id) {
26824         if (seen[id]) return;
26825         seen[id] = true;
26826
26827         var entity = graph.hasEntity(id);
26828         if (!entity) return;
26829
26830         if (entity.type === 'node') {
26831             nodes.push(entity);
26832         } else if (entity.type === 'way') {
26833             entity.nodes.forEach(getNodes);
26834         } else {
26835             entity.members.map(function(member) { return member.id; }).forEach(getNodes);
26836         }
26837     }
26838 }
26839
26840
26841 function utilDisplayName(entity) {
26842     var localizedNameKey = 'name:' + utilDetect().locale.toLowerCase().split('-')[0],
26843         name = entity.tags[localizedNameKey] || entity.tags.name || '',
26844         network = entity.tags.cycle_network || entity.tags.network;
26845
26846     if (!name && entity.tags.ref) {
26847         name = entity.tags.ref;
26848         if (network) {
26849             name = network + ' ' + name;
26850         }
26851     }
26852
26853     return name;
26854 }
26855
26856
26857 function utilDisplayNameForPath(entity) {
26858     var name = utilDisplayName(entity);
26859     var isFirefox = utilDetect().browser.toLowerCase().indexOf('firefox') > -1;
26860
26861     if (!isFirefox && name && rtlRegex.test(name)) {
26862         name = fixRTLTextForSvg(name);
26863     }
26864
26865     return name;
26866 }
26867
26868
26869 function utilDisplayType(id) {
26870     return {
26871         n: t('inspector.node'),
26872         w: t('inspector.way'),
26873         r: t('inspector.relation')
26874     }[id.charAt(0)];
26875 }
26876
26877
26878 function utilStringQs(str) {
26879     return str.split('&').reduce(function(obj, pair){
26880         var parts = pair.split('=');
26881         if (parts.length === 2) {
26882             obj[parts[0]] = (null === parts[1]) ? '' : decodeURIComponent(parts[1]);
26883         }
26884         return obj;
26885     }, {});
26886 }
26887
26888
26889 function utilQsString(obj, noencode) {
26890     function softEncode(s) {
26891       // encode everything except special characters used in certain hash parameters:
26892       // "/" in map states, ":", ",", {" and "}" in background
26893       return encodeURIComponent(s).replace(/(%2F|%3A|%2C|%7B|%7D)/g, decodeURIComponent);
26894     }
26895     return Object.keys(obj).sort().map(function(key) {
26896         return encodeURIComponent(key) + '=' + (
26897             noencode ? softEncode(obj[key]) : encodeURIComponent(obj[key]));
26898     }).join('&');
26899 }
26900
26901
26902 function utilPrefixDOMProperty(property) {
26903     var prefixes = ['webkit', 'ms', 'moz', 'o'],
26904         i = -1,
26905         n = prefixes.length,
26906         s = document.body;
26907
26908     if (property in s)
26909         return property;
26910
26911     property = property.substr(0, 1).toUpperCase() + property.substr(1);
26912
26913     while (++i < n)
26914         if (prefixes[i] + property in s)
26915             return prefixes[i] + property;
26916
26917     return false;
26918 }
26919
26920
26921 function utilPrefixCSSProperty(property) {
26922     var prefixes = ['webkit', 'ms', 'Moz', 'O'],
26923         i = -1,
26924         n = prefixes.length,
26925         s = document.body.style;
26926
26927     if (property.toLowerCase() in s)
26928         return property.toLowerCase();
26929
26930     while (++i < n)
26931         if (prefixes[i] + property in s)
26932             return '-' + prefixes[i].toLowerCase() + property.replace(/([A-Z])/g, '-$1').toLowerCase();
26933
26934     return false;
26935 }
26936
26937
26938 var transformProperty;
26939 function utilSetTransform(el, x, y, scale) {
26940     var prop = transformProperty = transformProperty || utilPrefixCSSProperty('Transform'),
26941         translate = utilDetect().opera ?
26942             'translate('   + x + 'px,' + y + 'px)' :
26943             'translate3d(' + x + 'px,' + y + 'px,0)';
26944     return el.style(prop, translate + (scale ? ' scale(' + scale + ')' : ''));
26945 }
26946
26947
26948 // Calculates Levenshtein distance between two strings
26949 // see:  https://en.wikipedia.org/wiki/Levenshtein_distance
26950 // first converts the strings to lowercase and replaces diacritic marks with ascii equivalents.
26951 function utilEditDistance(a, b) {
26952     a = remove$1(a.toLowerCase());
26953     b = remove$1(b.toLowerCase());
26954     if (a.length === 0) return b.length;
26955     if (b.length === 0) return a.length;
26956     var matrix = [];
26957     for (var i = 0; i <= b.length; i++) { matrix[i] = [i]; }
26958     for (var j = 0; j <= a.length; j++) { matrix[0][j] = j; }
26959     for (i = 1; i <= b.length; i++) {
26960         for (j = 1; j <= a.length; j++) {
26961             if (b.charAt(i-1) === a.charAt(j-1)) {
26962                 matrix[i][j] = matrix[i-1][j-1];
26963             } else {
26964                 matrix[i][j] = Math.min(matrix[i-1][j-1] + 1, // substitution
26965                     Math.min(matrix[i][j-1] + 1, // insertion
26966                     matrix[i-1][j] + 1)); // deletion
26967             }
26968         }
26969     }
26970     return matrix[b.length][a.length];
26971 }
26972
26973
26974 // a d3.mouse-alike which
26975 // 1. Only works on HTML elements, not SVG
26976 // 2. Does not cause style recalculation
26977 function utilFastMouse(container) {
26978     var rect = container.getBoundingClientRect(),
26979         rectLeft = rect.left,
26980         rectTop = rect.top,
26981         clientLeft = +container.clientLeft,
26982         clientTop = +container.clientTop;
26983     if (textDirection === 'rtl') {
26984         rectLeft = 0;
26985     }
26986     return function(e) {
26987         return [
26988             e.clientX - rectLeft - clientLeft,
26989             e.clientY - rectTop - clientTop];
26990     };
26991 }
26992
26993
26994 /* eslint-disable no-proto */
26995 var utilGetPrototypeOf = Object.getPrototypeOf || function(obj) { return obj.__proto__; };
26996 /* eslint-enable no-proto */
26997
26998
26999 function utilAsyncMap(inputs, func, callback) {
27000     var remaining = inputs.length,
27001         results = [],
27002         errors = [];
27003
27004     inputs.forEach(function(d, i) {
27005         func(d, function done(err, data) {
27006             errors[i] = err;
27007             results[i] = data;
27008             remaining--;
27009             if (!remaining) callback(errors, results);
27010         });
27011     });
27012 }
27013
27014
27015 // wraps an index to an interval [0..length-1]
27016 function utilWrap(index, length) {
27017     if (index < 0)
27018         index += Math.ceil(-index/length)*length;
27019     return index % length;
27020 }
27021
27022
27023 /**
27024  * a replacement for functor
27025  *
27026  * @param {*} value any value
27027  * @returns {Function} a function that returns that value or the value if it's a function
27028  */
27029 function utilFunctor(value) {
27030     if (typeof value === 'function') return value;
27031     return function() {
27032         return value;
27033     };
27034 }
27035
27036
27037 function utilNoAuto(selection) {
27038     var isText = (selection.size() && selection.node().tagName.toLowerCase() === 'textarea');
27039
27040     return selection
27041         .attr('autocomplete', 'off')
27042         .attr('autocorrect', 'off')
27043         .attr('autocapitalize', 'off')
27044         .attr('spellcheck', isText ? 'true' : 'false');
27045 }
27046
27047 // note the function should be of low priority
27048 // and should not be returning a value.
27049 function utilCallWhenIdle(func, timeout) {
27050     return function() {
27051         var args = arguments;
27052         var that = this;
27053         window.requestIdleCallback(function() {
27054             func.apply(that, args);
27055         }, {timeout: timeout});
27056     };
27057 }
27058
27059 // Like selection.property('value', ...), but avoids no-op value sets,
27060 // which can result in layout/repaint thrashing in some situations.
27061 function utilGetSetValue(selection, value) {
27062     function d3_selection_value(value) {
27063         function valueNull() {
27064             delete this.value;
27065         }
27066
27067         function valueConstant() {
27068             if (this.value !== value) {
27069                 this.value = value;
27070             }
27071         }
27072
27073         function valueFunction() {
27074             var x = value.apply(this, arguments);
27075             if (x == null) {
27076                 delete this.value;
27077             } else if (this.value !== x) {
27078                 this.value = x;
27079             }
27080         }
27081
27082         return value == null
27083             ? valueNull : (typeof value === 'function'
27084             ? valueFunction : valueConstant);
27085     }
27086
27087     if (arguments.length === 1) {
27088         return selection.property('value');
27089     }
27090
27091     return selection.each(d3_selection_value(value));
27092 }
27093
27094 function utilIdleWorker(tasks, processor, callback) {
27095     var results = [], result;
27096     for (var i = 0; i < tasks.length; i++) {
27097         result = processor(tasks[i]);
27098         if (result) results.push(result);
27099     }
27100     callback(results);
27101
27102     // var processed = [];
27103     // var currentPos = 0;
27104     // var totalTasks = tasks.length;
27105
27106     // function worker(deadline) {
27107     //     while (deadline.timeRemaining() > 0 && currentPos < totalTasks) {
27108     //         var result = processor(tasks[currentPos]);
27109
27110     //         // if falsy dont add to the processed list
27111     //         if (result) processed.push(result);
27112     //         currentPos++;
27113     //     }
27114
27115     //     // more tasks are left, we might need more idleCallbacks
27116     //     if (currentPos < totalTasks) {
27117     //         return window.requestIdleCallback(function(deadline) {worker(deadline);});
27118     //     }
27119
27120     //     // tasks are completed
27121     //     return callback(processed);
27122     // }
27123
27124     // window.requestIdleCallback(function(deadline) {worker(deadline);});
27125 }
27126
27127 // shim
27128 window.requestIdleCallback =
27129     window.requestIdleCallback ||
27130     function(cb) {
27131         var start = Date.now();
27132         return setTimeout(function() {
27133             cb({
27134                 didTimeout: false,
27135                 timeRemaining: function() {
27136                     return Math.max(0, 50 - (Date.now() - start));
27137                 }
27138             });
27139         }, 1);
27140     };
27141
27142 window.cancelIdleCallback =
27143     window.cancelIdleCallback ||
27144     function(id) {
27145         clearTimeout(id);
27146     };
27147
27148 // Copies a variable number of methods from source to target.
27149 function utilRebind(target, source) {
27150     var i = 1, n = arguments.length, method;
27151     while (++i < n) {
27152         target[method = arguments[i]] = d3_rebind(target, source, source[method]);
27153     }
27154     return target;
27155 }
27156
27157 // Method is assumed to be a standard D3 getter-setter:
27158 // If passed with no arguments, gets the value.
27159 // If passed with arguments, sets the value and returns the target.
27160 function d3_rebind(target, source, method) {
27161     return function() {
27162         var value = method.apply(source, arguments);
27163         return value === source ? target : value;
27164     };
27165 }
27166
27167 // A per-domain session mutex backed by a cookie and dead man's
27168 // switch. If the session crashes, the mutex will auto-release
27169 // after 5 seconds.
27170
27171 function utilSessionMutex(name) {
27172     var mutex = {},
27173         intervalID;
27174
27175     function renew() {
27176         var expires = new Date();
27177         expires.setSeconds(expires.getSeconds() + 5);
27178         document.cookie = name + '=1; expires=' + expires.toUTCString();
27179     }
27180
27181     mutex.lock = function() {
27182         if (intervalID) return true;
27183         var cookie = document.cookie.replace(new RegExp('(?:(?:^|.*;)\\s*' + name + '\\s*\\=\\s*([^;]*).*$)|^.*$'), '$1');
27184         if (cookie) return false;
27185         renew();
27186         intervalID = window.setInterval(renew, 4000);
27187         return true;
27188     };
27189
27190     mutex.unlock = function() {
27191         if (!intervalID) return;
27192         document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT';
27193         clearInterval(intervalID);
27194         intervalID = null;
27195     };
27196
27197     mutex.locked = function() {
27198         return !!intervalID;
27199     };
27200
27201     return mutex;
27202 }
27203
27204 function utilSuggestNames(preset, suggestions) {
27205     preset = preset.id.split('/', 2);
27206     var k = preset[0],
27207         v = preset[1];
27208
27209     return function(value, callback) {
27210         var result = [];
27211         if (value && value.length > 2) {
27212             if (suggestions[k] && suggestions[k][v]) {
27213                 for (var sugg in suggestions[k][v]) {
27214                     var dist = utilEditDistance(value, sugg.substring(0, value.length));
27215                     if (dist < 3) {
27216                         result.push({
27217                             title: sugg,
27218                             value: sugg,
27219                             dist: dist
27220                         });
27221                     }
27222                 }
27223             }
27224             result.sort(function(a, b) {
27225                 return a.dist - b.dist;
27226             });
27227         }
27228         result = result.slice(0,3);
27229         callback(result);
27230     };
27231 }
27232
27233 function utilTriggerEvent(target, type) {
27234     target.each(function() {
27235         var evt = document.createEvent('HTMLEvents');
27236         evt.initEvent(type, true, true);
27237         this.dispatchEvent(evt);
27238     });
27239 }
27240
27241 function validationDeprecatedTag() {
27242
27243     var validation = function(changes) {
27244         var warnings = [];
27245         for (var i = 0; i < changes.created.length; i++) {
27246             var change = changes.created[i],
27247                 deprecatedTags = change.deprecatedTags();
27248
27249             if (!isEmpty(deprecatedTags)) {
27250                 var tags = utilTagText({ tags: deprecatedTags });
27251                 warnings.push({
27252                     id: 'deprecated_tags',
27253                     message: t('validations.deprecated_tags', { tags: tags }),
27254                     entity: change
27255                 });
27256             }
27257         }
27258
27259         return warnings;
27260     };
27261
27262
27263     return validation;
27264 }
27265
27266 function validationDisconnectedHighway() {
27267
27268     function isDisconnectedHighway(entity, graph) {
27269         if (!entity.tags.highway) return false;
27270         if (entity.geometry(graph) !== 'line') return false;
27271
27272         return graph.childNodes(entity)
27273             .every(function(vertex) {
27274                 var parents = graph.parentWays(vertex);
27275                 if (parents.length === 1) {  // standalone vertex
27276                     return true;
27277                 } else {                     // shared vertex
27278                     return !vertex.tags.entrance &&
27279                         parents.filter(function(parent) {
27280                             return parent.tags.highway && parent !== entity;
27281                         }).length === 0;
27282                 }
27283             });
27284     }
27285
27286
27287     var validation = function(changes, graph) {
27288         var warnings = [];
27289         for (var i = 0; i < changes.created.length; i++) {
27290             var entity = changes.created[i];
27291
27292             if (isDisconnectedHighway(entity, graph)) {
27293                 warnings.push({
27294                     id: 'disconnected_highway',
27295                     message: t('validations.disconnected_highway'),
27296                     tooltip: t('validations.disconnected_highway_tooltip'),
27297                     entity: entity
27298                 });
27299             }
27300         }
27301
27302         return warnings;
27303     };
27304
27305
27306     return validation;
27307 }
27308
27309 function validationManyDeletions() {
27310     var threshold = 100;
27311
27312     var validation = function(changes, graph) {
27313         var warnings = [];
27314         var nodes=0, ways=0, areas=0, relations=0;
27315
27316         changes.deleted.forEach(function(c) {
27317             if (c.type === 'node') {nodes++;}
27318             else if (c.type === 'way' && c.geometry(graph) === 'line') {ways++;}
27319             else if (c.type === 'way' && c.geometry(graph) === 'area') {areas++;}
27320             else if (c.type === 'relation') {relations++;}
27321         });
27322         if (changes.deleted.length > threshold) {
27323             warnings.push({
27324                 id: 'many_deletions',
27325                 message: t('validations.many_deletions',
27326                     { n: changes.deleted.length, p: nodes, l: ways, a:areas, r: relations })
27327             });
27328         }
27329
27330         return warnings;
27331     };
27332
27333
27334     return validation;
27335 }
27336
27337 function validationMissingTag() {
27338
27339     // Slightly stricter check than Entity#isUsed (#3091)
27340     function hasTags(entity, graph) {
27341         return without(Object.keys(entity.tags), 'area', 'name').length > 0 ||
27342             graph.parentRelations(entity).length > 0;
27343     }
27344
27345     var validation = function(changes, graph) {
27346         var types = ['point', 'line', 'area', 'relation'],
27347             warnings = [];
27348
27349         for (var i = 0; i < changes.created.length; i++) {
27350             var change = changes.created[i],
27351                 geometry = change.geometry(graph);
27352
27353             if (types.indexOf(geometry) !== -1 && !hasTags(change, graph)) {
27354                 warnings.push({
27355                     id: 'missing_tag',
27356                     message: t('validations.untagged_' + geometry),
27357                     tooltip: t('validations.untagged_' + geometry + '_tooltip'),
27358                     entity: change
27359                 });
27360             }
27361         }
27362
27363         return warnings;
27364     };
27365
27366
27367     return validation;
27368 }
27369
27370 function validationOldMultipolygon() {
27371
27372     return function validation(changes, graph) {
27373         var warnings = [];
27374         for (var i = 0; i < changes.created.length; i++) {
27375             var entity = changes.created[i];
27376             var parent = osmIsSimpleMultipolygonOuterMember(entity, graph);
27377             if (parent) {
27378                 warnings.push({
27379                     id: 'old_multipolygon',
27380                     message: t('validations.old_multipolygon'),
27381                     tooltip: t('validations.old_multipolygon_tooltip'),
27382                     entity: parent
27383                 });
27384             }
27385         }
27386         return warnings;
27387     };
27388 }
27389
27390 // https://github.com/openstreetmap/josm/blob/mirror/src/org/
27391 // openstreetmap/josm/data/validation/tests/UnclosedWays.java#L80
27392 function validationTagSuggestsArea() {
27393
27394     function tagSuggestsArea(tags) {
27395         if (isEmpty(tags)) return false;
27396
27397         var presence = ['landuse', 'amenities', 'tourism', 'shop'];
27398         for (var i = 0; i < presence.length; i++) {
27399             if (tags[presence[i]] !== undefined) {
27400                 return presence[i] + '=' + tags[presence[i]];
27401             }
27402         }
27403
27404         if (tags.building && tags.building === 'yes') return 'building=yes';
27405     }
27406
27407
27408     var validation = function(changes, graph) {
27409         var warnings = [];
27410         for (var i = 0; i < changes.created.length; i++) {
27411             var change = changes.created[i],
27412                 geometry = change.geometry(graph),
27413                 suggestion = (geometry === 'line' ? tagSuggestsArea(change.tags) : undefined);
27414
27415             if (suggestion) {
27416                 warnings.push({
27417                     id: 'tag_suggests_area',
27418                     message: t('validations.tag_suggests_area', { tag: suggestion }),
27419                     entity: change
27420                 });
27421             }
27422         }
27423
27424         return warnings;
27425     };
27426
27427
27428     return validation;
27429 }
27430
27431
27432
27433 var Validations = Object.freeze({
27434         validationDeprecatedTag: validationDeprecatedTag,
27435         validationDisconnectedHighway: validationDisconnectedHighway,
27436         validationManyDeletions: validationManyDeletions,
27437         validationMissingTag: validationMissingTag,
27438         validationOldMultipolygon: validationOldMultipolygon,
27439         validationTagSuggestsArea: validationTagSuggestsArea
27440 });
27441
27442 /**
27443  * Performs a deep comparison between two values to determine if they are
27444  * equivalent.
27445  *
27446  * **Note:** This method supports comparing arrays, array buffers, booleans,
27447  * date objects, error objects, maps, numbers, `Object` objects, regexes,
27448  * sets, strings, symbols, and typed arrays. `Object` objects are compared
27449  * by their own, not inherited, enumerable properties. Functions and DOM
27450  * nodes are compared by strict equality, i.e. `===`.
27451  *
27452  * @static
27453  * @memberOf _
27454  * @since 0.1.0
27455  * @category Lang
27456  * @param {*} value The value to compare.
27457  * @param {*} other The other value to compare.
27458  * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
27459  * @example
27460  *
27461  * var object = { 'a': 1 };
27462  * var other = { 'a': 1 };
27463  *
27464  * _.isEqual(object, other);
27465  * // => true
27466  *
27467  * object === other;
27468  * // => false
27469  */
27470 function isEqual(value, other) {
27471   return baseIsEqual(value, other);
27472 }
27473
27474 /*
27475     iD.Difference represents the difference between two graphs.
27476     It knows how to calculate the set of entities that were
27477     created, modified, or deleted, and also contains the logic
27478     for recursively extending a difference to the complete set
27479     of entities that will require a redraw, taking into account
27480     child and parent relationships.
27481  */
27482 function coreDifference(base, head) {
27483     var changes = {},
27484         difference$$1 = {},
27485         length = 0;
27486
27487
27488     function changed(h, b) {
27489         return h !== b && !isEqual(omit(h, 'v'), omit(b, 'v'));
27490     }
27491
27492
27493     forEach(head.entities, function(h, id) {
27494         var b = base.entities[id];
27495         if (changed(h, b)) {
27496             changes[id] = {base: b, head: h};
27497             length++;
27498         }
27499     });
27500
27501
27502     forEach(base.entities, function(b, id) {
27503         var h = head.entities[id];
27504         if (!changes[id] && changed(h, b)) {
27505             changes[id] = {base: b, head: h};
27506             length++;
27507         }
27508     });
27509
27510
27511     function addParents(parents, result) {
27512         for (var i = 0; i < parents.length; i++) {
27513             var parent = parents[i];
27514
27515             if (parent.id in result)
27516                 continue;
27517
27518             result[parent.id] = parent;
27519             addParents(head.parentRelations(parent), result);
27520         }
27521     }
27522
27523
27524     difference$$1.length = function() {
27525         return length;
27526     };
27527
27528
27529     difference$$1.changes = function() {
27530         return changes;
27531     };
27532
27533
27534     difference$$1.extantIDs = function() {
27535         var result = [];
27536         forEach(changes, function(change, id) {
27537             if (change.head) result.push(id);
27538         });
27539         return result;
27540     };
27541
27542
27543     difference$$1.modified = function() {
27544         var result = [];
27545         forEach(changes, function(change) {
27546             if (change.base && change.head) result.push(change.head);
27547         });
27548         return result;
27549     };
27550
27551
27552     difference$$1.created = function() {
27553         var result = [];
27554         forEach(changes, function(change) {
27555             if (!change.base && change.head) result.push(change.head);
27556         });
27557         return result;
27558     };
27559
27560
27561     difference$$1.deleted = function() {
27562         var result = [];
27563         forEach(changes, function(change) {
27564             if (change.base && !change.head) result.push(change.base);
27565         });
27566         return result;
27567     };
27568
27569
27570     difference$$1.summary = function() {
27571         var relevant = {};
27572
27573         function addEntity(entity, graph, changeType) {
27574             relevant[entity.id] = {
27575                 entity: entity,
27576                 graph: graph,
27577                 changeType: changeType
27578             };
27579         }
27580
27581         function addParents(entity) {
27582             var parents = head.parentWays(entity);
27583             for (var j = parents.length - 1; j >= 0; j--) {
27584                 var parent = parents[j];
27585                 if (!(parent.id in relevant)) addEntity(parent, head, 'modified');
27586             }
27587         }
27588
27589         forEach(changes, function(change) {
27590             if (change.head && change.head.geometry(head) !== 'vertex') {
27591                 addEntity(change.head, head, change.base ? 'modified' : 'created');
27592
27593             } else if (change.base && change.base.geometry(base) !== 'vertex') {
27594                 addEntity(change.base, base, 'deleted');
27595
27596             } else if (change.base && change.head) { // modified vertex
27597                 var moved    = !isEqual(change.base.loc,  change.head.loc),
27598                     retagged = !isEqual(change.base.tags, change.head.tags);
27599
27600                 if (moved) {
27601                     addParents(change.head);
27602                 }
27603
27604                 if (retagged || (moved && change.head.hasInterestingTags())) {
27605                     addEntity(change.head, head, 'modified');
27606                 }
27607
27608             } else if (change.head && change.head.hasInterestingTags()) { // created vertex
27609                 addEntity(change.head, head, 'created');
27610
27611             } else if (change.base && change.base.hasInterestingTags()) { // deleted vertex
27612                 addEntity(change.base, base, 'deleted');
27613             }
27614         });
27615
27616         return values$1(relevant);
27617     };
27618
27619
27620     difference$$1.complete = function(extent) {
27621         var result = {}, id, change;
27622
27623         for (id in changes) {
27624             change = changes[id];
27625
27626             var h = change.head,
27627                 b = change.base,
27628                 entity = h || b;
27629
27630             if (extent &&
27631                 (!h || !h.intersects(extent, head)) &&
27632                 (!b || !b.intersects(extent, base)))
27633                 continue;
27634
27635             result[id] = h;
27636
27637             if (entity.type === 'way') {
27638                 var nh = h ? h.nodes : [],
27639                     nb = b ? b.nodes : [],
27640                     diff, i;
27641
27642                 diff = difference(nh, nb);
27643                 for (i = 0; i < diff.length; i++) {
27644                     result[diff[i]] = head.hasEntity(diff[i]);
27645                 }
27646
27647                 diff = difference(nb, nh);
27648                 for (i = 0; i < diff.length; i++) {
27649                     result[diff[i]] = head.hasEntity(diff[i]);
27650                 }
27651             }
27652
27653             addParents(head.parentWays(entity), result);
27654             addParents(head.parentRelations(entity), result);
27655         }
27656
27657         return result;
27658     };
27659
27660
27661     return difference$$1;
27662 }
27663
27664 /** Used for built-in method references. */
27665 var objectProto$18 = Object.prototype;
27666
27667 /** Used to check objects for own properties. */
27668 var hasOwnProperty$15 = objectProto$18.hasOwnProperty;
27669
27670 /**
27671  * Assigns own enumerable string keyed properties of source objects to the
27672  * destination object. Source objects are applied from left to right.
27673  * Subsequent sources overwrite property assignments of previous sources.
27674  *
27675  * **Note:** This method mutates `object` and is loosely based on
27676  * [`Object.assign`](https://mdn.io/Object/assign).
27677  *
27678  * @static
27679  * @memberOf _
27680  * @since 0.10.0
27681  * @category Object
27682  * @param {Object} object The destination object.
27683  * @param {...Object} [sources] The source objects.
27684  * @returns {Object} Returns `object`.
27685  * @see _.assignIn
27686  * @example
27687  *
27688  * function Foo() {
27689  *   this.a = 1;
27690  * }
27691  *
27692  * function Bar() {
27693  *   this.c = 3;
27694  * }
27695  *
27696  * Foo.prototype.b = 2;
27697  * Bar.prototype.d = 4;
27698  *
27699  * _.assign({ 'a': 0 }, new Foo, new Bar);
27700  * // => { 'a': 1, 'c': 3 }
27701  */
27702 var assign = createAssigner(function(object, source) {
27703   if (isPrototype(source) || isArrayLike(source)) {
27704     copyObject(source, keys$1(source), object);
27705     return;
27706   }
27707   for (var key in source) {
27708     if (hasOwnProperty$15.call(source, key)) {
27709       assignValue(object, key, source[key]);
27710     }
27711   }
27712 });
27713
27714 /* Built-in method references for those with the same name as other `lodash` methods. */
27715 var nativeMax$3 = Math.max;
27716
27717 /**
27718  * Checks if `value` is in `collection`. If `collection` is a string, it's
27719  * checked for a substring of `value`, otherwise
27720  * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
27721  * is used for equality comparisons. If `fromIndex` is negative, it's used as
27722  * the offset from the end of `collection`.
27723  *
27724  * @static
27725  * @memberOf _
27726  * @since 0.1.0
27727  * @category Collection
27728  * @param {Array|Object|string} collection The collection to inspect.
27729  * @param {*} value The value to search for.
27730  * @param {number} [fromIndex=0] The index to search from.
27731  * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
27732  * @returns {boolean} Returns `true` if `value` is found, else `false`.
27733  * @example
27734  *
27735  * _.includes([1, 2, 3], 1);
27736  * // => true
27737  *
27738  * _.includes([1, 2, 3], 1, 2);
27739  * // => false
27740  *
27741  * _.includes({ 'a': 1, 'b': 2 }, 1);
27742  * // => true
27743  *
27744  * _.includes('abcd', 'bc');
27745  * // => true
27746  */
27747 function includes(collection, value, fromIndex, guard) {
27748   collection = isArrayLike(collection) ? collection : values$1(collection);
27749   fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
27750
27751   var length = collection.length;
27752   if (fromIndex < 0) {
27753     fromIndex = nativeMax$3(length + fromIndex, 0);
27754   }
27755   return isString(collection)
27756     ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
27757     : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
27758 }
27759
27760 function coreGraph(other, mutable) {
27761     if (!(this instanceof coreGraph)) return new coreGraph(other, mutable);
27762
27763     if (other instanceof coreGraph) {
27764         var base = other.base();
27765         this.entities = assign(Object.create(base.entities), other.entities);
27766         this._parentWays = assign(Object.create(base.parentWays), other._parentWays);
27767         this._parentRels = assign(Object.create(base.parentRels), other._parentRels);
27768
27769     } else {
27770         this.entities = Object.create({});
27771         this._parentWays = Object.create({});
27772         this._parentRels = Object.create({});
27773         this.rebase(other || [], [this]);
27774     }
27775
27776     this.transients = {};
27777     this._childNodes = {};
27778     this.frozen = !mutable;
27779 }
27780
27781
27782 coreGraph.prototype = {
27783
27784     hasEntity: function(id) {
27785         return this.entities[id];
27786     },
27787
27788
27789     entity: function(id) {
27790         var entity = this.entities[id];
27791
27792         //https://github.com/openstreetmap/iD/issues/3973#issuecomment-307052376
27793         if (!entity) {
27794             entity = this.entities.__proto__[id];  // eslint-disable-line no-proto
27795         }
27796
27797         if (!entity) {
27798             throw new Error('entity ' + id + ' not found');
27799         }
27800         return entity;
27801     },
27802
27803
27804     transient: function(entity, key, fn) {
27805         var id = entity.id,
27806             transients = this.transients[id] ||
27807             (this.transients[id] = {});
27808
27809         if (transients[key] !== undefined) {
27810             return transients[key];
27811         }
27812
27813         transients[key] = fn.call(entity);
27814
27815         return transients[key];
27816     },
27817
27818
27819     parentWays: function(entity) {
27820         var parents = this._parentWays[entity.id],
27821             result = [];
27822
27823         if (parents) {
27824             for (var i = 0; i < parents.length; i++) {
27825                 result.push(this.entity(parents[i]));
27826             }
27827         }
27828         return result;
27829     },
27830
27831
27832     isPoi: function(entity) {
27833         var parentWays = this._parentWays[entity.id];
27834         return !parentWays || parentWays.length === 0;
27835     },
27836
27837
27838     isShared: function(entity) {
27839         var parentWays = this._parentWays[entity.id];
27840         return parentWays && parentWays.length > 1;
27841     },
27842
27843
27844     parentRelations: function(entity) {
27845         var parents = this._parentRels[entity.id],
27846             result = [];
27847
27848         if (parents) {
27849             for (var i = 0; i < parents.length; i++) {
27850                 result.push(this.entity(parents[i]));
27851             }
27852         }
27853         return result;
27854     },
27855
27856
27857     childNodes: function(entity) {
27858         if (this._childNodes[entity.id]) return this._childNodes[entity.id];
27859         if (!entity.nodes) return [];
27860
27861         var nodes = [];
27862         for (var i = 0; i < entity.nodes.length; i++) {
27863             nodes[i] = this.entity(entity.nodes[i]);
27864         }
27865
27866         if (debug) Object.freeze(nodes);
27867
27868         this._childNodes[entity.id] = nodes;
27869         return this._childNodes[entity.id];
27870     },
27871
27872
27873     base: function() {
27874         return {
27875             'entities': utilGetPrototypeOf(this.entities),
27876             'parentWays': utilGetPrototypeOf(this._parentWays),
27877             'parentRels': utilGetPrototypeOf(this._parentRels)
27878         };
27879     },
27880
27881
27882     // Unlike other graph methods, rebase mutates in place. This is because it
27883     // is used only during the history operation that merges newly downloaded
27884     // data into each state. To external consumers, it should appear as if the
27885     // graph always contained the newly downloaded data.
27886     rebase: function(entities, stack, force) {
27887         var base = this.base(),
27888             i, j, k, id;
27889
27890         for (i = 0; i < entities.length; i++) {
27891             var entity = entities[i];
27892
27893             if (!entity.visible || (!force && base.entities[entity.id]))
27894                 continue;
27895
27896             // Merging data into the base graph
27897             base.entities[entity.id] = entity;
27898             this._updateCalculated(undefined, entity, base.parentWays, base.parentRels);
27899
27900             // Restore provisionally-deleted nodes that are discovered to have an extant parent
27901             if (entity.type === 'way') {
27902                 for (j = 0; j < entity.nodes.length; j++) {
27903                     id = entity.nodes[j];
27904                     for (k = 1; k < stack.length; k++) {
27905                         var ents = stack[k].entities;
27906                         if (ents.hasOwnProperty(id) && ents[id] === undefined) {
27907                             delete ents[id];
27908                         }
27909                     }
27910                 }
27911             }
27912         }
27913
27914         for (i = 0; i < stack.length; i++) {
27915             stack[i]._updateRebased();
27916         }
27917     },
27918
27919
27920     _updateRebased: function() {
27921         var base = this.base(),
27922             i, k, child, id, keys;
27923
27924         keys = Object.keys(this._parentWays);
27925         for (i = 0; i < keys.length; i++) {
27926             child = keys[i];
27927             if (base.parentWays[child]) {
27928                 for (k = 0; k < base.parentWays[child].length; k++) {
27929                     id = base.parentWays[child][k];
27930                     if (!this.entities.hasOwnProperty(id) && !includes(this._parentWays[child], id)) {
27931                         this._parentWays[child].push(id);
27932                     }
27933                 }
27934             }
27935         }
27936
27937         keys = Object.keys(this._parentRels);
27938         for (i = 0; i < keys.length; i++) {
27939             child = keys[i];
27940             if (base.parentRels[child]) {
27941                 for (k = 0; k < base.parentRels[child].length; k++) {
27942                     id = base.parentRels[child][k];
27943                     if (!this.entities.hasOwnProperty(id) && !includes(this._parentRels[child], id)) {
27944                         this._parentRels[child].push(id);
27945                     }
27946                 }
27947             }
27948         }
27949
27950         this.transients = {};
27951
27952         // this._childNodes is not updated, under the assumption that
27953         // ways are always downloaded with their child nodes.
27954     },
27955
27956
27957     // Updates calculated properties (parentWays, parentRels) for the specified change
27958     _updateCalculated: function(oldentity, entity, parentWays, parentRels) {
27959
27960         parentWays = parentWays || this._parentWays;
27961         parentRels = parentRels || this._parentRels;
27962
27963         var type = entity && entity.type || oldentity && oldentity.type,
27964             removed, added, ways, rels, i;
27965
27966
27967         if (type === 'way') {
27968
27969             // Update parentWays
27970             if (oldentity && entity) {
27971                 removed = difference(oldentity.nodes, entity.nodes);
27972                 added = difference(entity.nodes, oldentity.nodes);
27973             } else if (oldentity) {
27974                 removed = oldentity.nodes;
27975                 added = [];
27976             } else if (entity) {
27977                 removed = [];
27978                 added = entity.nodes;
27979             }
27980             for (i = 0; i < removed.length; i++) {
27981                 parentWays[removed[i]] = without(parentWays[removed[i]], oldentity.id);
27982             }
27983             for (i = 0; i < added.length; i++) {
27984                 ways = without(parentWays[added[i]], entity.id);
27985                 ways.push(entity.id);
27986                 parentWays[added[i]] = ways;
27987             }
27988
27989         } else if (type === 'relation') {
27990
27991             // Update parentRels
27992             if (oldentity && entity) {
27993                 removed = difference(oldentity.members, entity.members);
27994                 added = difference(entity.members, oldentity);
27995             } else if (oldentity) {
27996                 removed = oldentity.members;
27997                 added = [];
27998             } else if (entity) {
27999                 removed = [];
28000                 added = entity.members;
28001             }
28002             for (i = 0; i < removed.length; i++) {
28003                 parentRels[removed[i].id] = without(parentRels[removed[i].id], oldentity.id);
28004             }
28005             for (i = 0; i < added.length; i++) {
28006                 rels = without(parentRels[added[i].id], entity.id);
28007                 rels.push(entity.id);
28008                 parentRels[added[i].id] = rels;
28009             }
28010         }
28011     },
28012
28013
28014     replace: function(entity) {
28015         if (this.entities[entity.id] === entity)
28016             return this;
28017
28018         return this.update(function() {
28019             this._updateCalculated(this.entities[entity.id], entity);
28020             this.entities[entity.id] = entity;
28021         });
28022     },
28023
28024
28025     remove: function(entity) {
28026         return this.update(function() {
28027             this._updateCalculated(entity, undefined);
28028             this.entities[entity.id] = undefined;
28029         });
28030     },
28031
28032
28033     revert: function(id) {
28034         var baseEntity = this.base().entities[id],
28035             headEntity = this.entities[id];
28036
28037         if (headEntity === baseEntity)
28038             return this;
28039
28040         return this.update(function() {
28041             this._updateCalculated(headEntity, baseEntity);
28042             delete this.entities[id];
28043         });
28044     },
28045
28046
28047     update: function() {
28048         var graph = this.frozen ? coreGraph(this, true) : this;
28049
28050         for (var i = 0; i < arguments.length; i++) {
28051             arguments[i].call(graph, graph);
28052         }
28053
28054         if (this.frozen) graph.frozen = true;
28055
28056         return graph;
28057     },
28058
28059
28060     // Obliterates any existing entities
28061     load: function(entities) {
28062         var base = this.base();
28063         this.entities = Object.create(base.entities);
28064
28065         for (var i in entities) {
28066             this.entities[i] = entities[i];
28067             this._updateCalculated(base.entities[i], this.entities[i]);
28068         }
28069
28070         return this;
28071     }
28072 };
28073
28074 var quickselect_1 = quickselect;
28075 var default_1 = quickselect;
28076
28077 function quickselect(arr, k, left, right, compare) {
28078     quickselectStep(arr, k, left || 0, right || (arr.length - 1), compare || defaultCompare);
28079 }
28080
28081 function quickselectStep(arr, k, left, right, compare) {
28082
28083     while (right > left) {
28084         if (right - left > 600) {
28085             var n = right - left + 1;
28086             var m = k - left + 1;
28087             var z = Math.log(n);
28088             var s = 0.5 * Math.exp(2 * z / 3);
28089             var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);
28090             var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));
28091             var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));
28092             quickselectStep(arr, k, newLeft, newRight, compare);
28093         }
28094
28095         var t = arr[k];
28096         var i = left;
28097         var j = right;
28098
28099         swap(arr, left, k);
28100         if (compare(arr[right], t) > 0) swap(arr, left, right);
28101
28102         while (i < j) {
28103             swap(arr, i, j);
28104             i++;
28105             j--;
28106             while (compare(arr[i], t) < 0) i++;
28107             while (compare(arr[j], t) > 0) j--;
28108         }
28109
28110         if (compare(arr[left], t) === 0) swap(arr, left, j);
28111         else {
28112             j++;
28113             swap(arr, j, right);
28114         }
28115
28116         if (j <= k) left = j + 1;
28117         if (k <= j) right = j - 1;
28118     }
28119 }
28120
28121 function swap(arr, i, j) {
28122     var tmp = arr[i];
28123     arr[i] = arr[j];
28124     arr[j] = tmp;
28125 }
28126
28127 function defaultCompare(a, b) {
28128     return a < b ? -1 : a > b ? 1 : 0;
28129 }
28130
28131 quickselect_1.default = default_1;
28132
28133 var rbush_1 = rbush;
28134 var default_1$1 = rbush;
28135
28136
28137
28138 function rbush(maxEntries, format) {
28139     if (!(this instanceof rbush)) return new rbush(maxEntries, format);
28140
28141     // max entries in a node is 9 by default; min node fill is 40% for best performance
28142     this._maxEntries = Math.max(4, maxEntries || 9);
28143     this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));
28144
28145     if (format) {
28146         this._initFormat(format);
28147     }
28148
28149     this.clear();
28150 }
28151
28152 rbush.prototype = {
28153
28154     all: function () {
28155         return this._all(this.data, []);
28156     },
28157
28158     search: function (bbox) {
28159
28160         var node = this.data,
28161             result = [],
28162             toBBox = this.toBBox;
28163
28164         if (!intersects$1(bbox, node)) return result;
28165
28166         var nodesToSearch = [],
28167             i, len, child, childBBox;
28168
28169         while (node) {
28170             for (i = 0, len = node.children.length; i < len; i++) {
28171
28172                 child = node.children[i];
28173                 childBBox = node.leaf ? toBBox(child) : child;
28174
28175                 if (intersects$1(bbox, childBBox)) {
28176                     if (node.leaf) result.push(child);
28177                     else if (contains$2(bbox, childBBox)) this._all(child, result);
28178                     else nodesToSearch.push(child);
28179                 }
28180             }
28181             node = nodesToSearch.pop();
28182         }
28183
28184         return result;
28185     },
28186
28187     collides: function (bbox) {
28188
28189         var node = this.data,
28190             toBBox = this.toBBox;
28191
28192         if (!intersects$1(bbox, node)) return false;
28193
28194         var nodesToSearch = [],
28195             i, len, child, childBBox;
28196
28197         while (node) {
28198             for (i = 0, len = node.children.length; i < len; i++) {
28199
28200                 child = node.children[i];
28201                 childBBox = node.leaf ? toBBox(child) : child;
28202
28203                 if (intersects$1(bbox, childBBox)) {
28204                     if (node.leaf || contains$2(bbox, childBBox)) return true;
28205                     nodesToSearch.push(child);
28206                 }
28207             }
28208             node = nodesToSearch.pop();
28209         }
28210
28211         return false;
28212     },
28213
28214     load: function (data) {
28215         if (!(data && data.length)) return this;
28216
28217         if (data.length < this._minEntries) {
28218             for (var i = 0, len = data.length; i < len; i++) {
28219                 this.insert(data[i]);
28220             }
28221             return this;
28222         }
28223
28224         // recursively build the tree with the given data from scratch using OMT algorithm
28225         var node = this._build(data.slice(), 0, data.length - 1, 0);
28226
28227         if (!this.data.children.length) {
28228             // save as is if tree is empty
28229             this.data = node;
28230
28231         } else if (this.data.height === node.height) {
28232             // split root if trees have the same height
28233             this._splitRoot(this.data, node);
28234
28235         } else {
28236             if (this.data.height < node.height) {
28237                 // swap trees if inserted one is bigger
28238                 var tmpNode = this.data;
28239                 this.data = node;
28240                 node = tmpNode;
28241             }
28242
28243             // insert the small tree into the large tree at appropriate level
28244             this._insert(node, this.data.height - node.height - 1, true);
28245         }
28246
28247         return this;
28248     },
28249
28250     insert: function (item) {
28251         if (item) this._insert(item, this.data.height - 1);
28252         return this;
28253     },
28254
28255     clear: function () {
28256         this.data = createNode([]);
28257         return this;
28258     },
28259
28260     remove: function (item, equalsFn) {
28261         if (!item) return this;
28262
28263         var node = this.data,
28264             bbox = this.toBBox(item),
28265             path = [],
28266             indexes = [],
28267             i, parent, index, goingUp;
28268
28269         // depth-first iterative tree traversal
28270         while (node || path.length) {
28271
28272             if (!node) { // go up
28273                 node = path.pop();
28274                 parent = path[path.length - 1];
28275                 i = indexes.pop();
28276                 goingUp = true;
28277             }
28278
28279             if (node.leaf) { // check current node
28280                 index = findItem(item, node.children, equalsFn);
28281
28282                 if (index !== -1) {
28283                     // item found, remove the item and condense tree upwards
28284                     node.children.splice(index, 1);
28285                     path.push(node);
28286                     this._condense(path);
28287                     return this;
28288                 }
28289             }
28290
28291             if (!goingUp && !node.leaf && contains$2(node, bbox)) { // go down
28292                 path.push(node);
28293                 indexes.push(i);
28294                 i = 0;
28295                 parent = node;
28296                 node = node.children[0];
28297
28298             } else if (parent) { // go right
28299                 i++;
28300                 node = parent.children[i];
28301                 goingUp = false;
28302
28303             } else node = null; // nothing found
28304         }
28305
28306         return this;
28307     },
28308
28309     toBBox: function (item) { return item; },
28310
28311     compareMinX: compareNodeMinX,
28312     compareMinY: compareNodeMinY,
28313
28314     toJSON: function () { return this.data; },
28315
28316     fromJSON: function (data) {
28317         this.data = data;
28318         return this;
28319     },
28320
28321     _all: function (node, result) {
28322         var nodesToSearch = [];
28323         while (node) {
28324             if (node.leaf) result.push.apply(result, node.children);
28325             else nodesToSearch.push.apply(nodesToSearch, node.children);
28326
28327             node = nodesToSearch.pop();
28328         }
28329         return result;
28330     },
28331
28332     _build: function (items, left, right, height) {
28333
28334         var N = right - left + 1,
28335             M = this._maxEntries,
28336             node;
28337
28338         if (N <= M) {
28339             // reached leaf level; return leaf
28340             node = createNode(items.slice(left, right + 1));
28341             calcBBox(node, this.toBBox);
28342             return node;
28343         }
28344
28345         if (!height) {
28346             // target height of the bulk-loaded tree
28347             height = Math.ceil(Math.log(N) / Math.log(M));
28348
28349             // target number of root entries to maximize storage utilization
28350             M = Math.ceil(N / Math.pow(M, height - 1));
28351         }
28352
28353         node = createNode([]);
28354         node.leaf = false;
28355         node.height = height;
28356
28357         // split the items into M mostly square tiles
28358
28359         var N2 = Math.ceil(N / M),
28360             N1 = N2 * Math.ceil(Math.sqrt(M)),
28361             i, j, right2, right3;
28362
28363         multiSelect(items, left, right, N1, this.compareMinX);
28364
28365         for (i = left; i <= right; i += N1) {
28366
28367             right2 = Math.min(i + N1 - 1, right);
28368
28369             multiSelect(items, i, right2, N2, this.compareMinY);
28370
28371             for (j = i; j <= right2; j += N2) {
28372
28373                 right3 = Math.min(j + N2 - 1, right2);
28374
28375                 // pack each entry recursively
28376                 node.children.push(this._build(items, j, right3, height - 1));
28377             }
28378         }
28379
28380         calcBBox(node, this.toBBox);
28381
28382         return node;
28383     },
28384
28385     _chooseSubtree: function (bbox, node, level, path) {
28386
28387         var i, len, child, targetNode, area, enlargement, minArea, minEnlargement;
28388
28389         while (true) {
28390             path.push(node);
28391
28392             if (node.leaf || path.length - 1 === level) break;
28393
28394             minArea = minEnlargement = Infinity;
28395
28396             for (i = 0, len = node.children.length; i < len; i++) {
28397                 child = node.children[i];
28398                 area = bboxArea(child);
28399                 enlargement = enlargedArea(bbox, child) - area;
28400
28401                 // choose entry with the least area enlargement
28402                 if (enlargement < minEnlargement) {
28403                     minEnlargement = enlargement;
28404                     minArea = area < minArea ? area : minArea;
28405                     targetNode = child;
28406
28407                 } else if (enlargement === minEnlargement) {
28408                     // otherwise choose one with the smallest area
28409                     if (area < minArea) {
28410                         minArea = area;
28411                         targetNode = child;
28412                     }
28413                 }
28414             }
28415
28416             node = targetNode || node.children[0];
28417         }
28418
28419         return node;
28420     },
28421
28422     _insert: function (item, level, isNode) {
28423
28424         var toBBox = this.toBBox,
28425             bbox = isNode ? item : toBBox(item),
28426             insertPath = [];
28427
28428         // find the best node for accommodating the item, saving all nodes along the path too
28429         var node = this._chooseSubtree(bbox, this.data, level, insertPath);
28430
28431         // put the item into the node
28432         node.children.push(item);
28433         extend$1(node, bbox);
28434
28435         // split on node overflow; propagate upwards if necessary
28436         while (level >= 0) {
28437             if (insertPath[level].children.length > this._maxEntries) {
28438                 this._split(insertPath, level);
28439                 level--;
28440             } else break;
28441         }
28442
28443         // adjust bboxes along the insertion path
28444         this._adjustParentBBoxes(bbox, insertPath, level);
28445     },
28446
28447     // split overflowed node into two
28448     _split: function (insertPath, level) {
28449
28450         var node = insertPath[level],
28451             M = node.children.length,
28452             m = this._minEntries;
28453
28454         this._chooseSplitAxis(node, m, M);
28455
28456         var splitIndex = this._chooseSplitIndex(node, m, M);
28457
28458         var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex));
28459         newNode.height = node.height;
28460         newNode.leaf = node.leaf;
28461
28462         calcBBox(node, this.toBBox);
28463         calcBBox(newNode, this.toBBox);
28464
28465         if (level) insertPath[level - 1].children.push(newNode);
28466         else this._splitRoot(node, newNode);
28467     },
28468
28469     _splitRoot: function (node, newNode) {
28470         // split root node
28471         this.data = createNode([node, newNode]);
28472         this.data.height = node.height + 1;
28473         this.data.leaf = false;
28474         calcBBox(this.data, this.toBBox);
28475     },
28476
28477     _chooseSplitIndex: function (node, m, M) {
28478
28479         var i, bbox1, bbox2, overlap, area, minOverlap, minArea, index;
28480
28481         minOverlap = minArea = Infinity;
28482
28483         for (i = m; i <= M - m; i++) {
28484             bbox1 = distBBox(node, 0, i, this.toBBox);
28485             bbox2 = distBBox(node, i, M, this.toBBox);
28486
28487             overlap = intersectionArea(bbox1, bbox2);
28488             area = bboxArea(bbox1) + bboxArea(bbox2);
28489
28490             // choose distribution with minimum overlap
28491             if (overlap < minOverlap) {
28492                 minOverlap = overlap;
28493                 index = i;
28494
28495                 minArea = area < minArea ? area : minArea;
28496
28497             } else if (overlap === minOverlap) {
28498                 // otherwise choose distribution with minimum area
28499                 if (area < minArea) {
28500                     minArea = area;
28501                     index = i;
28502                 }
28503             }
28504         }
28505
28506         return index;
28507     },
28508
28509     // sorts node children by the best axis for split
28510     _chooseSplitAxis: function (node, m, M) {
28511
28512         var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX,
28513             compareMinY = node.leaf ? this.compareMinY : compareNodeMinY,
28514             xMargin = this._allDistMargin(node, m, M, compareMinX),
28515             yMargin = this._allDistMargin(node, m, M, compareMinY);
28516
28517         // if total distributions margin value is minimal for x, sort by minX,
28518         // otherwise it's already sorted by minY
28519         if (xMargin < yMargin) node.children.sort(compareMinX);
28520     },
28521
28522     // total margin of all possible split distributions where each node is at least m full
28523     _allDistMargin: function (node, m, M, compare) {
28524
28525         node.children.sort(compare);
28526
28527         var toBBox = this.toBBox,
28528             leftBBox = distBBox(node, 0, m, toBBox),
28529             rightBBox = distBBox(node, M - m, M, toBBox),
28530             margin = bboxMargin(leftBBox) + bboxMargin(rightBBox),
28531             i, child;
28532
28533         for (i = m; i < M - m; i++) {
28534             child = node.children[i];
28535             extend$1(leftBBox, node.leaf ? toBBox(child) : child);
28536             margin += bboxMargin(leftBBox);
28537         }
28538
28539         for (i = M - m - 1; i >= m; i--) {
28540             child = node.children[i];
28541             extend$1(rightBBox, node.leaf ? toBBox(child) : child);
28542             margin += bboxMargin(rightBBox);
28543         }
28544
28545         return margin;
28546     },
28547
28548     _adjustParentBBoxes: function (bbox, path, level) {
28549         // adjust bboxes along the given tree path
28550         for (var i = level; i >= 0; i--) {
28551             extend$1(path[i], bbox);
28552         }
28553     },
28554
28555     _condense: function (path) {
28556         // go through the path, removing empty nodes and updating bboxes
28557         for (var i = path.length - 1, siblings; i >= 0; i--) {
28558             if (path[i].children.length === 0) {
28559                 if (i > 0) {
28560                     siblings = path[i - 1].children;
28561                     siblings.splice(siblings.indexOf(path[i]), 1);
28562
28563                 } else this.clear();
28564
28565             } else calcBBox(path[i], this.toBBox);
28566         }
28567     },
28568
28569     _initFormat: function (format) {
28570         // data format (minX, minY, maxX, maxY accessors)
28571
28572         // uses eval-type function compilation instead of just accepting a toBBox function
28573         // because the algorithms are very sensitive to sorting functions performance,
28574         // so they should be dead simple and without inner calls
28575
28576         var compareArr = ['return a', ' - b', ';'];
28577
28578         this.compareMinX = new Function('a', 'b', compareArr.join(format[0]));
28579         this.compareMinY = new Function('a', 'b', compareArr.join(format[1]));
28580
28581         this.toBBox = new Function('a',
28582             'return {minX: a' + format[0] +
28583             ', minY: a' + format[1] +
28584             ', maxX: a' + format[2] +
28585             ', maxY: a' + format[3] + '};');
28586     }
28587 };
28588
28589 function findItem(item, items, equalsFn) {
28590     if (!equalsFn) return items.indexOf(item);
28591
28592     for (var i = 0; i < items.length; i++) {
28593         if (equalsFn(item, items[i])) return i;
28594     }
28595     return -1;
28596 }
28597
28598 // calculate node's bbox from bboxes of its children
28599 function calcBBox(node, toBBox) {
28600     distBBox(node, 0, node.children.length, toBBox, node);
28601 }
28602
28603 // min bounding rectangle of node children from k to p-1
28604 function distBBox(node, k, p, toBBox, destNode) {
28605     if (!destNode) destNode = createNode(null);
28606     destNode.minX = Infinity;
28607     destNode.minY = Infinity;
28608     destNode.maxX = -Infinity;
28609     destNode.maxY = -Infinity;
28610
28611     for (var i = k, child; i < p; i++) {
28612         child = node.children[i];
28613         extend$1(destNode, node.leaf ? toBBox(child) : child);
28614     }
28615
28616     return destNode;
28617 }
28618
28619 function extend$1(a, b) {
28620     a.minX = Math.min(a.minX, b.minX);
28621     a.minY = Math.min(a.minY, b.minY);
28622     a.maxX = Math.max(a.maxX, b.maxX);
28623     a.maxY = Math.max(a.maxY, b.maxY);
28624     return a;
28625 }
28626
28627 function compareNodeMinX(a, b) { return a.minX - b.minX; }
28628 function compareNodeMinY(a, b) { return a.minY - b.minY; }
28629
28630 function bboxArea(a)   { return (a.maxX - a.minX) * (a.maxY - a.minY); }
28631 function bboxMargin(a) { return (a.maxX - a.minX) + (a.maxY - a.minY); }
28632
28633 function enlargedArea(a, b) {
28634     return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) *
28635            (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY));
28636 }
28637
28638 function intersectionArea(a, b) {
28639     var minX = Math.max(a.minX, b.minX),
28640         minY = Math.max(a.minY, b.minY),
28641         maxX = Math.min(a.maxX, b.maxX),
28642         maxY = Math.min(a.maxY, b.maxY);
28643
28644     return Math.max(0, maxX - minX) *
28645            Math.max(0, maxY - minY);
28646 }
28647
28648 function contains$2(a, b) {
28649     return a.minX <= b.minX &&
28650            a.minY <= b.minY &&
28651            b.maxX <= a.maxX &&
28652            b.maxY <= a.maxY;
28653 }
28654
28655 function intersects$1(a, b) {
28656     return b.minX <= a.maxX &&
28657            b.minY <= a.maxY &&
28658            b.maxX >= a.minX &&
28659            b.maxY >= a.minY;
28660 }
28661
28662 function createNode(children) {
28663     return {
28664         children: children,
28665         height: 1,
28666         leaf: true,
28667         minX: Infinity,
28668         minY: Infinity,
28669         maxX: -Infinity,
28670         maxY: -Infinity
28671     };
28672 }
28673
28674 // sort an array so that items come in groups of n unsorted items, with groups sorted between each other;
28675 // combines selection algorithm with binary divide & conquer approach
28676
28677 function multiSelect(arr, left, right, n, compare) {
28678     var stack = [left, right],
28679         mid;
28680
28681     while (stack.length) {
28682         right = stack.pop();
28683         left = stack.pop();
28684
28685         if (right - left <= n) continue;
28686
28687         mid = left + Math.ceil((right - left) / n / 2) * n;
28688         quickselect_1(arr, mid, left, right, compare);
28689
28690         stack.push(left, mid, mid, right);
28691     }
28692 }
28693
28694 rbush_1.default = default_1$1;
28695
28696 function coreTree(head) {
28697     var rtree = rbush_1(),
28698         bboxes = {},
28699         tree = {};
28700
28701
28702     function entityBBox(entity) {
28703         var bbox = entity.extent(head).bbox();
28704         bbox.id = entity.id;
28705         bboxes[entity.id] = bbox;
28706         return bbox;
28707     }
28708
28709
28710     function updateParents(entity, insertions, memo) {
28711         head.parentWays(entity).forEach(function(way) {
28712             if (bboxes[way.id]) {
28713                 rtree.remove(bboxes[way.id]);
28714                 insertions[way.id] = way;
28715             }
28716             updateParents(way, insertions, memo);
28717         });
28718
28719         head.parentRelations(entity).forEach(function(relation) {
28720             if (memo[entity.id]) return;
28721             memo[entity.id] = true;
28722             if (bboxes[relation.id]) {
28723                 rtree.remove(bboxes[relation.id]);
28724                 insertions[relation.id] = relation;
28725             }
28726             updateParents(relation, insertions, memo);
28727         });
28728     }
28729
28730
28731     tree.rebase = function(entities, force) {
28732         var insertions = {};
28733
28734         for (var i = 0; i < entities.length; i++) {
28735             var entity = entities[i];
28736
28737             if (!entity.visible)
28738                 continue;
28739
28740             if (head.entities.hasOwnProperty(entity.id) || bboxes[entity.id]) {
28741                 if (!force) {
28742                     continue;
28743                 } else if (bboxes[entity.id]) {
28744                     rtree.remove(bboxes[entity.id]);
28745                 }
28746             }
28747
28748             insertions[entity.id] = entity;
28749             updateParents(entity, insertions, {});
28750         }
28751
28752         rtree.load(map$4(insertions, entityBBox));
28753
28754         return tree;
28755     };
28756
28757
28758     tree.intersects = function(extent, graph) {
28759         if (graph !== head) {
28760             var diff = coreDifference(head, graph),
28761                 insertions = {};
28762
28763             head = graph;
28764
28765             diff.deleted().forEach(function(entity) {
28766                 rtree.remove(bboxes[entity.id]);
28767                 delete bboxes[entity.id];
28768             });
28769
28770             diff.modified().forEach(function(entity) {
28771                 rtree.remove(bboxes[entity.id]);
28772                 insertions[entity.id] = entity;
28773                 updateParents(entity, insertions, {});
28774             });
28775
28776             diff.created().forEach(function(entity) {
28777                 insertions[entity.id] = entity;
28778             });
28779
28780             rtree.load(map$4(insertions, entityBBox));
28781         }
28782
28783         return rtree.search(extent.bbox()).map(function(bbox) {
28784             return head.entity(bbox.id);
28785         });
28786     };
28787
28788
28789     return tree;
28790 }
28791
28792 /*
28793  * This code is licensed under the MIT license.
28794  *
28795  * Copyright © 2013, iD authors.
28796  *
28797  * Portions copyright © 2011, Keith Cirkel
28798  * See https://github.com/keithamus/jwerty
28799  *
28800  */
28801 function d3keybinding(namespace) {
28802     var bindings = [];
28803
28804
28805     function testBindings(isCapturing) {
28806         var didMatch = false,
28807             i, binding;
28808
28809         // Most key shortcuts will accept either lower or uppercase ('h' or 'H'),
28810         // so we don't strictly match on the shift key, but we prioritize
28811         // shifted bindings first, and fallback to unshifted only if no match.
28812         // (This lets us differentiate between '←'/'⇧←' or '⌘Z'/'⌘⇧Z')
28813
28814         // priority match shifted bindings first
28815         for (i = 0; i < bindings.length; i++) {
28816             binding = bindings[i];
28817             if (!binding.event.modifiers.shiftKey) continue;  // no shift
28818             if (!!binding.capture !== isCapturing) continue;
28819             if (matches(binding, true)) {
28820                 binding.callback();
28821                 didMatch = true;
28822             }
28823         }
28824
28825         // then unshifted bindings
28826         if (didMatch) return;
28827         for (i = 0; i < bindings.length; i++) {
28828             binding = bindings[i];
28829             if (binding.event.modifiers.shiftKey) continue;   // shift
28830             if (!!binding.capture !== isCapturing) continue;
28831             if (matches(binding, false)) {
28832                 binding.callback();
28833             }
28834         }
28835
28836
28837         function matches(binding, testShift) {
28838             var event$$1 = event;
28839             var isMatch = false;
28840             var tryKeyCode = true;
28841
28842             // Prefer a match on `KeyboardEvent.key`
28843             if (event$$1.key !== undefined) {
28844                 tryKeyCode = (event$$1.key.charCodeAt(0) > 255);  // outside ISO-Latin-1
28845                 isMatch = true;
28846
28847                 if (binding.event.key === undefined) {
28848                     isMatch = false;
28849                 } else if (Array.isArray(binding.event.key)) {
28850                     if (binding.event.key.map(function(s) { return s.toLowerCase(); }).indexOf(event$$1.key.toLowerCase()) === -1)
28851                         isMatch = false;
28852                 } else {
28853                     if (event$$1.key.toLowerCase() !== binding.event.key.toLowerCase())
28854                         isMatch = false;
28855                 }
28856             }
28857
28858             // Fallback match on `KeyboardEvent.keyCode`, can happen if:
28859             // - browser doesn't support `KeyboardEvent.key`
28860             // - `KeyboardEvent.key` is outside ISO-Latin-1 range (cyrillic?)
28861             if (!isMatch && tryKeyCode) {
28862                 isMatch = (event$$1.keyCode === binding.event.keyCode);
28863             }
28864
28865             if (!isMatch) return false;
28866
28867             // test modifier keys
28868             if (!(event$$1.ctrlKey && event$$1.altKey)) {  // if both are set, assume AltGr and skip it - #4096
28869                 if (event$$1.ctrlKey !== binding.event.modifiers.ctrlKey) return false;
28870                 if (event$$1.altKey !== binding.event.modifiers.altKey) return false;
28871             }
28872             if (event$$1.metaKey !== binding.event.modifiers.metaKey) return false;
28873             if (testShift && event$$1.shiftKey !== binding.event.modifiers.shiftKey) return false;
28874
28875             return true;
28876         }
28877     }
28878
28879
28880     function capture() {
28881         testBindings(true);
28882     }
28883
28884
28885     function bubble() {
28886         var tagName = d3_select(event.target).node().tagName;
28887         if (tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA') {
28888             return;
28889         }
28890         testBindings(false);
28891     }
28892
28893
28894     function keybinding(selection) {
28895         selection = selection || d3_select(document);
28896         selection.on('keydown.capture' + namespace, capture, true);
28897         selection.on('keydown.bubble' + namespace, bubble, false);
28898         return keybinding;
28899     }
28900
28901
28902     keybinding.off = function(selection) {
28903         bindings = [];
28904         selection = selection || d3_select(document);
28905         selection.on('keydown.capture' + namespace, null);
28906         selection.on('keydown.bubble' + namespace, null);
28907         return keybinding;
28908     };
28909
28910
28911     keybinding.on = function(codes, callback, capture) {
28912         var arr = [].concat(codes);
28913         for (var i = 0; i < arr.length; i++) {
28914             var code = arr[i];
28915             var binding = {
28916                 event: {
28917                     key: undefined,  // preferred
28918                     keyCode: 0,      // fallback
28919                     modifiers: {
28920                         shiftKey: false,
28921                         ctrlKey: false,
28922                         altKey: false,
28923                         metaKey: false
28924                     }
28925                 },
28926                 capture: capture,
28927                 callback: callback
28928             };
28929
28930             code = code.toLowerCase().match(/(?:(?:[^+⇧⌃⌥⌘])+|[⇧⌃⌥⌘]|\+\+|^\+$)/g);
28931
28932             for (var j = 0; j < code.length; j++) {
28933                 // Normalise matching errors
28934                 if (code[j] === '++') code[j] = '+';
28935
28936                 if (code[j] in d3keybinding.modifierCodes) {
28937                     binding.event.modifiers[d3keybinding.modifierProperties[d3keybinding.modifierCodes[code[j]]]] = true;
28938                 } else {
28939                     binding.event.key = d3keybinding.keys[code[j]] || code[j];
28940                     if (code[j] in d3keybinding.keyCodes) {
28941                         binding.event.keyCode = d3keybinding.keyCodes[code[j]];
28942                     }
28943                 }
28944             }
28945
28946             bindings.push(binding);
28947         }
28948
28949         return keybinding;
28950     };
28951
28952     return keybinding;
28953 }
28954
28955
28956 d3keybinding.modifierCodes = {
28957     // Shift key, ⇧
28958     '⇧': 16, shift: 16,
28959     // CTRL key, on Mac: ⌃
28960     '⌃': 17, ctrl: 17,
28961     // ALT key, on Mac: ⌥ (Alt)
28962     '⌥': 18, alt: 18, option: 18,
28963     // META, on Mac: ⌘ (CMD), on Windows (Win), on Linux (Super)
28964     '⌘': 91, meta: 91, cmd: 91, 'super': 91, win: 91
28965 };
28966
28967 d3keybinding.modifierProperties = {
28968     16: 'shiftKey',
28969     17: 'ctrlKey',
28970     18: 'altKey',
28971     91: 'metaKey'
28972 };
28973
28974 d3keybinding.keys = {
28975     // Backspace key, on Mac: ⌫ (Backspace)
28976     '⌫': 'Backspace', backspace: 'Backspace',
28977     // Tab Key, on Mac: ⇥ (Tab), on Windows ⇥⇥
28978     '⇥': 'Tab', '⇆': 'Tab', tab: 'Tab',
28979     // Return key, ↩
28980     '↩': 'Enter', 'return': 'Enter', enter: 'Enter', '⌅': 'Enter',
28981     // Pause/Break key
28982     'pause': 'Pause', 'pause-break': 'Pause',
28983     // Caps Lock key, ⇪
28984     '⇪': 'CapsLock', caps: 'CapsLock', 'caps-lock': 'CapsLock',
28985     // Escape key, on Mac: ⎋, on Windows: Esc
28986     '⎋': ['Escape', 'Esc'], escape: ['Escape', 'Esc'], esc: ['Escape', 'Esc'],
28987     // Space key
28988     space: [' ', 'Spacebar'],
28989     // Page-Up key, or pgup, on Mac: ↖
28990     '↖': 'PageUp', pgup: 'PageUp', 'page-up': 'PageUp',
28991     // Page-Down key, or pgdown, on Mac: ↘
28992     '↘': 'PageDown', pgdown: 'PageDown', 'page-down': 'PageDown',
28993     // END key, on Mac: ⇟
28994     '⇟': 'End', end: 'End',
28995     // HOME key, on Mac: ⇞
28996     '⇞': 'Home', home: 'Home',
28997     // Insert key, or ins
28998     ins: 'Insert', insert: 'Insert',
28999     // Delete key, on Mac: ⌦ (Delete)
29000     '⌦': ['Delete', 'Del'], del: ['Delete', 'Del'], 'delete': ['Delete', 'Del'],
29001     // Left Arrow Key, or ←
29002     '←': ['ArrowLeft', 'Left'], left: ['ArrowLeft', 'Left'], 'arrow-left': ['ArrowLeft', 'Left'],
29003     // Up Arrow Key, or ↑
29004     '↑': ['ArrowUp', 'Up'], up: ['ArrowUp', 'Up'], 'arrow-up': ['ArrowUp', 'Up'],
29005     // Right Arrow Key, or →
29006     '→': ['ArrowRight', 'Right'], right: ['ArrowRight', 'Right'], 'arrow-right': ['ArrowRight', 'Right'],
29007     // Up Arrow Key, or ↓
29008     '↓': ['ArrowDown', 'Down'], down: ['ArrowDown', 'Down'], 'arrow-down': ['ArrowDown', 'Down'],
29009     // odities, stuff for backward compatibility (browsers and code):
29010     // Num-Multiply, or *
29011     '*': ['*', 'Multiply'], star: ['*', 'Multiply'], asterisk: ['*', 'Multiply'], multiply: ['*', 'Multiply'],
29012     // Num-Plus or +
29013     '+': ['+', 'Add'], 'plus': ['+', 'Add'],
29014     // Num-Subtract, or -
29015     '-': ['-', 'Subtract'], subtract: ['-', 'Subtract'], 'dash': ['-', 'Subtract'],
29016     // Semicolon
29017     semicolon: ';',
29018     // = or equals
29019     equals: '=',
29020     // Comma, or ,
29021     comma: ',',
29022     // Period, or ., or full-stop
29023     period: '.', 'full-stop': '.',
29024     // Slash, or /, or forward-slash
29025     slash: '/', 'forward-slash': '/',
29026     // Tick, or `, or back-quote
29027     tick: '`', 'back-quote': '`',
29028     // Open bracket, or [
29029     'open-bracket': '[',
29030     // Back slash, or \
29031     'back-slash': '\\',
29032     // Close backet, or ]
29033     'close-bracket': ']',
29034     // Apostrophe, or Quote, or '
29035     quote: '\'', apostrophe: '\'',
29036     // NUMPAD 0-9
29037     'num-0': '0',
29038     'num-1': '1',
29039     'num-2': '2',
29040     'num-3': '3',
29041     'num-4': '4',
29042     'num-5': '5',
29043     'num-6': '6',
29044     'num-7': '7',
29045     'num-8': '8',
29046     'num-9': '9',
29047     // F1-F25
29048     f1: 'F1',
29049     f2: 'F2',
29050     f3: 'F3',
29051     f4: 'F4',
29052     f5: 'F5',
29053     f6: 'F6',
29054     f7: 'F7',
29055     f8: 'F8',
29056     f9: 'F9',
29057     f10: 'F10',
29058     f11: 'F11',
29059     f12: 'F12',
29060     f13: 'F13',
29061     f14: 'F14',
29062     f15: 'F15',
29063     f16: 'F16',
29064     f17: 'F17',
29065     f18: 'F18',
29066     f19: 'F19',
29067     f20: 'F20',
29068     f21: 'F21',
29069     f22: 'F22',
29070     f23: 'F23',
29071     f24: 'F24',
29072     f25: 'F25'
29073 };
29074
29075 d3keybinding.keyCodes = {
29076     // Backspace key, on Mac: ⌫ (Backspace)
29077     '⌫': 8, backspace: 8,
29078     // Tab Key, on Mac: ⇥ (Tab), on Windows ⇥⇥
29079     '⇥': 9, '⇆': 9, tab: 9,
29080     // Return key, ↩
29081     '↩': 13, 'return': 13, enter: 13, '⌅': 13,
29082     // Pause/Break key
29083     'pause': 19, 'pause-break': 19,
29084     // Caps Lock key, ⇪
29085     '⇪': 20, caps: 20, 'caps-lock': 20,
29086     // Escape key, on Mac: ⎋, on Windows: Esc
29087     '⎋': 27, escape: 27, esc: 27,
29088     // Space key
29089     space: 32,
29090     // Page-Up key, or pgup, on Mac: ↖
29091     '↖': 33, pgup: 33, 'page-up': 33,
29092     // Page-Down key, or pgdown, on Mac: ↘
29093     '↘': 34, pgdown: 34, 'page-down': 34,
29094     // END key, on Mac: ⇟
29095     '⇟': 35, end: 35,
29096     // HOME key, on Mac: ⇞
29097     '⇞': 36, home: 36,
29098     // Insert key, or ins
29099     ins: 45, insert: 45,
29100     // Delete key, on Mac: ⌦ (Delete)
29101     '⌦': 46, del: 46, 'delete': 46,
29102     // Left Arrow Key, or ←
29103     '←': 37, left: 37, 'arrow-left': 37,
29104     // Up Arrow Key, or ↑
29105     '↑': 38, up: 38, 'arrow-up': 38,
29106     // Right Arrow Key, or →
29107     '→': 39, right: 39, 'arrow-right': 39,
29108     // Up Arrow Key, or ↓
29109     '↓': 40, down: 40, 'arrow-down': 40,
29110     // odities, printing characters that come out wrong:
29111     // Firefox Equals
29112     'ffequals': 61,
29113     // Num-Multiply, or *
29114     '*': 106, star: 106, asterisk: 106, multiply: 106,
29115     // Num-Plus or +
29116     '+': 107, 'plus': 107,
29117     // Num-Subtract, or -
29118     '-': 109, subtract: 109,
29119     // Firefox Plus
29120     'ffplus': 171,
29121     // Firefox Minus
29122     'ffminus': 173,
29123     // Semicolon
29124     ';': 186, semicolon: 186,
29125     // = or equals
29126     '=': 187, 'equals': 187,
29127     // Comma, or ,
29128     ',': 188, comma: 188,
29129     // Dash / Underscore key
29130     'dash': 189,
29131     // Period, or ., or full-stop
29132     '.': 190, period: 190, 'full-stop': 190,
29133     // Slash, or /, or forward-slash
29134     '/': 191, slash: 191, 'forward-slash': 191,
29135     // Tick, or `, or back-quote
29136     '`': 192, tick: 192, 'back-quote': 192,
29137     // Open bracket, or [
29138     '[': 219, 'open-bracket': 219,
29139     // Back slash, or \
29140     '\\': 220, 'back-slash': 220,
29141     // Close backet, or ]
29142     ']': 221, 'close-bracket': 221,
29143     // Apostrophe, or Quote, or '
29144     '\'': 222, quote: 222, apostrophe: 222
29145 };
29146
29147 // NUMPAD 0-9
29148 var i$1 = 95;
29149 var n = 0;
29150 while (++i$1 < 106) {
29151     d3keybinding.keyCodes['num-' + n] = i$1;
29152     ++n;
29153 }
29154
29155 // 0-9
29156 i$1 = 47; n = 0;
29157 while (++i$1 < 58) {
29158     d3keybinding.keyCodes[n] = i$1;
29159     ++n;
29160 }
29161
29162 // F1-F25
29163 i$1 = 111; n = 1;
29164 while (++i$1 < 136) {
29165     d3keybinding.keyCodes['f' + n] = i$1;
29166     ++n;
29167 }
29168
29169 // a-z
29170 i$1 = 64;
29171 while (++i$1 < 91) {
29172     d3keybinding.keyCodes[String.fromCharCode(i$1).toLowerCase()] = i$1;
29173 }
29174
29175 function tooltip() {
29176   var tooltip = function(selection) {
29177       selection.each(setup);
29178     },
29179     animation = utilFunctor(false),
29180     html = utilFunctor(false),
29181     title = function() {
29182       var title = this.getAttribute('data-original-title');
29183       if (title) {
29184         return title;
29185       } else {
29186         title = this.getAttribute('title');
29187         this.removeAttribute('title');
29188         this.setAttribute('data-original-title', title);
29189       }
29190       return title;
29191     },
29192     over = 'mouseenter.tooltip',
29193     out = 'mouseleave.tooltip',
29194     placement = utilFunctor('top');
29195
29196
29197   tooltip.title = function(_) {
29198     if (arguments.length) {
29199       title = utilFunctor(_);
29200       return tooltip;
29201     } else {
29202       return title;
29203     }
29204   };
29205
29206
29207   tooltip.html = function(_) {
29208     if (arguments.length) {
29209       html = utilFunctor(_);
29210       return tooltip;
29211     } else {
29212       return html;
29213     }
29214   };
29215
29216
29217   tooltip.placement = function(_) {
29218     if (arguments.length) {
29219       placement = utilFunctor(_);
29220       return tooltip;
29221     } else {
29222       return placement;
29223     }
29224   };
29225
29226
29227   tooltip.show = function(selection) {
29228     selection.each(show);
29229   };
29230
29231
29232   tooltip.hide = function(selection) {
29233     selection.each(hide);
29234   };
29235
29236
29237   tooltip.toggle = function(selection) {
29238     selection.each(toggle);
29239   };
29240
29241
29242   tooltip.destroy = function(selection) {
29243     selection
29244       .on(over, null)
29245       .on(out, null)
29246       .attr('title', function() {
29247         return this.getAttribute('data-original-title') || this.getAttribute('title');
29248       })
29249       .attr('data-original-title', null)
29250       .selectAll('.tooltip')
29251       .remove();
29252   };
29253
29254
29255   function setup() {
29256     var root = d3_select(this),
29257         animate = animation.apply(this, arguments),
29258         tip = root.selectAll('.tooltip').data([0]);
29259
29260     var enter = tip.enter()
29261       .append('div')
29262       .attr('class', 'tooltip');
29263
29264     enter
29265       .append('div')
29266       .attr('class', 'tooltip-arrow');
29267
29268     enter
29269       .append('div')
29270       .attr('class', 'tooltip-inner');
29271
29272     tip = enter
29273       .merge(tip);
29274
29275     if (animate) {
29276       tip.classed('fade', true);
29277     }
29278
29279     var place = placement.apply(this, arguments);
29280     tip.classed(place, true);
29281
29282     root.on(over, show);
29283     root.on(out, hide);
29284   }
29285
29286
29287   function show() {
29288     var root = d3_select(this),
29289       content = title.apply(this, arguments),
29290       tip = root.selectAll('.tooltip')
29291         .classed('in', true),
29292       markup = html.apply(this, arguments);
29293
29294     tip.selectAll('.tooltip-inner')[markup ? 'html' : 'text'](content);
29295     var place = placement.apply(this, arguments),
29296       outer = getPosition(root.node()),
29297       inner = getPosition(tip.node()),
29298       pos;
29299
29300     switch (place) {
29301       case 'top':
29302         pos = {x: outer.x + (outer.w - inner.w) / 2, y: outer.y - inner.h};
29303         break;
29304       case 'right':
29305         pos = {x: outer.x + outer.w, y: outer.y + (outer.h - inner.h) / 2};
29306         break;
29307       case 'left':
29308         pos = {x: outer.x - inner.w, y: outer.y + (outer.h - inner.h) / 2};
29309         break;
29310       case 'bottom':
29311         pos = {x: Math.max(0, outer.x + (outer.w - inner.w) / 2), y: outer.y + outer.h};
29312         break;
29313     }
29314
29315     if (pos) {
29316       tip.style('left', ~~pos.x + 'px').style('top', ~~pos.y + 'px');
29317     } else {
29318       tip.style('left', null).style('top', null);
29319     }
29320
29321     this.tooltipVisible = true;
29322   }
29323
29324
29325   function hide() {
29326     d3_select(this).selectAll('.tooltip')
29327       .classed('in', false);
29328
29329     this.tooltipVisible = false;
29330   }
29331
29332
29333   function toggle() {
29334     if (this.tooltipVisible) {
29335       hide.apply(this, arguments);
29336     } else {
29337       show.apply(this, arguments);
29338     }
29339   }
29340
29341   return tooltip;
29342 }
29343
29344
29345 function getPosition(node) {
29346   var mode = d3_select(node).style('position');
29347   if (mode === 'absolute' || mode === 'static') {
29348     return {
29349       x: node.offsetLeft,
29350       y: node.offsetTop,
29351       w: node.offsetWidth,
29352       h: node.offsetHeight
29353     };
29354   } else {
29355     return {
29356       x: 0,
29357       y: 0,
29358       w: node.offsetWidth,
29359       h: node.offsetHeight
29360     };
29361   }
29362 }
29363
29364 function behaviorEdit(context) {
29365
29366     function edit() {
29367         context.map()
29368             .minzoom(context.minEditableZoom());
29369     }
29370
29371
29372     edit.off = function() {
29373         context.map()
29374             .minzoom(0);
29375     };
29376
29377
29378     return edit;
29379 }
29380
29381 /*
29382    The hover behavior adds the `.hover` class on mouseover to all elements to which
29383    the identical datum is bound, and removes it on mouseout.
29384
29385    The :hover pseudo-class is insufficient for iD's purposes because a datum's visual
29386    representation may consist of several elements scattered throughout the DOM hierarchy.
29387    Only one of these elements can have the :hover pseudo-class, but all of them will
29388    have the .hover class.
29389  */
29390 function behaviorHover(context) {
29391     var dispatch$$1 = dispatch('hover');
29392     var _selection = d3_select(null);
29393     var _newId = null;
29394     var _buttonDown;
29395     var _altDisables;
29396     var _target;
29397
29398
29399     function keydown() {
29400         if (_altDisables && event.keyCode === d3keybinding.modifierCodes.alt) {
29401             _selection.selectAll('.hover')
29402                 .classed('hover-suppressed', true)
29403                 .classed('hover', false);
29404
29405             _selection
29406                 .classed('hover-disabled', true);
29407
29408             dispatch$$1.call('hover', this, null);
29409         }
29410     }
29411
29412
29413     function keyup() {
29414         if (_altDisables && event.keyCode === d3keybinding.modifierCodes.alt) {
29415             _selection.selectAll('.hover-suppressed')
29416                 .classed('hover-suppressed', false)
29417                 .classed('hover', true);
29418
29419             _selection
29420                 .classed('hover-disabled', false);
29421
29422             dispatch$$1.call('hover', this, _target ? _target.id : null);
29423         }
29424     }
29425
29426
29427     var hover = function(selection) {
29428         _selection = selection;
29429         _newId = null;
29430
29431         _selection
29432             .on('mouseover.hover', mouseover)
29433             .on('mouseout.hover', mouseout)
29434             .on('mousedown.hover', mousedown);
29435
29436         d3_select(window)
29437             .on('keydown.hover', keydown)
29438             .on('keyup.hover', keyup);
29439
29440
29441         function mouseover() {
29442             if (_buttonDown) return;
29443             var target = event.target;
29444             enter(target ? target.__data__ : null);
29445         }
29446
29447
29448         function mouseout() {
29449             if (_buttonDown) return;
29450             var target = event.relatedTarget;
29451             enter(target ? target.__data__ : null);
29452         }
29453
29454
29455         function mousedown() {
29456             _buttonDown = true;
29457             d3_select(window)
29458                 .on('mouseup.hover', mouseup, true);
29459         }
29460
29461
29462         function mouseup() {
29463             _buttonDown = false;
29464             d3_select(window)
29465                 .on('mouseup.hover', null, true);
29466         }
29467
29468
29469         function enter(datum) {
29470             if (datum === _target) return;
29471             _target = datum;
29472
29473             _selection.selectAll('.hover')
29474                 .classed('hover', false);
29475             _selection.selectAll('.hover-suppressed')
29476                 .classed('hover-suppressed', false);
29477
29478             var entity;
29479             if (datum instanceof osmEntity) {
29480                 entity = datum;
29481             } else {
29482                 entity = datum && datum.properties && datum.properties.entity;
29483             }
29484
29485             if (entity && entity.id !== _newId) {
29486                 // If drawing a way, don't hover on a node that was just placed. #3974
29487                 var mode = context.mode() && context.mode().id;
29488                 if ((mode === 'draw-line' || mode === 'draw-area') && !_newId && entity.type === 'node') {
29489                     _newId = entity.id;
29490                     return;
29491                 }
29492
29493                 var selector = '.' + entity.id;
29494
29495                 if (entity.type === 'relation') {
29496                     entity.members.forEach(function(member) {
29497                         selector += ', .' + member.id;
29498                     });
29499                 }
29500
29501                 var suppressed = _altDisables && event && event.altKey;
29502
29503                 _selection.selectAll(selector)
29504                     .classed(suppressed ? 'hover-suppressed' : 'hover', true);
29505
29506                 dispatch$$1.call('hover', this, !suppressed && entity.id);
29507
29508             } else {
29509                 dispatch$$1.call('hover', this, null);
29510             }
29511         }
29512
29513     };
29514
29515
29516     hover.off = function(selection) {
29517         selection.selectAll('.hover')
29518             .classed('hover', false);
29519         selection.selectAll('.hover-suppressed')
29520             .classed('hover-suppressed', false);
29521         selection
29522             .classed('hover-disabled', false);
29523
29524         selection
29525             .on('mouseover.hover', null)
29526             .on('mouseout.hover', null)
29527             .on('mousedown.hover', null);
29528
29529         d3_select(window)
29530             .on('keydown.hover', null)
29531             .on('keyup.hover', null);
29532     };
29533
29534
29535     hover.altDisables = function(_) {
29536         if (!arguments.length) return _altDisables;
29537         _altDisables = _;
29538         return hover;
29539     };
29540
29541
29542     return utilRebind(hover, dispatch$$1, 'on');
29543 }
29544
29545 function refresh(selection, node) {
29546     var cr = node.getBoundingClientRect();
29547     var prop = [cr.width, cr.height];
29548     selection.property('__dimensions__', prop);
29549     return prop;
29550 }
29551
29552 function utilGetDimensions(selection, force) {
29553     if (!selection || selection.empty()) {
29554         return [0, 0];
29555     }
29556     var node = selection.node(),
29557         cached = selection.property('__dimensions__');
29558     return (!cached || force) ? refresh(selection, node) : cached;
29559 }
29560
29561
29562 function utilSetDimensions(selection, dimensions) {
29563     if (!selection || selection.empty()) {
29564         return selection;
29565     }
29566     var node = selection.node();
29567     if (dimensions === null) {
29568         refresh(selection, node);
29569         return selection;
29570     }
29571     return selection
29572         .property('__dimensions__', [dimensions[0], dimensions[1]])
29573         .attr('width', dimensions[0])
29574         .attr('height', dimensions[1]);
29575 }
29576
29577 function behaviorTail() {
29578     var text,
29579         container,
29580         xmargin = 25,
29581         tooltipSize = [0, 0],
29582         selectionSize = [0, 0];
29583
29584
29585     function tail(selection) {
29586         if (!text) return;
29587
29588         d3_select(window)
29589             .on('resize.tail', function() { selectionSize = utilGetDimensions(selection); });
29590
29591         container = d3_select(document.body)
29592             .append('div')
29593             .style('display', 'none')
29594             .attr('class', 'tail tooltip-inner');
29595
29596         container.append('div')
29597             .text(text);
29598
29599         selection
29600             .on('mousemove.tail', mousemove)
29601             .on('mouseenter.tail', mouseenter)
29602             .on('mouseleave.tail', mouseleave);
29603
29604         container
29605             .on('mousemove.tail', mousemove);
29606
29607         tooltipSize = utilGetDimensions(container);
29608         selectionSize = utilGetDimensions(selection);
29609
29610
29611         function show() {
29612             container.style('display', 'block');
29613             tooltipSize = utilGetDimensions(container);
29614         }
29615
29616
29617         function mousemove() {
29618             if (container.style('display') === 'none') show();
29619             var xoffset = ((event.clientX + tooltipSize[0] + xmargin) > selectionSize[0]) ?
29620                 -tooltipSize[0] - xmargin : xmargin;
29621             container.classed('left', xoffset > 0);
29622             utilSetTransform(container, event.clientX + xoffset, event.clientY);
29623         }
29624
29625
29626         function mouseleave() {
29627             if (event.relatedTarget !== container.node()) {
29628                 container.style('display', 'none');
29629             }
29630         }
29631
29632
29633         function mouseenter() {
29634             if (event.relatedTarget !== container.node()) {
29635                 show();
29636             }
29637         }
29638     }
29639
29640
29641     tail.off = function(selection) {
29642         if (!text) return;
29643
29644         container
29645             .on('mousemove.tail', null)
29646             .remove();
29647
29648         selection
29649             .on('mousemove.tail', null)
29650             .on('mouseenter.tail', null)
29651             .on('mouseleave.tail', null);
29652
29653         d3_select(window)
29654             .on('resize.tail', null);
29655     };
29656
29657
29658     tail.text = function(_) {
29659         if (!arguments.length) return text;
29660         text = _;
29661         return tail;
29662     };
29663
29664
29665     return tail;
29666 }
29667
29668 var _usedTails = {};
29669 var _disableSpace = false;
29670 var _lastSpace = null;
29671
29672
29673 function behaviorDraw(context) {
29674     var dispatch$$1 = dispatch(
29675         'move', 'click', 'clickWay', 'clickNode', 'undo', 'cancel', 'finish'
29676     );
29677
29678     var keybinding = d3keybinding('draw');
29679
29680     var hover = behaviorHover(context).altDisables(true)
29681         .on('hover', context.ui().sidebar.hover);
29682     var tail = behaviorTail();
29683     var edit = behaviorEdit(context);
29684
29685     var closeTolerance = 4;
29686     var tolerance = 12;
29687     var _mouseLeave = false;
29688     var _lastMouse = null;
29689
29690
29691     // related code
29692     // - `mode/drag_node.js` `datum()`
29693     function datum() {
29694         if (event.altKey) return {};
29695
29696         var element;
29697         if (event.type === 'keydown') {
29698             element = _lastMouse && _lastMouse.target;
29699         } else {
29700             element = event.target;
29701         }
29702
29703         // When drawing, snap only to touch targets..
29704         // (this excludes area fills and active drawing elements)
29705         var d = element.__data__;
29706         return (d && d.properties && d.properties.target) ? d : {};
29707     }
29708
29709
29710     function mousedown() {
29711
29712         function point() {
29713             var p = context.container().node();
29714             return touchId !== null ? d3_touches(p).filter(function(p) {
29715                 return p.identifier === touchId;
29716             })[0] : d3_mouse(p);
29717         }
29718
29719         var element = d3_select(this);
29720         var touchId = event.touches ? event.changedTouches[0].identifier : null;
29721         var t1 = +new Date();
29722         var p1 = point();
29723
29724         element.on('mousemove.draw', null);
29725
29726         d3_select(window).on('mouseup.draw', function() {
29727             var t2 = +new Date();
29728             var p2 = point();
29729             var dist = geoVecLength(p1, p2);
29730
29731             element.on('mousemove.draw', mousemove);
29732             d3_select(window).on('mouseup.draw', null);
29733
29734             if (dist < closeTolerance || (dist < tolerance && (t2 - t1) < 500)) {
29735                 // Prevent a quick second click
29736                 d3_select(window).on('click.draw-block', function() {
29737                     event.stopPropagation();
29738                 }, true);
29739
29740                 context.map().dblclickEnable(false);
29741
29742                 window.setTimeout(function() {
29743                     context.map().dblclickEnable(true);
29744                     d3_select(window).on('click.draw-block', null);
29745                 }, 500);
29746
29747                 click();
29748             }
29749         }, true);
29750     }
29751
29752
29753     function mousemove() {
29754         _lastMouse = event;
29755         dispatch$$1.call('move', this, datum());
29756     }
29757
29758
29759     function mouseenter() {
29760         _mouseLeave = false;
29761     }
29762
29763
29764     function mouseleave() {
29765         _mouseLeave = true;
29766     }
29767
29768
29769     // related code
29770     // - `mode/drag_node.js`     `doMode()`
29771     // - `behavior/draw.js`      `click()`
29772     // - `behavior/draw_way.js`  `move()`
29773     function click() {
29774         var d = datum();
29775         var target = d && d.properties && d.properties.entity;
29776
29777         if (target && target.type === 'node') {   // Snap to a node
29778             dispatch$$1.call('clickNode', this, target, d);
29779             return;
29780
29781         } else if (target && target.type === 'way') {   // Snap to a way
29782             var choice = geoChooseEdge(
29783                 context.childNodes(target), context.mouse(), context.projection, context.activeID()
29784             );
29785             if (choice) {
29786                 var edge = [target.nodes[choice.index - 1], target.nodes[choice.index]];
29787                 dispatch$$1.call('clickWay', this, choice.loc, edge, d);
29788                 return;
29789             }
29790         }
29791
29792         dispatch$$1.call('click', this, context.map().mouseCoordinates(), d);
29793     }
29794
29795
29796     function space() {
29797         event.preventDefault();
29798         event.stopPropagation();
29799
29800         var currSpace = context.mouse();
29801         if (_disableSpace && _lastSpace) {
29802             var dist = geoVecLength(_lastSpace, currSpace);
29803             if (dist > tolerance) {
29804                 _disableSpace = false;
29805             }
29806         }
29807
29808         if (_disableSpace || _mouseLeave || !_lastMouse) return;
29809
29810         // user must move mouse or release space bar to allow another click
29811         _lastSpace = currSpace;
29812         _disableSpace = true;
29813
29814         d3_select(window).on('keyup.space-block', function() {
29815             event.preventDefault();
29816             event.stopPropagation();
29817             _disableSpace = false;
29818             d3_select(window).on('keyup.space-block', null);
29819         });
29820
29821         click();
29822     }
29823
29824
29825     function backspace() {
29826         event.preventDefault();
29827         dispatch$$1.call('undo');
29828     }
29829
29830
29831     function del() {
29832         event.preventDefault();
29833         dispatch$$1.call('cancel');
29834     }
29835
29836
29837     function ret() {
29838         event.preventDefault();
29839         dispatch$$1.call('finish');
29840     }
29841
29842
29843     function draw(selection) {
29844         context.install(hover);
29845         context.install(edit);
29846
29847         if (!context.inIntro() && !_usedTails[tail.text()]) {
29848             context.install(tail);
29849         }
29850
29851         keybinding
29852             .on('⌫', backspace)
29853             .on('⌦', del)
29854             .on('⎋', ret)
29855             .on('↩', ret)
29856             .on('space', space)
29857             .on('⌥space', space);
29858
29859         selection
29860             .on('mouseenter.draw', mouseenter)
29861             .on('mouseleave.draw', mouseleave)
29862             .on('mousedown.draw', mousedown)
29863             .on('mousemove.draw', mousemove);
29864
29865         d3_select(document)
29866             .call(keybinding);
29867
29868         return draw;
29869     }
29870
29871
29872     draw.off = function(selection) {
29873         context.ui().sidebar.hover.cancel();
29874         context.uninstall(hover);
29875         context.uninstall(edit);
29876
29877         if (!context.inIntro() && !_usedTails[tail.text()]) {
29878             context.uninstall(tail);
29879             _usedTails[tail.text()] = true;
29880         }
29881
29882         selection
29883             .on('mouseenter.draw', null)
29884             .on('mouseleave.draw', null)
29885             .on('mousedown.draw', null)
29886             .on('mousemove.draw', null);
29887
29888         d3_select(window)
29889             .on('mouseup.draw', null);
29890             // note: keyup.space-block, click.draw-block should remain
29891
29892         d3_select(document)
29893             .call(keybinding.off);
29894     };
29895
29896
29897     draw.tail = function(_) {
29898         tail.text(_);
29899         return draw;
29900     };
29901
29902
29903     return utilRebind(draw, dispatch$$1, 'on');
29904 }
29905
29906 function modeAddArea(context) {
29907     var mode = {
29908         id: 'add-area',
29909         button: 'area',
29910         title: t('modes.add_area.title'),
29911         description: t('modes.add_area.description'),
29912         key: '3'
29913     };
29914
29915     var behavior = behaviorAddWay(context)
29916             .tail(t('modes.add_area.tail'))
29917             .on('start', start)
29918             .on('startFromWay', startFromWay)
29919             .on('startFromNode', startFromNode),
29920         defaultTags = { area: 'yes' };
29921
29922
29923     function actionClose(wayId) {
29924         return function (graph) {
29925             return graph.replace(graph.entity(wayId).close());
29926         };
29927     }
29928
29929
29930     function start(loc) {
29931         var startGraph = context.graph(),
29932             node = osmNode({ loc: loc }),
29933             way = osmWay({ tags: defaultTags });
29934
29935         context.perform(
29936             actionAddEntity(node),
29937             actionAddEntity(way),
29938             actionAddVertex(way.id, node.id),
29939             actionClose(way.id)
29940         );
29941
29942         context.enter(modeDrawArea(context, way.id, startGraph));
29943     }
29944
29945
29946     function startFromWay(loc, edge) {
29947         var startGraph = context.graph(),
29948             node = osmNode({ loc: loc }),
29949             way = osmWay({ tags: defaultTags });
29950
29951         context.perform(
29952             actionAddEntity(node),
29953             actionAddEntity(way),
29954             actionAddVertex(way.id, node.id),
29955             actionClose(way.id),
29956             actionAddMidpoint({ loc: loc, edge: edge }, node)
29957         );
29958
29959         context.enter(modeDrawArea(context, way.id, startGraph));
29960     }
29961
29962
29963     function startFromNode(node) {
29964         var startGraph = context.graph(),
29965             way = osmWay({ tags: defaultTags });
29966
29967         context.perform(
29968             actionAddEntity(way),
29969             actionAddVertex(way.id, node.id),
29970             actionClose(way.id)
29971         );
29972
29973         context.enter(modeDrawArea(context, way.id, startGraph));
29974     }
29975
29976
29977     mode.enter = function() {
29978         context.install(behavior);
29979     };
29980
29981
29982     mode.exit = function() {
29983         context.uninstall(behavior);
29984     };
29985
29986
29987     return mode;
29988 }
29989
29990 function modeAddLine(context) {
29991     var mode = {
29992         id: 'add-line',
29993         button: 'line',
29994         title: t('modes.add_line.title'),
29995         description: t('modes.add_line.description'),
29996         key: '2'
29997     };
29998
29999     var behavior = behaviorAddWay(context)
30000         .tail(t('modes.add_line.tail'))
30001         .on('start', start)
30002         .on('startFromWay', startFromWay)
30003         .on('startFromNode', startFromNode);
30004
30005
30006     function start(loc) {
30007         var startGraph = context.graph(),
30008             node = osmNode({ loc: loc }),
30009             way = osmWay();
30010
30011         context.perform(
30012             actionAddEntity(node),
30013             actionAddEntity(way),
30014             actionAddVertex(way.id, node.id)
30015         );
30016
30017         context.enter(modeDrawLine(context, way.id, startGraph));
30018     }
30019
30020
30021     function startFromWay(loc, edge) {
30022         var startGraph = context.graph(),
30023             node = osmNode({ loc: loc }),
30024             way = osmWay();
30025
30026         context.perform(
30027             actionAddEntity(node),
30028             actionAddEntity(way),
30029             actionAddVertex(way.id, node.id),
30030             actionAddMidpoint({ loc: loc, edge: edge }, node)
30031         );
30032
30033         context.enter(modeDrawLine(context, way.id, startGraph));
30034     }
30035
30036
30037     function startFromNode(node) {
30038         var startGraph = context.graph(),
30039             way = osmWay();
30040
30041         context.perform(
30042             actionAddEntity(way),
30043             actionAddVertex(way.id, node.id)
30044         );
30045
30046         context.enter(modeDrawLine(context, way.id, startGraph));
30047     }
30048
30049
30050     mode.enter = function() {
30051         context.install(behavior);
30052     };
30053
30054
30055     mode.exit = function() {
30056         context.uninstall(behavior);
30057     };
30058
30059     return mode;
30060 }
30061
30062 function modeAddPoint(context) {
30063     var mode = {
30064         id: 'add-point',
30065         button: 'point',
30066         title: t('modes.add_point.title'),
30067         description: t('modes.add_point.description'),
30068         key: '1'
30069     };
30070
30071     var behavior = behaviorDraw(context)
30072         .tail(t('modes.add_point.tail'))
30073         .on('click', add)
30074         .on('clickWay', addWay)
30075         .on('clickNode', addNode)
30076         .on('cancel', cancel)
30077         .on('finish', cancel);
30078
30079
30080     function add(loc) {
30081         var node = osmNode({ loc: loc });
30082
30083         context.perform(
30084             actionAddEntity(node),
30085             t('operations.add.annotation.point')
30086         );
30087
30088         context.enter(
30089             modeSelect(context, [node.id]).newFeature(true)
30090         );
30091     }
30092
30093
30094     function addWay(loc) {
30095         add(loc);
30096     }
30097
30098
30099     function addNode(node) {
30100         add(node.loc);
30101     }
30102
30103
30104     function cancel() {
30105         context.enter(modeBrowse(context));
30106     }
30107
30108
30109     mode.enter = function() {
30110         context.install(behavior);
30111     };
30112
30113
30114     mode.exit = function() {
30115         context.uninstall(behavior);
30116     };
30117
30118
30119     return mode;
30120 }
30121
30122 function modeDragNode(context) {
30123     var mode = {
30124         id: 'drag-node',
30125         button: 'browse'
30126     };
30127     var hover = behaviorHover(context).altDisables(true)
30128         .on('hover', context.ui().sidebar.hover);
30129     var edit = behaviorEdit(context);
30130
30131     var _nudgeInterval;
30132     var _restoreSelectedIDs = [];
30133     var _wasMidpoint = false;
30134     var _isCancelled = false;
30135     var _activeEntity;
30136     var _startLoc;
30137     var _lastLoc;
30138
30139
30140     function startNudge(entity, nudge) {
30141         if (_nudgeInterval) window.clearInterval(_nudgeInterval);
30142         _nudgeInterval = window.setInterval(function() {
30143             context.pan(nudge);
30144             doMove(entity, nudge);
30145         }, 50);
30146     }
30147
30148
30149     function stopNudge() {
30150         if (_nudgeInterval) {
30151             window.clearInterval(_nudgeInterval);
30152             _nudgeInterval = null;
30153         }
30154     }
30155
30156
30157     function moveAnnotation(entity) {
30158         return t('operations.move.annotation.' + entity.geometry(context.graph()));
30159     }
30160
30161
30162     function connectAnnotation(entity) {
30163         return t('operations.connect.annotation.' + entity.geometry(context.graph()));
30164     }
30165
30166
30167     function origin(entity) {
30168         return context.projection(entity.loc);
30169     }
30170
30171
30172     function keydown() {
30173         if (event.keyCode === d3keybinding.modifierCodes.alt) {
30174             if (context.surface().classed('nope')) {
30175                 context.surface()
30176                     .classed('nope-suppressed', true);
30177             }
30178             context.surface()
30179                 .classed('nope', false)
30180                 .classed('nope-disabled', true);
30181         }
30182     }
30183
30184
30185     function keyup() {
30186         if (event.keyCode === d3keybinding.modifierCodes.alt) {
30187             if (context.surface().classed('nope-suppressed')) {
30188                 context.surface()
30189                     .classed('nope', true);
30190             }
30191             context.surface()
30192                 .classed('nope-suppressed', false)
30193                 .classed('nope-disabled', false);
30194         }
30195     }
30196
30197
30198     function start(entity) {
30199         _wasMidpoint = entity.type === 'midpoint';
30200         var hasHidden = context.features().hasHiddenConnections(entity, context.graph());
30201         _isCancelled = event.sourceEvent.shiftKey || hasHidden;
30202
30203
30204         if (_isCancelled) {
30205             if (hasHidden) {
30206                 uiFlash().text(t('modes.drag_node.connected_to_hidden'))();
30207             }
30208             return drag.cancel();
30209         }
30210
30211         if (_wasMidpoint) {
30212             var midpoint = entity;
30213             entity = osmNode();
30214             context.perform(actionAddMidpoint(midpoint, entity));
30215             entity = context.entity(entity.id);   // get post-action entity
30216
30217             var vertex = context.surface().selectAll('.' + entity.id);
30218             drag.target(vertex.node(), entity);
30219
30220         } else {
30221             context.perform(actionNoop());
30222         }
30223
30224         _activeEntity = entity;
30225         _startLoc = entity.loc;
30226
30227         context.surface().selectAll('.' + _activeEntity.id)
30228             .classed('active', true);
30229
30230         context.enter(mode);
30231     }
30232
30233
30234     // related code
30235     // - `behavior/draw.js` `datum()`
30236     function datum() {
30237         var event$$1 = event && event.sourceEvent;
30238         if (!event$$1 || event$$1.altKey) {
30239             return {};
30240         } else {
30241             // When dragging, snap only to touch targets..
30242             // (this excludes area fills and active drawing elements)
30243             var d = event$$1.target.__data__;
30244             return (d && d.properties && d.properties.target) ? d : {};
30245         }
30246     }
30247
30248
30249     function doMove(entity, nudge) {
30250         nudge = nudge || [0, 0];
30251
30252         var currPoint = (event && event.point) || context.projection(_lastLoc);
30253         var currMouse = geoVecSubtract(currPoint, nudge);
30254         var loc = context.projection.invert(currMouse);
30255
30256         if (!_nudgeInterval) {   // If not nudging at the edge of the viewport, try to snap..
30257             // related code
30258             // - `mode/drag_node.js`     `doMode()`
30259             // - `behavior/draw.js`      `click()`
30260             // - `behavior/draw_way.js`  `move()`
30261             var d = datum();
30262             var targetLoc = d && d.properties && d.properties.entity && d.properties.entity.loc;
30263             var targetNodes = d && d.properties && d.properties.nodes;
30264
30265             if (targetLoc) {   // snap to node/vertex - a point target with `.loc`
30266                 loc = targetLoc;
30267
30268             } else if (targetNodes) {   // snap to way - a line target with `.nodes`
30269                 var choice = geoChooseEdge(targetNodes, context.mouse(), context.projection, end.id);
30270                 if (choice) {
30271                     loc = choice.loc;
30272                 }
30273             }
30274         }
30275
30276         context.replace(
30277             actionMoveNode(entity.id, loc),
30278             moveAnnotation(entity)
30279         );
30280
30281
30282         // check if this movement causes the geometry to break
30283         var nopeDisabled = context.surface().classed('nope-disabled');
30284         var isInvalid = isInvalidGeometry(entity, context.graph());
30285         if (nopeDisabled) {
30286             context.surface()
30287                 .classed('nope', false)
30288                 .classed('nope-suppressed', isInvalid);
30289         } else {
30290             context.surface()
30291                 .classed('nope', isInvalid)
30292                 .classed('nope-suppressed', false);
30293         }
30294
30295         _lastLoc = loc;
30296     }
30297
30298
30299     function isInvalidGeometry(entity, graph) {
30300         var parents = graph.parentWays(entity);
30301         var i, j, k;
30302
30303         for (i = 0; i < parents.length; i++) {
30304             var parent = parents[i];
30305             var nodes = [];
30306             var activeIndex = null;    // which multipolygon ring contains node being dragged
30307
30308             // test any parent multipolygons for valid geometry
30309             var relations = graph.parentRelations(parent);
30310             for (j = 0; j < relations.length; j++) {
30311                 if (!relations[j].isMultipolygon()) continue;
30312
30313                 var rings = osmJoinWays(relations[j].members, graph);
30314
30315                 // find active ring and test it for self intersections
30316                 for (k = 0; k < rings.length; k++) {
30317                     nodes = rings[k].nodes;
30318                     if (find$1(nodes, function(n) { return n.id === entity.id; })) {
30319                         activeIndex = k;
30320                         if (geoHasSelfIntersections(nodes, entity.id)) {
30321                             return true;
30322                         }
30323                     }
30324                     rings[k].coords = nodes.map(function(n) { return n.loc; });
30325                 }
30326
30327                 // test active ring for intersections with other rings in the multipolygon
30328                 for (k = 0; k < rings.length; k++) {
30329                     if (k === activeIndex) continue;
30330
30331                     // make sure active ring doesnt cross passive rings
30332                     if (geoHasLineIntersections(rings[activeIndex].nodes, rings[k].nodes, entity.id)) {
30333                         return true;
30334                     }
30335                 }
30336             }
30337
30338
30339             // If we still haven't tested this node's parent way for self-intersections.
30340             // (because it's not a member of a multipolygon), test it now.
30341             if (activeIndex === null) {
30342                 nodes = parent.nodes.map(function(nodeID) { return graph.entity(nodeID); });
30343                 if (nodes.length && geoHasSelfIntersections(nodes, entity.id)) {
30344                     return true;
30345                 }
30346             }
30347
30348         }
30349
30350         return false;
30351     }
30352
30353
30354     function move(entity) {
30355         if (_isCancelled) return;
30356         event.sourceEvent.stopPropagation();
30357
30358         context.surface().classed('nope-disabled', event.sourceEvent.altKey);
30359
30360         _lastLoc = context.projection.invert(event.point);
30361
30362         doMove(entity);
30363         var nudge = geoViewportEdge(event.point, context.map().dimensions());
30364         if (nudge) {
30365             startNudge(entity, nudge);
30366         } else {
30367             stopNudge();
30368         }
30369     }
30370
30371
30372     function end(entity) {
30373         if (_isCancelled) return;
30374
30375         var d = datum();
30376         var nope = (d && d.properties && d.properties.nope) || context.surface().classed('nope');
30377         var target = d && d.properties && d.properties.entity;   // entity to snap to
30378
30379         if (nope) {   // bounce back
30380             context.perform(
30381                 _actionBounceBack(entity.id, _startLoc)
30382             );
30383
30384         } else if (target && target.type === 'way') {
30385             var choice = geoChooseEdge(context.childNodes(target), context.mouse(), context.projection, entity.id);
30386             context.replace(
30387                 actionAddMidpoint({
30388                     loc: choice.loc,
30389                     edge: [target.nodes[choice.index - 1], target.nodes[choice.index]]
30390                 }, entity),
30391                 connectAnnotation(target)
30392             );
30393
30394         } else if (target && target.type === 'node') {
30395             context.replace(
30396                 actionConnect([target.id, entity.id]),
30397                 connectAnnotation(target)
30398             );
30399
30400         } else if (_wasMidpoint) {
30401             context.replace(
30402                 actionNoop(),
30403                 t('operations.add.annotation.vertex')
30404             );
30405
30406         } else {
30407             context.replace(
30408                 actionNoop(),
30409                 moveAnnotation(entity)
30410             );
30411         }
30412
30413         var reselection = _restoreSelectedIDs.filter(function(id) {
30414             return context.graph().hasEntity(id);
30415         });
30416
30417         if (reselection.length) {
30418             context.enter(modeSelect(context, reselection));
30419         } else {
30420             context.enter(modeBrowse(context));
30421         }
30422     }
30423
30424
30425     function _actionBounceBack(nodeID, toLoc) {
30426         var moveNode = actionMoveNode(nodeID, toLoc);
30427         var action = function(graph, t$$1) {
30428             // last time through, pop off the bounceback perform.
30429             // it will then overwrite the initial perform with a moveNode that does nothing
30430             if (t$$1 === 1) context.pop();
30431             return moveNode(graph, t$$1);
30432         };
30433         action.transitionable = true;
30434         return action;
30435     }
30436
30437
30438     function cancel() {
30439         drag.cancel();
30440         context.enter(modeBrowse(context));
30441     }
30442
30443
30444     var drag = behaviorDrag()
30445         .selector('.layer-points-targets .target')
30446         .surface(d3_select('#map').node())
30447         .origin(origin)
30448         .on('start', start)
30449         .on('move', move)
30450         .on('end', end);
30451
30452
30453     mode.enter = function() {
30454         context.install(hover);
30455         context.install(edit);
30456
30457         d3_select(window)
30458             .on('keydown.drawWay', keydown)
30459             .on('keyup.drawWay', keyup);
30460
30461         context.history()
30462             .on('undone.drag-node', cancel);
30463     };
30464
30465
30466     mode.exit = function() {
30467         context.ui().sidebar.hover.cancel();
30468         context.uninstall(hover);
30469         context.uninstall(edit);
30470
30471         d3_select(window)
30472             .on('keydown.hover', null)
30473             .on('keyup.hover', null);
30474
30475         context.history()
30476             .on('undone.drag-node', null);
30477
30478         context.map()
30479             .on('drawn.drag-node', null);
30480
30481         _activeEntity = null;
30482
30483         context.surface()
30484             .classed('nope', false)
30485             .classed('nope-suppressed', false)
30486             .classed('nope-disabled', false)
30487             .selectAll('.active')
30488             .classed('active', false);
30489
30490         stopNudge();
30491     };
30492
30493
30494     mode.selectedIDs = function() {
30495         if (!arguments.length) return _activeEntity ? [_activeEntity.id] : [];
30496         // no assign
30497         return mode;
30498     };
30499
30500
30501     mode.activeID = function() {
30502         if (!arguments.length) return _activeEntity && _activeEntity.id;
30503         // no assign
30504         return mode;
30505     };
30506
30507
30508     mode.restoreSelectedIDs = function(_) {
30509         if (!arguments.length) return _restoreSelectedIDs;
30510         _restoreSelectedIDs = _;
30511         return mode;
30512     };
30513
30514
30515     mode.behavior = drag;
30516
30517
30518     return mode;
30519 }
30520
30521 function modeBrowse(context) {
30522     var mode = {
30523         button: 'browse',
30524         id: 'browse',
30525         title: t('modes.browse.title'),
30526         description: t('modes.browse.description')
30527     }, sidebar;
30528
30529     var behaviors = [
30530         behaviorPaste(context),
30531         behaviorHover(context).on('hover', context.ui().sidebar.hover),
30532         behaviorSelect(context),
30533         behaviorLasso(context),
30534         modeDragNode(context).behavior
30535     ];
30536
30537
30538     mode.enter = function() {
30539         behaviors.forEach(function(behavior) {
30540             context.install(behavior);
30541         });
30542
30543         // Get focus on the body.
30544         if (document.activeElement && document.activeElement.blur) {
30545             document.activeElement.blur();
30546         }
30547
30548         if (sidebar) {
30549             context.ui().sidebar.show(sidebar);
30550         } else {
30551             context.ui().sidebar.select(null);
30552         }
30553     };
30554
30555
30556     mode.exit = function() {
30557         context.ui().sidebar.hover.cancel();
30558         behaviors.forEach(function(behavior) {
30559             context.uninstall(behavior);
30560         });
30561
30562         if (sidebar) {
30563             context.ui().sidebar.hide();
30564         }
30565     };
30566
30567
30568     mode.sidebar = function(_) {
30569         if (!arguments.length) return sidebar;
30570         sidebar = _;
30571         return mode;
30572     };
30573
30574
30575     return mode;
30576 }
30577
30578 function modeDrawArea(context, wayId, startGraph) {
30579     var mode = {
30580         button: 'area',
30581         id: 'draw-area'
30582     };
30583
30584     var behavior;
30585
30586
30587     mode.enter = function() {
30588         var way = context.entity(wayId);
30589
30590         behavior = behaviorDrawWay(context, wayId, undefined, mode, startGraph)
30591             .tail(t('modes.draw_area.tail'));
30592
30593         var addNode = behavior.addNode;
30594
30595         behavior.addNode = function(node, d) {
30596             var length = way.nodes.length;
30597             var penultimate = length > 2 ? way.nodes[length - 2] : null;
30598
30599             if (node.id === way.first() || node.id === penultimate) {
30600                 behavior.finish();
30601             } else {
30602                 addNode(node, d);
30603             }
30604         };
30605
30606         context.install(behavior);
30607     };
30608
30609
30610     mode.exit = function() {
30611         context.uninstall(behavior);
30612     };
30613
30614
30615     mode.selectedIDs = function() {
30616         return [wayId];
30617     };
30618
30619
30620     mode.activeID = function() {
30621         return (behavior && behavior.activeID()) || [];
30622     };
30623
30624
30625     return mode;
30626 }
30627
30628 function modeDrawLine(context, wayId, startGraph, affix) {
30629     var mode = {
30630         button: 'line',
30631         id: 'draw-line'
30632     };
30633
30634     var behavior;
30635
30636
30637     mode.enter = function() {
30638         var way = context.entity(wayId);
30639         var index = (affix === 'prefix') ? 0 : undefined;
30640         var headId = (affix === 'prefix') ? way.first() : way.last();
30641
30642         behavior = behaviorDrawWay(context, wayId, index, mode, startGraph)
30643             .tail(t('modes.draw_line.tail'));
30644
30645         var addNode = behavior.addNode;
30646         behavior.addNode = function(node, d) {
30647             if (node.id === headId) {
30648                 behavior.finish();
30649             } else {
30650                 addNode(node, d);
30651             }
30652         };
30653
30654         context.install(behavior);
30655     };
30656
30657
30658     mode.exit = function() {
30659         context.uninstall(behavior);
30660     };
30661
30662
30663     mode.selectedIDs = function() {
30664         return [wayId];
30665     };
30666
30667
30668     mode.activeID = function() {
30669         return (behavior && behavior.activeID()) || [];
30670     };
30671
30672     return mode;
30673 }
30674
30675 function operationCircularize(selectedIDs, context) {
30676     var entityId = selectedIDs[0],
30677         entity = context.entity(entityId),
30678         extent = entity.extent(context.graph()),
30679         geometry = context.geometry(entityId),
30680         action = actionCircularize(entityId, context.projection);
30681
30682
30683     var operation = function() {
30684         context.perform(action, operation.annotation());
30685     };
30686
30687
30688     operation.available = function() {
30689         return selectedIDs.length === 1 &&
30690             entity.type === 'way' &&
30691             uniq(entity.nodes).length > 1;
30692     };
30693
30694
30695     operation.disabled = function() {
30696         var reason;
30697         if (extent.percentContainedIn(context.extent()) < 0.8) {
30698             reason = 'too_large';
30699         } else if (context.hasHiddenConnections(entityId)) {
30700             reason = 'connected_to_hidden';
30701         }
30702         return action.disabled(context.graph()) || reason;
30703     };
30704
30705
30706     operation.tooltip = function() {
30707         var disable = operation.disabled();
30708         return disable ?
30709             t('operations.circularize.' + disable) :
30710             t('operations.circularize.description.' + geometry);
30711     };
30712
30713
30714     operation.annotation = function() {
30715         return t('operations.circularize.annotation.' + geometry);
30716     };
30717
30718
30719     operation.id = 'circularize';
30720     operation.keys = [t('operations.circularize.key')];
30721     operation.title = t('operations.circularize.title');
30722     operation.behavior = behaviorOperation(context).which(operation);
30723
30724     return operation;
30725 }
30726
30727 function operationContinue(selectedIDs, context) {
30728     var graph = context.graph(),
30729         entities = selectedIDs.map(function(id) { return graph.entity(id); }),
30730         geometries = assignIn({ line: [], vertex: [] },
30731             groupBy(entities, function(entity) { return entity.geometry(graph); })),
30732         vertex = geometries.vertex[0];
30733
30734
30735     function candidateWays() {
30736         return graph.parentWays(vertex).filter(function(parent) {
30737             return parent.geometry(graph) === 'line' &&
30738                 !parent.isClosed() &&
30739                 parent.affix(vertex.id) &&
30740                 (geometries.line.length === 0 || geometries.line[0] === parent);
30741         });
30742     }
30743
30744
30745     var operation = function() {
30746         var candidate = candidateWays()[0];
30747         context.enter(
30748             modeDrawLine(context, candidate.id, context.graph(), candidate.affix(vertex.id))
30749         );
30750     };
30751
30752
30753     operation.available = function() {
30754         return geometries.vertex.length === 1 && geometries.line.length <= 1 &&
30755             !context.features().hasHiddenConnections(vertex, context.graph());
30756     };
30757
30758
30759     operation.disabled = function() {
30760         var candidates = candidateWays();
30761         if (candidates.length === 0)
30762             return 'not_eligible';
30763         if (candidates.length > 1)
30764             return 'multiple';
30765     };
30766
30767
30768     operation.tooltip = function() {
30769         var disable = operation.disabled();
30770         return disable ?
30771             t('operations.continue.' + disable) :
30772             t('operations.continue.description');
30773     };
30774
30775
30776     operation.annotation = function() {
30777         return t('operations.continue.annotation.line');
30778     };
30779
30780
30781     operation.id = 'continue';
30782     operation.keys = [t('operations.continue.key')];
30783     operation.title = t('operations.continue.title');
30784     operation.behavior = behaviorOperation(context).which(operation);
30785
30786     return operation;
30787 }
30788
30789 function operationDelete(selectedIDs, context) {
30790     var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
30791         action = actionDeleteMultiple(selectedIDs),
30792         extent = selectedIDs.reduce(function(extent, id) {
30793                 return extent.extend(context.entity(id).extent(context.graph()));
30794             }, geoExtent());
30795
30796
30797     var operation = function() {
30798         var nextSelectedID;
30799         var nextSelectedLoc;
30800
30801         if (selectedIDs.length === 1) {
30802             var id = selectedIDs[0],
30803                 entity = context.entity(id),
30804                 geometry = context.geometry(id),
30805                 parents = context.graph().parentWays(entity),
30806                 parent = parents[0];
30807
30808             // Select the next closest node in the way.
30809             if (geometry === 'vertex') {
30810                 var nodes = parent.nodes,
30811                     i = nodes.indexOf(id);
30812
30813                 if (i === 0) {
30814                     i++;
30815                 } else if (i === nodes.length - 1) {
30816                     i--;
30817                 } else {
30818                     var a = geoSphericalDistance(entity.loc, context.entity(nodes[i - 1]).loc),
30819                         b = geoSphericalDistance(entity.loc, context.entity(nodes[i + 1]).loc);
30820                     i = a < b ? i - 1 : i + 1;
30821                 }
30822
30823                 nextSelectedID = nodes[i];
30824                 nextSelectedLoc = context.entity(nextSelectedID).loc;
30825             }
30826         }
30827
30828         context.perform(action, operation.annotation());
30829
30830         if (nextSelectedID && nextSelectedLoc) {
30831             if (context.hasEntity(nextSelectedID)) {
30832                 context.enter(modeSelect(context, [nextSelectedID]).follow(true));
30833             } else {
30834                 context.map().centerEase(nextSelectedLoc);
30835                 context.enter(modeBrowse(context));
30836             }
30837         } else {
30838             context.enter(modeBrowse(context));
30839         }
30840
30841     };
30842
30843
30844     operation.available = function() {
30845         return true;
30846     };
30847
30848
30849     operation.disabled = function() {
30850         var reason;
30851         if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
30852             reason = 'too_large';
30853         } else if (some(selectedIDs, context.hasHiddenConnections)) {
30854             reason = 'connected_to_hidden';
30855         } else if (some(selectedIDs, protectedMember)) {
30856             reason = 'part_of_relation';
30857         } else if (some(selectedIDs, incompleteRelation)) {
30858             reason = 'incomplete_relation';
30859         }
30860         return reason;
30861
30862         function incompleteRelation(id) {
30863             var entity = context.entity(id);
30864             return entity.type === 'relation' && !entity.isComplete(context.graph());
30865         }
30866
30867         function protectedMember(id) {
30868             var entity = context.entity(id);
30869             if (entity.type !== 'way') return false;
30870
30871             var parents = context.graph().parentRelations(entity);
30872             for (var i = 0; i < parents.length; i++) {
30873                 var parent = parents[i],
30874                     type = parent.tags.type,
30875                     role = parent.memberById(id).role || 'outer';
30876                 if (type === 'route' || type === 'boundary' || (type === 'multipolygon' && role === 'outer')) {
30877                     return true;
30878                 }
30879             }
30880             return false;
30881         }
30882
30883     };
30884
30885
30886     operation.tooltip = function() {
30887         var disable = operation.disabled();
30888         return disable ?
30889             t('operations.delete.' + disable + '.' + multi) :
30890             t('operations.delete.description' + '.' + multi);
30891     };
30892
30893
30894     operation.annotation = function() {
30895         return selectedIDs.length === 1 ?
30896             t('operations.delete.annotation.' + context.geometry(selectedIDs[0])) :
30897             t('operations.delete.annotation.multiple', { n: selectedIDs.length });
30898     };
30899
30900
30901     operation.id = 'delete';
30902     operation.keys = [uiCmd('⌘⌫'), uiCmd('⌘⌦'), uiCmd('⌦')];
30903     operation.title = t('operations.delete.title');
30904     operation.behavior = behaviorOperation(context).which(operation);
30905
30906     return operation;
30907 }
30908
30909 function operationDisconnect(selectedIDs, context) {
30910     var vertices = filter(selectedIDs, function(entityId) {
30911         return context.geometry(entityId) === 'vertex';
30912     });
30913
30914     var entityId = vertices[0],
30915         action = actionDisconnect(entityId);
30916
30917     if (selectedIDs.length > 1) {
30918         action.limitWays(without(selectedIDs, entityId));
30919     }
30920
30921
30922     var operation = function() {
30923         context.perform(action, operation.annotation());
30924     };
30925
30926
30927     operation.available = function() {
30928         return vertices.length === 1;
30929     };
30930
30931
30932     operation.disabled = function() {
30933         var reason;
30934         if (some(selectedIDs, context.hasHiddenConnections)) {
30935             reason = 'connected_to_hidden';
30936         }
30937         return action.disabled(context.graph()) || reason;
30938     };
30939
30940
30941     operation.tooltip = function() {
30942         var disable = operation.disabled();
30943         return disable ?
30944             t('operations.disconnect.' + disable) :
30945             t('operations.disconnect.description');
30946     };
30947
30948
30949     operation.annotation = function() {
30950         return t('operations.disconnect.annotation');
30951     };
30952
30953
30954     operation.id = 'disconnect';
30955     operation.keys = [t('operations.disconnect.key')];
30956     operation.title = t('operations.disconnect.title');
30957     operation.behavior = behaviorOperation(context).which(operation);
30958
30959     return operation;
30960 }
30961
30962 function operationMerge(selectedIDs, context) {
30963
30964     function updatePresetTags(newGraph, ids) {
30965         var id = ids[0],
30966             newEntity = newGraph.hasEntity(id);
30967
30968         if (!newEntity) return;
30969
30970         var newPreset = context.presets().match(newEntity, newGraph);
30971
30972         context.replace(actionChangePreset(id, null, newPreset), operation.annotation());
30973     }
30974
30975
30976     var join = actionJoin(selectedIDs),
30977         merge = actionMerge(selectedIDs),
30978         mergePolygon = actionMergePolygon(selectedIDs);
30979
30980
30981     var operation = function() {
30982         var origGraph = context.graph(),
30983             action;
30984
30985         if (!join.disabled(origGraph)) {
30986             action = join;
30987         } else if (!merge.disabled(origGraph)) {
30988             action = merge;
30989         } else {
30990             action = mergePolygon;
30991         }
30992
30993         context.perform(action, operation.annotation());
30994
30995         var ids = selectedIDs.filter(function(id) {
30996             var entity = context.hasEntity(id);
30997             return entity && entity.type !== 'node';
30998         });
30999
31000         // if we merged tags, rematch preset to update tags if necessary (#3851)
31001         if (action === merge) {
31002             updatePresetTags(context.graph(), ids);
31003         }
31004
31005         context.enter(modeSelect(context, ids));
31006     };
31007
31008
31009     operation.available = function() {
31010         return selectedIDs.length >= 2;
31011     };
31012
31013
31014     operation.disabled = function() {
31015         return join.disabled(context.graph()) &&
31016             merge.disabled(context.graph()) &&
31017             mergePolygon.disabled(context.graph());
31018     };
31019
31020
31021     operation.tooltip = function() {
31022         var j = join.disabled(context.graph()),
31023             m = merge.disabled(context.graph()),
31024             p = mergePolygon.disabled(context.graph());
31025
31026         if (j === 'restriction' && m && p) {
31027             return t('operations.merge.restriction',
31028                 { relation: context.presets().item('type/restriction').name() });
31029         }
31030
31031         if (p === 'incomplete_relation' && j && m) {
31032             return t('operations.merge.incomplete_relation');
31033         }
31034
31035         if (j && m && p) {
31036             return t('operations.merge.' + j);
31037         }
31038
31039         return t('operations.merge.description');
31040     };
31041
31042
31043     operation.annotation = function() {
31044         return t('operations.merge.annotation', { n: selectedIDs.length });
31045     };
31046
31047
31048     operation.id = 'merge';
31049     operation.keys = [t('operations.merge.key')];
31050     operation.title = t('operations.merge.title');
31051     operation.behavior = behaviorOperation(context).which(operation);
31052
31053     return operation;
31054 }
31055
31056 function operationMove(selectedIDs, context) {
31057     var multi = (selectedIDs.length === 1 ? 'single' : 'multiple');
31058     var extent = selectedIDs.reduce(function(extent, id) {
31059         return extent.extend(context.entity(id).extent(context.graph()));
31060     }, geoExtent());
31061
31062
31063     var operation = function() {
31064         context.enter(modeMove(context, selectedIDs));
31065     };
31066
31067
31068     operation.available = function() {
31069         return selectedIDs.length > 1 ||
31070             context.entity(selectedIDs[0]).type !== 'node';
31071     };
31072
31073
31074     operation.disabled = function() {
31075         var reason;
31076         if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
31077             reason = 'too_large';
31078         } else if (some(selectedIDs, context.hasHiddenConnections)) {
31079             reason = 'connected_to_hidden';
31080         } else if (some(selectedIDs, incompleteRelation)) {
31081             reason = 'incomplete_relation';
31082         }
31083         return reason;
31084
31085         function incompleteRelation(id) {
31086             var entity = context.entity(id);
31087             return entity.type === 'relation' && !entity.isComplete(context.graph());
31088         }
31089     };
31090
31091
31092     operation.tooltip = function() {
31093         var disable = operation.disabled();
31094         return disable ?
31095             t('operations.move.' + disable + '.' + multi) :
31096             t('operations.move.description.' + multi);
31097     };
31098
31099
31100     operation.annotation = function() {
31101         return selectedIDs.length === 1 ?
31102             t('operations.move.annotation.' + context.geometry(selectedIDs[0])) :
31103             t('operations.move.annotation.multiple');
31104     };
31105
31106
31107     operation.id = 'move';
31108     operation.keys = [t('operations.move.key')];
31109     operation.title = t('operations.move.title');
31110     operation.behavior = behaviorOperation(context).which(operation);
31111
31112     return operation;
31113 }
31114
31115 function operationOrthogonalize(selectedIDs, context) {
31116     var entityId = selectedIDs[0],
31117         entity = context.entity(entityId),
31118         extent = entity.extent(context.graph()),
31119         geometry = context.geometry(entityId),
31120         action = actionOrthogonalize(entityId, context.projection);
31121
31122
31123     var operation = function() {
31124         context.perform(action, operation.annotation());
31125     };
31126
31127
31128     operation.available = function() {
31129         return selectedIDs.length === 1 &&
31130             entity.type === 'way' &&
31131             entity.isClosed() &&
31132             uniq(entity.nodes).length > 2;
31133     };
31134
31135
31136     operation.disabled = function() {
31137         var reason;
31138         if (extent.percentContainedIn(context.extent()) < 0.8) {
31139             reason = 'too_large';
31140         } else if (context.hasHiddenConnections(entityId)) {
31141             reason = 'connected_to_hidden';
31142         }
31143         return action.disabled(context.graph()) || reason;
31144     };
31145
31146
31147     operation.tooltip = function() {
31148         var disable = operation.disabled();
31149         return disable ?
31150             t('operations.orthogonalize.' + disable) :
31151             t('operations.orthogonalize.description.' + geometry);
31152     };
31153
31154
31155     operation.annotation = function() {
31156         return t('operations.orthogonalize.annotation.' + geometry);
31157     };
31158
31159
31160     operation.id = 'orthogonalize';
31161     operation.keys = [t('operations.orthogonalize.key')];
31162     operation.title = t('operations.orthogonalize.title');
31163     operation.behavior = behaviorOperation(context).which(operation);
31164
31165     return operation;
31166 }
31167
31168 /**
31169  * This method is like `_.uniq` except that it accepts `iteratee` which is
31170  * invoked for each element in `array` to generate the criterion by which
31171  * uniqueness is computed. The order of result values is determined by the
31172  * order they occur in the array. The iteratee is invoked with one argument:
31173  * (value).
31174  *
31175  * @static
31176  * @memberOf _
31177  * @since 4.0.0
31178  * @category Array
31179  * @param {Array} array The array to inspect.
31180  * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
31181  * @returns {Array} Returns the new duplicate free array.
31182  * @example
31183  *
31184  * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
31185  * // => [2.1, 1.2]
31186  *
31187  * // The `_.property` iteratee shorthand.
31188  * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
31189  * // => [{ 'x': 1 }, { 'x': 2 }]
31190  */
31191 function uniqBy(array, iteratee) {
31192   return (array && array.length) ? baseUniq(array, baseIteratee(iteratee, 2)) : [];
31193 }
31194
31195 function operationReflectShort(selectedIDs, context) {
31196     return operationReflect(selectedIDs, context, 'short');
31197 }
31198
31199
31200 function operationReflectLong(selectedIDs, context) {
31201     return operationReflect(selectedIDs, context, 'long');
31202 }
31203
31204
31205 function operationReflect(selectedIDs, context, axis) {
31206     axis = axis || 'long';
31207     var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
31208         extent = selectedIDs.reduce(function(extent, id) {
31209             return extent.extend(context.entity(id).extent(context.graph()));
31210         }, geoExtent());
31211
31212
31213     var operation = function() {
31214         var action = actionReflect(selectedIDs, context.projection)
31215             .useLongAxis(Boolean(axis === 'long'));
31216         context.perform(action, operation.annotation());
31217     };
31218
31219
31220     operation.available = function() {
31221         var nodes = utilGetAllNodes(selectedIDs, context.graph());
31222         return uniqBy(nodes, function(n) { return n.loc; }).length >= 3;
31223     };
31224
31225
31226     operation.disabled = function() {
31227         var reason;
31228         if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
31229             reason = 'too_large';
31230         } else if (some(selectedIDs, context.hasHiddenConnections)) {
31231             reason = 'connected_to_hidden';
31232         } else if (some(selectedIDs, incompleteRelation)) {
31233             reason = 'incomplete_relation';
31234         }
31235         return reason;
31236
31237         function incompleteRelation(id) {
31238             var entity = context.entity(id);
31239             return entity.type === 'relation' && !entity.isComplete(context.graph());
31240         }
31241     };
31242
31243
31244     operation.tooltip = function() {
31245         var disable = operation.disabled();
31246         return disable ?
31247             t('operations.reflect.' + disable + '.' + multi) :
31248             t('operations.reflect.description.' + axis + '.' + multi);
31249     };
31250
31251
31252     operation.annotation = function() {
31253         return t('operations.reflect.annotation.' + axis + '.' + multi);
31254     };
31255
31256
31257     operation.id = 'reflect-' + axis;
31258     operation.keys = [t('operations.reflect.key.' + axis)];
31259     operation.title = t('operations.reflect.title.' + axis);
31260     operation.behavior = behaviorOperation(context).which(operation);
31261
31262     return operation;
31263 }
31264
31265 function operationReverse(selectedIDs, context) {
31266     var entityId = selectedIDs[0];
31267
31268     var operation = function() {
31269         context.perform(actionReverse(entityId), operation.annotation());
31270     };
31271
31272
31273     operation.available = function() {
31274         return selectedIDs.length === 1 && context.geometry(entityId) === 'line';
31275     };
31276
31277
31278     operation.disabled = function() {
31279         return false;
31280     };
31281
31282
31283     operation.tooltip = function() {
31284         return t('operations.reverse.description');
31285     };
31286
31287
31288     operation.annotation = function() {
31289         return t('operations.reverse.annotation');
31290     };
31291
31292
31293     operation.id = 'reverse';
31294     operation.keys = [t('operations.reverse.key')];
31295     operation.title = t('operations.reverse.title');
31296     operation.behavior = behaviorOperation(context).which(operation);
31297
31298     return operation;
31299 }
31300
31301 function operationRotate(selectedIDs, context) {
31302     var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
31303         extent = selectedIDs.reduce(function(extent, id) {
31304             return extent.extend(context.entity(id).extent(context.graph()));
31305         }, geoExtent());
31306
31307
31308     var operation = function() {
31309         context.enter(modeRotate(context, selectedIDs));
31310     };
31311
31312
31313     operation.available = function() {
31314         var nodes = utilGetAllNodes(selectedIDs, context.graph());
31315         return uniqBy(nodes, function(n) { return n.loc; }).length >= 2;
31316     };
31317
31318
31319     operation.disabled = function() {
31320         var reason;
31321         if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
31322             reason = 'too_large';
31323         } else if (some(selectedIDs, context.hasHiddenConnections)) {
31324             reason = 'connected_to_hidden';
31325         } else if (some(selectedIDs, incompleteRelation)) {
31326             reason = 'incomplete_relation';
31327         }
31328         return reason;
31329
31330         function incompleteRelation(id) {
31331             var entity = context.entity(id);
31332             return entity.type === 'relation' && !entity.isComplete(context.graph());
31333         }
31334     };
31335
31336
31337     operation.tooltip = function() {
31338         var disable = operation.disabled();
31339         return disable ?
31340             t('operations.rotate.' + disable + '.' + multi) :
31341             t('operations.rotate.description.' + multi);
31342     };
31343
31344
31345     operation.annotation = function() {
31346         return selectedIDs.length === 1 ?
31347             t('operations.rotate.annotation.' + context.geometry(selectedIDs[0])) :
31348             t('operations.rotate.annotation.multiple');
31349     };
31350
31351
31352     operation.id = 'rotate';
31353     operation.keys = [t('operations.rotate.key')];
31354     operation.title = t('operations.rotate.title');
31355     operation.behavior = behaviorOperation(context).which(operation);
31356
31357     return operation;
31358 }
31359
31360 function operationSplit(selectedIDs, context) {
31361     var vertices = filter(selectedIDs, function(entityId) {
31362         return context.geometry(entityId) === 'vertex';
31363     });
31364
31365     var entityId = vertices[0],
31366         action = actionSplit(entityId),
31367         ways = [];
31368
31369     if (vertices.length === 1) {
31370         if (selectedIDs.length > 1) {
31371             action.limitWays(without(selectedIDs, entityId));
31372         }
31373         ways = action.ways(context.graph());
31374     }
31375
31376
31377     var operation = function() {
31378         var difference = context.perform(action, operation.annotation());
31379         context.enter(modeSelect(context, difference.extantIDs()));
31380     };
31381
31382
31383     operation.available = function() {
31384         return vertices.length === 1;
31385     };
31386
31387
31388     operation.disabled = function() {
31389         var reason;
31390         if (some(selectedIDs, context.hasHiddenConnections)) {
31391             reason = 'connected_to_hidden';
31392         }
31393         return action.disabled(context.graph()) || reason;
31394     };
31395
31396
31397     operation.tooltip = function() {
31398         var disable = operation.disabled();
31399         if (disable) {
31400             return t('operations.split.' + disable);
31401         }
31402         if (ways.length === 1) {
31403             return t('operations.split.description.' + context.geometry(ways[0].id));
31404         } else {
31405             return t('operations.split.description.multiple');
31406         }
31407     };
31408
31409
31410     operation.annotation = function() {
31411         return ways.length === 1 ?
31412             t('operations.split.annotation.' + context.geometry(ways[0].id)) :
31413             t('operations.split.annotation.multiple', { n: ways.length });
31414     };
31415
31416
31417     operation.id = 'split';
31418     operation.keys = [t('operations.split.key')];
31419     operation.title = t('operations.split.title');
31420     operation.behavior = behaviorOperation(context).which(operation);
31421
31422     return operation;
31423 }
31424
31425 function operationStraighten(selectedIDs, context) {
31426     var entityId = selectedIDs[0],
31427         action = actionStraighten(entityId, context.projection);
31428
31429
31430     function operation() {
31431         context.perform(action, operation.annotation());
31432     }
31433
31434
31435     operation.available = function() {
31436         var entity = context.entity(entityId);
31437         return selectedIDs.length === 1 &&
31438             entity.type === 'way' &&
31439             !entity.isClosed() &&
31440             uniq(entity.nodes).length > 2;
31441     };
31442
31443
31444     operation.disabled = function() {
31445         var reason;
31446         if (context.hasHiddenConnections(entityId)) {
31447             reason = 'connected_to_hidden';
31448         }
31449         return action.disabled(context.graph()) || reason;
31450     };
31451
31452
31453     operation.tooltip = function() {
31454         var disable = operation.disabled();
31455         return disable ?
31456             t('operations.straighten.' + disable) :
31457             t('operations.straighten.description');
31458     };
31459
31460
31461     operation.annotation = function() {
31462         return t('operations.straighten.annotation');
31463     };
31464
31465
31466     operation.id = 'straighten';
31467     operation.keys = [t('operations.straighten.key')];
31468     operation.title = t('operations.straighten.title');
31469     operation.behavior = behaviorOperation(context).which(operation);
31470
31471     return operation;
31472 }
31473
31474
31475
31476 var Operations = Object.freeze({
31477         operationCircularize: operationCircularize,
31478         operationContinue: operationContinue,
31479         operationDelete: operationDelete,
31480         operationDisconnect: operationDisconnect,
31481         operationMerge: operationMerge,
31482         operationMove: operationMove,
31483         operationOrthogonalize: operationOrthogonalize,
31484         operationReflectShort: operationReflectShort,
31485         operationReflectLong: operationReflectLong,
31486         operationReverse: operationReverse,
31487         operationRotate: operationRotate,
31488         operationSplit: operationSplit,
31489         operationStraighten: operationStraighten
31490 });
31491
31492 function modeMove(context, entityIDs, baseGraph) {
31493     var mode = {
31494         id: 'move',
31495         button: 'browse'
31496     };
31497
31498     var keybinding = d3keybinding('move');
31499     var behaviors = [
31500         behaviorEdit(context),
31501         operationCircularize(entityIDs, context).behavior,
31502         operationDelete(entityIDs, context).behavior,
31503         operationOrthogonalize(entityIDs, context).behavior,
31504         operationReflectLong(entityIDs, context).behavior,
31505         operationReflectShort(entityIDs, context).behavior,
31506         operationRotate(entityIDs, context).behavior
31507     ];
31508     var annotation = entityIDs.length === 1 ?
31509         t('operations.move.annotation.' + context.geometry(entityIDs[0])) :
31510         t('operations.move.annotation.multiple');
31511
31512     var _prevGraph;
31513     var _cache;
31514     var _origin;
31515     var _nudgeInterval;
31516
31517
31518     function doMove(nudge) {
31519         nudge = nudge || [0, 0];
31520
31521         var fn;
31522         if (_prevGraph !== context.graph()) {
31523             _cache = {};
31524             _origin = context.map().mouseCoordinates();
31525             fn = context.perform;
31526         } else {
31527             fn = context.overwrite;
31528         }
31529
31530         var currMouse = context.mouse();
31531         var origMouse = context.projection(_origin);
31532         var delta = geoVecSubtract(geoVecSubtract(currMouse, origMouse), nudge);
31533
31534         fn(actionMove(entityIDs, delta, context.projection, _cache), annotation);
31535         _prevGraph = context.graph();
31536     }
31537
31538
31539     function startNudge(nudge) {
31540         if (_nudgeInterval) window.clearInterval(_nudgeInterval);
31541         _nudgeInterval = window.setInterval(function() {
31542             context.pan(nudge);
31543             doMove(nudge);
31544         }, 50);
31545     }
31546
31547
31548     function stopNudge() {
31549         if (_nudgeInterval) {
31550             window.clearInterval(_nudgeInterval);
31551             _nudgeInterval = null;
31552         }
31553     }
31554
31555
31556     function move() {
31557         doMove();
31558         var nudge = geoViewportEdge(context.mouse(), context.map().dimensions());
31559         if (nudge) {
31560             startNudge(nudge);
31561         } else {
31562             stopNudge();
31563         }
31564     }
31565
31566
31567     function finish() {
31568         event.stopPropagation();
31569         context.enter(modeSelect(context, entityIDs));
31570         stopNudge();
31571     }
31572
31573
31574     function cancel() {
31575         if (baseGraph) {
31576             while (context.graph() !== baseGraph) context.pop();
31577             context.enter(modeBrowse(context));
31578         } else {
31579             context.pop();
31580             context.enter(modeSelect(context, entityIDs));
31581         }
31582         stopNudge();
31583     }
31584
31585
31586     function undone() {
31587         context.enter(modeBrowse(context));
31588     }
31589
31590
31591     mode.enter = function() {
31592         _origin = context.map().mouseCoordinates();
31593         _prevGraph = null;
31594         _cache = {};
31595
31596         behaviors.forEach(function(behavior) {
31597             context.install(behavior);
31598         });
31599
31600         context.surface()
31601             .on('mousemove.move', move)
31602             .on('click.move', finish);
31603
31604         context.history()
31605             .on('undone.move', undone);
31606
31607         keybinding
31608             .on('⎋', cancel)
31609             .on('↩', finish);
31610
31611         d3_select(document)
31612             .call(keybinding);
31613     };
31614
31615
31616     mode.exit = function() {
31617         stopNudge();
31618
31619         behaviors.forEach(function(behavior) {
31620             context.uninstall(behavior);
31621         });
31622
31623         context.surface()
31624             .on('mousemove.move', null)
31625             .on('click.move', null);
31626
31627         context.history()
31628             .on('undone.move', null);
31629
31630         keybinding.off();
31631     };
31632
31633
31634     mode.selectedIDs = function() {
31635         if (!arguments.length) return entityIDs;
31636         // no assign
31637         return mode;
31638     };
31639
31640
31641     return mode;
31642 }
31643
31644 function modeRotate(context, entityIDs) {
31645     var mode = {
31646         id: 'rotate',
31647         button: 'browse'
31648     };
31649
31650     var keybinding = d3keybinding('rotate');
31651     var behaviors = [
31652         behaviorEdit(context),
31653         operationCircularize(entityIDs, context).behavior,
31654         operationDelete(entityIDs, context).behavior,
31655         operationMove(entityIDs, context).behavior,
31656         operationOrthogonalize(entityIDs, context).behavior,
31657         operationReflectLong(entityIDs, context).behavior,
31658         operationReflectShort(entityIDs, context).behavior
31659     ];
31660     var annotation = entityIDs.length === 1 ?
31661         t('operations.rotate.annotation.' + context.geometry(entityIDs[0])) :
31662         t('operations.rotate.annotation.multiple');
31663
31664     var _prevGraph;
31665     var _prevAngle;
31666     var _prevTransform;
31667     var _pivot;
31668
31669
31670     function doRotate() {
31671         var fn;
31672         if (context.graph() !== _prevGraph) {
31673             fn = context.perform;
31674         } else {
31675             fn = context.replace;
31676         }
31677
31678         // projection changed, recalculate _pivot
31679         var projection = context.projection;
31680         var currTransform = projection.transform();
31681         if (!_prevTransform ||
31682             currTransform.k !== _prevTransform.k ||
31683             currTransform.x !== _prevTransform.x ||
31684             currTransform.y !== _prevTransform.y) {
31685
31686             var nodes = utilGetAllNodes(entityIDs, context.graph());
31687             var points = nodes.map(function(n) { return projection(n.loc); });
31688
31689             if (points.length === 1) {  // degenerate case
31690                 _pivot = points[0];
31691             } else if (points.length === 2) {
31692                 _pivot = geoVecInterp(points[0], points[1], 0.5);
31693             } else {
31694                 _pivot = d3_polygonCentroid(d3_polygonHull(points));
31695             }
31696             _prevAngle = undefined;
31697         }
31698
31699
31700         var currMouse = context.mouse();
31701         var currAngle = Math.atan2(currMouse[1] - _pivot[1], currMouse[0] - _pivot[0]);
31702
31703         if (typeof _prevAngle === 'undefined') _prevAngle = currAngle;
31704         var delta = currAngle - _prevAngle;
31705
31706         fn(actionRotate(entityIDs, _pivot, delta, projection), annotation);
31707
31708         _prevTransform = currTransform;
31709         _prevAngle = currAngle;
31710         _prevGraph = context.graph();
31711     }
31712
31713
31714     function finish() {
31715         event.stopPropagation();
31716         context.enter(modeSelect(context, entityIDs));
31717     }
31718
31719
31720     function cancel() {
31721         context.pop();
31722         context.enter(modeSelect(context, entityIDs));
31723     }
31724
31725
31726     function undone() {
31727         context.enter(modeBrowse(context));
31728     }
31729
31730
31731     mode.enter = function() {
31732         behaviors.forEach(function(behavior) {
31733             context.install(behavior);
31734         });
31735
31736         context.surface()
31737             .on('mousemove.rotate', doRotate)
31738             .on('click.rotate', finish);
31739
31740         context.history()
31741             .on('undone.rotate', undone);
31742
31743         keybinding
31744             .on('⎋', cancel)
31745             .on('↩', finish);
31746
31747         d3_select(document)
31748             .call(keybinding);
31749     };
31750
31751
31752     mode.exit = function() {
31753         behaviors.forEach(function(behavior) {
31754             context.uninstall(behavior);
31755         });
31756
31757         context.surface()
31758             .on('mousemove.rotate', null)
31759             .on('click.rotate', null);
31760
31761         context.history()
31762             .on('undone.rotate', null);
31763
31764         keybinding.off();
31765     };
31766
31767
31768     mode.selectedIDs = function() {
31769         if (!arguments.length) return entityIDs;
31770         // no assign
31771         return mode;
31772     };
31773
31774
31775     return mode;
31776 }
31777
31778 /**
31779  * The base implementation of `_.reduce` and `_.reduceRight`, without support
31780  * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
31781  *
31782  * @private
31783  * @param {Array|Object} collection The collection to iterate over.
31784  * @param {Function} iteratee The function invoked per iteration.
31785  * @param {*} accumulator The initial value.
31786  * @param {boolean} initAccum Specify using the first or last element of
31787  *  `collection` as the initial value.
31788  * @param {Function} eachFunc The function to iterate over `collection`.
31789  * @returns {*} Returns the accumulated value.
31790  */
31791 function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
31792   eachFunc(collection, function(value, index, collection) {
31793     accumulator = initAccum
31794       ? (initAccum = false, value)
31795       : iteratee(accumulator, value, index, collection);
31796   });
31797   return accumulator;
31798 }
31799
31800 /**
31801  * Reduces `collection` to a value which is the accumulated result of running
31802  * each element in `collection` thru `iteratee`, where each successive
31803  * invocation is supplied the return value of the previous. If `accumulator`
31804  * is not given, the first element of `collection` is used as the initial
31805  * value. The iteratee is invoked with four arguments:
31806  * (accumulator, value, index|key, collection).
31807  *
31808  * Many lodash methods are guarded to work as iteratees for methods like
31809  * `_.reduce`, `_.reduceRight`, and `_.transform`.
31810  *
31811  * The guarded methods are:
31812  * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
31813  * and `sortBy`
31814  *
31815  * @static
31816  * @memberOf _
31817  * @since 0.1.0
31818  * @category Collection
31819  * @param {Array|Object} collection The collection to iterate over.
31820  * @param {Function} [iteratee=_.identity] The function invoked per iteration.
31821  * @param {*} [accumulator] The initial value.
31822  * @returns {*} Returns the accumulated value.
31823  * @see _.reduceRight
31824  * @example
31825  *
31826  * _.reduce([1, 2], function(sum, n) {
31827  *   return sum + n;
31828  * }, 0);
31829  * // => 3
31830  *
31831  * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
31832  *   (result[value] || (result[value] = [])).push(key);
31833  *   return result;
31834  * }, {});
31835  * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
31836  */
31837 function reduce(collection, iteratee, accumulator) {
31838   var func = isArray(collection) ? arrayReduce : baseReduce,
31839       initAccum = arguments.length < 3;
31840
31841   return func(collection, baseIteratee(iteratee, 4), accumulator, initAccum, baseEach);
31842 }
31843
31844 var _isSaving = false;
31845
31846
31847 function modeSave(context) {
31848     var mode = { id: 'save' };
31849     var keybinding = d3keybinding('modeSave');
31850
31851     var loading = uiLoading(context)
31852         .message(t('save.uploading'))
31853         .blocking(true);
31854
31855     var commit = uiCommit(context)
31856         .on('cancel', cancel)
31857         .on('save', save);
31858
31859     var _toCheck = [];
31860     var _toLoad = [];
31861     var _loaded = {};
31862     var _toLoadCount = 0;
31863     var _toLoadTotal = 0;
31864
31865     var _conflicts = [];
31866     var _errors = [];
31867     var _origChanges;
31868
31869
31870     function cancel(selectedID) {
31871         if (selectedID) {
31872             context.enter(modeSelect(context, [selectedID]));
31873         } else {
31874             context.enter(modeBrowse(context));
31875         }
31876     }
31877
31878
31879     function save(changeset, tryAgain, checkConflicts) {
31880         // Guard against accidentally entering save code twice - #4641
31881         if (_isSaving && !tryAgain) {
31882             return;
31883         }
31884
31885         var osm = context.connection();
31886         if (!osm) {
31887             cancel();
31888             return;
31889         }
31890
31891         // If user somehow got logged out mid-save, try to reauthenticate..
31892         // This can happen if they were logged in from before, but the tokens are no longer valid.
31893         if (!osm.authenticated()) {
31894             osm.authenticate(function(err) {
31895                 if (err) {
31896                     cancel();   // quit save mode..
31897                 } else {
31898                     save(changeset, tryAgain, checkConflicts);  // continue where we left off..
31899                 }
31900             });
31901             return;
31902         }
31903
31904         if (!_isSaving) {
31905             keybindingOff();
31906             context.container().call(loading);  // block input
31907             _isSaving = true;
31908         }
31909
31910         var history = context.history();
31911         var localGraph = context.graph();
31912         var remoteGraph = coreGraph(history.base(), true);
31913
31914         _conflicts = [];
31915         _errors = [];
31916
31917         // Store original changes, in case user wants to download them as an .osc file
31918         _origChanges = history.changes(actionDiscardTags(history.difference()));
31919
31920         // First time, `history.perform` a no-op action.
31921         // Any conflict resolutions will be done as `history.replace`
31922         if (!tryAgain) {
31923             history.perform(actionNoop());
31924         }
31925
31926         // Attempt a fast upload.. If there are conflicts, re-enter with `checkConflicts = true`
31927         if (!checkConflicts) {
31928             upload(changeset);
31929
31930         // Do the full (slow) conflict check..
31931         } else {
31932             var modified = filter(history.difference().summary(), { changeType: 'modified' });
31933             _toCheck = map$4(map$4(modified, 'entity'), 'id');
31934             _toLoad = withChildNodes(_toCheck, localGraph);
31935             _loaded = {};
31936             _toLoadCount = 0;
31937             _toLoadTotal = _toLoad.length;
31938
31939             if (_toCheck.length) {
31940                 showProgress(_toLoadCount, _toLoadTotal);
31941                 _toLoad.forEach(function(id) { _loaded[id] = false; });
31942                 osm.loadMultiple(_toLoad, loaded);
31943             } else {
31944                 upload(changeset);
31945             }
31946         }
31947
31948         return;
31949
31950
31951         function withChildNodes(ids, graph) {
31952             return uniq(reduce(ids, function(result, id) {
31953                 var entity = graph.entity(id);
31954                 if (entity.type === 'way') {
31955                     try {
31956                         var children = graph.childNodes(entity);
31957                         result.push.apply(result, map$4(filter(children, 'version'), 'id'));
31958                     } catch (err) {
31959                         /* eslint-disable no-console */
31960                         if (typeof console !== 'undefined') console.error(err);
31961                         /* eslint-enable no-console */
31962                     }
31963                 }
31964                 return result;
31965             }, clone(ids)));
31966         }
31967
31968
31969         // Reload modified entities into an alternate graph and check for conflicts..
31970         function loaded(err, result) {
31971             if (_errors.length) return;
31972
31973             if (err) {
31974                 _errors.push({
31975                     msg: err.message || err.responseText,
31976                     details: [ t('save.status_code', { code: err.status }) ]
31977                 });
31978                 showErrors();
31979
31980             } else {
31981                 var loadMore = [];
31982
31983                 result.data.forEach(function(entity) {
31984                     remoteGraph.replace(entity);
31985                     _loaded[entity.id] = true;
31986                     _toLoad = without(_toLoad, entity.id);
31987
31988                     if (!entity.visible) return;
31989
31990                     // Because loadMultiple doesn't download /full like loadEntity,
31991                     // need to also load children that aren't already being checked..
31992                     var i, id;
31993                     if (entity.type === 'way') {
31994                         for (i = 0; i < entity.nodes.length; i++) {
31995                             id = entity.nodes[i];
31996                             if (_loaded[id] === undefined) {
31997                                 _loaded[id] = false;
31998                                 loadMore.push(id);
31999                             }
32000                         }
32001                     } else if (entity.type === 'relation' && entity.isMultipolygon()) {
32002                         for (i = 0; i < entity.members.length; i++) {
32003                             id = entity.members[i].id;
32004                             if (_loaded[id] === undefined) {
32005                                 _loaded[id] = false;
32006                                 loadMore.push(id);
32007                             }
32008                         }
32009                     }
32010                 });
32011
32012                 _toLoadCount += result.data.length;
32013                 _toLoadTotal += loadMore.length;
32014                 showProgress(_toLoadCount, _toLoadTotal);
32015
32016                 if (loadMore.length) {
32017                     _toLoad.push.apply(_toLoad, loadMore);
32018                     osm.loadMultiple(loadMore, loaded);
32019                 }
32020
32021                 if (!_toLoad.length) {
32022                     detectConflicts();
32023                 }
32024             }
32025         }
32026
32027
32028         function detectConflicts() {
32029             function choice(id, text, action) {
32030                 return { id: id, text: text, action: function() { history.replace(action); } };
32031             }
32032             function formatUser(d) {
32033                 return '<a href="' + osm.userURL(d) + '" target="_blank">' + d + '</a>';
32034             }
32035             function entityName(entity) {
32036                 return utilDisplayName(entity) || (utilDisplayType(entity.id) + ' ' + entity.id);
32037             }
32038
32039             function sameVersions(local, remote) {
32040                 if (local.version !== remote.version) return false;
32041
32042                 if (local.type === 'way') {
32043                     var children = union(local.nodes, remote.nodes);
32044                     for (var i = 0; i < children.length; i++) {
32045                         var a = localGraph.hasEntity(children[i]);
32046                         var b = remoteGraph.hasEntity(children[i]);
32047                         if (a && b && a.version !== b.version) return false;
32048                     }
32049                 }
32050
32051                 return true;
32052             }
32053
32054             _toCheck.forEach(function(id) {
32055                 var local = localGraph.entity(id);
32056                 var remote = remoteGraph.entity(id);
32057
32058                 if (sameVersions(local, remote)) return;
32059
32060                 var action = actionMergeRemoteChanges;
32061                 var merge = action(id, localGraph, remoteGraph, formatUser);
32062
32063                 history.replace(merge);
32064
32065                 var mergeConflicts = merge.conflicts();
32066                 if (!mergeConflicts.length) return;  // merged safely
32067
32068                 var forceLocal = action(id, localGraph, remoteGraph).withOption('force_local');
32069                 var forceRemote = action(id, localGraph, remoteGraph).withOption('force_remote');
32070                 var keepMine = t('save.conflict.' + (remote.visible ? 'keep_local' : 'restore'));
32071                 var keepTheirs = t('save.conflict.' + (remote.visible ? 'keep_remote' : 'delete'));
32072
32073                 _conflicts.push({
32074                     id: id,
32075                     name: entityName(local),
32076                     details: mergeConflicts,
32077                     chosen: 1,
32078                     choices: [
32079                         choice(id, keepMine, forceLocal),
32080                         choice(id, keepTheirs, forceRemote)
32081                     ]
32082                 });
32083             });
32084
32085             upload(changeset);
32086         }
32087     }
32088
32089
32090     function upload(changeset) {
32091         var osm = context.connection();
32092         if (!osm) {
32093             _errors.push({ msg: 'No OSM Service' });
32094         }
32095
32096         if (_conflicts.length) {
32097             _conflicts.sort(function(a, b) { return b.id.localeCompare(a.id); });
32098             showConflicts(changeset);
32099
32100         } else if (_errors.length) {
32101             showErrors();
32102
32103         } else {
32104             var history = context.history();
32105             var changes = history.changes(actionDiscardTags(history.difference()));
32106             if (changes.modified.length || changes.created.length || changes.deleted.length) {
32107                 osm.putChangeset(changeset, changes, uploadCallback);
32108             } else {        // changes were insignificant or reverted by user
32109                 d3_select('.inspector-wrap *').remove();
32110                 loading.close();
32111                 _isSaving = false;
32112                 context.flush();
32113                 cancel();
32114             }
32115         }
32116     }
32117
32118
32119     function uploadCallback(err, changeset) {
32120         if (err) {
32121             if (err.status === 409) {          // 409 Conflict
32122                 save(changeset, true, true);   // tryAgain = true, checkConflicts = true
32123             } else {
32124                 _errors.push({
32125                     msg: err.message || err.responseText,
32126                     details: [ t('save.status_code', { code: err.status }) ]
32127                 });
32128                 showErrors();
32129             }
32130
32131         } else {
32132             context.history().clearSaved();
32133             success(changeset);
32134             // Add delay to allow for postgres replication #1646 #2678
32135             window.setTimeout(function() {
32136                 d3_select('.inspector-wrap *').remove();
32137                 loading.close();
32138                 _isSaving = false;
32139                 context.flush();
32140             }, 2500);
32141         }
32142     }
32143
32144
32145     function showProgress(num, total) {
32146         var modal = context.container().select('.loading-modal .modal-section');
32147         var progress = modal.selectAll('.progress')
32148             .data([0]);
32149
32150         // enter/update
32151         progress.enter()
32152             .append('div')
32153             .attr('class', 'progress')
32154             .merge(progress)
32155             .text(t('save.conflict_progress', { num: num, total: total }));
32156     }
32157
32158
32159     function showConflicts(changeset) {
32160         var history = context.history();
32161         var selection = context.container()
32162             .select('#sidebar')
32163             .append('div')
32164             .attr('class','sidebar-component');
32165
32166         loading.close();
32167         _isSaving = false;
32168
32169         var ui = uiConflicts(context)
32170             .conflictList(_conflicts)
32171             .origChanges(_origChanges)
32172             .on('cancel', function() {
32173                 history.pop();
32174                 selection.remove();
32175                 keybindingOn();
32176             })
32177             .on('save', function() {
32178                 for (var i = 0; i < _conflicts.length; i++) {
32179                     if (_conflicts[i].chosen === 1) {  // user chose "keep theirs"
32180                         var entity = context.hasEntity(_conflicts[i].id);
32181                         if (entity && entity.type === 'way') {
32182                             var children = uniq(entity.nodes);
32183                             for (var j = 0; j < children.length; j++) {
32184                                 history.replace(actionRevert(children[j]));
32185                             }
32186                         }
32187                         history.replace(actionRevert(_conflicts[i].id));
32188                     }
32189                 }
32190
32191                 selection.remove();
32192                 save(changeset, true, false);  // tryAgain = true, checkConflicts = false
32193             });
32194
32195         selection.call(ui);
32196     }
32197
32198
32199     function showErrors() {
32200         keybindingOn();
32201         context.history().pop();
32202         loading.close();
32203         _isSaving = false;
32204
32205         var selection = uiConfirm(context.container());
32206         selection
32207             .select('.modal-section.header')
32208             .append('h3')
32209             .text(t('save.error'));
32210
32211         addErrors(selection, _errors);
32212         selection.okButton();
32213     }
32214
32215
32216     function addErrors(selection, data) {
32217         var message = selection
32218             .select('.modal-section.message-text');
32219
32220         var items = message
32221             .selectAll('.error-container')
32222             .data(data);
32223
32224         var enter = items.enter()
32225             .append('div')
32226             .attr('class', 'error-container');
32227
32228         enter
32229             .append('a')
32230             .attr('class', 'error-description')
32231             .attr('href', '#')
32232             .classed('hide-toggle', true)
32233             .text(function(d) { return d.msg || t('save.unknown_error_details'); })
32234             .on('click', function() {
32235                 event.preventDefault();
32236
32237                 var error = d3_select(this);
32238                 var detail = d3_select(this.nextElementSibling);
32239                 var exp = error.classed('expanded');
32240
32241                 detail.style('display', exp ? 'none' : 'block');
32242                 error.classed('expanded', !exp);
32243             });
32244
32245         var details = enter
32246             .append('div')
32247             .attr('class', 'error-detail-container')
32248             .style('display', 'none');
32249
32250         details
32251             .append('ul')
32252             .attr('class', 'error-detail-list')
32253             .selectAll('li')
32254             .data(function(d) { return d.details || []; })
32255             .enter()
32256             .append('li')
32257             .attr('class', 'error-detail-item')
32258             .text(function(d) { return d; });
32259
32260         items.exit()
32261             .remove();
32262     }
32263
32264
32265     function success(changeset) {
32266         commit.reset();
32267
32268         var ui = uiSuccess(context)
32269             .changeset(changeset)
32270             .on('cancel', function() { context.ui().sidebar.hide(); });
32271
32272         context.enter(modeBrowse(context).sidebar(ui));
32273     }
32274
32275
32276     function keybindingOn() {
32277         d3_select(document)
32278             .call(keybinding.on('⎋', cancel, true));
32279     }
32280
32281
32282     function keybindingOff() {
32283         d3_select(document)
32284             .call(keybinding.off);
32285     }
32286
32287
32288     mode.enter = function() {
32289         function done() {
32290             context.ui().sidebar.show(commit);
32291         }
32292
32293         keybindingOn();
32294
32295         context.container().selectAll('#content')
32296             .attr('class', 'inactive');
32297
32298         var osm = context.connection();
32299         if (!osm) {
32300             cancel();
32301             return;
32302         }
32303
32304         if (osm.authenticated()) {
32305             done();
32306         } else {
32307             osm.authenticate(function(err) {
32308                 if (err) {
32309                     cancel();
32310                 } else {
32311                     done();
32312                 }
32313             });
32314         }
32315     };
32316
32317
32318     mode.exit = function() {
32319         _isSaving = false;
32320
32321         keybindingOff();
32322
32323         context.container().selectAll('#content')
32324             .attr('class', 'active');
32325
32326         context.ui().sidebar.hide();
32327     };
32328
32329     return mode;
32330 }
32331
32332 /* Built-in method references for those with the same name as other `lodash` methods. */
32333 var nativeMin$1 = Math.min;
32334
32335 /**
32336  * The base implementation of methods like `_.intersection`, without support
32337  * for iteratee shorthands, that accepts an array of arrays to inspect.
32338  *
32339  * @private
32340  * @param {Array} arrays The arrays to inspect.
32341  * @param {Function} [iteratee] The iteratee invoked per element.
32342  * @param {Function} [comparator] The comparator invoked per element.
32343  * @returns {Array} Returns the new array of shared values.
32344  */
32345 function baseIntersection(arrays, iteratee, comparator) {
32346   var includes = comparator ? arrayIncludesWith : arrayIncludes,
32347       length = arrays[0].length,
32348       othLength = arrays.length,
32349       othIndex = othLength,
32350       caches = Array(othLength),
32351       maxLength = Infinity,
32352       result = [];
32353
32354   while (othIndex--) {
32355     var array = arrays[othIndex];
32356     if (othIndex && iteratee) {
32357       array = arrayMap(array, baseUnary(iteratee));
32358     }
32359     maxLength = nativeMin$1(array.length, maxLength);
32360     caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
32361       ? new SetCache(othIndex && array)
32362       : undefined;
32363   }
32364   array = arrays[0];
32365
32366   var index = -1,
32367       seen = caches[0];
32368
32369   outer:
32370   while (++index < length && result.length < maxLength) {
32371     var value = array[index],
32372         computed = iteratee ? iteratee(value) : value;
32373
32374     value = (comparator || value !== 0) ? value : 0;
32375     if (!(seen
32376           ? cacheHas(seen, computed)
32377           : includes(result, computed, comparator)
32378         )) {
32379       othIndex = othLength;
32380       while (--othIndex) {
32381         var cache = caches[othIndex];
32382         if (!(cache
32383               ? cacheHas(cache, computed)
32384               : includes(arrays[othIndex], computed, comparator))
32385             ) {
32386           continue outer;
32387         }
32388       }
32389       if (seen) {
32390         seen.push(computed);
32391       }
32392       result.push(value);
32393     }
32394   }
32395   return result;
32396 }
32397
32398 /**
32399  * Casts `value` to an empty array if it's not an array like object.
32400  *
32401  * @private
32402  * @param {*} value The value to inspect.
32403  * @returns {Array|Object} Returns the cast array-like object.
32404  */
32405 function castArrayLikeObject(value) {
32406   return isArrayLikeObject(value) ? value : [];
32407 }
32408
32409 /**
32410  * Creates an array of unique values that are included in all given arrays
32411  * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
32412  * for equality comparisons. The order and references of result values are
32413  * determined by the first array.
32414  *
32415  * @static
32416  * @memberOf _
32417  * @since 0.1.0
32418  * @category Array
32419  * @param {...Array} [arrays] The arrays to inspect.
32420  * @returns {Array} Returns the new array of intersecting values.
32421  * @example
32422  *
32423  * _.intersection([2, 1], [2, 3]);
32424  * // => [2]
32425  */
32426 var intersection = baseRest(function(arrays) {
32427   var mapped = arrayMap(arrays, castArrayLikeObject);
32428   return (mapped.length && mapped[0] === arrays[0])
32429     ? baseIntersection(mapped)
32430     : [];
32431 });
32432
32433 // Translate a MacOS key command into the appropriate Windows/Linux equivalent.
32434 // For example, ⌘Z -> Ctrl+Z
32435 var uiCmd = function (code) {
32436     var detected = utilDetect();
32437
32438     if (detected.os === 'mac') {
32439         return code;
32440     }
32441
32442     if (detected.os === 'win') {
32443         if (code === '⌘⇧Z') return 'Ctrl+Y';
32444     }
32445
32446     var result = '',
32447         replacements = {
32448             '⌘': 'Ctrl',
32449             '⇧': 'Shift',
32450             '⌥': 'Alt',
32451             '⌫': 'Backspace',
32452             '⌦': 'Delete'
32453         };
32454
32455     for (var i = 0; i < code.length; i++) {
32456         if (code[i] in replacements) {
32457             result += replacements[code[i]] + (i < code.length - 1 ? '+' : '');
32458         } else {
32459             result += code[i];
32460         }
32461     }
32462
32463     return result;
32464 };
32465
32466
32467 // return a display-focused string for a given keyboard code
32468 uiCmd.display = function(code) {
32469     if (code.length !== 1) return code;
32470
32471     var detected = utilDetect();
32472     var mac = (detected.os === 'mac');
32473     var replacements = {
32474         '⌘': mac ? '⌘ ' + t('shortcuts.key.cmd')    : t('shortcuts.key.ctrl'),
32475         '⇧': mac ? '⇧ ' + t('shortcuts.key.shift')  : t('shortcuts.key.shift'),
32476         '⌥': mac ? '⌥ ' + t('shortcuts.key.option') : t('shortcuts.key.alt'),
32477         '⌃': mac ? '⌃ ' + t('shortcuts.key.ctrl')   : t('shortcuts.key.ctrl'),
32478         '⌫': mac ? '⌫ ' + t('shortcuts.key.delete') : t('shortcuts.key.backspace'),
32479         '⌦': mac ? '⌦ ' + t('shortcuts.key.del')    : t('shortcuts.key.del'),
32480         '↖': mac ? '↖ ' + t('shortcuts.key.pgup')   : t('shortcuts.key.pgup'),
32481         '↘': mac ? '↘ ' + t('shortcuts.key.pgdn')   : t('shortcuts.key.pgdn'),
32482         '⇞': mac ? '⇞ ' + t('shortcuts.key.home')   : t('shortcuts.key.home'),
32483         '⇟': mac ? '⇟ ' + t('shortcuts.key.end')    : t('shortcuts.key.end'),
32484         '↵': mac ? '↵ ' + t('shortcuts.key.return') : t('shortcuts.key.enter'),
32485         '⎋': mac ? '⎋ ' + t('shortcuts.key.esc')    : t('shortcuts.key.esc'),
32486     };
32487
32488     return replacements[code] || code;
32489 };
32490
32491 // deprecation warning - Radial Menu to be removed in iD v3
32492 var relatedParent;
32493
32494
32495 function modeSelect(context, selectedIDs) {
32496     var mode = {
32497         id: 'select',
32498         button: 'browse'
32499     };
32500
32501     var keybinding = d3keybinding('select'),
32502         timeout = null,
32503         behaviors = [
32504             behaviorCopy(context),
32505             behaviorPaste(context),
32506             behaviorBreathe(context),
32507             behaviorHover(context),
32508             behaviorSelect(context),
32509             behaviorLasso(context),
32510             modeDragNode(context).restoreSelectedIDs(selectedIDs).behavior
32511         ],
32512         inspector,
32513         editMenu,
32514         newFeature = false,
32515         suppressMenu = true,
32516         follow = false;
32517
32518
32519     var wrap = context.container()
32520         .select('.inspector-wrap');
32521
32522
32523     function singular() {
32524         if (selectedIDs.length === 1) {
32525             return context.hasEntity(selectedIDs[0]);
32526         }
32527     }
32528
32529
32530     function checkSelectedIDs() {
32531         var ids = [];
32532         if (Array.isArray(selectedIDs)) {
32533             ids = selectedIDs.filter(function(id) {
32534                 return context.hasEntity(id);
32535             });
32536         }
32537
32538         if (ids.length) {
32539             selectedIDs = ids;
32540         } else {
32541             context.enter(modeBrowse(context));
32542         }
32543         return !!ids.length;
32544     }
32545
32546
32547     // find the common parent ways for nextVertex, previousVertex
32548     function commonParents() {
32549         var graph = context.graph(),
32550             commonParents = [];
32551
32552         for (var i = 0; i < selectedIDs.length; i++) {
32553             var entity = context.hasEntity(selectedIDs[i]);
32554             if (!entity || entity.geometry(graph) !== 'vertex') {
32555                 return [];  // selection includes some not vertexes
32556             }
32557
32558             var currParents = map$4(graph.parentWays(entity), 'id');
32559             if (!commonParents.length) {
32560                 commonParents = currParents;
32561                 continue;
32562             }
32563
32564             commonParents = intersection(commonParents, currParents);
32565             if (!commonParents.length) {
32566                 return [];
32567             }
32568         }
32569
32570         return commonParents;
32571     }
32572
32573
32574     function singularParent() {
32575         var parents = commonParents();
32576         if (!parents || parents.length === 0) {
32577             relatedParent = null;
32578             return null;
32579         }
32580
32581         // relatedParent is used when we visit a vertex with multiple
32582         // parents, and we want to remember which parent line we started on.
32583
32584         if (parents.length === 1) {
32585             relatedParent = parents[0];  // remember this parent for later
32586             return relatedParent;
32587         }
32588
32589         if (parents.indexOf(relatedParent) !== -1) {
32590             return relatedParent;   // prefer the previously seen parent
32591         }
32592
32593         return parents[0];
32594     }
32595
32596
32597     function closeMenu() {
32598         if (editMenu) {
32599             context.surface().call(editMenu.close);
32600         }
32601     }
32602
32603
32604     function positionMenu() {
32605         if (!editMenu) { return; }
32606
32607         var entity = singular();
32608         if (entity && context.geometry(entity.id) === 'relation') {
32609             suppressMenu = true;
32610         } else {
32611             var point = context.mouse(),
32612                 viewport = geoExtent(context.projection.clipExtent()).polygon();
32613
32614             if (point && geoPointInPolygon(point, viewport)) {
32615                 editMenu.center(point);
32616             } else {
32617                 suppressMenu = true;
32618             }
32619         }
32620     }
32621
32622
32623     function showMenu() {
32624         closeMenu();
32625         if (editMenu) {
32626             context.surface().call(editMenu);
32627         }
32628     }
32629
32630
32631     function toggleMenu() {
32632         // deprecation warning - Radial Menu to be removed in iD v3
32633         if (d3_select('.edit-menu, .radial-menu').empty()) {
32634             positionMenu();
32635             showMenu();
32636         } else {
32637             closeMenu();
32638         }
32639     }
32640
32641
32642     mode.selectedIDs = function() {
32643         return selectedIDs;
32644     };
32645
32646
32647     mode.reselect = function() {
32648         if (!checkSelectedIDs()) return;
32649
32650         var surfaceNode = context.surface().node();
32651         if (surfaceNode.focus) {   // FF doesn't support it
32652             surfaceNode.focus();
32653         }
32654
32655         positionMenu();
32656         if (!suppressMenu) {
32657             showMenu();
32658         }
32659     };
32660
32661
32662     mode.newFeature = function(_) {
32663         if (!arguments.length) return newFeature;
32664         newFeature = _;
32665         return mode;
32666     };
32667
32668
32669     mode.suppressMenu = function(_) {
32670         if (!arguments.length) return suppressMenu;
32671         suppressMenu = _;
32672         return mode;
32673     };
32674
32675
32676     mode.follow = function(_) {
32677         if (!arguments.length) return follow;
32678         follow = _;
32679         return mode;
32680     };
32681
32682
32683     mode.enter = function() {
32684
32685         function update() {
32686             closeMenu();
32687             checkSelectedIDs();
32688         }
32689
32690
32691         function dblclick() {
32692             var target = d3_select(event.target);
32693
32694             var datum = target.datum();
32695             var entity = datum && datum.properties && datum.properties.entity;
32696             if (!entity) return;
32697
32698             if (entity instanceof osmWay && target.classed('target')) {
32699                 var choice = geoChooseEdge(context.childNodes(entity), context.mouse(), context.projection);
32700                 var prev = entity.nodes[choice.index - 1];
32701                 var next = entity.nodes[choice.index];
32702
32703                 context.perform(
32704                     actionAddMidpoint({loc: choice.loc, edge: [prev, next]}, osmNode()),
32705                     t('operations.add.annotation.vertex')
32706                 );
32707
32708                 event.preventDefault();
32709                 event.stopPropagation();
32710
32711             } else if (entity.type === 'midpoint') {
32712                 context.perform(
32713                     actionAddMidpoint({loc: entity.loc, edge: entity.edge}, osmNode()),
32714                     t('operations.add.annotation.vertex'));
32715
32716                 event.preventDefault();
32717                 event.stopPropagation();
32718             }
32719         }
32720
32721
32722         function selectElements(drawn) {
32723             if (!checkSelectedIDs()) return;
32724
32725             var surface = context.surface(),
32726                 entity = singular();
32727
32728             if (entity && context.geometry(entity.id) === 'relation') {
32729                 suppressMenu = true;
32730                 return;
32731             }
32732
32733             surface.selectAll('.related')
32734                 .classed('related', false);
32735
32736             singularParent();
32737             if (relatedParent) {
32738                 surface.selectAll(utilEntitySelector([relatedParent]))
32739                     .classed('related', true);
32740             }
32741
32742             var selection = context.surface()
32743                 .selectAll(utilEntityOrMemberSelector(selectedIDs, context.graph()));
32744
32745             if (selection.empty()) {
32746                 // Return to browse mode if selected DOM elements have
32747                 // disappeared because the user moved them out of view..
32748                 var source = event && event.type === 'zoom' && event.sourceEvent;
32749                 if (drawn && source && (source.type === 'mousemove' || source.type === 'touchmove')) {
32750                     context.enter(modeBrowse(context));
32751                 }
32752             } else {
32753                 selection
32754                     .classed('selected', true);
32755             }
32756         }
32757
32758
32759         function esc() {
32760             context.enter(modeBrowse(context));
32761         }
32762
32763
32764         function firstVertex() {
32765             event.preventDefault();
32766             var parent = singularParent();
32767             if (parent) {
32768                 var way = context.entity(parent);
32769                 context.enter(
32770                     modeSelect(context, [way.first()]).follow(true)
32771                 );
32772             }
32773         }
32774
32775
32776         function lastVertex() {
32777             event.preventDefault();
32778             var parent = singularParent();
32779             if (parent) {
32780                 var way = context.entity(parent);
32781                 context.enter(
32782                     modeSelect(context, [way.last()]).follow(true)
32783                 );
32784             }
32785         }
32786
32787
32788         function previousVertex() {
32789             event.preventDefault();
32790             var parent = singularParent();
32791             if (!parent) return;
32792
32793             var way = context.entity(parent),
32794                 length = way.nodes.length,
32795                 curr = way.nodes.indexOf(selectedIDs[0]),
32796                 index = -1;
32797
32798             if (curr > 0) {
32799                 index = curr - 1;
32800             } else if (way.isClosed()) {
32801                 index = length - 2;
32802             }
32803
32804             if (index !== -1) {
32805                 context.enter(
32806                     modeSelect(context, [way.nodes[index]]).follow(true)
32807                 );
32808             }
32809         }
32810
32811
32812         function nextVertex() {
32813             event.preventDefault();
32814             var parent = singularParent();
32815             if (!parent) return;
32816
32817             var way = context.entity(parent),
32818                 length = way.nodes.length,
32819                 curr = way.nodes.indexOf(selectedIDs[0]),
32820                 index = -1;
32821
32822             if (curr < length - 1) {
32823                 index = curr + 1;
32824             } else if (way.isClosed()) {
32825                 index = 0;
32826             }
32827
32828             if (index !== -1) {
32829                 context.enter(
32830                     modeSelect(context, [way.nodes[index]]).follow(true)
32831                 );
32832             }
32833         }
32834
32835
32836         function nextParent() {
32837             event.preventDefault();
32838             var parents = uniq(commonParents());
32839             if (!parents || parents.length < 2) return;
32840
32841             var index = parents.indexOf(relatedParent);
32842             if (index < 0 || index > parents.length - 2) {
32843                 relatedParent = parents[0];
32844             } else {
32845                 relatedParent = parents[index + 1];
32846             }
32847
32848             var surface = context.surface();
32849             surface.selectAll('.related')
32850                 .classed('related', false);
32851
32852             if (relatedParent) {
32853                 surface.selectAll(utilEntitySelector([relatedParent]))
32854                     .classed('related', true);
32855             }
32856         }
32857
32858
32859         if (!checkSelectedIDs()) return;
32860
32861         var operations = without(values$1(Operations), operationDelete)
32862                 .map(function(o) { return o(selectedIDs, context); })
32863                 .filter(function(o) { return o.available(); });
32864
32865         // deprecation warning - Radial Menu to be removed in iD v3
32866         var isRadialMenu = context.storage('edit-menu-style') === 'radial';
32867         if (isRadialMenu) {
32868             operations = operations.slice(0,7);
32869             operations.unshift(operationDelete(selectedIDs, context));
32870         } else {
32871             operations.push(operationDelete(selectedIDs, context));
32872         }
32873
32874         operations.forEach(function(operation) {
32875             if (operation.behavior) {
32876                 behaviors.push(operation.behavior);
32877             }
32878         });
32879
32880         behaviors.forEach(function(behavior) {
32881             context.install(behavior);
32882         });
32883
32884         keybinding
32885             .on(['[', 'pgup'], previousVertex)
32886             .on([']', 'pgdown'], nextVertex)
32887             .on(['{', uiCmd('⌘['), 'home'], firstVertex)
32888             .on(['}', uiCmd('⌘]'), 'end'], lastVertex)
32889             .on(['\\', 'pause'], nextParent)
32890             .on('⎋', esc, true)
32891             .on('space', toggleMenu);
32892
32893         d3_select(document)
32894             .call(keybinding);
32895
32896
32897         // deprecation warning - Radial Menu to be removed in iD v3
32898         editMenu = isRadialMenu
32899             ? uiRadialMenu(context, operations)
32900             : uiEditMenu(context, operations);
32901
32902         context.ui().sidebar
32903             .select(singular() ? singular().id : null, newFeature);
32904
32905         context.history()
32906             .on('undone.select', update)
32907             .on('redone.select', update);
32908
32909         context.map()
32910             .on('move.select', closeMenu)
32911             .on('drawn.select', selectElements);
32912
32913         context.surface()
32914             .on('dblclick.select', dblclick);
32915
32916
32917         selectElements();
32918
32919         if (selectedIDs.length > 1) {
32920             var entities = uiSelectionList(context, selectedIDs);
32921             context.ui().sidebar.show(entities);
32922         }
32923
32924         if (follow) {
32925             var extent = geoExtent(),
32926                 graph = context.graph();
32927             selectedIDs.forEach(function(id) {
32928                 var entity = context.entity(id);
32929                 extent._extend(entity.extent(graph));
32930             });
32931
32932             var loc = extent.center();
32933             context.map().centerEase(loc);
32934         } else if (singular() && singular().type === 'way') {
32935             context.map().pan([0,0]);  // full redraw, to adjust z-sorting #2914
32936         }
32937
32938         timeout = window.setTimeout(function() {
32939             positionMenu();
32940             if (!suppressMenu) {
32941                 showMenu();
32942             }
32943         }, 270);  /* after any centerEase completes */
32944
32945     };
32946
32947
32948     mode.exit = function() {
32949         if (timeout) window.clearTimeout(timeout);
32950
32951         if (inspector) wrap.call(inspector.close);
32952
32953         behaviors.forEach(function(behavior) {
32954             context.uninstall(behavior);
32955         });
32956
32957         keybinding.off();
32958         closeMenu();
32959         editMenu = undefined;
32960
32961         context.history()
32962             .on('undone.select', null)
32963             .on('redone.select', null);
32964
32965         var surface = context.surface();
32966
32967         surface
32968             .on('dblclick.select', null);
32969
32970         surface
32971             .selectAll('.selected')
32972             .classed('selected', false);
32973
32974         surface
32975             .selectAll('.related')
32976             .classed('related', false);
32977
32978         context.map().on('drawn.select', null);
32979         context.ui().sidebar.hide();
32980     };
32981
32982
32983     return mode;
32984 }
32985
32986 function behaviorAddWay(context) {
32987     var dispatch$$1 = dispatch('start', 'startFromWay', 'startFromNode'),
32988         draw = behaviorDraw(context);
32989
32990     var addWay = function(surface) {
32991         draw.on('click', function() { dispatch$$1.apply('start', this, arguments); })
32992             .on('clickWay', function() { dispatch$$1.apply('startFromWay', this, arguments); })
32993             .on('clickNode', function() { dispatch$$1.apply('startFromNode', this, arguments); })
32994             .on('cancel', addWay.cancel)
32995             .on('finish', addWay.cancel);
32996
32997         context.map()
32998             .dblclickEnable(false);
32999
33000         surface.call(draw);
33001     };
33002
33003
33004     addWay.off = function(surface) {
33005         surface.call(draw.off);
33006     };
33007
33008
33009     addWay.cancel = function() {
33010         window.setTimeout(function() {
33011             context.map().dblclickEnable(true);
33012         }, 1000);
33013
33014         context.enter(modeBrowse(context));
33015     };
33016
33017
33018     addWay.tail = function(text) {
33019         draw.tail(text);
33020         return addWay;
33021     };
33022
33023
33024     return utilRebind(addWay, dispatch$$1, 'on');
33025 }
33026
33027 function behaviorBreathe() {
33028     var duration = 800,
33029         steps = 4,
33030         selector = '.selected.shadow, .selected .shadow',
33031         selected = d3_select(null),
33032         classed = '',
33033         params = {},
33034         done = false,
33035         timer$$1;
33036
33037
33038     function ratchetyInterpolator(a, b, steps, units) {
33039         a = parseFloat(a);
33040         b = parseFloat(b);
33041         var sample = quantize()
33042             .domain([0, 1])
33043             .range(d3_quantize(d3_interpolateNumber(a, b), steps));
33044
33045         return function(t) {
33046             return String(sample(t)) + (units || '');
33047         };
33048     }
33049
33050
33051     function reset(selection) {
33052         selection
33053             .style('stroke-opacity', null)
33054             .style('stroke-width', null)
33055             .style('fill-opacity', null)
33056             .style('r', null);
33057     }
33058
33059
33060     function setAnimationParams(transition, fromTo) {
33061         var toFrom = (fromTo === 'from' ? 'to' : 'from');
33062
33063         transition
33064             .styleTween('stroke-opacity', function(d) {
33065                 return ratchetyInterpolator(
33066                     params[d.id][toFrom].opacity,
33067                     params[d.id][fromTo].opacity,
33068                     steps
33069                 );
33070             })
33071             .styleTween('stroke-width', function(d) {
33072                 return ratchetyInterpolator(
33073                     params[d.id][toFrom].width,
33074                     params[d.id][fromTo].width,
33075                     steps,
33076                     'px'
33077                 );
33078             })
33079             .styleTween('fill-opacity', function(d) {
33080                 return ratchetyInterpolator(
33081                     params[d.id][toFrom].opacity,
33082                     params[d.id][fromTo].opacity,
33083                     steps
33084                 );
33085             })
33086             .styleTween('r', function(d) {
33087                 return ratchetyInterpolator(
33088                     params[d.id][toFrom].width,
33089                     params[d.id][fromTo].width,
33090                     steps,
33091                     'px'
33092                 );
33093             });
33094     }
33095
33096
33097     function calcAnimationParams(selection) {
33098         selection
33099             .call(reset)
33100             .each(function(d) {
33101                 var s = d3_select(this),
33102                     tag = s.node().tagName,
33103                     p = {'from': {}, 'to': {}},
33104                     opacity, width;
33105
33106                 // determine base opacity and width
33107                 if (tag === 'circle') {
33108                     opacity = parseFloat(s.style('fill-opacity') || 0.5);
33109                     width = parseFloat(s.style('r') || 15.5);
33110                 } else {
33111                     opacity = parseFloat(s.style('stroke-opacity') || 0.7);
33112                     width = parseFloat(s.style('stroke-width') || 10);
33113                 }
33114
33115                 // calculate from/to interpolation params..
33116                 p.tag = tag;
33117                 p.from.opacity = opacity * 0.6;
33118                 p.to.opacity = opacity * 1.25;
33119                 p.from.width = width * 0.7;
33120                 p.to.width = width * (tag === 'circle' ? 1.5 : 1);
33121                 params[d.id] = p;
33122             });
33123     }
33124
33125
33126     function run(surface, fromTo) {
33127         var toFrom = (fromTo === 'from' ? 'to' : 'from'),
33128             currSelected = surface.selectAll(selector),
33129             currClassed = surface.attr('class');
33130
33131         if (done || currSelected.empty()) {
33132             selected.call(reset);
33133             return;
33134         }
33135
33136         if (!isEqual(currSelected.data(), selected.data()) || currClassed !== classed) {
33137             selected.call(reset);
33138             classed = currClassed;
33139             selected = currSelected.call(calcAnimationParams);
33140         }
33141
33142         selected
33143             .transition()
33144             .duration(duration)
33145             .call(setAnimationParams, fromTo)
33146             .on('end', function() {
33147                 surface.call(run, toFrom);
33148             });
33149     }
33150
33151
33152     var breathe = function(surface) {
33153         done = false;
33154         timer$$1 = timer(function() {
33155             // wait for elements to actually become selected
33156             if (surface.selectAll(selector).empty()) {
33157                 return false;
33158             }
33159
33160             surface.call(run, 'from');
33161             timer$$1.stop();
33162             return true;
33163         }, 20);
33164     };
33165
33166
33167     breathe.off = function() {
33168         done = true;
33169         if (timer$$1) {
33170             timer$$1.stop();
33171         }
33172         selected
33173             .interrupt()
33174             .call(reset);
33175     };
33176
33177
33178     return breathe;
33179 }
33180
33181 function behaviorCopy(context) {
33182     var keybinding = d3keybinding('copy');
33183
33184
33185     function groupEntities(ids, graph) {
33186         var entities = ids.map(function (id) { return graph.entity(id); });
33187         return assignIn({relation: [], way: [], node: []},
33188             groupBy(entities, function(entity) { return entity.type; }));
33189     }
33190
33191
33192     function getDescendants(id, graph, descendants) {
33193         var entity = graph.entity(id),
33194             i, children;
33195
33196         descendants = descendants || {};
33197
33198         if (entity.type === 'relation') {
33199             children = map$4(entity.members, 'id');
33200         } else if (entity.type === 'way') {
33201             children = entity.nodes;
33202         } else {
33203             children = [];
33204         }
33205
33206         for (i = 0; i < children.length; i++) {
33207             if (!descendants[children[i]]) {
33208                 descendants[children[i]] = true;
33209                 descendants = getDescendants(children[i], graph, descendants);
33210             }
33211         }
33212
33213         return descendants;
33214     }
33215
33216
33217     function doCopy() {
33218         if (!getSelectionText()) event.preventDefault();
33219
33220         var graph = context.graph(),
33221             selected = groupEntities(context.selectedIDs(), graph),
33222             canCopy = [],
33223             skip = {},
33224             i, entity;
33225
33226         for (i = 0; i < selected.relation.length; i++) {
33227             entity = selected.relation[i];
33228             if (!skip[entity.id] && entity.isComplete(graph)) {
33229                 canCopy.push(entity.id);
33230                 skip = getDescendants(entity.id, graph, skip);
33231             }
33232         }
33233         for (i = 0; i < selected.way.length; i++) {
33234             entity = selected.way[i];
33235             if (!skip[entity.id]) {
33236                 canCopy.push(entity.id);
33237                 skip = getDescendants(entity.id, graph, skip);
33238             }
33239         }
33240         for (i = 0; i < selected.node.length; i++) {
33241             entity = selected.node[i];
33242             if (!skip[entity.id]) {
33243                 canCopy.push(entity.id);
33244             }
33245         }
33246
33247         context.copyIDs(canCopy);
33248     }
33249
33250
33251     function copy() {
33252         keybinding.on(uiCmd('⌘C'), doCopy);
33253         d3_select(document).call(keybinding);
33254         return copy;
33255     }
33256
33257     function getSelectionText() {
33258         return window.getSelection().toString();
33259     }
33260
33261     copy.off = function() {
33262         d3_select(document).call(keybinding.off);
33263     };
33264
33265
33266     return copy;
33267 }
33268
33269 /*
33270     `behaviorDrag` is like `d3_behavior.drag`, with the following differences:
33271
33272     * The `origin` function is expected to return an [x, y] tuple rather than an
33273       {x, y} object.
33274     * The events are `start`, `move`, and `end`.
33275       (https://github.com/mbostock/d3/issues/563)
33276     * The `start` event is not dispatched until the first cursor movement occurs.
33277       (https://github.com/mbostock/d3/pull/368)
33278     * The `move` event has a `point` and `delta` [x, y] tuple properties rather
33279       than `x`, `y`, `dx`, and `dy` properties.
33280     * The `end` event is not dispatched if no movement occurs.
33281     * An `off` function is available that unbinds the drag's internal event handlers.
33282  */
33283
33284 function behaviorDrag() {
33285     var dispatch$$1 = dispatch('start', 'move', 'end');
33286     var _origin = null;
33287     var _selector = '';
33288     var _event;
33289     var _target;
33290     var _surface;
33291
33292
33293     var d3_event_userSelectProperty = utilPrefixCSSProperty('UserSelect');
33294     var d3_event_userSelectSuppress = function() {
33295             var selection$$1 = selection();
33296             var select$$1 = selection$$1.style(d3_event_userSelectProperty);
33297             selection$$1.style(d3_event_userSelectProperty, 'none');
33298             return function() {
33299                 selection$$1.style(d3_event_userSelectProperty, select$$1);
33300             };
33301         };
33302
33303
33304     function d3_eventCancel() {
33305         event.stopPropagation();
33306         event.preventDefault();
33307     }
33308
33309
33310     function eventOf(thiz, argumentz) {
33311         return function(e1) {
33312             e1.target = drag;
33313             customEvent(e1, dispatch$$1.apply, dispatch$$1, [e1.type, thiz, argumentz]);
33314         };
33315     }
33316
33317
33318     function dragstart() {
33319         _target = this;
33320         _event = eventOf(_target, arguments);
33321
33322         var eventTarget = event.target;
33323         var touchId = event.touches ? event.changedTouches[0].identifier : null;
33324         var offset;
33325         var startOrigin = point();
33326         var started = false;
33327         var selectEnable = d3_event_userSelectSuppress(touchId !== null ? 'drag-' + touchId : 'drag');
33328
33329         d3_select(window)
33330             .on(touchId !== null ? 'touchmove.drag-' + touchId : 'mousemove.drag', dragmove)
33331             .on(touchId !== null ? 'touchend.drag-' + touchId : 'mouseup.drag', dragend, true);
33332
33333         if (_origin) {
33334             offset = _origin.apply(_target, arguments);
33335             offset = [offset[0] - startOrigin[0], offset[1] - startOrigin[1]];
33336         } else {
33337             offset = [0, 0];
33338         }
33339
33340         if (touchId === null) {
33341             event.stopPropagation();
33342         }
33343
33344
33345         function point() {
33346             var p = _surface || _target.parentNode;
33347             return touchId !== null ? d3_touches(p).filter(function(p) {
33348                 return p.identifier === touchId;
33349             })[0] : d3_mouse(p);
33350         }
33351
33352
33353         function dragmove() {
33354             var p = point();
33355             var dx = p[0] - startOrigin[0];
33356             var dy = p[1] - startOrigin[1];
33357
33358             if (dx === 0 && dy === 0)
33359                 return;
33360
33361             startOrigin = p;
33362             d3_eventCancel();
33363
33364             if (!started) {
33365                 started = true;
33366                 _event({ type: 'start' });
33367             } else {
33368                 _event({
33369                     type: 'move',
33370                     point: [p[0] + offset[0],  p[1] + offset[1]],
33371                     delta: [dx, dy]
33372                 });
33373             }
33374         }
33375
33376
33377         function dragend() {
33378             if (started) {
33379                 _event({ type: 'end' });
33380
33381                 d3_eventCancel();
33382                 if (event.target === eventTarget) {
33383                     d3_select(window)
33384                         .on('click.drag', click, true);
33385                 }
33386             }
33387
33388             d3_select(window)
33389                 .on(touchId !== null ? 'touchmove.drag-' + touchId : 'mousemove.drag', null)
33390                 .on(touchId !== null ? 'touchend.drag-' + touchId : 'mouseup.drag', null);
33391
33392             selectEnable();
33393         }
33394
33395
33396         function click() {
33397             d3_eventCancel();
33398             d3_select(window)
33399                 .on('click.drag', null);
33400         }
33401     }
33402
33403
33404     function drag(selection$$1) {
33405         var matchesSelector = utilPrefixDOMProperty('matchesSelector');
33406         var delegate = dragstart;
33407
33408         if (_selector) {
33409             delegate = function() {
33410                 var root = this;
33411                 var target = event.target;
33412                 for (; target && target !== root; target = target.parentNode) {
33413                     var datum = target.__data__;
33414                     var entity = datum && datum.properties && datum.properties.entity;
33415                     if (entity && target[matchesSelector](_selector)) {
33416                         return dragstart.call(target, entity);
33417                     }
33418                 }
33419             };
33420         }
33421
33422         selection$$1
33423             .on('mousedown.drag' + _selector, delegate)
33424             .on('touchstart.drag' + _selector, delegate);
33425     }
33426
33427
33428     drag.off = function(selection$$1) {
33429         selection$$1
33430             .on('mousedown.drag' + _selector, null)
33431             .on('touchstart.drag' + _selector, null);
33432     };
33433
33434
33435     drag.selector = function(_) {
33436         if (!arguments.length) return _selector;
33437         _selector = _;
33438         return drag;
33439     };
33440
33441
33442     drag.origin = function (_) {
33443         if (!arguments.length) return _origin;
33444         _origin = _;
33445         return drag;
33446     };
33447
33448
33449     drag.cancel = function() {
33450         d3_select(window)
33451             .on('mousemove.drag', null)
33452             .on('mouseup.drag', null);
33453         return drag;
33454     };
33455
33456
33457     drag.target = function() {
33458         if (!arguments.length) return _target;
33459         _target = arguments[0];
33460         _event = eventOf(_target, Array.prototype.slice.call(arguments, 1));
33461         return drag;
33462     };
33463
33464
33465     drag.surface = function() {
33466         if (!arguments.length) return _surface;
33467         _surface = arguments[0];
33468         return drag;
33469     };
33470
33471
33472     return utilRebind(drag, dispatch$$1, 'on');
33473 }
33474
33475 function behaviorDrawWay(context, wayId, index, mode, startGraph) {
33476     var origWay = context.entity(wayId);
33477     var annotation = t((origWay.isDegenerate() ?
33478         'operations.start.annotation.' :
33479         'operations.continue.annotation.') + context.geometry(wayId)
33480     );
33481     var behavior = behaviorDraw(context);
33482     var _tempEdits = 0;
33483
33484     var end = osmNode({ loc: context.map().mouseCoordinates() });
33485
33486     // Push an annotated state for undo to return back to.
33487     // We must make sure to remove this edit later.
33488     context.perform(actionNoop(), annotation);
33489     _tempEdits++;
33490
33491     // Add the drawing node to the graph.
33492     // We must make sure to remove this edit later.
33493     context.perform(_actionAddDrawNode());
33494     _tempEdits++;
33495
33496
33497
33498     function keydown() {
33499         if (event.keyCode === d3keybinding.modifierCodes.alt) {
33500             if (context.surface().classed('nope')) {
33501                 context.surface()
33502                     .classed('nope-suppressed', true);
33503             }
33504             context.surface()
33505                 .classed('nope', false)
33506                 .classed('nope-disabled', true);
33507         }
33508     }
33509
33510
33511     function keyup() {
33512         if (event.keyCode === d3keybinding.modifierCodes.alt) {
33513             if (context.surface().classed('nope-suppressed')) {
33514                 context.surface()
33515                     .classed('nope', true);
33516             }
33517             context.surface()
33518                 .classed('nope-suppressed', false)
33519                 .classed('nope-disabled', false);
33520         }
33521     }
33522
33523
33524     // related code
33525     // - `mode/drag_node.js`     `doMode()`
33526     // - `behavior/draw.js`      `click()`
33527     // - `behavior/draw_way.js`  `move()`
33528     function move(datum) {
33529         context.surface().classed('nope-disabled', event.altKey);
33530
33531         var targetLoc = datum && datum.properties && datum.properties.entity && datum.properties.entity.loc;
33532         var targetNodes = datum && datum.properties && datum.properties.nodes;
33533         var loc = context.map().mouseCoordinates();
33534
33535         if (targetLoc) {   // snap to node/vertex - a point target with `.loc`
33536             loc = targetLoc;
33537
33538         } else if (targetNodes) {   // snap to way - a line target with `.nodes`
33539             var choice = geoChooseEdge(targetNodes, context.mouse(), context.projection, end.id);
33540             if (choice) {
33541                 loc = choice.loc;
33542             }
33543         }
33544
33545         context.replace(actionMoveNode(end.id, loc));
33546         end = context.entity(end.id);
33547         checkGeometry(origWay.isClosed());    // skipLast = true when drawing areas
33548     }
33549
33550
33551     // Check whether this edit causes the geometry to break.
33552     // If so, class the surface with a nope cursor.
33553     // `skipLast` - include closing segment in the check, see #4655
33554     function checkGeometry(skipLast) {
33555         var nopeDisabled = context.surface().classed('nope-disabled');
33556         var isInvalid = isInvalidGeometry(end, context.graph(), skipLast);
33557
33558         if (nopeDisabled) {
33559             context.surface()
33560                 .classed('nope', false)
33561                 .classed('nope-suppressed', isInvalid);
33562         } else {
33563             context.surface()
33564                 .classed('nope', isInvalid)
33565                 .classed('nope-suppressed', false);
33566         }
33567     }
33568
33569
33570     function isInvalidGeometry(entity, graph, skipLast) {
33571         var parents = graph.parentWays(entity);
33572
33573         for (var i = 0; i < parents.length; i++) {
33574             var parent = parents[i];
33575             var nodes = parent.nodes.map(function(nodeID) { return graph.entity(nodeID); });
33576             if (skipLast)  nodes.pop();   // disregard closing segment - #4655
33577             if (geoHasSelfIntersections(nodes, entity.id)) {
33578                 return true;
33579             }
33580         }
33581
33582         return false;
33583     }
33584
33585
33586     function undone() {
33587         // Undo popped the history back to the initial annotated no-op edit.
33588         // Remove initial no-op edit and whatever edit happened immediately before it.
33589         context.pop(2);
33590         _tempEdits = 0;
33591
33592         if (context.hasEntity(wayId)) {
33593             context.enter(mode);
33594         } else {
33595             context.enter(modeBrowse(context));
33596         }
33597     }
33598
33599
33600     function setActiveElements() {
33601         context.surface().selectAll('.' + end.id)
33602             .classed('active', true);
33603     }
33604
33605
33606     var drawWay = function(surface) {
33607         behavior
33608             .on('move', move)
33609             .on('click', drawWay.add)
33610             .on('clickWay', drawWay.addWay)
33611             .on('clickNode', drawWay.addNode)
33612             .on('undo', context.undo)
33613             .on('cancel', drawWay.cancel)
33614             .on('finish', drawWay.finish);
33615
33616         d3_select(window)
33617             .on('keydown.drawWay', keydown)
33618             .on('keyup.drawWay', keyup);
33619
33620         context.map()
33621             .dblclickEnable(false)
33622             .on('drawn.draw', setActiveElements);
33623
33624         setActiveElements();
33625
33626         surface.call(behavior);
33627
33628         context.history()
33629             .on('undone.draw', undone);
33630     };
33631
33632
33633     drawWay.off = function(surface) {
33634         // Drawing was interrupted unexpectedly.
33635         // This can happen if the user changes modes,
33636         // clicks geolocate button, a hashchange event occurs, etc.
33637         if (_tempEdits) {
33638             context.pop(_tempEdits);
33639             while (context.graph() !== startGraph) {
33640                 context.pop();
33641             }
33642         }
33643
33644         context.map()
33645             .on('drawn.draw', null);
33646
33647         surface.call(behavior.off)
33648             .selectAll('.active')
33649             .classed('active', false);
33650
33651         surface
33652             .classed('nope', false)
33653             .classed('nope-suppressed', false)
33654             .classed('nope-disabled', false);
33655
33656         d3_select(window)
33657             .on('keydown.hover', null)
33658             .on('keyup.hover', null);
33659
33660         context.history()
33661             .on('undone.draw', null);
33662     };
33663
33664
33665     function _actionAddDrawNode() {
33666         return function(graph) {
33667             return graph
33668                 .replace(end)
33669                 .replace(origWay.addNode(end.id, index));
33670         };
33671     }
33672
33673
33674     function _actionReplaceDrawNode(newNode) {
33675         return function(graph) {
33676             return graph
33677                 .replace(origWay.addNode(newNode.id, index))
33678                 .remove(end);
33679         };
33680     }
33681
33682
33683     // Accept the current position of the drawing node and continue drawing.
33684     drawWay.add = function(loc, d) {
33685         if ((d && d.properties && d.properties.nope) || context.surface().classed('nope')) {
33686             return;   // can't click here
33687         }
33688
33689         context.pop(_tempEdits);
33690         _tempEdits = 0;
33691
33692         context.perform(
33693             _actionAddDrawNode(),
33694             annotation
33695         );
33696
33697         checkGeometry(false);   // skipLast = false
33698         context.enter(mode);
33699     };
33700
33701
33702     // Connect the way to an existing way.
33703     drawWay.addWay = function(loc, edge, d) {
33704         if ((d && d.properties && d.properties.nope) || context.surface().classed('nope')) {
33705             return;   // can't click here
33706         }
33707
33708         context.pop(_tempEdits);
33709         _tempEdits = 0;
33710
33711         context.perform(
33712             _actionAddDrawNode(),
33713             actionAddMidpoint({ loc: loc, edge: edge }, end),
33714             annotation
33715         );
33716
33717         checkGeometry(false);   // skipLast = false
33718         context.enter(mode);
33719     };
33720
33721
33722     // Connect the way to an existing node and continue drawing.
33723     drawWay.addNode = function(node, d) {
33724         if ((d && d.properties && d.properties.nope) || context.surface().classed('nope')) {
33725             return;   // can't click here
33726         }
33727
33728         context.pop(_tempEdits);
33729         _tempEdits = 0;
33730
33731         context.perform(
33732             _actionReplaceDrawNode(node),
33733             annotation
33734         );
33735
33736         checkGeometry(false);   // skipLast = false
33737         context.enter(mode);
33738     };
33739
33740
33741     // Finish the draw operation, removing the temporary edits.
33742     // If the way has enough nodes to be valid, it's selected.
33743     // Otherwise, delete everything and return to browse mode.
33744     drawWay.finish = function() {
33745         checkGeometry(true);   // skipLast = true
33746         if (context.surface().classed('nope')) {
33747             return;   // can't click here
33748         }
33749
33750         context.pop(_tempEdits);
33751         _tempEdits = 0;
33752
33753         var way = context.hasEntity(wayId);
33754         if (!way || way.isDegenerate()) {
33755             drawWay.cancel();
33756             return;
33757         }
33758
33759         window.setTimeout(function() {
33760             context.map().dblclickEnable(true);
33761         }, 1000);
33762
33763         context.enter(modeSelect(context, [wayId]).newFeature(true));
33764     };
33765
33766
33767     // Cancel the draw operation, delete everything, and return to browse mode.
33768     drawWay.cancel = function() {
33769         context.pop(_tempEdits);
33770         _tempEdits = 0;
33771
33772         while (context.graph() !== startGraph) {
33773             context.pop();
33774         }
33775
33776         window.setTimeout(function() {
33777             context.map().dblclickEnable(true);
33778         }, 1000);
33779
33780         context.surface()
33781             .classed('nope', false)
33782             .classed('nope-disabled', false)
33783             .classed('nope-suppressed', false);
33784
33785         context.enter(modeBrowse(context));
33786     };
33787
33788
33789     drawWay.activeID = function() {
33790         if (!arguments.length) return end.id;
33791         // no assign
33792         return drawWay;
33793     };
33794
33795
33796     drawWay.tail = function(text) {
33797         behavior.tail(text);
33798         return drawWay;
33799     };
33800
33801
33802     return drawWay;
33803 }
33804
33805 /** Error message constants. */
33806 var FUNC_ERROR_TEXT$3 = 'Expected a function';
33807
33808 /**
33809  * Creates a throttled function that only invokes `func` at most once per
33810  * every `wait` milliseconds. The throttled function comes with a `cancel`
33811  * method to cancel delayed `func` invocations and a `flush` method to
33812  * immediately invoke them. Provide `options` to indicate whether `func`
33813  * should be invoked on the leading and/or trailing edge of the `wait`
33814  * timeout. The `func` is invoked with the last arguments provided to the
33815  * throttled function. Subsequent calls to the throttled function return the
33816  * result of the last `func` invocation.
33817  *
33818  * **Note:** If `leading` and `trailing` options are `true`, `func` is
33819  * invoked on the trailing edge of the timeout only if the throttled function
33820  * is invoked more than once during the `wait` timeout.
33821  *
33822  * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
33823  * until to the next tick, similar to `setTimeout` with a timeout of `0`.
33824  *
33825  * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
33826  * for details over the differences between `_.throttle` and `_.debounce`.
33827  *
33828  * @static
33829  * @memberOf _
33830  * @since 0.1.0
33831  * @category Function
33832  * @param {Function} func The function to throttle.
33833  * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
33834  * @param {Object} [options={}] The options object.
33835  * @param {boolean} [options.leading=true]
33836  *  Specify invoking on the leading edge of the timeout.
33837  * @param {boolean} [options.trailing=true]
33838  *  Specify invoking on the trailing edge of the timeout.
33839  * @returns {Function} Returns the new throttled function.
33840  * @example
33841  *
33842  * // Avoid excessively updating the position while scrolling.
33843  * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
33844  *
33845  * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
33846  * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
33847  * jQuery(element).on('click', throttled);
33848  *
33849  * // Cancel the trailing throttled invocation.
33850  * jQuery(window).on('popstate', throttled.cancel);
33851  */
33852 function throttle(func, wait, options) {
33853   var leading = true,
33854       trailing = true;
33855
33856   if (typeof func != 'function') {
33857     throw new TypeError(FUNC_ERROR_TEXT$3);
33858   }
33859   if (isObject(options)) {
33860     leading = 'leading' in options ? !!options.leading : leading;
33861     trailing = 'trailing' in options ? !!options.trailing : trailing;
33862   }
33863   return debounce(func, wait, {
33864     'leading': leading,
33865     'maxWait': wait,
33866     'trailing': trailing
33867   });
33868 }
33869
33870 function behaviorHash(context) {
33871     var s0 = null, // cached window.location.hash
33872         lat = 90 - 1e-8; // allowable latitude range
33873
33874
33875     var parser = function(map, s) {
33876         var q = utilStringQs(s);
33877         var args = (q.map || '').split('/').map(Number);
33878
33879         if (args.length < 3 || args.some(isNaN)) {
33880             return true; // replace bogus hash
33881
33882         } else if (s !== formatter(map).slice(1)) {   // hash has changed
33883             var mode = context.mode(),
33884                 dist = geoSphericalDistance(map.center(), [args[2], args[1]]),
33885                 maxdist = 500;
33886
33887             // Don't allow the hash location to change too much while drawing
33888             // This can happen if the user accidently hit the back button.  #3996
33889             if (mode && mode.id.match(/^draw/) !== null && dist > maxdist) {
33890                 context.enter(modeBrowse(context));
33891             }
33892
33893             map.centerZoom([args[2], Math.min(lat, Math.max(-lat, args[1]))], args[0]);
33894         }
33895     };
33896
33897
33898     var formatter = function(map) {
33899         var center = map.center(),
33900             zoom = map.zoom(),
33901             precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2)),
33902             q = omit(utilStringQs(window.location.hash.substring(1)),
33903                 ['comment', 'hashtags', 'walkthrough']
33904             ),
33905             newParams = {};
33906
33907         delete q.id;
33908         var selected = context.selectedIDs().filter(function(id) {
33909             return !context.entity(id).isNew();
33910         });
33911         if (selected.length) {
33912             newParams.id = selected.join(',');
33913         }
33914
33915         newParams.map = zoom.toFixed(2) +
33916             '/' + center[1].toFixed(precision) +
33917             '/' + center[0].toFixed(precision);
33918
33919         return '#' + utilQsString(assign(q, newParams), true);
33920     };
33921
33922
33923     function update() {
33924         if (context.inIntro()) return;
33925         var s1 = formatter(context.map());
33926         if (s0 !== s1) {
33927             window.location.replace(s0 = s1);  // don't recenter the map!
33928         }
33929     }
33930
33931
33932     var throttledUpdate = throttle(update, 500);
33933
33934
33935     function hashchange() {
33936         if (window.location.hash === s0) return;  // ignore spurious hashchange events
33937         if (parser(context.map(), (s0 = window.location.hash).substring(1))) {
33938             update(); // replace bogus hash
33939         }
33940     }
33941
33942
33943     function hash() {
33944         context.map()
33945             .on('move.hash', throttledUpdate);
33946
33947         context
33948             .on('enter.hash', throttledUpdate);
33949
33950         d3_select(window)
33951             .on('hashchange.hash', hashchange);
33952
33953         if (window.location.hash) {
33954
33955             var q = utilStringQs(window.location.hash.substring(1));
33956
33957             if (q.id) {
33958                 context.zoomToEntity(q.id.split(',')[0], !q.map);
33959             }
33960
33961             if (q.comment) {
33962                 context.storage('comment', q.comment);
33963                 context.storage('commentDate', Date.now());
33964             }
33965
33966             if (q.hashtags) {
33967                 context.storage('hashtags', q.hashtags);
33968             }
33969
33970             if (q.walkthrough === 'true') {
33971                 hash.startWalkthrough = true;
33972             }
33973
33974             hashchange();
33975
33976             if (q.map) {
33977                 hash.hadHash = true;
33978             }
33979         }
33980     }
33981
33982
33983     hash.off = function() {
33984         throttledUpdate.cancel();
33985
33986         context.map()
33987             .on('move.hash', null);
33988
33989         context
33990             .on('enter.hash', null);
33991
33992         d3_select(window)
33993             .on('hashchange.hash', null);
33994
33995         window.location.hash = '';
33996     };
33997
33998
33999     return hash;
34000 }
34001
34002 function behaviorLasso(context) {
34003
34004     var behavior = function(selection) {
34005         var lasso;
34006
34007
34008         function mousedown() {
34009             var button = 0;  // left
34010             if (event.button === button && event.shiftKey === true) {
34011                 lasso = null;
34012
34013                 d3_select(window)
34014                     .on('mousemove.lasso', mousemove)
34015                     .on('mouseup.lasso', mouseup);
34016
34017                 event.stopPropagation();
34018             }
34019         }
34020
34021
34022         function mousemove() {
34023             if (!lasso) {
34024                 lasso = uiLasso(context);
34025                 context.surface().call(lasso);
34026             }
34027
34028             lasso.p(context.mouse());
34029         }
34030
34031
34032         function normalize(a, b) {
34033             return [
34034                 [Math.min(a[0], b[0]), Math.min(a[1], b[1])],
34035                 [Math.max(a[0], b[0]), Math.max(a[1], b[1])]];
34036         }
34037
34038
34039         function lassoed() {
34040             if (!lasso) return [];
34041
34042             var graph = context.graph(),
34043                 bounds = lasso.extent().map(context.projection.invert),
34044                 extent = geoExtent(normalize(bounds[0], bounds[1]));
34045
34046             return map$4(context.intersects(extent).filter(function(entity) {
34047                 return entity.type === 'node' &&
34048                     geoPointInPolygon(context.projection(entity.loc), lasso.coordinates) &&
34049                     !context.features().isHidden(entity, graph, entity.geometry(graph));
34050             }), 'id');
34051         }
34052
34053
34054         function mouseup() {
34055             d3_select(window)
34056                 .on('mousemove.lasso', null)
34057                 .on('mouseup.lasso', null);
34058
34059             if (!lasso) return;
34060
34061             var ids = lassoed();
34062             lasso.close();
34063
34064             if (ids.length) {
34065                 context.enter(modeSelect(context, ids));
34066             }
34067         }
34068
34069         selection
34070             .on('mousedown.lasso', mousedown);
34071     };
34072
34073
34074     behavior.off = function(selection) {
34075         selection.on('mousedown.lasso', null);
34076     };
34077
34078
34079     return behavior;
34080 }
34081
34082 /* Creates a keybinding behavior for an operation */
34083 function behaviorOperation() {
34084     var _operation, keybinding;
34085
34086     var behavior = function () {
34087         if (_operation && _operation.available()) {
34088             keybinding = d3keybinding('behavior.key.' + _operation.id);
34089             keybinding.on(_operation.keys, function() {
34090                 event.preventDefault();
34091                 var disabled = _operation.disabled();
34092                 var flash;
34093
34094                 if (disabled) {
34095                     flash = uiFlash()
34096                         .duration(4000)
34097                         .iconName('#operation-' + _operation.id)
34098                         .iconClass('operation disabled')
34099                         .text(_operation.tooltip);
34100
34101                     flash();
34102
34103                 } else {
34104                     flash = uiFlash()
34105                         .duration(2000)
34106                         .iconName('#operation-' + _operation.id)
34107                         .iconClass('operation')
34108                         .text(_operation.annotation() || _operation.title);
34109
34110                     flash();
34111                     _operation();
34112                 }
34113             });
34114
34115             d3_select(document).call(keybinding);
34116         }
34117
34118         return behavior;
34119     };
34120
34121
34122     behavior.off = function() {
34123         if (keybinding) {
34124             d3_select(document).call(keybinding.off);
34125         }
34126     };
34127
34128
34129     behavior.which = function (_) {
34130         if (!arguments.length) return _operation;
34131         _operation = _;
34132         return behavior;
34133     };
34134
34135
34136     return behavior;
34137 }
34138
34139 /**
34140  * The base implementation of `_.invert` and `_.invertBy` which inverts
34141  * `object` with values transformed by `iteratee` and set by `setter`.
34142  *
34143  * @private
34144  * @param {Object} object The object to iterate over.
34145  * @param {Function} setter The function to set `accumulator` values.
34146  * @param {Function} iteratee The iteratee to transform values.
34147  * @param {Object} accumulator The initial inverted object.
34148  * @returns {Function} Returns `accumulator`.
34149  */
34150 function baseInverter(object, setter, iteratee, accumulator) {
34151   baseForOwn(object, function(value, key, object) {
34152     setter(accumulator, iteratee(value), key, object);
34153   });
34154   return accumulator;
34155 }
34156
34157 /**
34158  * Creates a function like `_.invertBy`.
34159  *
34160  * @private
34161  * @param {Function} setter The function to set accumulator values.
34162  * @param {Function} toIteratee The function to resolve iteratees.
34163  * @returns {Function} Returns the new inverter function.
34164  */
34165 function createInverter(setter, toIteratee) {
34166   return function(object, iteratee) {
34167     return baseInverter(object, setter, toIteratee(iteratee), {});
34168   };
34169 }
34170
34171 /**
34172  * Creates an object composed of the inverted keys and values of `object`.
34173  * If `object` contains duplicate values, subsequent values overwrite
34174  * property assignments of previous values.
34175  *
34176  * @static
34177  * @memberOf _
34178  * @since 0.7.0
34179  * @category Object
34180  * @param {Object} object The object to invert.
34181  * @returns {Object} Returns the new inverted object.
34182  * @example
34183  *
34184  * var object = { 'a': 1, 'b': 2, 'c': 1 };
34185  *
34186  * _.invert(object);
34187  * // => { '1': 'c', '2': 'b' }
34188  */
34189 var invert = createInverter(function(result, value, key) {
34190   result[value] = key;
34191 }, constant$13(identity$8));
34192
34193 /**
34194  * Creates an object with the same keys as `object` and values generated
34195  * by running each own enumerable string keyed property of `object` thru
34196  * `iteratee`. The iteratee is invoked with three arguments:
34197  * (value, key, object).
34198  *
34199  * @static
34200  * @memberOf _
34201  * @since 2.4.0
34202  * @category Object
34203  * @param {Object} object The object to iterate over.
34204  * @param {Function} [iteratee=_.identity] The function invoked per iteration.
34205  * @returns {Object} Returns the new mapped object.
34206  * @see _.mapKeys
34207  * @example
34208  *
34209  * var users = {
34210  *   'fred':    { 'user': 'fred',    'age': 40 },
34211  *   'pebbles': { 'user': 'pebbles', 'age': 1 }
34212  * };
34213  *
34214  * _.mapValues(users, function(o) { return o.age; });
34215  * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
34216  *
34217  * // The `_.property` iteratee shorthand.
34218  * _.mapValues(users, 'age');
34219  * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
34220  */
34221 function mapValues(object, iteratee) {
34222   var result = {};
34223   iteratee = baseIteratee(iteratee, 3);
34224
34225   baseForOwn(object, function(value, key, object) {
34226     baseAssignValue(result, key, iteratee(value, key, object));
34227   });
34228   return result;
34229 }
34230
34231 function behaviorPaste(context) {
34232     var keybinding = d3keybinding('paste');
34233
34234
34235     function doPaste() {
34236         event.preventDefault();
34237
34238         var baseGraph = context.graph(),
34239             mouse = context.mouse(),
34240             projection = context.projection,
34241             viewport = geoExtent(projection.clipExtent()).polygon();
34242
34243         if (!geoPointInPolygon(mouse, viewport)) return;
34244
34245         var extent = geoExtent(),
34246             oldIDs = context.copyIDs(),
34247             oldGraph = context.copyGraph(),
34248             newIDs = [];
34249
34250         if (!oldIDs.length) return;
34251
34252         var action = actionCopyEntities(oldIDs, oldGraph);
34253         context.perform(action);
34254
34255         var copies = action.copies();
34256         var originals = invert(mapValues(copies, 'id'));
34257         for (var id in copies) {
34258             var oldEntity = oldGraph.entity(id),
34259                 newEntity = copies[id];
34260
34261             extent._extend(oldEntity.extent(oldGraph));
34262
34263             // Exclude child nodes from newIDs if their parent way was also copied.
34264             var parents = context.graph().parentWays(newEntity),
34265                 parentCopied = false;
34266             for (var i = 0; i < parents.length; i++) {
34267                 if (originals[parents[i].id]) {
34268                     parentCopied = true;
34269                     break;
34270                 }
34271             }
34272
34273             if (!parentCopied) {
34274                 newIDs.push(newEntity.id);
34275             }
34276         }
34277
34278         // Put pasted objects where mouse pointer is..
34279         var center = projection(extent.center()),
34280             delta = [ mouse[0] - center[0], mouse[1] - center[1] ];
34281
34282         context.perform(actionMove(newIDs, delta, projection));
34283         context.enter(modeMove(context, newIDs, baseGraph));
34284     }
34285
34286
34287     function paste() {
34288         keybinding.on(uiCmd('⌘V'), doPaste);
34289         d3_select(document).call(keybinding);
34290         return paste;
34291     }
34292
34293
34294     paste.off = function() {
34295         d3_select(document).call(keybinding.off);
34296     };
34297
34298
34299     return paste;
34300 }
34301
34302 function behaviorSelect(context) {
34303     var lastMouse = null;
34304     var suppressMenu = true;
34305     var tolerance = 4;
34306     var p1 = null;
34307
34308
34309     function point() {
34310         return d3_mouse(context.container().node());
34311     }
34312
34313
34314     function keydown() {
34315         var e = event;
34316         if (e && e.shiftKey) {
34317             context.surface()
34318                 .classed('behavior-multiselect', true);
34319         }
34320
34321         if (e && e.keyCode === 93) {  // context menu
34322             e.preventDefault();
34323             e.stopPropagation();
34324         }
34325     }
34326
34327
34328     function keyup() {
34329         var e = event;
34330         if (!e || !e.shiftKey) {
34331             context.surface()
34332                 .classed('behavior-multiselect', false);
34333         }
34334
34335
34336         if (e && e.keyCode === 93) {  // context menu
34337             e.preventDefault();
34338             e.stopPropagation();
34339             contextmenu();
34340         }
34341     }
34342
34343
34344     function mousedown() {
34345         if (!p1) p1 = point();
34346         d3_select(window)
34347             .on('mouseup.select', mouseup, true);
34348
34349         var isShowAlways = +context.storage('edit-menu-show-always') === 1;
34350         suppressMenu = !isShowAlways;
34351     }
34352
34353
34354     function mousemove() {
34355         if (event) lastMouse = event;
34356     }
34357
34358
34359     function mouseup() {
34360         click();
34361     }
34362
34363
34364     function contextmenu() {
34365         var e = event;
34366         e.preventDefault();
34367         e.stopPropagation();
34368
34369         if (!+e.clientX && !+e.clientY) {
34370             if (lastMouse) {
34371                 e.sourceEvent = lastMouse;
34372             } else {
34373                 return;
34374             }
34375         }
34376
34377         if (!p1) p1 = point();
34378         suppressMenu = false;
34379         click();
34380     }
34381
34382
34383     function click() {
34384         d3_select(window)
34385             .on('mouseup.select', null, true);
34386
34387         if (!p1) return;
34388         var p2 = point();
34389         var dist = geoVecLength(p1, p2);
34390
34391         p1 = null;
34392         if (dist > tolerance) {
34393             return;
34394         }
34395
34396         var isMultiselect = event.shiftKey || d3_select('#surface .lasso').node();
34397         var isShowAlways = +context.storage('edit-menu-show-always') === 1;
34398         var datum = event.target.__data__ || (lastMouse && lastMouse.target.__data__);
34399         var mode = context.mode();
34400
34401         var entity = datum && datum.properties && datum.properties.entity;
34402         if (entity) datum = entity;
34403
34404         if (datum && datum.type === 'midpoint') {
34405             datum = datum.parents[0];
34406         }
34407
34408         if (!(datum instanceof osmEntity)) {
34409             // clicked nothing..
34410             if (!isMultiselect && mode.id !== 'browse') {
34411                 context.enter(modeBrowse(context));
34412             }
34413
34414         } else {
34415             // clicked an entity..
34416             var selectedIDs = context.selectedIDs();
34417
34418             if (!isMultiselect) {
34419                 if (selectedIDs.length > 1 && (!suppressMenu && !isShowAlways)) {
34420                     // multiple things already selected, just show the menu...
34421                     mode.suppressMenu(false).reselect();
34422                 } else {
34423                     // select a single thing..
34424                     context.enter(modeSelect(context, [datum.id]).suppressMenu(suppressMenu));
34425                 }
34426
34427             } else {
34428                 if (selectedIDs.indexOf(datum.id) !== -1) {
34429                     // clicked entity is already in the selectedIDs list..
34430                     if (!suppressMenu && !isShowAlways) {
34431                         // don't deselect clicked entity, just show the menu.
34432                         mode.suppressMenu(false).reselect();
34433                     } else {
34434                         // deselect clicked entity, then reenter select mode or return to browse mode..
34435                         selectedIDs = without(selectedIDs, datum.id);
34436                         context.enter(selectedIDs.length ? modeSelect(context, selectedIDs) : modeBrowse(context));
34437                     }
34438                 } else {
34439                     // clicked entity is not in the selected list, add it..
34440                     selectedIDs = selectedIDs.concat([datum.id]);
34441                     context.enter(modeSelect(context, selectedIDs).suppressMenu(suppressMenu));
34442                 }
34443             }
34444         }
34445
34446         // reset for next time..
34447         suppressMenu = true;
34448     }
34449
34450
34451     var behavior = function(selection) {
34452         lastMouse = null;
34453         suppressMenu = true;
34454         p1 = null;
34455
34456         d3_select(window)
34457             .on('keydown.select', keydown)
34458             .on('keyup.select', keyup)
34459             .on('contextmenu.select-window', function() {
34460                 // Edge and IE really like to show the contextmenu on the
34461                 // menubar when user presses a keyboard menu button
34462                 // even after we've already preventdefaulted the key event.
34463                 var e = event;
34464                 if (+e.clientX === 0 && +e.clientY === 0) {
34465                     event.preventDefault();
34466                     event.stopPropagation();
34467                 }
34468             });
34469
34470         selection
34471             .on('mousedown.select', mousedown)
34472             .on('mousemove.select', mousemove)
34473             .on('contextmenu.select', contextmenu);
34474
34475         if (event && event.shiftKey) {
34476             context.surface()
34477                 .classed('behavior-multiselect', true);
34478         }
34479     };
34480
34481
34482     behavior.off = function(selection) {
34483         d3_select(window)
34484             .on('keydown.select', null)
34485             .on('keyup.select', null)
34486             .on('contextmenu.select-window', null)
34487             .on('mouseup.select', null, true);
34488
34489         selection
34490             .on('mousedown.select', null)
34491             .on('mousemove.select', null)
34492             .on('contextmenu.select', null);
34493
34494         context.surface()
34495             .classed('behavior-multiselect', false);
34496     };
34497
34498
34499     return behavior;
34500 }
34501
34502 function d3geoTile() {
34503   var size = [960, 500],
34504       scale = 256,
34505       scaleExtent = [0, 20],
34506       translate = [size[0] / 2, size[1] / 2],
34507       zoomDelta = 0;
34508
34509   function bound(_) {
34510       return Math.min(scaleExtent[1], Math.max(scaleExtent[0], _));
34511   }
34512
34513   function tile() {
34514     var z = Math.max(Math.log(scale) / Math.LN2 - 8, 0),
34515         z0 = bound(Math.round(z + zoomDelta)),
34516         k = Math.pow(2, z - z0 + 8),
34517         origin = [(translate[0] - scale / 2) / k, (translate[1] - scale / 2) / k],
34518         tiles = [],
34519         cols = d3_range(Math.max(0, Math.floor(-origin[0])), Math.max(0, Math.ceil(size[0] / k - origin[0]))),
34520         rows = d3_range(Math.max(0, Math.floor(-origin[1])), Math.max(0, Math.ceil(size[1] / k - origin[1])));
34521
34522     rows.forEach(function(y) {
34523       cols.forEach(function(x) {
34524         tiles.push([x, y, z0]);
34525       });
34526     });
34527
34528     tiles.translate = origin;
34529     tiles.scale = k;
34530
34531     return tiles;
34532   }
34533
34534   tile.scaleExtent = function(_) {
34535     if (!arguments.length) return scaleExtent;
34536     scaleExtent = _;
34537     return tile;
34538   };
34539
34540   tile.size = function(_) {
34541     if (!arguments.length) return size;
34542     size = _;
34543     return tile;
34544   };
34545
34546   tile.scale = function(_) {
34547     if (!arguments.length) return scale;
34548     scale = _;
34549     return tile;
34550   };
34551
34552   tile.translate = function(_) {
34553     if (!arguments.length) return translate;
34554     translate = _;
34555     return tile;
34556   };
34557
34558   tile.zoomDelta = function(_) {
34559     if (!arguments.length) return zoomDelta;
34560     zoomDelta = +_;
34561     return tile;
34562   };
34563
34564   return tile;
34565 }
34566
34567 /* global Mapillary:false */
34568 var apibase = 'https://a.mapillary.com/v3/';
34569 var viewercss = 'mapillary-js/mapillary.min.css';
34570 var viewerjs = 'mapillary-js/mapillary.min.js';
34571 var clientId = 'NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1ZWYyMmYwNjdmNDdlNmVi';
34572 var maxResults = 1000;
34573 var tileZoom = 14;
34574 var dispatch$1 = dispatch('loadedImages', 'loadedSigns');
34575 var _mlyFallback = false;
34576 var _mlyCache;
34577 var _mlyClicks;
34578 var _mlySelectedImage;
34579 var _mlySignDefs;
34580 var _mlySignSprite;
34581 var _mlyViewer;
34582
34583
34584 function abortRequest(i) {
34585     i.abort();
34586 }
34587
34588
34589 function nearNullIsland(x, y, z) {
34590     if (z >= 7) {
34591         var center = Math.pow(2, z - 1),
34592             width = Math.pow(2, z - 6),
34593             min = center - (width / 2),
34594             max = center + (width / 2) - 1;
34595         return x >= min && x <= max && y >= min && y <= max;
34596     }
34597     return false;
34598 }
34599
34600
34601 function maxPageAtZoom(z) {
34602     if (z < 15)   return 2;
34603     if (z === 15) return 5;
34604     if (z === 16) return 10;
34605     if (z === 17) return 20;
34606     if (z === 18) return 40;
34607     if (z > 18)   return 80;
34608 }
34609
34610
34611 function localeTimestamp(s) {
34612     if (!s) return null;
34613     var detected = utilDetect();
34614     var options = {
34615         day: 'numeric', month: 'short', year: 'numeric',
34616         hour: 'numeric', minute: 'numeric', second: 'numeric',
34617         timeZone: 'UTC'
34618     };
34619     var d = new Date(s);
34620     if (isNaN(d.getTime())) return null;
34621     return d.toLocaleString(detected.locale, options);
34622 }
34623
34624
34625 function getTiles(projection) {
34626     var s = projection.scale() * 2 * Math.PI,
34627         z = Math.max(Math.log(s) / Math.log(2) - 8, 0),
34628         ts = 256 * Math.pow(2, z - tileZoom),
34629         origin = [
34630             s / 2 - projection.translate()[0],
34631             s / 2 - projection.translate()[1]];
34632
34633     return d3geoTile()
34634         .scaleExtent([tileZoom, tileZoom])
34635         .scale(s)
34636         .size(projection.clipExtent()[1])
34637         .translate(projection.translate())()
34638         .map(function(tile) {
34639             var x = tile[0] * ts - origin[0],
34640                 y = tile[1] * ts - origin[1];
34641
34642             return {
34643                 id: tile.toString(),
34644                 xyz: tile,
34645                 extent: geoExtent(
34646                     projection.invert([x, y + ts]),
34647                     projection.invert([x + ts, y])
34648                 )
34649             };
34650         });
34651 }
34652
34653
34654 function loadTiles(which, url, projection) {
34655     var s = projection.scale() * 2 * Math.PI,
34656         currZoom = Math.floor(Math.max(Math.log(s) / Math.log(2) - 8, 0));
34657
34658     var tiles = getTiles(projection).filter(function(t) {
34659             return !nearNullIsland(t.xyz[0], t.xyz[1], t.xyz[2]);
34660         });
34661
34662     filter(which.inflight, function(v, k) {
34663         var wanted = find$1(tiles, function(tile) { return k === (tile.id + ',0'); });
34664         if (!wanted) delete which.inflight[k];
34665         return !wanted;
34666     }).map(abortRequest);
34667
34668     tiles.forEach(function(tile) {
34669         loadNextTilePage(which, currZoom, url, tile);
34670     });
34671 }
34672
34673
34674 function loadNextTilePage(which, currZoom, url, tile) {
34675     var cache = _mlyCache[which],
34676         rect = tile.extent.rectangle(),
34677         maxPages = maxPageAtZoom(currZoom),
34678         nextPage = cache.nextPage[tile.id] || 0,
34679         nextURL = cache.nextURL[tile.id] || url +
34680             utilQsString({
34681                 per_page: maxResults,
34682                 page: nextPage,
34683                 client_id: clientId,
34684                 bbox: [rect[0], rect[1], rect[2], rect[3]].join(','),
34685             });
34686
34687     if (nextPage > maxPages) return;
34688
34689     var id = tile.id + ',' + String(nextPage);
34690     if (cache.loaded[id] || cache.inflight[id]) return;
34691     cache.inflight[id] = d3_request(nextURL)
34692         .mimeType('application/json')
34693         .response(function(xhr) {
34694             var linkHeader = xhr.getResponseHeader('Link');
34695             if (linkHeader) {
34696                 var pagination = parsePagination(xhr.getResponseHeader('Link'));
34697                 if (pagination.next) {
34698                     cache.nextURL[tile.id] = pagination.next;
34699                 }
34700             }
34701             return JSON.parse(xhr.responseText);
34702         })
34703         .get(function(err, data) {
34704             cache.loaded[id] = true;
34705             delete cache.inflight[id];
34706             if (err || !data.features || !data.features.length) return;
34707
34708             var features = data.features.map(function(feature) {
34709                 var loc = feature.geometry.coordinates,
34710                     d;
34711
34712                 if (which === 'images') {
34713                     d = {
34714                         loc: loc,
34715                         key: feature.properties.key,
34716                         ca: feature.properties.ca,
34717                         captured_at: feature.properties.captured_at,
34718                         captured_by: feature.properties.username,
34719                         pano: feature.properties.pano
34720                     };
34721                     cache.forImageKey[d.key] = d;     // cache imageKey -> image
34722
34723                 } else if (which === 'sequences') {
34724                     var sequenceKey = feature.properties.key;
34725                     cache.lineString[sequenceKey] = feature;           // cache sequenceKey -> lineString
34726                     feature.properties.coordinateProperties.image_keys.forEach(function(imageKey) {
34727                         cache.forImageKey[imageKey] = sequenceKey;     // cache imageKey -> sequenceKey
34728                     });
34729                     return false;  // because no `d` data worth loading into an rbush
34730
34731                 } else if (which === 'objects') {
34732                     d = {
34733                         loc: loc,
34734                         key: feature.properties.key,
34735                         value: feature.properties.value,
34736                         package: feature.properties.package,
34737                         detections: feature.properties.detections
34738                     };
34739
34740                     // cache imageKey -> detectionKey
34741                     feature.properties.detections.forEach(function(detection) {
34742                         var imageKey = detection.image_key;
34743                         var detectionKey = detection.detection_key;
34744                         if (!_mlyCache.detections[imageKey]) {
34745                             _mlyCache.detections[imageKey] = {};
34746                         }
34747                         if (!_mlyCache.detections[imageKey][detectionKey]) {
34748                             _mlyCache.detections[imageKey][detectionKey] = {};
34749                         }
34750                     });
34751                 }
34752
34753                 return {
34754                     minX: loc[0], minY: loc[1], maxX: loc[0], maxY: loc[1], data: d
34755                 };
34756
34757             }).filter(Boolean);
34758
34759             cache.rtree.load(features);
34760
34761             if (which === 'images' || which === 'sequences') {
34762                 dispatch$1.call('loadedImages');
34763             } else if (which === 'objects') {
34764                 dispatch$1.call('loadedSigns');
34765             }
34766
34767             if (data.features.length === maxResults) {  // more pages to load
34768                 cache.nextPage[tile.id] = nextPage + 1;
34769                 loadNextTilePage(which, currZoom, url, tile);
34770             } else {
34771                 cache.nextPage[tile.id] = Infinity;     // no more pages to load
34772             }
34773         });
34774 }
34775
34776 // extract links to pages of API results
34777 function parsePagination(links) {
34778     return links.split(',').map(function(rel) {
34779         var elements = rel.split(';');
34780         if (elements.length === 2) {
34781             return [
34782                 /<(.+)>/.exec(elements[0])[1],
34783                 /rel="(.+)"/.exec(elements[1])[1]
34784                 ];
34785         } else {
34786             return ['',''];
34787         }
34788     }).reduce(function(pagination, val) {
34789         pagination[val[1]] = val[0];
34790         return pagination;
34791     }, {});
34792 }
34793
34794
34795 // partition viewport into `psize` x `psize` regions
34796 function partitionViewport(psize, projection) {
34797     var dimensions = projection.clipExtent()[1];
34798     psize = psize || 16;
34799     var cols = d3_range(0, dimensions[0], psize),
34800         rows = d3_range(0, dimensions[1], psize),
34801         partitions = [];
34802
34803     rows.forEach(function(y) {
34804         cols.forEach(function(x) {
34805             var min = [x, y + psize],
34806                 max = [x + psize, y];
34807             partitions.push(
34808                 geoExtent(projection.invert(min), projection.invert(max)));
34809         });
34810     });
34811
34812     return partitions;
34813 }
34814
34815
34816 // no more than `limit` results per partition.
34817 function searchLimited(psize, limit, projection, rtree) {
34818     limit = limit || 3;
34819
34820     var partitions = partitionViewport(psize, projection);
34821     var results;
34822
34823     // console.time('previous');
34824     results =  flatten(map$4(partitions, function(extent) {
34825         return rtree.search(extent.bbox())
34826             .slice(0, limit)
34827             .map(function(d) { return d.data; });
34828     }));
34829     // console.timeEnd('previous');
34830
34831     // console.time('new');
34832     // results = partitions.reduce(function(result, extent) {
34833     //     var found = rtree.search(extent.bbox())
34834     //         .map(function(d) { return d.data; })
34835     //         .sort(function(a, b) {
34836     //             return a.loc[1] - b.loc[1];
34837     //             // return a.key.localeCompare(b.key);
34838     //         })
34839     //         .slice(0, limit);
34840
34841     //     return (found.length ? result.concat(found) : result);
34842     // }, []);
34843     // console.timeEnd('new');
34844
34845     return results;
34846 }
34847
34848
34849
34850 var serviceMapillary = {
34851
34852     init: function() {
34853         if (!_mlyCache) {
34854             this.reset();
34855         }
34856
34857         this.event = utilRebind(this, dispatch$1, 'on');
34858     },
34859
34860     reset: function() {
34861         var cache = _mlyCache;
34862
34863         if (cache) {
34864             if (cache.images && cache.images.inflight) {
34865                 forEach(cache.images.inflight, abortRequest);
34866             }
34867             if (cache.objects && cache.objects.inflight) {
34868                 forEach(cache.objects.inflight, abortRequest);
34869             }
34870             if (cache.sequences && cache.sequences.inflight) {
34871                 forEach(cache.sequences.inflight, abortRequest);
34872             }
34873         }
34874
34875         _mlyCache = {
34876             images: { inflight: {}, loaded: {}, nextPage: {}, nextURL: {}, rtree: rbush_1(), forImageKey: {} },
34877             objects: { inflight: {}, loaded: {}, nextPage: {}, nextURL: {}, rtree: rbush_1() },
34878             sequences: { inflight: {}, loaded: {}, nextPage: {}, nextURL: {}, rtree: rbush_1(), forImageKey: {}, lineString: {} },
34879             detections: {}
34880         };
34881
34882         _mlySelectedImage = null;
34883         _mlyClicks = [];
34884     },
34885
34886
34887     images: function(projection) {
34888         var psize = 16, limit = 3;
34889         return searchLimited(psize, limit, projection, _mlyCache.images.rtree);
34890     },
34891
34892
34893     signs: function(projection) {
34894         var psize = 32, limit = 3;
34895         return searchLimited(psize, limit, projection, _mlyCache.objects.rtree);
34896     },
34897
34898
34899     sequences: function(projection) {
34900         var viewport = projection.clipExtent();
34901         var min = [viewport[0][0], viewport[1][1]];
34902         var max = [viewport[1][0], viewport[0][1]];
34903         var bbox = geoExtent(projection.invert(min), projection.invert(max)).bbox();
34904         var sequenceKeys = {};
34905
34906         // all sequences for images in viewport
34907         _mlyCache.images.rtree.search(bbox)
34908             .forEach(function(d) {
34909                 var sequenceKey = _mlyCache.sequences.forImageKey[d.data.key];
34910                 if (sequenceKey) {
34911                     sequenceKeys[sequenceKey] = true;
34912                 }
34913             });
34914
34915         // Return lineStrings for the sequences
34916         return Object.keys(sequenceKeys).map(function(sequenceKey) {
34917             return _mlyCache.sequences.lineString[sequenceKey];
34918         });
34919     },
34920
34921
34922     signsSupported: function() {
34923         var detected = utilDetect();
34924         if (detected.ie) return false;
34925         if ((detected.browser.toLowerCase() === 'safari') && (parseFloat(detected.version) < 10)) return false;
34926         return true;
34927     },
34928
34929
34930     signHTML: function(d) {
34931         if (!_mlySignDefs || !_mlySignSprite) return;
34932         var position = _mlySignDefs[d.value];
34933         if (!position) return '<div></div>';
34934         var iconStyle = [
34935             'background-image:url(' + _mlySignSprite + ')',
34936             'background-repeat:no-repeat',
34937             'height:' + position.height + 'px',
34938             'width:' + position.width + 'px',
34939             'background-position-x:-' + position.x + 'px',
34940             'background-position-y:-' + position.y + 'px',
34941         ];
34942
34943         return '<div style="' + iconStyle.join(';') +'"></div>';
34944     },
34945
34946
34947     loadImages: function(projection) {
34948         loadTiles('images', apibase + 'images?', projection);
34949         loadTiles('sequences', apibase + 'sequences?', projection);
34950     },
34951
34952
34953     loadSigns: function(context, projection) {
34954         // if we are looking at signs, we'll actually need to fetch images too
34955         loadTiles('images', apibase + 'images?', projection);
34956         loadTiles('objects', apibase + 'objects?', projection);
34957
34958         // load traffic sign defs
34959         if (!_mlySignDefs) {
34960             _mlySignSprite = context.asset('img/traffic-signs/traffic-signs.png');
34961             _mlySignDefs = {};
34962             d3_json(context.asset('img/traffic-signs/traffic-signs.json'), function(err, data) {
34963                 if (err) return;
34964                 _mlySignDefs = data;
34965             });
34966         }
34967     },
34968
34969
34970     loadViewer: function(context) {
34971         // add mly-wrapper
34972         var wrap = d3_select('#photoviewer').selectAll('.mly-wrapper')
34973             .data([0]);
34974
34975         var wrapEnter = wrap.enter()
34976             .append('div')
34977             .attr('id', 'mly')
34978             .attr('class', 'photo-wrapper mly-wrapper')
34979             .classed('hide', true);
34980
34981         wrapEnter
34982             .append('div')
34983             .attr('class', 'photo-attribution fillD');
34984
34985
34986         // load mapillary-viewercss
34987         d3_select('head').selectAll('#mapillary-viewercss')
34988             .data([0])
34989             .enter()
34990             .append('link')
34991             .attr('id', 'mapillary-viewercss')
34992             .attr('rel', 'stylesheet')
34993             .attr('href', context.asset(viewercss));
34994
34995         // load mapillary-viewerjs
34996         d3_select('head').selectAll('#mapillary-viewerjs')
34997             .data([0])
34998             .enter()
34999             .append('script')
35000             .attr('id', 'mapillary-viewerjs')
35001             .attr('src', context.asset(viewerjs));
35002     },
35003
35004
35005     showViewer: function() {
35006         var wrap = d3_select('#photoviewer')
35007             .classed('hide', false);
35008
35009         var isHidden = wrap.selectAll('.photo-wrapper.mly-wrapper.hide').size();
35010
35011         if (isHidden) {
35012             wrap
35013                 .selectAll('.photo-wrapper:not(.mly-wrapper)')
35014                 .classed('hide', true);
35015
35016             wrap
35017                 .selectAll('.photo-wrapper.mly-wrapper')
35018                 .classed('hide', false);
35019
35020             _mlyViewer.resize();
35021         }
35022
35023         return this;
35024     },
35025
35026
35027     hideViewer: function() {
35028         _mlySelectedImage = null;
35029
35030         if (!_mlyFallback) {
35031             _mlyViewer.getComponent('sequence').stop();
35032         }
35033
35034         var viewer = d3_select('#photoviewer');
35035         if (!viewer.empty()) viewer.datum(null);
35036
35037         viewer
35038             .classed('hide', true)
35039             .selectAll('.photo-wrapper')
35040             .classed('hide', true);
35041
35042         d3_selectAll('.viewfield-group, .sequence, .icon-sign')
35043             .classed('selected', false);
35044
35045         return this.setStyles(null, true);
35046     },
35047
35048
35049     parsePagination: parsePagination,
35050
35051
35052     updateViewer: function(imageKey, context) {
35053         if (!imageKey) return this;
35054
35055         if (!_mlyViewer) {
35056             this.initViewer(imageKey, context);
35057         } else {
35058             _mlyViewer.moveToKey(imageKey)
35059                 .catch(function(e) { console.error('mly3', e); });  // eslint-disable-line no-console
35060         }
35061
35062         return this;
35063     },
35064
35065
35066     initViewer: function(imageKey, context) {
35067         var that = this;
35068         if (Mapillary && imageKey) {
35069             var opts = {
35070                 baseImageSize: 320,
35071                 component: {
35072                     cover: false,
35073                     keyboard: false,
35074                     tag: true
35075                 }
35076             };
35077
35078             // Disable components requiring WebGL support
35079             if (!Mapillary.isSupported() && Mapillary.isFallbackSupported()) {
35080                 _mlyFallback = true;
35081                 opts.component = {
35082                     cover: false,
35083                     direction: false,
35084                     imagePlane: false,
35085                     keyboard: false,
35086                     mouse: false,
35087                     sequence: false,
35088                     tag: false,
35089                     image: true,        // fallback
35090                     navigation: true    // fallback
35091                 };
35092             }
35093
35094             _mlyViewer = new Mapillary.Viewer('mly', clientId, null, opts);
35095             _mlyViewer.on('nodechanged', nodeChanged);
35096             _mlyViewer.moveToKey(imageKey)
35097                 .catch(function(e) { console.error('mly3', e); });  // eslint-disable-line no-console
35098         }
35099
35100         // nodeChanged: called after the viewer has changed images and is ready.
35101         //
35102         // There is some logic here to batch up clicks into a _mlyClicks array
35103         // because the user might click on a lot of markers quickly and nodechanged
35104         // may be called out of order asychronously.
35105         //
35106         // Clicks are added to the array in `selectedImage` and removed here.
35107         //
35108         function nodeChanged(node) {
35109             if (!_mlyFallback) {
35110                 _mlyViewer.getComponent('tag').removeAll();  // remove previous detections
35111             }
35112
35113             var clicks = _mlyClicks;
35114             var index = clicks.indexOf(node.key);
35115             var selectedKey = _mlySelectedImage && _mlySelectedImage.key;
35116
35117             if (index > -1) {              // `nodechanged` initiated from clicking on a marker..
35118                 clicks.splice(index, 1);   // remove the click
35119                 // If `node.key` matches the current _mlySelectedImage, call `selectImage()`
35120                 // one more time to update the detections and attribution..
35121                 if (node.key === selectedKey) {
35122                     that.selectImage(_mlySelectedImage, node.key, true);
35123                 }
35124             } else {             // `nodechanged` initiated from the Mapillary viewer controls..
35125                 var loc = node.computedLatLon ? [node.computedLatLon.lon, node.computedLatLon.lat] : [node.latLon.lon, node.latLon.lat];
35126                 context.map().centerEase(loc);
35127                 that.selectImage(undefined, node.key, true);
35128             }
35129         }
35130     },
35131
35132
35133     // Pass the image datum itself in `d` or the `imageKey` string.
35134     // This allows images to be selected from places that dont have access
35135     // to the full image datum (like the street signs layer or the js viewer)
35136     selectImage: function(d, imageKey, fromViewer) {
35137         if (!d && imageKey) {
35138             // If the user clicked on something that's not an image marker, we
35139             // might get in here.. Cache lookup can fail, e.g. if the user
35140             // clicked a streetsign, but images are loading slowly asynchronously.
35141             // We'll try to carry on anyway if there is no datum.  There just
35142             // might be a delay before user sees detections, captured_at, etc.
35143             d = _mlyCache.images.forImageKey[imageKey];
35144         }
35145
35146         _mlySelectedImage = d;
35147         var viewer = d3_select('#photoviewer');
35148         if (!viewer.empty()) viewer.datum(d);
35149
35150         imageKey = (d && d.key) || imageKey;
35151         if (!fromViewer && imageKey) {
35152             _mlyClicks.push(imageKey);
35153         }
35154
35155         this.setStyles(null, true);
35156
35157         d3_selectAll('.layer-mapillary-signs .icon-sign')
35158             .classed('selected', function(d) {
35159                 return some(d.detections, function(detection) {
35160                     return detection.image_key === imageKey;
35161                 });
35162             });
35163
35164         var wrap = d3_select('#photoviewer .mly-wrapper');
35165         var attribution = wrap.selectAll('.photo-attribution').html('');
35166
35167         if (d) {
35168             if (d.captured_by) {
35169                 attribution
35170                     .append('a')
35171                     .attr('class', 'captured_by')
35172                     .attr('target', '_blank')
35173                     .attr('href', 'https://www.mapillary.com/app/user/' + encodeURIComponent(d.captured_by))
35174                     .text('@' + d.captured_by);
35175
35176                 attribution
35177                     .append('span')
35178                     .text('|');
35179             }
35180
35181             if (d.captured_at) {
35182                 attribution
35183                     .append('span')
35184                     .attr('class', 'captured_at')
35185                     .text(localeTimestamp(d.captured_at));
35186
35187                 attribution
35188                     .append('span')
35189                     .text('|');
35190             }
35191
35192             attribution
35193                 .append('a')
35194                 .attr('class', 'image_link')
35195                 .attr('target', '_blank')
35196                 .attr('href', 'https://www.mapillary.com/app/?pKey=' + encodeURIComponent(d.key) +
35197                     '&focus=photo&lat=' + d.loc[1] + '&lng=' + d.loc[0] + '&z=17')
35198                 .text('mapillary.com');
35199
35200             this.updateDetections(d);
35201         }
35202
35203         return this;
35204     },
35205
35206
35207     getSelectedImage: function() {
35208         return _mlySelectedImage;
35209     },
35210
35211
35212     getSequenceKeyForImage: function(d) {
35213         var imageKey = d && d.key;
35214         return imageKey && _mlyCache.sequences.forImageKey[imageKey];
35215     },
35216
35217
35218     setStyles: function(hovered, reset) {
35219         if (reset) {  // reset all layers
35220             d3_selectAll('.viewfield-group')
35221                 .classed('highlighted', false)
35222                 .classed('hovered', false)
35223                 .classed('selected', false);
35224
35225             d3_selectAll('.sequence')
35226                 .classed('highlighted', false)
35227                 .classed('selected', false);
35228         }
35229
35230         var hoveredImageKey = hovered && hovered.key;
35231         var hoveredSequenceKey = this.getSequenceKeyForImage(hovered);
35232         var hoveredLineString = hoveredSequenceKey && _mlyCache.sequences.lineString[hoveredSequenceKey];
35233         var hoveredImageKeys = (hoveredLineString && hoveredLineString.properties.coordinateProperties.image_keys) || [];
35234
35235         var viewer = d3_select('#photoviewer');
35236         var selected = viewer.empty() ? undefined : viewer.datum();
35237         var selectedImageKey = selected && selected.key;
35238         var selectedSequenceKey = this.getSequenceKeyForImage(selected);
35239         var selectedLineString = selectedSequenceKey && _mlyCache.sequences.lineString[selectedSequenceKey];
35240         var selectedImageKeys = (selectedLineString && selectedLineString.properties.coordinateProperties.image_keys) || [];
35241
35242         // highlight sibling viewfields on either the selected or the hovered sequences
35243         var highlightedImageKeys = union(hoveredImageKeys, selectedImageKeys);
35244
35245         d3_selectAll('.layer-mapillary-images .viewfield-group')
35246             .classed('highlighted', function(d) { return highlightedImageKeys.indexOf(d.key) !== -1; })
35247             .classed('hovered', function(d) { return d.key === hoveredImageKey; })
35248             .classed('selected', function(d) { return d.key === selectedImageKey; });
35249
35250         d3_selectAll('.layer-mapillary-images .sequence')
35251             .classed('highlighted', function(d) { return d.properties.key === hoveredSequenceKey; })
35252             .classed('selected', function(d) { return d.properties.key === selectedSequenceKey; });
35253
35254         return this;
35255     },
35256
35257
35258     updateDetections: function(d) {
35259         if (!_mlyViewer || _mlyFallback) return;
35260
35261         var imageKey = d && d.key;
35262         var detections = (imageKey && _mlyCache.detections[imageKey]) || [];
35263
35264         forEach(detections, function(data, k) {
35265             if (isEmpty(data)) {
35266                 loadDetection(k);
35267             } else {
35268                 var tag = makeTag(data);
35269                 if (tag) {
35270                     var tagComponent = _mlyViewer.getComponent('tag');
35271                     tagComponent.add([tag]);
35272                 }
35273             }
35274         });
35275
35276
35277         function loadDetection(detectionKey) {
35278             var url = apibase + 'detections/'+
35279                 detectionKey + '?' + utilQsString({
35280                     client_id: clientId,
35281                 });
35282
35283             d3_request(url)
35284                 .mimeType('application/json')
35285                 .response(function(xhr) {
35286                     return JSON.parse(xhr.responseText);
35287                 })
35288                 .get(function(err, data) {
35289                     if (!data || !data.properties) return;
35290
35291                     var imageKey = data.properties.image_key;
35292                     _mlyCache.detections[imageKey][detectionKey] = data;
35293
35294                     var selectedKey = _mlySelectedImage && _mlySelectedImage.key;
35295                     if (imageKey === selectedKey) {
35296                         var tag = makeTag(data);
35297                         if (tag) {
35298                             var tagComponent = _mlyViewer.getComponent('tag');
35299                             tagComponent.add([tag]);
35300                         }
35301                     }
35302                 });
35303         }
35304
35305
35306         function makeTag(data) {
35307             var valueParts = data.properties.value.split('--');
35308             if (valueParts.length !== 3) return;
35309
35310             var text = valueParts[1].replace(/-/g, ' ');
35311             var tag;
35312
35313             // Currently only two shapes <Polygon|Point>
35314             if (data.properties.shape.type === 'Polygon') {
35315                 var polygonGeometry = new Mapillary
35316                     .TagComponent
35317                     .PolygonGeometry(data.properties.shape.coordinates[0]);
35318
35319                 tag = new Mapillary.TagComponent.OutlineTag(
35320                     data.properties.key,
35321                     polygonGeometry,
35322                     {
35323                         text: text,
35324                         textColor: 0xffff00,
35325                         lineColor: 0xffff00,
35326                         lineWidth: 2,
35327                         fillColor: 0xffff00,
35328                         fillOpacity: 0.3,
35329                     }
35330                 );
35331
35332             } else if (data.properties.shape.type === 'Point') {
35333                 var pointGeometry = new Mapillary
35334                     .TagComponent
35335                     .PointGeometry(data.properties.shape.coordinates[0]);
35336
35337                 tag = new Mapillary.TagComponent.SpotTag(
35338                     data.properties.key,
35339                     pointGeometry,
35340                     {
35341                         text: text,
35342                         color: 0xffff00,
35343                         textColor: 0xffff00
35344                     }
35345                 );
35346             }
35347
35348             return tag;
35349         }
35350     },
35351
35352
35353     cache: function() {
35354         return _mlyCache;
35355     },
35356
35357
35358     signDefs: function(_) {
35359         if (!arguments.length) return _mlySignDefs;
35360         _mlySignDefs = _;
35361         return this;
35362     }
35363
35364 };
35365
35366 var apibase$1 = 'https://nominatim.openstreetmap.org/';
35367 var inflight = {};
35368 var nominatimCache;
35369
35370
35371 var serviceNominatim = {
35372
35373     init: function() {
35374         inflight = {};
35375         nominatimCache = rbush_1();
35376     },
35377
35378     reset: function() {
35379         forEach(inflight, function(req) { req.abort(); });
35380         inflight = {};
35381         nominatimCache = rbush_1();
35382     },
35383
35384
35385     countryCode: function (location, callback) {
35386         this.reverse(location, function(err, result) {
35387             if (err) {
35388                 return callback(err);
35389             } else if (result.address) {
35390                 return callback(null, result.address.country_code);
35391             } else {
35392                 return callback('Unable to geocode', null);
35393             }
35394         });
35395     },
35396
35397
35398     reverse: function (location, callback) {
35399         var cached = nominatimCache.search(
35400             { minX: location[0], minY: location[1], maxX: location[0], maxY: location[1] }
35401         );
35402
35403         if (cached.length > 0) {
35404             return callback(null, cached[0].data);
35405         }
35406
35407         var params = { zoom: 13, format: 'json', addressdetails: 1, lat: location[1], lon: location[0] };
35408         var url = apibase$1 + 'reverse?' + utilQsString(params);
35409         if (inflight[url]) return;
35410
35411         inflight[url] = d3_json(url, function(err, result) {
35412             delete inflight[url];
35413
35414             if (err) {
35415                 return callback(err);
35416             } else if (result && result.error) {
35417                 return callback(result.error);
35418             }
35419
35420             var extent = geoExtent(location).padByMeters(200);
35421             nominatimCache.insert(assign(extent.bbox(), {data: result}));
35422
35423             callback(null, result);
35424         });
35425     },
35426
35427
35428     search: function (val, callback) {
35429         var searchVal = encodeURIComponent(val);
35430         var url = apibase$1 + 'search/' + searchVal + '?limit=10&format=json';
35431         if (inflight[url]) return;
35432
35433         inflight[url] = d3_json(url, function(err, result) {
35434             delete inflight[url];
35435             callback(err, result);
35436         });
35437     }
35438
35439 };
35440
35441 var apibase$2 = 'https://openstreetcam.org';
35442 var maxResults$1 = 1000;
35443 var tileZoom$1 = 14;
35444 var dispatch$2 = dispatch('loadedImages');
35445 var imgZoom = d3_zoom()
35446         .extent([[0, 0], [320, 240]])
35447         .translateExtent([[0, 0], [320, 240]])
35448         .scaleExtent([1, 15])
35449         .on('zoom', zoomPan);
35450 var _oscCache;
35451 var _oscSelectedImage;
35452
35453
35454 function abortRequest$1(i) {
35455     i.abort();
35456 }
35457
35458
35459 function nearNullIsland$1(x, y, z) {
35460     if (z >= 7) {
35461         var center = Math.pow(2, z - 1),
35462             width = Math.pow(2, z - 6),
35463             min = center - (width / 2),
35464             max = center + (width / 2) - 1;
35465         return x >= min && x <= max && y >= min && y <= max;
35466     }
35467     return false;
35468 }
35469
35470
35471 function maxPageAtZoom$1(z) {
35472     if (z < 15)   return 2;
35473     if (z === 15) return 5;
35474     if (z === 16) return 10;
35475     if (z === 17) return 20;
35476     if (z === 18) return 40;
35477     if (z > 18)   return 80;
35478 }
35479
35480
35481 function getTiles$1(projection) {
35482     var s = projection.scale() * 2 * Math.PI,
35483         z = Math.max(Math.log(s) / Math.log(2) - 8, 0),
35484         ts = 256 * Math.pow(2, z - tileZoom$1),
35485         origin = [
35486             s / 2 - projection.translate()[0],
35487             s / 2 - projection.translate()[1]];
35488
35489     return d3geoTile()
35490         .scaleExtent([tileZoom$1, tileZoom$1])
35491         .scale(s)
35492         .size(projection.clipExtent()[1])
35493         .translate(projection.translate())()
35494         .map(function(tile) {
35495             var x = tile[0] * ts - origin[0],
35496                 y = tile[1] * ts - origin[1];
35497
35498             return {
35499                 id: tile.toString(),
35500                 xyz: tile,
35501                 extent: geoExtent(
35502                     projection.invert([x, y + ts]),
35503                     projection.invert([x + ts, y])
35504                 )
35505             };
35506         });
35507 }
35508
35509
35510 function loadTiles$1(which, url, projection) {
35511     var s = projection.scale() * 2 * Math.PI,
35512         currZoom = Math.floor(Math.max(Math.log(s) / Math.log(2) - 8, 0));
35513
35514     var tiles = getTiles$1(projection).filter(function(t) {
35515             return !nearNullIsland$1(t.xyz[0], t.xyz[1], t.xyz[2]);
35516         });
35517
35518     filter(which.inflight, function(v, k) {
35519         var wanted = find$1(tiles, function(tile) { return k === (tile.id + ',0'); });
35520         if (!wanted) delete which.inflight[k];
35521         return !wanted;
35522     }).map(abortRequest$1);
35523
35524     tiles.forEach(function(tile) {
35525         loadNextTilePage$1(which, currZoom, url, tile);
35526     });
35527 }
35528
35529
35530 function loadNextTilePage$1(which, currZoom, url, tile) {
35531     var cache = _oscCache[which];
35532     var bbox = tile.extent.bbox();
35533     var maxPages = maxPageAtZoom$1(currZoom);
35534     var nextPage = cache.nextPage[tile.id] || 1;
35535     var params = utilQsString({
35536             ipp: maxResults$1,
35537             page: nextPage,
35538             // client_id: clientId,
35539             bbTopLeft: [bbox.maxY, bbox.minX].join(','),
35540             bbBottomRight: [bbox.minY, bbox.maxX].join(',')
35541         }, true);
35542
35543     if (nextPage > maxPages) return;
35544
35545     var id = tile.id + ',' + String(nextPage);
35546     if (cache.loaded[id] || cache.inflight[id]) return;
35547
35548     cache.inflight[id] = d3_request(url)
35549         .mimeType('application/json')
35550         .header('Content-type', 'application/x-www-form-urlencoded')
35551         .response(function(xhr) { return JSON.parse(xhr.responseText); })
35552         .post(params, function(err, data) {
35553             cache.loaded[id] = true;
35554             delete cache.inflight[id];
35555             if (err || !data.currentPageItems || !data.currentPageItems.length) return;
35556
35557             function localeDateString(s) {
35558                 if (!s) return null;
35559                 var detected = utilDetect();
35560                 var options = { day: 'numeric', month: 'short', year: 'numeric' };
35561                 var d = new Date(s);
35562                 if (isNaN(d.getTime())) return null;
35563                 return d.toLocaleDateString(detected.locale, options);
35564             }
35565
35566             var features = data.currentPageItems.map(function(item) {
35567                 var loc = [+item.lng, +item.lat],
35568                     d;
35569
35570                 if (which === 'images') {
35571                     d = {
35572                         loc: loc,
35573                         key: item.id,
35574                         ca: +item.heading,
35575                         captured_at: localeDateString(item.shot_date || item.date_added),
35576                         captured_by: item.username,
35577                         imagePath: item.lth_name,
35578                         sequence_id: item.sequence_id,
35579                         sequence_index: +item.sequence_index
35580                     };
35581
35582                     // cache sequence info
35583                     var seq = _oscCache.sequences[d.sequence_id];
35584                     if (!seq) {
35585                         seq = { rotation: 0, images: [] };
35586                         _oscCache.sequences[d.sequence_id] = seq;
35587                     }
35588                     seq.images[d.sequence_index] = d;
35589                 }
35590
35591                 return {
35592                     minX: loc[0], minY: loc[1], maxX: loc[0], maxY: loc[1], data: d
35593                 };
35594             });
35595
35596             cache.rtree.load(features);
35597
35598             if (which === 'images') {
35599                 dispatch$2.call('loadedImages');
35600             }
35601
35602             if (data.currentPageItems.length === maxResults$1) {  // more pages to load
35603                 cache.nextPage[tile.id] = nextPage + 1;
35604                 loadNextTilePage$1(which, currZoom, url, tile);
35605             } else {
35606                 cache.nextPage[tile.id] = Infinity;     // no more pages to load
35607             }
35608         });
35609 }
35610
35611
35612 // partition viewport into `psize` x `psize` regions
35613 function partitionViewport$1(psize, projection) {
35614     var dimensions = projection.clipExtent()[1];
35615     psize = psize || 16;
35616     var cols = d3_range(0, dimensions[0], psize),
35617         rows = d3_range(0, dimensions[1], psize),
35618         partitions = [];
35619
35620     rows.forEach(function(y) {
35621         cols.forEach(function(x) {
35622             var min = [x, y + psize],
35623                 max = [x + psize, y];
35624             partitions.push(
35625                 geoExtent(projection.invert(min), projection.invert(max)));
35626         });
35627     });
35628
35629     return partitions;
35630 }
35631
35632
35633 // no more than `limit` results per partition.
35634 function searchLimited$1(psize, limit, projection, rtree) {
35635     limit = limit || 3;
35636
35637     var partitions = partitionViewport$1(psize, projection);
35638     var results;
35639
35640     results = flatten(map$4(partitions, function(extent) {
35641         return rtree.search(extent.bbox())
35642             .slice(0, limit)
35643             .map(function(d) { return d.data; });
35644     }));
35645     return results;
35646 }
35647
35648
35649 function zoomPan() {
35650     var t = event.transform;
35651     d3_select('#photoviewer .osc-image-wrap')
35652         .call(utilSetTransform, t.x, t.y, t.k);
35653 }
35654
35655
35656 var serviceOpenstreetcam = {
35657
35658     init: function() {
35659         if (!_oscCache) {
35660             this.reset();
35661         }
35662
35663         this.event = utilRebind(this, dispatch$2, 'on');
35664     },
35665
35666     reset: function() {
35667         var cache = _oscCache;
35668
35669         if (cache) {
35670             if (cache.images && cache.images.inflight) {
35671                 forEach(cache.images.inflight, abortRequest$1);
35672             }
35673         }
35674
35675         _oscCache = {
35676             images: { inflight: {}, loaded: {}, nextPage: {}, rtree: rbush_1() },
35677             sequences: {}
35678         };
35679
35680         _oscSelectedImage = null;
35681     },
35682
35683
35684     images: function(projection) {
35685         var psize = 16, limit = 3;
35686         return searchLimited$1(psize, limit, projection, _oscCache.images.rtree);
35687     },
35688
35689
35690     sequences: function(projection) {
35691         var viewport = projection.clipExtent();
35692         var min = [viewport[0][0], viewport[1][1]];
35693         var max = [viewport[1][0], viewport[0][1]];
35694         var bbox = geoExtent(projection.invert(min), projection.invert(max)).bbox();
35695         var sequenceKeys = {};
35696
35697         // all sequences for images in viewport
35698         _oscCache.images.rtree.search(bbox)
35699             .forEach(function(d) { sequenceKeys[d.data.sequence_id] = true; });
35700
35701         // make linestrings from those sequences
35702         var lineStrings = [];
35703         Object.keys(sequenceKeys)
35704             .forEach(function(sequenceKey) {
35705                 var seq = _oscCache.sequences[sequenceKey];
35706                 var images = seq && seq.images;
35707                 if (images) {
35708                     lineStrings.push({
35709                         type: 'LineString',
35710                         coordinates: images.map(function (d) { return d.loc; }).filter(Boolean),
35711                         properties: { key: sequenceKey }
35712                     });
35713                 }
35714             });
35715         return lineStrings;
35716     },
35717
35718
35719     loadImages: function(projection) {
35720         var url = apibase$2 + '/1.0/list/nearby-photos/';
35721         loadTiles$1('images', url, projection);
35722     },
35723
35724
35725     loadViewer: function(context) {
35726         var that = this;
35727
35728         // add osc-wrapper
35729         var wrap = d3_select('#photoviewer').selectAll('.osc-wrapper')
35730             .data([0]);
35731
35732         var wrapEnter = wrap.enter()
35733             .append('div')
35734             .attr('class', 'photo-wrapper osc-wrapper')
35735             .classed('hide', true)
35736             .call(imgZoom)
35737             .on('dblclick.zoom', null);
35738
35739         wrapEnter
35740             .append('div')
35741             .attr('class', 'photo-attribution fillD');
35742
35743         var controlsEnter = wrapEnter
35744             .append('div')
35745             .attr('class', 'osc-controls-wrap')
35746             .append('div')
35747             .attr('class', 'osc-controls');
35748
35749         controlsEnter
35750             .append('button')
35751             .on('click.back', step(-1))
35752             .text('◄');
35753
35754         controlsEnter
35755             .append('button')
35756             .on('click.rotate-ccw', rotate(-90))
35757             .text('⤿');
35758
35759         controlsEnter
35760             .append('button')
35761             .on('click.rotate-cw', rotate(90))
35762             .text('⤾');
35763
35764         controlsEnter
35765             .append('button')
35766             .on('click.forward', step(1))
35767             .text('►');
35768
35769         wrapEnter
35770             .append('div')
35771             .attr('class', 'osc-image-wrap');
35772
35773
35774         function rotate(deg) {
35775             return function() {
35776                 if (!_oscSelectedImage) return;
35777                 var sequenceKey = _oscSelectedImage.sequence_id;
35778                 var sequence = _oscCache.sequences[sequenceKey];
35779                 if (!sequence) return;
35780
35781                 var r = sequence.rotation || 0;
35782                 r += deg;
35783
35784                 if (r > 180) r -= 360;
35785                 if (r < -180) r += 360;
35786                 sequence.rotation = r;
35787
35788                 var wrap = d3_select('#photoviewer .osc-wrapper');
35789
35790                 wrap
35791                     .transition()
35792                     .duration(100)
35793                     .call(imgZoom.transform, identity$7);
35794
35795                 wrap.selectAll('.osc-image')
35796                     .transition()
35797                     .duration(100)
35798                     .style('transform', 'rotate(' + r + 'deg)');
35799             };
35800         }
35801
35802         function step(stepBy) {
35803             return function() {
35804                 if (!_oscSelectedImage) return;
35805                 var sequenceKey = _oscSelectedImage.sequence_id;
35806                 var sequence = _oscCache.sequences[sequenceKey];
35807                 if (!sequence) return;
35808
35809                 var nextIndex = _oscSelectedImage.sequence_index + stepBy;
35810                 var nextImage = sequence.images[nextIndex];
35811                 if (!nextImage) return;
35812
35813                 context.map().centerEase(nextImage.loc);
35814
35815                 that
35816                     .selectImage(nextImage)
35817                     .updateViewer(nextImage);
35818             };
35819         }
35820     },
35821
35822
35823     showViewer: function() {
35824         var viewer = d3_select('#photoviewer')
35825             .classed('hide', false);
35826
35827         var isHidden = viewer.selectAll('.photo-wrapper.osc-wrapper.hide').size();
35828
35829         if (isHidden) {
35830             viewer
35831                 .selectAll('.photo-wrapper:not(.osc-wrapper)')
35832                 .classed('hide', true);
35833
35834             viewer
35835                 .selectAll('.photo-wrapper.osc-wrapper')
35836                 .classed('hide', false);
35837         }
35838
35839         return this;
35840     },
35841
35842
35843     hideViewer: function() {
35844         _oscSelectedImage = null;
35845
35846         var viewer = d3_select('#photoviewer');
35847         if (!viewer.empty()) viewer.datum(null);
35848
35849         viewer
35850             .classed('hide', true)
35851             .selectAll('.photo-wrapper')
35852             .classed('hide', true);
35853
35854         d3_selectAll('.viewfield-group, .sequence, .icon-sign')
35855             .classed('selected', false);
35856
35857         return this.setStyles(null, true);
35858     },
35859
35860
35861     updateViewer: function(d) {
35862         var wrap = d3_select('#photoviewer .osc-wrapper');
35863         var imageWrap = wrap.selectAll('.osc-image-wrap');
35864         var attribution = wrap.selectAll('.photo-attribution').html('');
35865
35866         wrap
35867             .transition()
35868             .duration(100)
35869             .call(imgZoom.transform, identity$7);
35870
35871         imageWrap
35872             .selectAll('.osc-image')
35873             .remove();
35874
35875         if (d) {
35876             var sequence = _oscCache.sequences[d.sequence_id];
35877             var r = (sequence && sequence.rotation) || 0;
35878
35879             imageWrap
35880                 .append('img')
35881                 .attr('class', 'osc-image')
35882                 .attr('src', apibase$2 + '/' + d.imagePath)
35883                 .style('transform', 'rotate(' + r + 'deg)');
35884
35885             if (d.captured_by) {
35886                 attribution
35887                     .append('a')
35888                     .attr('class', 'captured_by')
35889                     .attr('target', '_blank')
35890                     .attr('href', 'https://openstreetcam.org/user/' + encodeURIComponent(d.captured_by))
35891                     .text('@' + d.captured_by);
35892
35893                 attribution
35894                     .append('span')
35895                     .text('|');
35896             }
35897
35898             if (d.captured_at) {
35899                 attribution
35900                     .append('span')
35901                     .attr('class', 'captured_at')
35902                     .text(d.captured_at);
35903
35904                 attribution
35905                     .append('span')
35906                     .text('|');
35907             }
35908
35909             attribution
35910                 .append('a')
35911                 .attr('class', 'image_link')
35912                 .attr('target', '_blank')
35913                 .attr('href', 'https://openstreetcam.org/details/' + d.sequence_id + '/' + d.sequence_index)
35914                 .text('openstreetcam.org');
35915         }
35916         return this;
35917     },
35918
35919
35920     selectImage: function(d) {
35921         _oscSelectedImage = d;
35922         var viewer = d3_select('#photoviewer');
35923         if (!viewer.empty()) viewer.datum(d);
35924
35925         this.setStyles(null, true);
35926
35927         d3_selectAll('.icon-sign')
35928             .classed('selected', false);
35929
35930         return this;
35931     },
35932
35933
35934     getSelectedImage: function() {
35935         return _oscSelectedImage;
35936     },
35937
35938
35939     getSequenceKeyForImage: function(d) {
35940         return d && d.sequence_id;
35941     },
35942
35943
35944     setStyles: function(hovered, reset) {
35945         if (reset) {  // reset all layers
35946             d3_selectAll('.viewfield-group')
35947                 .classed('highlighted', false)
35948                 .classed('hovered', false)
35949                 .classed('selected', false);
35950
35951             d3_selectAll('.sequence')
35952                 .classed('highlighted', false)
35953                 .classed('selected', false);
35954         }
35955
35956         var hoveredImageKey = hovered && hovered.key;
35957         var hoveredSequenceKey = this.getSequenceKeyForImage(hovered);
35958         var hoveredSequence = hoveredSequenceKey && _oscCache.sequences[hoveredSequenceKey];
35959         var hoveredImageKeys = (hoveredSequence && hoveredSequence.images.map(function (d) { return d.key; })) || [];
35960
35961         var viewer = d3_select('#photoviewer');
35962         var selected = viewer.empty() ? undefined : viewer.datum();
35963         var selectedImageKey = selected && selected.key;
35964         var selectedSequenceKey = this.getSequenceKeyForImage(selected);
35965         var selectedSequence = selectedSequenceKey && _oscCache.sequences[selectedSequenceKey];
35966         var selectedImageKeys = (selectedSequence && selectedSequence.images.map(function (d) { return d.key; })) || [];
35967
35968         // highlight sibling viewfields on either the selected or the hovered sequences
35969         var highlightedImageKeys = union(hoveredImageKeys, selectedImageKeys);
35970
35971         d3_selectAll('.layer-openstreetcam-images .viewfield-group')
35972             .classed('highlighted', function(d) { return highlightedImageKeys.indexOf(d.key) !== -1; })
35973             .classed('hovered', function(d) { return d.key === hoveredImageKey; })
35974             .classed('selected', function(d) { return d.key === selectedImageKey; });
35975
35976         d3_selectAll('.layer-openstreetcam-images .sequence')
35977             .classed('highlighted', function(d) { return d.properties.key === hoveredSequenceKey; })
35978             .classed('selected', function(d) { return d.properties.key === selectedSequenceKey; });
35979
35980         return this;
35981     },
35982
35983
35984     cache: function() {
35985         return _oscCache;
35986     }
35987
35988 };
35989
35990 /* Built-in method references for those with the same name as other `lodash` methods. */
35991 var nativeCeil = Math.ceil;
35992 var nativeMax$4 = Math.max;
35993
35994 /**
35995  * Creates an array of elements split into groups the length of `size`.
35996  * If `array` can't be split evenly, the final chunk will be the remaining
35997  * elements.
35998  *
35999  * @static
36000  * @memberOf _
36001  * @since 3.0.0
36002  * @category Array
36003  * @param {Array} array The array to process.
36004  * @param {number} [size=1] The length of each chunk
36005  * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
36006  * @returns {Array} Returns the new array of chunks.
36007  * @example
36008  *
36009  * _.chunk(['a', 'b', 'c', 'd'], 2);
36010  * // => [['a', 'b'], ['c', 'd']]
36011  *
36012  * _.chunk(['a', 'b', 'c', 'd'], 3);
36013  * // => [['a', 'b', 'c'], ['d']]
36014  */
36015 function chunk(array, size, guard) {
36016   if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
36017     size = 1;
36018   } else {
36019     size = nativeMax$4(toInteger(size), 0);
36020   }
36021   var length = array == null ? 0 : array.length;
36022   if (!length || size < 1) {
36023     return [];
36024   }
36025   var index = 0,
36026       resIndex = 0,
36027       result = Array(nativeCeil(length / size));
36028
36029   while (index < length) {
36030     result[resIndex++] = baseSlice(array, index, (index += size));
36031   }
36032   return result;
36033 }
36034
36035 var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
36036
36037
36038
36039
36040
36041 function createCommonjsModule(fn, module) {
36042         return module = { exports: {} }, fn(module, module.exports), module.exports;
36043 }
36044
36045 var hashes = createCommonjsModule(function (module, exports) {
36046 /**
36047  * jshashes - https://github.com/h2non/jshashes
36048  * Released under the "New BSD" license
36049  *
36050  * Algorithms specification:
36051  *
36052  * MD5 - http://www.ietf.org/rfc/rfc1321.txt
36053  * RIPEMD-160 - http://homes.esat.kuleuven.be/~bosselae/ripemd160.html
36054  * SHA1   - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
36055  * SHA256 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
36056  * SHA512 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
36057  * HMAC - http://www.ietf.org/rfc/rfc2104.txt
36058  */
36059 (function() {
36060   var Hashes;
36061
36062   function utf8Encode(str) {
36063     var x, y, output = '',
36064       i = -1,
36065       l;
36066
36067     if (str && str.length) {
36068       l = str.length;
36069       while ((i += 1) < l) {
36070         /* Decode utf-16 surrogate pairs */
36071         x = str.charCodeAt(i);
36072         y = i + 1 < l ? str.charCodeAt(i + 1) : 0;
36073         if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) {
36074           x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
36075           i += 1;
36076         }
36077         /* Encode output as utf-8 */
36078         if (x <= 0x7F) {
36079           output += String.fromCharCode(x);
36080         } else if (x <= 0x7FF) {
36081           output += String.fromCharCode(0xC0 | ((x >>> 6) & 0x1F),
36082             0x80 | (x & 0x3F));
36083         } else if (x <= 0xFFFF) {
36084           output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
36085             0x80 | ((x >>> 6) & 0x3F),
36086             0x80 | (x & 0x3F));
36087         } else if (x <= 0x1FFFFF) {
36088           output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
36089             0x80 | ((x >>> 12) & 0x3F),
36090             0x80 | ((x >>> 6) & 0x3F),
36091             0x80 | (x & 0x3F));
36092         }
36093       }
36094     }
36095     return output;
36096   }
36097
36098   function utf8Decode(str) {
36099     var i, ac, c1, c2, c3, arr = [],
36100       l;
36101     i = ac = c1 = c2 = c3 = 0;
36102
36103     if (str && str.length) {
36104       l = str.length;
36105       str += '';
36106
36107       while (i < l) {
36108         c1 = str.charCodeAt(i);
36109         ac += 1;
36110         if (c1 < 128) {
36111           arr[ac] = String.fromCharCode(c1);
36112           i += 1;
36113         } else if (c1 > 191 && c1 < 224) {
36114           c2 = str.charCodeAt(i + 1);
36115           arr[ac] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
36116           i += 2;
36117         } else {
36118           c2 = str.charCodeAt(i + 1);
36119           c3 = str.charCodeAt(i + 2);
36120           arr[ac] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
36121           i += 3;
36122         }
36123       }
36124     }
36125     return arr.join('');
36126   }
36127
36128   /**
36129    * Add integers, wrapping at 2^32. This uses 16-bit operations internally
36130    * to work around bugs in some JS interpreters.
36131    */
36132
36133   function safe_add(x, y) {
36134     var lsw = (x & 0xFFFF) + (y & 0xFFFF),
36135       msw = (x >> 16) + (y >> 16) + (lsw >> 16);
36136     return (msw << 16) | (lsw & 0xFFFF);
36137   }
36138
36139   /**
36140    * Bitwise rotate a 32-bit number to the left.
36141    */
36142
36143   function bit_rol(num, cnt) {
36144     return (num << cnt) | (num >>> (32 - cnt));
36145   }
36146
36147   /**
36148    * Convert a raw string to a hex string
36149    */
36150
36151   function rstr2hex(input, hexcase) {
36152     var hex_tab = hexcase ? '0123456789ABCDEF' : '0123456789abcdef',
36153       output = '',
36154       x, i = 0,
36155       l = input.length;
36156     for (; i < l; i += 1) {
36157       x = input.charCodeAt(i);
36158       output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt(x & 0x0F);
36159     }
36160     return output;
36161   }
36162
36163   /**
36164    * Encode a string as utf-16
36165    */
36166
36167   function binb2rstr(input) {
36168     var i, l = input.length * 32,
36169       output = '';
36170     for (i = 0; i < l; i += 8) {
36171       output += String.fromCharCode((input[i >> 5] >>> (24 - i % 32)) & 0xFF);
36172     }
36173     return output;
36174   }
36175
36176   /**
36177    * Convert an array of little-endian words to a string
36178    */
36179
36180   function binl2rstr(input) {
36181     var i, l = input.length * 32,
36182       output = '';
36183     for (i = 0; i < l; i += 8) {
36184       output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
36185     }
36186     return output;
36187   }
36188
36189   /**
36190    * Convert a raw string to an array of little-endian words
36191    * Characters >255 have their high-byte silently ignored.
36192    */
36193
36194   function rstr2binl(input) {
36195     var i, l = input.length * 8,
36196       output = Array(input.length >> 2),
36197       lo = output.length;
36198     for (i = 0; i < lo; i += 1) {
36199       output[i] = 0;
36200     }
36201     for (i = 0; i < l; i += 8) {
36202       output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32);
36203     }
36204     return output;
36205   }
36206
36207   /**
36208    * Convert a raw string to an array of big-endian words
36209    * Characters >255 have their high-byte silently ignored.
36210    */
36211
36212   function rstr2binb(input) {
36213     var i, l = input.length * 8,
36214       output = Array(input.length >> 2),
36215       lo = output.length;
36216     for (i = 0; i < lo; i += 1) {
36217       output[i] = 0;
36218     }
36219     for (i = 0; i < l; i += 8) {
36220       output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
36221     }
36222     return output;
36223   }
36224
36225   /**
36226    * Convert a raw string to an arbitrary string encoding
36227    */
36228
36229   function rstr2any(input, encoding) {
36230     var divisor = encoding.length,
36231       remainders = Array(),
36232       i, q, x, ld, quotient, dividend, output, full_length;
36233
36234     /* Convert to an array of 16-bit big-endian values, forming the dividend */
36235     dividend = Array(Math.ceil(input.length / 2));
36236     ld = dividend.length;
36237     for (i = 0; i < ld; i += 1) {
36238       dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
36239     }
36240
36241     /**
36242      * Repeatedly perform a long division. The binary array forms the dividend,
36243      * the length of the encoding is the divisor. Once computed, the quotient
36244      * forms the dividend for the next step. We stop when the dividend is zerHashes.
36245      * All remainders are stored for later use.
36246      */
36247     while (dividend.length > 0) {
36248       quotient = Array();
36249       x = 0;
36250       for (i = 0; i < dividend.length; i += 1) {
36251         x = (x << 16) + dividend[i];
36252         q = Math.floor(x / divisor);
36253         x -= q * divisor;
36254         if (quotient.length > 0 || q > 0) {
36255           quotient[quotient.length] = q;
36256         }
36257       }
36258       remainders[remainders.length] = x;
36259       dividend = quotient;
36260     }
36261
36262     /* Convert the remainders to the output string */
36263     output = '';
36264     for (i = remainders.length - 1; i >= 0; i--) {
36265       output += encoding.charAt(remainders[i]);
36266     }
36267
36268     /* Append leading zero equivalents */
36269     full_length = Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2)));
36270     for (i = output.length; i < full_length; i += 1) {
36271       output = encoding[0] + output;
36272     }
36273     return output;
36274   }
36275
36276   /**
36277    * Convert a raw string to a base-64 string
36278    */
36279
36280   function rstr2b64(input, b64pad) {
36281     var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
36282       output = '',
36283       len = input.length,
36284       i, j, triplet;
36285     b64pad = b64pad || '=';
36286     for (i = 0; i < len; i += 3) {
36287       triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0);
36288       for (j = 0; j < 4; j += 1) {
36289         if (i * 8 + j * 6 > input.length * 8) {
36290           output += b64pad;
36291         } else {
36292           output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F);
36293         }
36294       }
36295     }
36296     return output;
36297   }
36298
36299   Hashes = {
36300     /**
36301      * @property {String} version
36302      * @readonly
36303      */
36304     VERSION: '1.0.6',
36305     /**
36306      * @member Hashes
36307      * @class Base64
36308      * @constructor
36309      */
36310     Base64: function() {
36311       // private properties
36312       var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
36313         pad = '=', // default pad according with the RFC standard
36314         url = false, // URL encoding support @todo
36315         utf8 = true; // by default enable UTF-8 support encoding
36316
36317       // public method for encoding
36318       this.encode = function(input) {
36319         var i, j, triplet,
36320           output = '',
36321           len = input.length;
36322
36323         pad = pad || '=';
36324         input = (utf8) ? utf8Encode(input) : input;
36325
36326         for (i = 0; i < len; i += 3) {
36327           triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0);
36328           for (j = 0; j < 4; j += 1) {
36329             if (i * 8 + j * 6 > len * 8) {
36330               output += pad;
36331             } else {
36332               output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F);
36333             }
36334           }
36335         }
36336         return output;
36337       };
36338
36339       // public method for decoding
36340       this.decode = function(input) {
36341         // var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
36342         var i, o1, o2, o3, h1, h2, h3, h4, bits, ac,
36343           dec = '',
36344           arr = [];
36345         if (!input) {
36346           return input;
36347         }
36348
36349         i = ac = 0;
36350         input = input.replace(new RegExp('\\' + pad, 'gi'), ''); // use '='
36351         //input += '';
36352
36353         do { // unpack four hexets into three octets using index points in b64
36354           h1 = tab.indexOf(input.charAt(i += 1));
36355           h2 = tab.indexOf(input.charAt(i += 1));
36356           h3 = tab.indexOf(input.charAt(i += 1));
36357           h4 = tab.indexOf(input.charAt(i += 1));
36358
36359           bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
36360
36361           o1 = bits >> 16 & 0xff;
36362           o2 = bits >> 8 & 0xff;
36363           o3 = bits & 0xff;
36364           ac += 1;
36365
36366           if (h3 === 64) {
36367             arr[ac] = String.fromCharCode(o1);
36368           } else if (h4 === 64) {
36369             arr[ac] = String.fromCharCode(o1, o2);
36370           } else {
36371             arr[ac] = String.fromCharCode(o1, o2, o3);
36372           }
36373         } while (i < input.length);
36374
36375         dec = arr.join('');
36376         dec = (utf8) ? utf8Decode(dec) : dec;
36377
36378         return dec;
36379       };
36380
36381       // set custom pad string
36382       this.setPad = function(str) {
36383         pad = str || pad;
36384         return this;
36385       };
36386       // set custom tab string characters
36387       this.setTab = function(str) {
36388         tab = str || tab;
36389         return this;
36390       };
36391       this.setUTF8 = function(bool) {
36392         if (typeof bool === 'boolean') {
36393           utf8 = bool;
36394         }
36395         return this;
36396       };
36397     },
36398
36399     /**
36400      * CRC-32 calculation
36401      * @member Hashes
36402      * @method CRC32
36403      * @static
36404      * @param {String} str Input String
36405      * @return {String}
36406      */
36407     CRC32: function(str) {
36408       var crc = 0,
36409         x = 0,
36410         y = 0,
36411         table, i, iTop;
36412       str = utf8Encode(str);
36413
36414       table = [
36415         '00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 ',
36416         '79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 ',
36417         '84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F ',
36418         '63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD ',
36419         'A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC ',
36420         '51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 ',
36421         'B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 ',
36422         '06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 ',
36423         'E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 ',
36424         '12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 ',
36425         'D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 ',
36426         '33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 ',
36427         'CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 ',
36428         '9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E ',
36429         '7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D ',
36430         '806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 ',
36431         '60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA ',
36432         'AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 ',
36433         '5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 ',
36434         'B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 ',
36435         '05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 ',
36436         'F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA ',
36437         '11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 ',
36438         'D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F ',
36439         '30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E ',
36440         'C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D'
36441       ].join('');
36442
36443       crc = crc ^ (-1);
36444       for (i = 0, iTop = str.length; i < iTop; i += 1) {
36445         y = (crc ^ str.charCodeAt(i)) & 0xFF;
36446         x = '0x' + table.substr(y * 9, 8);
36447         crc = (crc >>> 8) ^ x;
36448       }
36449       // always return a positive number (that's what >>> 0 does)
36450       return (crc ^ (-1)) >>> 0;
36451     },
36452     /**
36453      * @member Hashes
36454      * @class MD5
36455      * @constructor
36456      * @param {Object} [config]
36457      *
36458      * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
36459      * Digest Algorithm, as defined in RFC 1321.
36460      * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
36461      * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
36462      * See <http://pajhome.org.uk/crypt/md5> for more infHashes.
36463      */
36464     MD5: function(options) {
36465       /**
36466        * Private config properties. You may need to tweak these to be compatible with
36467        * the server-side, but the defaults work in most cases.
36468        * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase}
36469        */
36470       var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase
36471         b64pad = (options && typeof options.pad === 'string') ? options.pad : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance
36472         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding
36473
36474       // privileged (public) methods
36475       this.hex = function(s) {
36476         return rstr2hex(rstr(s, utf8), hexcase);
36477       };
36478       this.b64 = function(s) {
36479         return rstr2b64(rstr(s), b64pad);
36480       };
36481       this.any = function(s, e) {
36482         return rstr2any(rstr(s, utf8), e);
36483       };
36484       this.raw = function(s) {
36485         return rstr(s, utf8);
36486       };
36487       this.hex_hmac = function(k, d) {
36488         return rstr2hex(rstr_hmac(k, d), hexcase);
36489       };
36490       this.b64_hmac = function(k, d) {
36491         return rstr2b64(rstr_hmac(k, d), b64pad);
36492       };
36493       this.any_hmac = function(k, d, e) {
36494         return rstr2any(rstr_hmac(k, d), e);
36495       };
36496       /**
36497        * Perform a simple self-test to see if the VM is working
36498        * @return {String} Hexadecimal hash sample
36499        */
36500       this.vm_test = function() {
36501         return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
36502       };
36503       /**
36504        * Enable/disable uppercase hexadecimal returned string
36505        * @param {Boolean}
36506        * @return {Object} this
36507        */
36508       this.setUpperCase = function(a) {
36509         if (typeof a === 'boolean') {
36510           hexcase = a;
36511         }
36512         return this;
36513       };
36514       /**
36515        * Defines a base64 pad string
36516        * @param {String} Pad
36517        * @return {Object} this
36518        */
36519       this.setPad = function(a) {
36520         b64pad = a || b64pad;
36521         return this;
36522       };
36523       /**
36524        * Defines a base64 pad string
36525        * @param {Boolean}
36526        * @return {Object} [this]
36527        */
36528       this.setUTF8 = function(a) {
36529         if (typeof a === 'boolean') {
36530           utf8 = a;
36531         }
36532         return this;
36533       };
36534
36535       // private methods
36536
36537       /**
36538        * Calculate the MD5 of a raw string
36539        */
36540
36541       function rstr(s) {
36542         s = (utf8) ? utf8Encode(s) : s;
36543         return binl2rstr(binl(rstr2binl(s), s.length * 8));
36544       }
36545
36546       /**
36547        * Calculate the HMAC-MD5, of a key and some data (raw strings)
36548        */
36549
36550       function rstr_hmac(key, data) {
36551         var bkey, ipad, opad, hash, i;
36552
36553         key = (utf8) ? utf8Encode(key) : key;
36554         data = (utf8) ? utf8Encode(data) : data;
36555         bkey = rstr2binl(key);
36556         if (bkey.length > 16) {
36557           bkey = binl(bkey, key.length * 8);
36558         }
36559
36560         ipad = Array(16), opad = Array(16);
36561         for (i = 0; i < 16; i += 1) {
36562           ipad[i] = bkey[i] ^ 0x36363636;
36563           opad[i] = bkey[i] ^ 0x5C5C5C5C;
36564         }
36565         hash = binl(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
36566         return binl2rstr(binl(opad.concat(hash), 512 + 128));
36567       }
36568
36569       /**
36570        * Calculate the MD5 of an array of little-endian words, and a bit length.
36571        */
36572
36573       function binl(x, len) {
36574         var i, olda, oldb, oldc, oldd,
36575           a = 1732584193,
36576           b = -271733879,
36577           c = -1732584194,
36578           d = 271733878;
36579
36580         /* append padding */
36581         x[len >> 5] |= 0x80 << ((len) % 32);
36582         x[(((len + 64) >>> 9) << 4) + 14] = len;
36583
36584         for (i = 0; i < x.length; i += 16) {
36585           olda = a;
36586           oldb = b;
36587           oldc = c;
36588           oldd = d;
36589
36590           a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
36591           d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
36592           c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
36593           b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
36594           a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
36595           d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
36596           c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
36597           b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
36598           a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
36599           d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
36600           c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
36601           b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
36602           a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
36603           d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
36604           c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
36605           b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
36606
36607           a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
36608           d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
36609           c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
36610           b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302);
36611           a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
36612           d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
36613           c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
36614           b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
36615           a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
36616           d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
36617           c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
36618           b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
36619           a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
36620           d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
36621           c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
36622           b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
36623
36624           a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
36625           d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
36626           c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
36627           b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
36628           a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
36629           d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
36630           c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
36631           b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
36632           a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
36633           d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222);
36634           c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
36635           b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
36636           a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
36637           d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
36638           c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
36639           b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
36640
36641           a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844);
36642           d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
36643           c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
36644           b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
36645           a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
36646           d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
36647           c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
36648           b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
36649           a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
36650           d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
36651           c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
36652           b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
36653           a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
36654           d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
36655           c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
36656           b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
36657
36658           a = safe_add(a, olda);
36659           b = safe_add(b, oldb);
36660           c = safe_add(c, oldc);
36661           d = safe_add(d, oldd);
36662         }
36663         return Array(a, b, c, d);
36664       }
36665
36666       /**
36667        * These functions implement the four basic operations the algorithm uses.
36668        */
36669
36670       function md5_cmn(q, a, b, x, s, t) {
36671         return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
36672       }
36673
36674       function md5_ff(a, b, c, d, x, s, t) {
36675         return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
36676       }
36677
36678       function md5_gg(a, b, c, d, x, s, t) {
36679         return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
36680       }
36681
36682       function md5_hh(a, b, c, d, x, s, t) {
36683         return md5_cmn(b ^ c ^ d, a, b, x, s, t);
36684       }
36685
36686       function md5_ii(a, b, c, d, x, s, t) {
36687         return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
36688       }
36689     },
36690     /**
36691      * @member Hashes
36692      * @class Hashes.SHA1
36693      * @param {Object} [config]
36694      * @constructor
36695      *
36696      * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined in FIPS 180-1
36697      * Version 2.2 Copyright Paul Johnston 2000 - 2009.
36698      * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
36699      * See http://pajhome.org.uk/crypt/md5 for details.
36700      */
36701     SHA1: function(options) {
36702       /**
36703        * Private config properties. You may need to tweak these to be compatible with
36704        * the server-side, but the defaults work in most cases.
36705        * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase}
36706        */
36707       var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase
36708         b64pad = (options && typeof options.pad === 'string') ? options.pad : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance
36709         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding
36710
36711       // public methods
36712       this.hex = function(s) {
36713         return rstr2hex(rstr(s, utf8), hexcase);
36714       };
36715       this.b64 = function(s) {
36716         return rstr2b64(rstr(s, utf8), b64pad);
36717       };
36718       this.any = function(s, e) {
36719         return rstr2any(rstr(s, utf8), e);
36720       };
36721       this.raw = function(s) {
36722         return rstr(s, utf8);
36723       };
36724       this.hex_hmac = function(k, d) {
36725         return rstr2hex(rstr_hmac(k, d));
36726       };
36727       this.b64_hmac = function(k, d) {
36728         return rstr2b64(rstr_hmac(k, d), b64pad);
36729       };
36730       this.any_hmac = function(k, d, e) {
36731         return rstr2any(rstr_hmac(k, d), e);
36732       };
36733       /**
36734        * Perform a simple self-test to see if the VM is working
36735        * @return {String} Hexadecimal hash sample
36736        * @public
36737        */
36738       this.vm_test = function() {
36739         return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
36740       };
36741       /**
36742        * @description Enable/disable uppercase hexadecimal returned string
36743        * @param {boolean}
36744        * @return {Object} this
36745        * @public
36746        */
36747       this.setUpperCase = function(a) {
36748         if (typeof a === 'boolean') {
36749           hexcase = a;
36750         }
36751         return this;
36752       };
36753       /**
36754        * @description Defines a base64 pad string
36755        * @param {string} Pad
36756        * @return {Object} this
36757        * @public
36758        */
36759       this.setPad = function(a) {
36760         b64pad = a || b64pad;
36761         return this;
36762       };
36763       /**
36764        * @description Defines a base64 pad string
36765        * @param {boolean}
36766        * @return {Object} this
36767        * @public
36768        */
36769       this.setUTF8 = function(a) {
36770         if (typeof a === 'boolean') {
36771           utf8 = a;
36772         }
36773         return this;
36774       };
36775
36776       // private methods
36777
36778       /**
36779        * Calculate the SHA-512 of a raw string
36780        */
36781
36782       function rstr(s) {
36783         s = (utf8) ? utf8Encode(s) : s;
36784         return binb2rstr(binb(rstr2binb(s), s.length * 8));
36785       }
36786
36787       /**
36788        * Calculate the HMAC-SHA1 of a key and some data (raw strings)
36789        */
36790
36791       function rstr_hmac(key, data) {
36792         var bkey, ipad, opad, i, hash;
36793         key = (utf8) ? utf8Encode(key) : key;
36794         data = (utf8) ? utf8Encode(data) : data;
36795         bkey = rstr2binb(key);
36796
36797         if (bkey.length > 16) {
36798           bkey = binb(bkey, key.length * 8);
36799         }
36800         ipad = Array(16), opad = Array(16);
36801         for (i = 0; i < 16; i += 1) {
36802           ipad[i] = bkey[i] ^ 0x36363636;
36803           opad[i] = bkey[i] ^ 0x5C5C5C5C;
36804         }
36805         hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
36806         return binb2rstr(binb(opad.concat(hash), 512 + 160));
36807       }
36808
36809       /**
36810        * Calculate the SHA-1 of an array of big-endian words, and a bit length
36811        */
36812
36813       function binb(x, len) {
36814         var i, j, t, olda, oldb, oldc, oldd, olde,
36815           w = Array(80),
36816           a = 1732584193,
36817           b = -271733879,
36818           c = -1732584194,
36819           d = 271733878,
36820           e = -1009589776;
36821
36822         /* append padding */
36823         x[len >> 5] |= 0x80 << (24 - len % 32);
36824         x[((len + 64 >> 9) << 4) + 15] = len;
36825
36826         for (i = 0; i < x.length; i += 16) {
36827           olda = a;
36828           oldb = b;
36829           oldc = c;
36830           oldd = d;
36831           olde = e;
36832
36833           for (j = 0; j < 80; j += 1) {
36834             if (j < 16) {
36835               w[j] = x[i + j];
36836             } else {
36837               w[j] = bit_rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
36838             }
36839             t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
36840               safe_add(safe_add(e, w[j]), sha1_kt(j)));
36841             e = d;
36842             d = c;
36843             c = bit_rol(b, 30);
36844             b = a;
36845             a = t;
36846           }
36847
36848           a = safe_add(a, olda);
36849           b = safe_add(b, oldb);
36850           c = safe_add(c, oldc);
36851           d = safe_add(d, oldd);
36852           e = safe_add(e, olde);
36853         }
36854         return Array(a, b, c, d, e);
36855       }
36856
36857       /**
36858        * Perform the appropriate triplet combination function for the current
36859        * iteration
36860        */
36861
36862       function sha1_ft(t, b, c, d) {
36863         if (t < 20) {
36864           return (b & c) | ((~b) & d);
36865         }
36866         if (t < 40) {
36867           return b ^ c ^ d;
36868         }
36869         if (t < 60) {
36870           return (b & c) | (b & d) | (c & d);
36871         }
36872         return b ^ c ^ d;
36873       }
36874
36875       /**
36876        * Determine the appropriate additive constant for the current iteration
36877        */
36878
36879       function sha1_kt(t) {
36880         return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
36881           (t < 60) ? -1894007588 : -899497514;
36882       }
36883     },
36884     /**
36885      * @class Hashes.SHA256
36886      * @param {config}
36887      *
36888      * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined in FIPS 180-2
36889      * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009.
36890      * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
36891      * See http://pajhome.org.uk/crypt/md5 for details.
36892      * Also http://anmar.eu.org/projects/jssha2/
36893      */
36894     SHA256: function(options) {
36895       /**
36896        * Private properties configuration variables. You may need to tweak these to be compatible with
36897        * the server-side, but the defaults work in most cases.
36898        * @see this.setUpperCase() method
36899        * @see this.setPad() method
36900        */
36901       var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase  */
36902         b64pad = (options && typeof options.pad === 'string') ? options.pad : '=',
36903         /* base-64 pad character. Default '=' for strict RFC compliance   */
36904         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
36905         /* enable/disable utf8 encoding */
36906         sha256_K;
36907
36908       /* privileged (public) methods */
36909       this.hex = function(s) {
36910         return rstr2hex(rstr(s, utf8));
36911       };
36912       this.b64 = function(s) {
36913         return rstr2b64(rstr(s, utf8), b64pad);
36914       };
36915       this.any = function(s, e) {
36916         return rstr2any(rstr(s, utf8), e);
36917       };
36918       this.raw = function(s) {
36919         return rstr(s, utf8);
36920       };
36921       this.hex_hmac = function(k, d) {
36922         return rstr2hex(rstr_hmac(k, d));
36923       };
36924       this.b64_hmac = function(k, d) {
36925         return rstr2b64(rstr_hmac(k, d), b64pad);
36926       };
36927       this.any_hmac = function(k, d, e) {
36928         return rstr2any(rstr_hmac(k, d), e);
36929       };
36930       /**
36931        * Perform a simple self-test to see if the VM is working
36932        * @return {String} Hexadecimal hash sample
36933        * @public
36934        */
36935       this.vm_test = function() {
36936         return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
36937       };
36938       /**
36939        * Enable/disable uppercase hexadecimal returned string
36940        * @param {boolean}
36941        * @return {Object} this
36942        * @public
36943        */
36944       this.setUpperCase = function(a) {
36945         if (typeof a === 'boolean') {
36946           hexcase = a;
36947         }
36948         return this;
36949       };
36950       /**
36951        * @description Defines a base64 pad string
36952        * @param {string} Pad
36953        * @return {Object} this
36954        * @public
36955        */
36956       this.setPad = function(a) {
36957         b64pad = a || b64pad;
36958         return this;
36959       };
36960       /**
36961        * Defines a base64 pad string
36962        * @param {boolean}
36963        * @return {Object} this
36964        * @public
36965        */
36966       this.setUTF8 = function(a) {
36967         if (typeof a === 'boolean') {
36968           utf8 = a;
36969         }
36970         return this;
36971       };
36972
36973       // private methods
36974
36975       /**
36976        * Calculate the SHA-512 of a raw string
36977        */
36978
36979       function rstr(s, utf8) {
36980         s = (utf8) ? utf8Encode(s) : s;
36981         return binb2rstr(binb(rstr2binb(s), s.length * 8));
36982       }
36983
36984       /**
36985        * Calculate the HMAC-sha256 of a key and some data (raw strings)
36986        */
36987
36988       function rstr_hmac(key, data) {
36989         key = (utf8) ? utf8Encode(key) : key;
36990         data = (utf8) ? utf8Encode(data) : data;
36991         var hash, i = 0,
36992           bkey = rstr2binb(key),
36993           ipad = Array(16),
36994           opad = Array(16);
36995
36996         if (bkey.length > 16) {
36997           bkey = binb(bkey, key.length * 8);
36998         }
36999
37000         for (; i < 16; i += 1) {
37001           ipad[i] = bkey[i] ^ 0x36363636;
37002           opad[i] = bkey[i] ^ 0x5C5C5C5C;
37003         }
37004
37005         hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
37006         return binb2rstr(binb(opad.concat(hash), 512 + 256));
37007       }
37008
37009       /*
37010        * Main sha256 function, with its support functions
37011        */
37012
37013       function sha256_S(X, n) {
37014         return (X >>> n) | (X << (32 - n));
37015       }
37016
37017       function sha256_R(X, n) {
37018         return (X >>> n);
37019       }
37020
37021       function sha256_Ch(x, y, z) {
37022         return ((x & y) ^ ((~x) & z));
37023       }
37024
37025       function sha256_Maj(x, y, z) {
37026         return ((x & y) ^ (x & z) ^ (y & z));
37027       }
37028
37029       function sha256_Sigma0256(x) {
37030         return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));
37031       }
37032
37033       function sha256_Sigma1256(x) {
37034         return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));
37035       }
37036
37037       function sha256_Gamma0256(x) {
37038         return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));
37039       }
37040
37041       function sha256_Gamma1256(x) {
37042         return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));
37043       }
37044
37045       sha256_K = [
37046         1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993, -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987,
37047         1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522,
37048         264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585,
37049         113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291,
37050         1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885, -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344,
37051         430227734, 506948616, 659060556, 883997877, 958139571, 1322822218,
37052         1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872, -1866530822, -1538233109, -1090935817, -965641998
37053       ];
37054
37055       function binb(m, l) {
37056         var HASH = [1779033703, -1150833019, 1013904242, -1521486534,
37057           1359893119, -1694144372, 528734635, 1541459225
37058         ];
37059         var W = new Array(64);
37060         var a, b, c, d, e, f, g, h;
37061         var i, j, T1, T2;
37062
37063         /* append padding */
37064         m[l >> 5] |= 0x80 << (24 - l % 32);
37065         m[((l + 64 >> 9) << 4) + 15] = l;
37066
37067         for (i = 0; i < m.length; i += 16) {
37068           a = HASH[0];
37069           b = HASH[1];
37070           c = HASH[2];
37071           d = HASH[3];
37072           e = HASH[4];
37073           f = HASH[5];
37074           g = HASH[6];
37075           h = HASH[7];
37076
37077           for (j = 0; j < 64; j += 1) {
37078             if (j < 16) {
37079               W[j] = m[j + i];
37080             } else {
37081               W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]),
37082                 sha256_Gamma0256(W[j - 15])), W[j - 16]);
37083             }
37084
37085             T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)),
37086               sha256_K[j]), W[j]);
37087             T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c));
37088             h = g;
37089             g = f;
37090             f = e;
37091             e = safe_add(d, T1);
37092             d = c;
37093             c = b;
37094             b = a;
37095             a = safe_add(T1, T2);
37096           }
37097
37098           HASH[0] = safe_add(a, HASH[0]);
37099           HASH[1] = safe_add(b, HASH[1]);
37100           HASH[2] = safe_add(c, HASH[2]);
37101           HASH[3] = safe_add(d, HASH[3]);
37102           HASH[4] = safe_add(e, HASH[4]);
37103           HASH[5] = safe_add(f, HASH[5]);
37104           HASH[6] = safe_add(g, HASH[6]);
37105           HASH[7] = safe_add(h, HASH[7]);
37106         }
37107         return HASH;
37108       }
37109
37110     },
37111
37112     /**
37113      * @class Hashes.SHA512
37114      * @param {config}
37115      *
37116      * A JavaScript implementation of the Secure Hash Algorithm, SHA-512, as defined in FIPS 180-2
37117      * Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009.
37118      * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
37119      * See http://pajhome.org.uk/crypt/md5 for details.
37120      */
37121     SHA512: function(options) {
37122       /**
37123        * Private properties configuration variables. You may need to tweak these to be compatible with
37124        * the server-side, but the defaults work in most cases.
37125        * @see this.setUpperCase() method
37126        * @see this.setPad() method
37127        */
37128       var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false,
37129         /* hexadecimal output case format. false - lowercase; true - uppercase  */
37130         b64pad = (options && typeof options.pad === 'string') ? options.pad : '=',
37131         /* base-64 pad character. Default '=' for strict RFC compliance   */
37132         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
37133         /* enable/disable utf8 encoding */
37134         sha512_k;
37135
37136       /* privileged (public) methods */
37137       this.hex = function(s) {
37138         return rstr2hex(rstr(s));
37139       };
37140       this.b64 = function(s) {
37141         return rstr2b64(rstr(s), b64pad);
37142       };
37143       this.any = function(s, e) {
37144         return rstr2any(rstr(s), e);
37145       };
37146       this.raw = function(s) {
37147         return rstr(s, utf8);
37148       };
37149       this.hex_hmac = function(k, d) {
37150         return rstr2hex(rstr_hmac(k, d));
37151       };
37152       this.b64_hmac = function(k, d) {
37153         return rstr2b64(rstr_hmac(k, d), b64pad);
37154       };
37155       this.any_hmac = function(k, d, e) {
37156         return rstr2any(rstr_hmac(k, d), e);
37157       };
37158       /**
37159        * Perform a simple self-test to see if the VM is working
37160        * @return {String} Hexadecimal hash sample
37161        * @public
37162        */
37163       this.vm_test = function() {
37164         return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
37165       };
37166       /**
37167        * @description Enable/disable uppercase hexadecimal returned string
37168        * @param {boolean}
37169        * @return {Object} this
37170        * @public
37171        */
37172       this.setUpperCase = function(a) {
37173         if (typeof a === 'boolean') {
37174           hexcase = a;
37175         }
37176         return this;
37177       };
37178       /**
37179        * @description Defines a base64 pad string
37180        * @param {string} Pad
37181        * @return {Object} this
37182        * @public
37183        */
37184       this.setPad = function(a) {
37185         b64pad = a || b64pad;
37186         return this;
37187       };
37188       /**
37189        * @description Defines a base64 pad string
37190        * @param {boolean}
37191        * @return {Object} this
37192        * @public
37193        */
37194       this.setUTF8 = function(a) {
37195         if (typeof a === 'boolean') {
37196           utf8 = a;
37197         }
37198         return this;
37199       };
37200
37201       /* private methods */
37202
37203       /**
37204        * Calculate the SHA-512 of a raw string
37205        */
37206
37207       function rstr(s) {
37208         s = (utf8) ? utf8Encode(s) : s;
37209         return binb2rstr(binb(rstr2binb(s), s.length * 8));
37210       }
37211       /*
37212        * Calculate the HMAC-SHA-512 of a key and some data (raw strings)
37213        */
37214
37215       function rstr_hmac(key, data) {
37216         key = (utf8) ? utf8Encode(key) : key;
37217         data = (utf8) ? utf8Encode(data) : data;
37218
37219         var hash, i = 0,
37220           bkey = rstr2binb(key),
37221           ipad = Array(32),
37222           opad = Array(32);
37223
37224         if (bkey.length > 32) {
37225           bkey = binb(bkey, key.length * 8);
37226         }
37227
37228         for (; i < 32; i += 1) {
37229           ipad[i] = bkey[i] ^ 0x36363636;
37230           opad[i] = bkey[i] ^ 0x5C5C5C5C;
37231         }
37232
37233         hash = binb(ipad.concat(rstr2binb(data)), 1024 + data.length * 8);
37234         return binb2rstr(binb(opad.concat(hash), 1024 + 512));
37235       }
37236
37237       /**
37238        * Calculate the SHA-512 of an array of big-endian dwords, and a bit length
37239        */
37240
37241       function binb(x, len) {
37242         var j, i, l,
37243           W = new Array(80),
37244           hash = new Array(16),
37245           //Initial hash values
37246           H = [
37247             new int64(0x6a09e667, -205731576),
37248             new int64(-1150833019, -2067093701),
37249             new int64(0x3c6ef372, -23791573),
37250             new int64(-1521486534, 0x5f1d36f1),
37251             new int64(0x510e527f, -1377402159),
37252             new int64(-1694144372, 0x2b3e6c1f),
37253             new int64(0x1f83d9ab, -79577749),
37254             new int64(0x5be0cd19, 0x137e2179)
37255           ],
37256           T1 = new int64(0, 0),
37257           T2 = new int64(0, 0),
37258           a = new int64(0, 0),
37259           b = new int64(0, 0),
37260           c = new int64(0, 0),
37261           d = new int64(0, 0),
37262           e = new int64(0, 0),
37263           f = new int64(0, 0),
37264           g = new int64(0, 0),
37265           h = new int64(0, 0),
37266           //Temporary variables not specified by the document
37267           s0 = new int64(0, 0),
37268           s1 = new int64(0, 0),
37269           Ch = new int64(0, 0),
37270           Maj = new int64(0, 0),
37271           r1 = new int64(0, 0),
37272           r2 = new int64(0, 0),
37273           r3 = new int64(0, 0);
37274
37275         if (sha512_k === undefined) {
37276           //SHA512 constants
37277           sha512_k = [
37278             new int64(0x428a2f98, -685199838), new int64(0x71374491, 0x23ef65cd),
37279             new int64(-1245643825, -330482897), new int64(-373957723, -2121671748),
37280             new int64(0x3956c25b, -213338824), new int64(0x59f111f1, -1241133031),
37281             new int64(-1841331548, -1357295717), new int64(-1424204075, -630357736),
37282             new int64(-670586216, -1560083902), new int64(0x12835b01, 0x45706fbe),
37283             new int64(0x243185be, 0x4ee4b28c), new int64(0x550c7dc3, -704662302),
37284             new int64(0x72be5d74, -226784913), new int64(-2132889090, 0x3b1696b1),
37285             new int64(-1680079193, 0x25c71235), new int64(-1046744716, -815192428),
37286             new int64(-459576895, -1628353838), new int64(-272742522, 0x384f25e3),
37287             new int64(0xfc19dc6, -1953704523), new int64(0x240ca1cc, 0x77ac9c65),
37288             new int64(0x2de92c6f, 0x592b0275), new int64(0x4a7484aa, 0x6ea6e483),
37289             new int64(0x5cb0a9dc, -1119749164), new int64(0x76f988da, -2096016459),
37290             new int64(-1740746414, -295247957), new int64(-1473132947, 0x2db43210),
37291             new int64(-1341970488, -1728372417), new int64(-1084653625, -1091629340),
37292             new int64(-958395405, 0x3da88fc2), new int64(-710438585, -1828018395),
37293             new int64(0x6ca6351, -536640913), new int64(0x14292967, 0xa0e6e70),
37294             new int64(0x27b70a85, 0x46d22ffc), new int64(0x2e1b2138, 0x5c26c926),
37295             new int64(0x4d2c6dfc, 0x5ac42aed), new int64(0x53380d13, -1651133473),
37296             new int64(0x650a7354, -1951439906), new int64(0x766a0abb, 0x3c77b2a8),
37297             new int64(-2117940946, 0x47edaee6), new int64(-1838011259, 0x1482353b),
37298             new int64(-1564481375, 0x4cf10364), new int64(-1474664885, -1136513023),
37299             new int64(-1035236496, -789014639), new int64(-949202525, 0x654be30),
37300             new int64(-778901479, -688958952), new int64(-694614492, 0x5565a910),
37301             new int64(-200395387, 0x5771202a), new int64(0x106aa070, 0x32bbd1b8),
37302             new int64(0x19a4c116, -1194143544), new int64(0x1e376c08, 0x5141ab53),
37303             new int64(0x2748774c, -544281703), new int64(0x34b0bcb5, -509917016),
37304             new int64(0x391c0cb3, -976659869), new int64(0x4ed8aa4a, -482243893),
37305             new int64(0x5b9cca4f, 0x7763e373), new int64(0x682e6ff3, -692930397),
37306             new int64(0x748f82ee, 0x5defb2fc), new int64(0x78a5636f, 0x43172f60),
37307             new int64(-2067236844, -1578062990), new int64(-1933114872, 0x1a6439ec),
37308             new int64(-1866530822, 0x23631e28), new int64(-1538233109, -561857047),
37309             new int64(-1090935817, -1295615723), new int64(-965641998, -479046869),
37310             new int64(-903397682, -366583396), new int64(-779700025, 0x21c0c207),
37311             new int64(-354779690, -840897762), new int64(-176337025, -294727304),
37312             new int64(0x6f067aa, 0x72176fba), new int64(0xa637dc5, -1563912026),
37313             new int64(0x113f9804, -1090974290), new int64(0x1b710b35, 0x131c471b),
37314             new int64(0x28db77f5, 0x23047d84), new int64(0x32caab7b, 0x40c72493),
37315             new int64(0x3c9ebe0a, 0x15c9bebc), new int64(0x431d67c4, -1676669620),
37316             new int64(0x4cc5d4be, -885112138), new int64(0x597f299c, -60457430),
37317             new int64(0x5fcb6fab, 0x3ad6faec), new int64(0x6c44198c, 0x4a475817)
37318           ];
37319         }
37320
37321         for (i = 0; i < 80; i += 1) {
37322           W[i] = new int64(0, 0);
37323         }
37324
37325         // append padding to the source string. The format is described in the FIPS.
37326         x[len >> 5] |= 0x80 << (24 - (len & 0x1f));
37327         x[((len + 128 >> 10) << 5) + 31] = len;
37328         l = x.length;
37329         for (i = 0; i < l; i += 32) { //32 dwords is the block size
37330           int64copy(a, H[0]);
37331           int64copy(b, H[1]);
37332           int64copy(c, H[2]);
37333           int64copy(d, H[3]);
37334           int64copy(e, H[4]);
37335           int64copy(f, H[5]);
37336           int64copy(g, H[6]);
37337           int64copy(h, H[7]);
37338
37339           for (j = 0; j < 16; j += 1) {
37340             W[j].h = x[i + 2 * j];
37341             W[j].l = x[i + 2 * j + 1];
37342           }
37343
37344           for (j = 16; j < 80; j += 1) {
37345             //sigma1
37346             int64rrot(r1, W[j - 2], 19);
37347             int64revrrot(r2, W[j - 2], 29);
37348             int64shr(r3, W[j - 2], 6);
37349             s1.l = r1.l ^ r2.l ^ r3.l;
37350             s1.h = r1.h ^ r2.h ^ r3.h;
37351             //sigma0
37352             int64rrot(r1, W[j - 15], 1);
37353             int64rrot(r2, W[j - 15], 8);
37354             int64shr(r3, W[j - 15], 7);
37355             s0.l = r1.l ^ r2.l ^ r3.l;
37356             s0.h = r1.h ^ r2.h ^ r3.h;
37357
37358             int64add4(W[j], s1, W[j - 7], s0, W[j - 16]);
37359           }
37360
37361           for (j = 0; j < 80; j += 1) {
37362             //Ch
37363             Ch.l = (e.l & f.l) ^ (~e.l & g.l);
37364             Ch.h = (e.h & f.h) ^ (~e.h & g.h);
37365
37366             //Sigma1
37367             int64rrot(r1, e, 14);
37368             int64rrot(r2, e, 18);
37369             int64revrrot(r3, e, 9);
37370             s1.l = r1.l ^ r2.l ^ r3.l;
37371             s1.h = r1.h ^ r2.h ^ r3.h;
37372
37373             //Sigma0
37374             int64rrot(r1, a, 28);
37375             int64revrrot(r2, a, 2);
37376             int64revrrot(r3, a, 7);
37377             s0.l = r1.l ^ r2.l ^ r3.l;
37378             s0.h = r1.h ^ r2.h ^ r3.h;
37379
37380             //Maj
37381             Maj.l = (a.l & b.l) ^ (a.l & c.l) ^ (b.l & c.l);
37382             Maj.h = (a.h & b.h) ^ (a.h & c.h) ^ (b.h & c.h);
37383
37384             int64add5(T1, h, s1, Ch, sha512_k[j], W[j]);
37385             int64add(T2, s0, Maj);
37386
37387             int64copy(h, g);
37388             int64copy(g, f);
37389             int64copy(f, e);
37390             int64add(e, d, T1);
37391             int64copy(d, c);
37392             int64copy(c, b);
37393             int64copy(b, a);
37394             int64add(a, T1, T2);
37395           }
37396           int64add(H[0], H[0], a);
37397           int64add(H[1], H[1], b);
37398           int64add(H[2], H[2], c);
37399           int64add(H[3], H[3], d);
37400           int64add(H[4], H[4], e);
37401           int64add(H[5], H[5], f);
37402           int64add(H[6], H[6], g);
37403           int64add(H[7], H[7], h);
37404         }
37405
37406         //represent the hash as an array of 32-bit dwords
37407         for (i = 0; i < 8; i += 1) {
37408           hash[2 * i] = H[i].h;
37409           hash[2 * i + 1] = H[i].l;
37410         }
37411         return hash;
37412       }
37413
37414       //A constructor for 64-bit numbers
37415
37416       function int64(h, l) {
37417         this.h = h;
37418         this.l = l;
37419         //this.toString = int64toString;
37420       }
37421
37422       //Copies src into dst, assuming both are 64-bit numbers
37423
37424       function int64copy(dst, src) {
37425         dst.h = src.h;
37426         dst.l = src.l;
37427       }
37428
37429       //Right-rotates a 64-bit number by shift
37430       //Won't handle cases of shift>=32
37431       //The function revrrot() is for that
37432
37433       function int64rrot(dst, x, shift) {
37434         dst.l = (x.l >>> shift) | (x.h << (32 - shift));
37435         dst.h = (x.h >>> shift) | (x.l << (32 - shift));
37436       }
37437
37438       //Reverses the dwords of the source and then rotates right by shift.
37439       //This is equivalent to rotation by 32+shift
37440
37441       function int64revrrot(dst, x, shift) {
37442         dst.l = (x.h >>> shift) | (x.l << (32 - shift));
37443         dst.h = (x.l >>> shift) | (x.h << (32 - shift));
37444       }
37445
37446       //Bitwise-shifts right a 64-bit number by shift
37447       //Won't handle shift>=32, but it's never needed in SHA512
37448
37449       function int64shr(dst, x, shift) {
37450         dst.l = (x.l >>> shift) | (x.h << (32 - shift));
37451         dst.h = (x.h >>> shift);
37452       }
37453
37454       //Adds two 64-bit numbers
37455       //Like the original implementation, does not rely on 32-bit operations
37456
37457       function int64add(dst, x, y) {
37458         var w0 = (x.l & 0xffff) + (y.l & 0xffff);
37459         var w1 = (x.l >>> 16) + (y.l >>> 16) + (w0 >>> 16);
37460         var w2 = (x.h & 0xffff) + (y.h & 0xffff) + (w1 >>> 16);
37461         var w3 = (x.h >>> 16) + (y.h >>> 16) + (w2 >>> 16);
37462         dst.l = (w0 & 0xffff) | (w1 << 16);
37463         dst.h = (w2 & 0xffff) | (w3 << 16);
37464       }
37465
37466       //Same, except with 4 addends. Works faster than adding them one by one.
37467
37468       function int64add4(dst, a, b, c, d) {
37469         var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff);
37470         var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (w0 >>> 16);
37471         var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (w1 >>> 16);
37472         var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (w2 >>> 16);
37473         dst.l = (w0 & 0xffff) | (w1 << 16);
37474         dst.h = (w2 & 0xffff) | (w3 << 16);
37475       }
37476
37477       //Same, except with 5 addends
37478
37479       function int64add5(dst, a, b, c, d, e) {
37480         var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff) + (e.l & 0xffff),
37481           w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (e.l >>> 16) + (w0 >>> 16),
37482           w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (e.h & 0xffff) + (w1 >>> 16),
37483           w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (e.h >>> 16) + (w2 >>> 16);
37484         dst.l = (w0 & 0xffff) | (w1 << 16);
37485         dst.h = (w2 & 0xffff) | (w3 << 16);
37486       }
37487     },
37488     /**
37489      * @class Hashes.RMD160
37490      * @constructor
37491      * @param {Object} [config]
37492      *
37493      * A JavaScript implementation of the RIPEMD-160 Algorithm
37494      * Version 2.2 Copyright Jeremy Lin, Paul Johnston 2000 - 2009.
37495      * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
37496      * See http://pajhome.org.uk/crypt/md5 for details.
37497      * Also http://www.ocf.berkeley.edu/~jjlin/jsotp/
37498      */
37499     RMD160: function(options) {
37500       /**
37501        * Private properties configuration variables. You may need to tweak these to be compatible with
37502        * the server-side, but the defaults work in most cases.
37503        * @see this.setUpperCase() method
37504        * @see this.setPad() method
37505        */
37506       var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false,
37507         /* hexadecimal output case format. false - lowercase; true - uppercase  */
37508         b64pad = (options && typeof options.pad === 'string') ? options.pa : '=',
37509         /* base-64 pad character. Default '=' for strict RFC compliance   */
37510         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
37511         /* enable/disable utf8 encoding */
37512         rmd160_r1 = [
37513           0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
37514           7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
37515           3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
37516           1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
37517           4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
37518         ],
37519         rmd160_r2 = [
37520           5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
37521           6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
37522           15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
37523           8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
37524           12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
37525         ],
37526         rmd160_s1 = [
37527           11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
37528           7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
37529           11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
37530           11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
37531           9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
37532         ],
37533         rmd160_s2 = [
37534           8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
37535           9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
37536           9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
37537           15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
37538           8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
37539         ];
37540
37541       /* privileged (public) methods */
37542       this.hex = function(s) {
37543         return rstr2hex(rstr(s, utf8));
37544       };
37545       this.b64 = function(s) {
37546         return rstr2b64(rstr(s, utf8), b64pad);
37547       };
37548       this.any = function(s, e) {
37549         return rstr2any(rstr(s, utf8), e);
37550       };
37551       this.raw = function(s) {
37552         return rstr(s, utf8);
37553       };
37554       this.hex_hmac = function(k, d) {
37555         return rstr2hex(rstr_hmac(k, d));
37556       };
37557       this.b64_hmac = function(k, d) {
37558         return rstr2b64(rstr_hmac(k, d), b64pad);
37559       };
37560       this.any_hmac = function(k, d, e) {
37561         return rstr2any(rstr_hmac(k, d), e);
37562       };
37563       /**
37564        * Perform a simple self-test to see if the VM is working
37565        * @return {String} Hexadecimal hash sample
37566        * @public
37567        */
37568       this.vm_test = function() {
37569         return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
37570       };
37571       /**
37572        * @description Enable/disable uppercase hexadecimal returned string
37573        * @param {boolean}
37574        * @return {Object} this
37575        * @public
37576        */
37577       this.setUpperCase = function(a) {
37578         if (typeof a === 'boolean') {
37579           hexcase = a;
37580         }
37581         return this;
37582       };
37583       /**
37584        * @description Defines a base64 pad string
37585        * @param {string} Pad
37586        * @return {Object} this
37587        * @public
37588        */
37589       this.setPad = function(a) {
37590         if (typeof a !== 'undefined') {
37591           b64pad = a;
37592         }
37593         return this;
37594       };
37595       /**
37596        * @description Defines a base64 pad string
37597        * @param {boolean}
37598        * @return {Object} this
37599        * @public
37600        */
37601       this.setUTF8 = function(a) {
37602         if (typeof a === 'boolean') {
37603           utf8 = a;
37604         }
37605         return this;
37606       };
37607
37608       /* private methods */
37609
37610       /**
37611        * Calculate the rmd160 of a raw string
37612        */
37613
37614       function rstr(s) {
37615         s = (utf8) ? utf8Encode(s) : s;
37616         return binl2rstr(binl(rstr2binl(s), s.length * 8));
37617       }
37618
37619       /**
37620        * Calculate the HMAC-rmd160 of a key and some data (raw strings)
37621        */
37622
37623       function rstr_hmac(key, data) {
37624         key = (utf8) ? utf8Encode(key) : key;
37625         data = (utf8) ? utf8Encode(data) : data;
37626         var i, hash,
37627           bkey = rstr2binl(key),
37628           ipad = Array(16),
37629           opad = Array(16);
37630
37631         if (bkey.length > 16) {
37632           bkey = binl(bkey, key.length * 8);
37633         }
37634
37635         for (i = 0; i < 16; i += 1) {
37636           ipad[i] = bkey[i] ^ 0x36363636;
37637           opad[i] = bkey[i] ^ 0x5C5C5C5C;
37638         }
37639         hash = binl(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
37640         return binl2rstr(binl(opad.concat(hash), 512 + 160));
37641       }
37642
37643       /**
37644        * Convert an array of little-endian words to a string
37645        */
37646
37647       function binl2rstr(input) {
37648         var i, output = '',
37649           l = input.length * 32;
37650         for (i = 0; i < l; i += 8) {
37651           output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
37652         }
37653         return output;
37654       }
37655
37656       /**
37657        * Calculate the RIPE-MD160 of an array of little-endian words, and a bit length.
37658        */
37659
37660       function binl(x, len) {
37661         var T, j, i, l,
37662           h0 = 0x67452301,
37663           h1 = 0xefcdab89,
37664           h2 = 0x98badcfe,
37665           h3 = 0x10325476,
37666           h4 = 0xc3d2e1f0,
37667           A1, B1, C1, D1, E1,
37668           A2, B2, C2, D2, E2;
37669
37670         /* append padding */
37671         x[len >> 5] |= 0x80 << (len % 32);
37672         x[(((len + 64) >>> 9) << 4) + 14] = len;
37673         l = x.length;
37674
37675         for (i = 0; i < l; i += 16) {
37676           A1 = A2 = h0;
37677           B1 = B2 = h1;
37678           C1 = C2 = h2;
37679           D1 = D2 = h3;
37680           E1 = E2 = h4;
37681           for (j = 0; j <= 79; j += 1) {
37682             T = safe_add(A1, rmd160_f(j, B1, C1, D1));
37683             T = safe_add(T, x[i + rmd160_r1[j]]);
37684             T = safe_add(T, rmd160_K1(j));
37685             T = safe_add(bit_rol(T, rmd160_s1[j]), E1);
37686             A1 = E1;
37687             E1 = D1;
37688             D1 = bit_rol(C1, 10);
37689             C1 = B1;
37690             B1 = T;
37691             T = safe_add(A2, rmd160_f(79 - j, B2, C2, D2));
37692             T = safe_add(T, x[i + rmd160_r2[j]]);
37693             T = safe_add(T, rmd160_K2(j));
37694             T = safe_add(bit_rol(T, rmd160_s2[j]), E2);
37695             A2 = E2;
37696             E2 = D2;
37697             D2 = bit_rol(C2, 10);
37698             C2 = B2;
37699             B2 = T;
37700           }
37701
37702           T = safe_add(h1, safe_add(C1, D2));
37703           h1 = safe_add(h2, safe_add(D1, E2));
37704           h2 = safe_add(h3, safe_add(E1, A2));
37705           h3 = safe_add(h4, safe_add(A1, B2));
37706           h4 = safe_add(h0, safe_add(B1, C2));
37707           h0 = T;
37708         }
37709         return [h0, h1, h2, h3, h4];
37710       }
37711
37712       // specific algorithm methods
37713
37714       function rmd160_f(j, x, y, z) {
37715         return (0 <= j && j <= 15) ? (x ^ y ^ z) :
37716           (16 <= j && j <= 31) ? (x & y) | (~x & z) :
37717           (32 <= j && j <= 47) ? (x | ~y) ^ z :
37718           (48 <= j && j <= 63) ? (x & z) | (y & ~z) :
37719           (64 <= j && j <= 79) ? x ^ (y | ~z) :
37720           'rmd160_f: j out of range';
37721       }
37722
37723       function rmd160_K1(j) {
37724         return (0 <= j && j <= 15) ? 0x00000000 :
37725           (16 <= j && j <= 31) ? 0x5a827999 :
37726           (32 <= j && j <= 47) ? 0x6ed9eba1 :
37727           (48 <= j && j <= 63) ? 0x8f1bbcdc :
37728           (64 <= j && j <= 79) ? 0xa953fd4e :
37729           'rmd160_K1: j out of range';
37730       }
37731
37732       function rmd160_K2(j) {
37733         return (0 <= j && j <= 15) ? 0x50a28be6 :
37734           (16 <= j && j <= 31) ? 0x5c4dd124 :
37735           (32 <= j && j <= 47) ? 0x6d703ef3 :
37736           (48 <= j && j <= 63) ? 0x7a6d76e9 :
37737           (64 <= j && j <= 79) ? 0x00000000 :
37738           'rmd160_K2: j out of range';
37739       }
37740     }
37741   };
37742
37743   // exposes Hashes
37744   (function(window, undefined) {
37745     var freeExports = false;
37746     {
37747       freeExports = exports;
37748       if (exports && typeof commonjsGlobal === 'object' && commonjsGlobal && commonjsGlobal === commonjsGlobal.global) {
37749         window = commonjsGlobal;
37750       }
37751     }
37752
37753     if (typeof undefined === 'function' && typeof undefined.amd === 'object' && undefined.amd) {
37754       // define as an anonymous module, so, through path mapping, it can be aliased
37755       undefined(function() {
37756         return Hashes;
37757       });
37758     } else if (freeExports) {
37759       // in Node.js or RingoJS v0.8.0+
37760       if ('object' === 'object' && module && module.exports === freeExports) {
37761         module.exports = Hashes;
37762       }
37763       // in Narwhal or RingoJS v0.7.0-
37764       else {
37765         freeExports.Hashes = Hashes;
37766       }
37767     } else {
37768       // in a browser or Rhino
37769       window.Hashes = Hashes;
37770     }
37771   }(this));
37772 }()); // IIFE
37773 });
37774
37775 var immutable = extend$2;
37776
37777 var hasOwnProperty$16 = Object.prototype.hasOwnProperty;
37778
37779 function extend$2() {
37780     var target = {};
37781
37782     for (var i = 0; i < arguments.length; i++) {
37783         var source = arguments[i];
37784
37785         for (var key in source) {
37786             if (hasOwnProperty$16.call(source, key)) {
37787                 target[key] = source[key];
37788             }
37789         }
37790     }
37791
37792     return target
37793 }
37794
37795 var sha1 = new hashes.SHA1();
37796
37797 var ohauth = {};
37798
37799 ohauth.qsString = function(obj) {
37800     return Object.keys(obj).sort().map(function(key) {
37801         return ohauth.percentEncode(key) + '=' +
37802             ohauth.percentEncode(obj[key]);
37803     }).join('&');
37804 };
37805
37806 ohauth.stringQs = function(str) {
37807     return str.split('&').filter(function (pair) {
37808         return pair !== '';
37809     }).reduce(function(obj, pair){
37810         var parts = pair.split('=');
37811         obj[decodeURIComponent(parts[0])] = (null === parts[1]) ?
37812             '' : decodeURIComponent(parts[1]);
37813         return obj;
37814     }, {});
37815 };
37816
37817 ohauth.rawxhr = function(method, url, data, headers, callback) {
37818     var xhr = new XMLHttpRequest(),
37819         twoHundred = /^20\d$/;
37820     xhr.onreadystatechange = function() {
37821         if (4 === xhr.readyState && 0 !== xhr.status) {
37822             if (twoHundred.test(xhr.status)) callback(null, xhr);
37823             else return callback(xhr, null);
37824         }
37825     };
37826     xhr.onerror = function(e) { return callback(e, null); };
37827     xhr.open(method, url, true);
37828     for (var h in headers) xhr.setRequestHeader(h, headers[h]);
37829     xhr.send(data);
37830     return xhr;
37831 };
37832
37833 ohauth.xhr = function(method, url, auth, data, options, callback) {
37834     var headers = (options && options.header) || {
37835         'Content-Type': 'application/x-www-form-urlencoded'
37836     };
37837     headers.Authorization = 'OAuth ' + ohauth.authHeader(auth);
37838     return ohauth.rawxhr(method, url, data, headers, callback);
37839 };
37840
37841 ohauth.nonce = function() {
37842     for (var o = ''; o.length < 6;) {
37843         o += '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'[Math.floor(Math.random() * 61)];
37844     }
37845     return o;
37846 };
37847
37848 ohauth.authHeader = function(obj) {
37849     return Object.keys(obj).sort().map(function(key) {
37850         return encodeURIComponent(key) + '="' + encodeURIComponent(obj[key]) + '"';
37851     }).join(', ');
37852 };
37853
37854 ohauth.timestamp = function() { return ~~((+new Date()) / 1000); };
37855
37856 ohauth.percentEncode = function(s) {
37857     return encodeURIComponent(s)
37858         .replace(/\!/g, '%21').replace(/\'/g, '%27')
37859         .replace(/\*/g, '%2A').replace(/\(/g, '%28').replace(/\)/g, '%29');
37860 };
37861
37862 ohauth.baseString = function(method, url, params) {
37863     if (params.oauth_signature) delete params.oauth_signature;
37864     return [
37865         method,
37866         ohauth.percentEncode(url),
37867         ohauth.percentEncode(ohauth.qsString(params))].join('&');
37868 };
37869
37870 ohauth.signature = function(oauth_secret, token_secret, baseString) {
37871     return sha1.b64_hmac(
37872         ohauth.percentEncode(oauth_secret) + '&' +
37873         ohauth.percentEncode(token_secret),
37874         baseString);
37875 };
37876
37877 /**
37878  * Takes an options object for configuration (consumer_key,
37879  * consumer_secret, version, signature_method, token, token_secret)
37880  * and returns a function that generates the Authorization header
37881  * for given data.
37882  *
37883  * The returned function takes these parameters:
37884  * - method: GET/POST/...
37885  * - uri: full URI with protocol, port, path and query string
37886  * - extra_params: any extra parameters (that are passed in the POST data),
37887  *   can be an object or a from-urlencoded string.
37888  *
37889  * Returned function returns full OAuth header with "OAuth" string in it.
37890  */
37891
37892 ohauth.headerGenerator = function(options) {
37893     options = options || {};
37894     var consumer_key = options.consumer_key || '',
37895         consumer_secret = options.consumer_secret || '',
37896         signature_method = options.signature_method || 'HMAC-SHA1',
37897         version = options.version || '1.0',
37898         token = options.token || '',
37899         token_secret = options.token_secret || '';
37900
37901     return function(method, uri, extra_params) {
37902         method = method.toUpperCase();
37903         if (typeof extra_params === 'string' && extra_params.length > 0) {
37904             extra_params = ohauth.stringQs(extra_params);
37905         }
37906
37907         var uri_parts = uri.split('?', 2),
37908         base_uri = uri_parts[0];
37909
37910         var query_params = uri_parts.length === 2 ?
37911             ohauth.stringQs(uri_parts[1]) : {};
37912
37913         var oauth_params = {
37914             oauth_consumer_key: consumer_key,
37915             oauth_signature_method: signature_method,
37916             oauth_version: version,
37917             oauth_timestamp: ohauth.timestamp(),
37918             oauth_nonce: ohauth.nonce()
37919         };
37920
37921         if (token) oauth_params.oauth_token = token;
37922
37923         var all_params = immutable({}, oauth_params, query_params, extra_params),
37924             base_str = ohauth.baseString(method, base_uri, all_params);
37925
37926         oauth_params.oauth_signature = ohauth.signature(consumer_secret, token_secret, base_str);
37927
37928         return 'OAuth ' + ohauth.authHeader(oauth_params);
37929     };
37930 };
37931
37932 var ohauth_1 = ohauth;
37933
37934 var resolveUrl = createCommonjsModule(function (module, exports) {
37935 // Copyright 2014 Simon Lydell
37936 // X11 (“MIT”) Licensed. (See LICENSE.)
37937
37938 void (function(root, factory) {
37939   if (typeof undefined === "function" && undefined.amd) {
37940     undefined(factory);
37941   } else {
37942     module.exports = factory();
37943   }
37944 }(commonjsGlobal, function() {
37945
37946   function resolveUrl(/* ...urls */) {
37947     var numUrls = arguments.length;
37948
37949     if (numUrls === 0) {
37950       throw new Error("resolveUrl requires at least one argument; got none.")
37951     }
37952
37953     var base = document.createElement("base");
37954     base.href = arguments[0];
37955
37956     if (numUrls === 1) {
37957       return base.href
37958     }
37959
37960     var head = document.getElementsByTagName("head")[0];
37961     head.insertBefore(base, head.firstChild);
37962
37963     var a = document.createElement("a");
37964     var resolved;
37965
37966     for (var index = 1; index < numUrls; index++) {
37967       a.href = arguments[index];
37968       resolved = a.href;
37969       base.href = resolved;
37970     }
37971
37972     head.removeChild(base);
37973
37974     return resolved
37975   }
37976
37977   return resolveUrl
37978
37979 }));
37980 });
37981
37982 var assign$1 = make_assign();
37983 var create$2 = make_create();
37984 var trim = make_trim();
37985 var Global = (typeof window !== 'undefined' ? window : commonjsGlobal);
37986
37987 var util = {
37988         assign: assign$1,
37989         create: create$2,
37990         trim: trim,
37991         bind: bind,
37992         slice: slice$7,
37993         each: each,
37994         map: map$5,
37995         pluck: pluck,
37996         isList: isList,
37997         isFunction: isFunction$1,
37998         isObject: isObject$2,
37999         Global: Global
38000 };
38001
38002 function make_assign() {
38003         if (Object.assign) {
38004                 return Object.assign
38005         } else {
38006                 return function shimAssign(obj, props1, props2, etc) {
38007                         for (var i = 1; i < arguments.length; i++) {
38008                                 each(Object(arguments[i]), function(val, key) {
38009                                         obj[key] = val;
38010                                 });
38011                         }                       
38012                         return obj
38013                 }
38014         }
38015 }
38016
38017 function make_create() {
38018         if (Object.create) {
38019                 return function create(obj, assignProps1, assignProps2, etc) {
38020                         var assignArgsList = slice$7(arguments, 1);
38021                         return assign$1.apply(this, [Object.create(obj)].concat(assignArgsList))
38022                 }
38023         } else {
38024                 function F() {} // eslint-disable-line no-inner-declarations
38025                 return function create(obj, assignProps1, assignProps2, etc) {
38026                         var assignArgsList = slice$7(arguments, 1);
38027                         F.prototype = obj;
38028                         return assign$1.apply(this, [new F()].concat(assignArgsList))
38029                 }
38030         }
38031 }
38032
38033 function make_trim() {
38034         if (String.prototype.trim) {
38035                 return function trim(str) {
38036                         return String.prototype.trim.call(str)
38037                 }
38038         } else {
38039                 return function trim(str) {
38040                         return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '')
38041                 }
38042         }
38043 }
38044
38045 function bind(obj, fn) {
38046         return function() {
38047                 return fn.apply(obj, Array.prototype.slice.call(arguments, 0))
38048         }
38049 }
38050
38051 function slice$7(arr, index) {
38052         return Array.prototype.slice.call(arr, index || 0)
38053 }
38054
38055 function each(obj, fn) {
38056         pluck(obj, function(val, key) {
38057                 fn(val, key);
38058                 return false
38059         });
38060 }
38061
38062 function map$5(obj, fn) {
38063         var res = (isList(obj) ? [] : {});
38064         pluck(obj, function(v, k) {
38065                 res[k] = fn(v, k);
38066                 return false
38067         });
38068         return res
38069 }
38070
38071 function pluck(obj, fn) {
38072         if (isList(obj)) {
38073                 for (var i=0; i<obj.length; i++) {
38074                         if (fn(obj[i], i)) {
38075                                 return obj[i]
38076                         }
38077                 }
38078         } else {
38079                 for (var key in obj) {
38080                         if (obj.hasOwnProperty(key)) {
38081                                 if (fn(obj[key], key)) {
38082                                         return obj[key]
38083                                 }
38084                         }
38085                 }
38086         }
38087 }
38088
38089 function isList(val) {
38090         return (val != null && typeof val != 'function' && typeof val.length == 'number')
38091 }
38092
38093 function isFunction$1(val) {
38094         return val && {}.toString.call(val) === '[object Function]'
38095 }
38096
38097 function isObject$2(val) {
38098         return val && {}.toString.call(val) === '[object Object]'
38099 }
38100
38101 var slice$8 = util.slice;
38102 var pluck$1 = util.pluck;
38103 var each$1 = util.each;
38104 var bind$1 = util.bind;
38105 var create$3 = util.create;
38106 var isList$1 = util.isList;
38107 var isFunction$2 = util.isFunction;
38108 var isObject$3 = util.isObject;
38109
38110 var storeEngine = {
38111         createStore: createStore
38112 };
38113
38114 var storeAPI = {
38115         version: '2.0.12',
38116         enabled: false,
38117         
38118         // get returns the value of the given key. If that value
38119         // is undefined, it returns optionalDefaultValue instead.
38120         get: function(key, optionalDefaultValue) {
38121                 var data = this.storage.read(this._namespacePrefix + key);
38122                 return this._deserialize(data, optionalDefaultValue)
38123         },
38124
38125         // set will store the given value at key and returns value.
38126         // Calling set with value === undefined is equivalent to calling remove.
38127         set: function(key, value) {
38128                 if (value === undefined) {
38129                         return this.remove(key)
38130                 }
38131                 this.storage.write(this._namespacePrefix + key, this._serialize(value));
38132                 return value
38133         },
38134
38135         // remove deletes the key and value stored at the given key.
38136         remove: function(key) {
38137                 this.storage.remove(this._namespacePrefix + key);
38138         },
38139
38140         // each will call the given callback once for each key-value pair
38141         // in this store.
38142         each: function(callback) {
38143                 var self = this;
38144                 this.storage.each(function(val, namespacedKey) {
38145                         callback.call(self, self._deserialize(val), (namespacedKey || '').replace(self._namespaceRegexp, ''));
38146                 });
38147         },
38148
38149         // clearAll will remove all the stored key-value pairs in this store.
38150         clearAll: function() {
38151                 this.storage.clearAll();
38152         },
38153
38154         // additional functionality that can't live in plugins
38155         // ---------------------------------------------------
38156
38157         // hasNamespace returns true if this store instance has the given namespace.
38158         hasNamespace: function(namespace) {
38159                 return (this._namespacePrefix == '__storejs_'+namespace+'_')
38160         },
38161
38162         // createStore creates a store.js instance with the first
38163         // functioning storage in the list of storage candidates,
38164         // and applies the the given mixins to the instance.
38165         createStore: function() {
38166                 return createStore.apply(this, arguments)
38167         },
38168         
38169         addPlugin: function(plugin) {
38170                 this._addPlugin(plugin);
38171         },
38172         
38173         namespace: function(namespace) {
38174                 return createStore(this.storage, this.plugins, namespace)
38175         }
38176 };
38177
38178 function _warn() {
38179         var _console = (typeof console == 'undefined' ? null : console);
38180         if (!_console) { return }
38181         var fn = (_console.warn ? _console.warn : _console.log);
38182         fn.apply(_console, arguments);
38183 }
38184
38185 function createStore(storages, plugins, namespace) {
38186         if (!namespace) {
38187                 namespace = '';
38188         }
38189         if (storages && !isList$1(storages)) {
38190                 storages = [storages];
38191         }
38192         if (plugins && !isList$1(plugins)) {
38193                 plugins = [plugins];
38194         }
38195
38196         var namespacePrefix = (namespace ? '__storejs_'+namespace+'_' : '');
38197         var namespaceRegexp = (namespace ? new RegExp('^'+namespacePrefix) : null);
38198         var legalNamespaces = /^[a-zA-Z0-9_\-]*$/; // alpha-numeric + underscore and dash
38199         if (!legalNamespaces.test(namespace)) {
38200                 throw new Error('store.js namespaces can only have alphanumerics + underscores and dashes')
38201         }
38202         
38203         var _privateStoreProps = {
38204                 _namespacePrefix: namespacePrefix,
38205                 _namespaceRegexp: namespaceRegexp,
38206
38207                 _testStorage: function(storage) {
38208                         try {
38209                                 var testStr = '__storejs__test__';
38210                                 storage.write(testStr, testStr);
38211                                 var ok = (storage.read(testStr) === testStr);
38212                                 storage.remove(testStr);
38213                                 return ok
38214                         } catch(e) {
38215                                 return false
38216                         }
38217                 },
38218
38219                 _assignPluginFnProp: function(pluginFnProp, propName) {
38220                         var oldFn = this[propName];
38221                         this[propName] = function pluginFn() {
38222                                 var args = slice$8(arguments, 0);
38223                                 var self = this;
38224
38225                                 // super_fn calls the old function which was overwritten by
38226                                 // this mixin.
38227                                 function super_fn() {
38228                                         if (!oldFn) { return }
38229                                         each$1(arguments, function(arg, i) {
38230                                                 args[i] = arg;
38231                                         });
38232                                         return oldFn.apply(self, args)
38233                                 }
38234
38235                                 // Give mixing function access to super_fn by prefixing all mixin function
38236                                 // arguments with super_fn.
38237                                 var newFnArgs = [super_fn].concat(args);
38238
38239                                 return pluginFnProp.apply(self, newFnArgs)
38240                         };
38241                 },
38242
38243                 _serialize: function(obj) {
38244                         return JSON.stringify(obj)
38245                 },
38246
38247                 _deserialize: function(strVal, defaultVal) {
38248                         if (!strVal) { return defaultVal }
38249                         // It is possible that a raw string value has been previously stored
38250                         // in a storage without using store.js, meaning it will be a raw
38251                         // string value instead of a JSON serialized string. By defaulting
38252                         // to the raw string value in case of a JSON parse error, we allow
38253                         // for past stored values to be forwards-compatible with store.js
38254                         var val = '';
38255                         try { val = JSON.parse(strVal); }
38256                         catch(e) { val = strVal; }
38257
38258                         return (val !== undefined ? val : defaultVal)
38259                 },
38260                 
38261                 _addStorage: function(storage) {
38262                         if (this.enabled) { return }
38263                         if (this._testStorage(storage)) {
38264                                 this.storage = storage;
38265                                 this.enabled = true;
38266                         }
38267                 },
38268
38269                 _addPlugin: function(plugin) {
38270                         var self = this;
38271
38272                         // If the plugin is an array, then add all plugins in the array.
38273                         // This allows for a plugin to depend on other plugins.
38274                         if (isList$1(plugin)) {
38275                                 each$1(plugin, function(plugin) {
38276                                         self._addPlugin(plugin);
38277                                 });
38278                                 return
38279                         }
38280
38281                         // Keep track of all plugins we've seen so far, so that we
38282                         // don't add any of them twice.
38283                         var seenPlugin = pluck$1(this.plugins, function(seenPlugin) {
38284                                 return (plugin === seenPlugin)
38285                         });
38286                         if (seenPlugin) {
38287                                 return
38288                         }
38289                         this.plugins.push(plugin);
38290
38291                         // Check that the plugin is properly formed
38292                         if (!isFunction$2(plugin)) {
38293                                 throw new Error('Plugins must be function values that return objects')
38294                         }
38295
38296                         var pluginProperties = plugin.call(this);
38297                         if (!isObject$3(pluginProperties)) {
38298                                 throw new Error('Plugins must return an object of function properties')
38299                         }
38300
38301                         // Add the plugin function properties to this store instance.
38302                         each$1(pluginProperties, function(pluginFnProp, propName) {
38303                                 if (!isFunction$2(pluginFnProp)) {
38304                                         throw new Error('Bad plugin property: '+propName+' from plugin '+plugin.name+'. Plugins should only return functions.')
38305                                 }
38306                                 self._assignPluginFnProp(pluginFnProp, propName);
38307                         });
38308                 },
38309                 
38310                 // Put deprecated properties in the private API, so as to not expose it to accidential
38311                 // discovery through inspection of the store object.
38312                 
38313                 // Deprecated: addStorage
38314                 addStorage: function(storage) {
38315                         _warn('store.addStorage(storage) is deprecated. Use createStore([storages])');
38316                         this._addStorage(storage);
38317                 }
38318         };
38319
38320         var store = create$3(_privateStoreProps, storeAPI, {
38321                 plugins: []
38322         });
38323         store.raw = {};
38324         each$1(store, function(prop, propName) {
38325                 if (isFunction$2(prop)) {
38326                         store.raw[propName] = bind$1(store, prop);                      
38327                 }
38328         });
38329         each$1(storages, function(storage) {
38330                 store._addStorage(storage);
38331         });
38332         each$1(plugins, function(plugin) {
38333                 store._addPlugin(plugin);
38334         });
38335         return store
38336 }
38337
38338 var Global$1 = util.Global;
38339
38340 var localStorage_1 = {
38341         name: 'localStorage',
38342         read: read,
38343         write: write,
38344         each: each$2,
38345         remove: remove$2,
38346         clearAll: clearAll,
38347 };
38348
38349 function localStorage$1() {
38350         return Global$1.localStorage
38351 }
38352
38353 function read(key) {
38354         return localStorage$1().getItem(key)
38355 }
38356
38357 function write(key, data) {
38358         return localStorage$1().setItem(key, data)
38359 }
38360
38361 function each$2(fn) {
38362         for (var i = localStorage$1().length - 1; i >= 0; i--) {
38363                 var key = localStorage$1().key(i);
38364                 fn(read(key), key);
38365         }
38366 }
38367
38368 function remove$2(key) {
38369         return localStorage$1().removeItem(key)
38370 }
38371
38372 function clearAll() {
38373         return localStorage$1().clear()
38374 }
38375
38376 // oldFF-globalStorage provides storage for Firefox
38377 // versions 6 and 7, where no localStorage, etc
38378 // is available.
38379
38380
38381 var Global$2 = util.Global;
38382
38383 var oldFFGlobalStorage = {
38384         name: 'oldFF-globalStorage',
38385         read: read$1,
38386         write: write$1,
38387         each: each$3,
38388         remove: remove$3,
38389         clearAll: clearAll$1,
38390 };
38391
38392 var globalStorage = Global$2.globalStorage;
38393
38394 function read$1(key) {
38395         return globalStorage[key]
38396 }
38397
38398 function write$1(key, data) {
38399         globalStorage[key] = data;
38400 }
38401
38402 function each$3(fn) {
38403         for (var i = globalStorage.length - 1; i >= 0; i--) {
38404                 var key = globalStorage.key(i);
38405                 fn(globalStorage[key], key);
38406         }
38407 }
38408
38409 function remove$3(key) {
38410         return globalStorage.removeItem(key)
38411 }
38412
38413 function clearAll$1() {
38414         each$3(function(key, _) {
38415                 delete globalStorage[key];
38416         });
38417 }
38418
38419 // oldIE-userDataStorage provides storage for Internet Explorer
38420 // versions 6 and 7, where no localStorage, sessionStorage, etc
38421 // is available.
38422
38423
38424 var Global$3 = util.Global;
38425
38426 var oldIEUserDataStorage = {
38427         name: 'oldIE-userDataStorage',
38428         write: write$2,
38429         read: read$2,
38430         each: each$4,
38431         remove: remove$4,
38432         clearAll: clearAll$2,
38433 };
38434
38435 var storageName = 'storejs';
38436 var doc = Global$3.document;
38437 var _withStorageEl = _makeIEStorageElFunction();
38438 var disable = (Global$3.navigator ? Global$3.navigator.userAgent : '').match(/ (MSIE 8|MSIE 9|MSIE 10)\./); // MSIE 9.x, MSIE 10.x
38439
38440 function write$2(unfixedKey, data) {
38441         if (disable) { return }
38442         var fixedKey = fixKey(unfixedKey);
38443         _withStorageEl(function(storageEl) {
38444                 storageEl.setAttribute(fixedKey, data);
38445                 storageEl.save(storageName);
38446         });
38447 }
38448
38449 function read$2(unfixedKey) {
38450         if (disable) { return }
38451         var fixedKey = fixKey(unfixedKey);
38452         var res = null;
38453         _withStorageEl(function(storageEl) {
38454                 res = storageEl.getAttribute(fixedKey);
38455         });
38456         return res
38457 }
38458
38459 function each$4(callback) {
38460         _withStorageEl(function(storageEl) {
38461                 var attributes = storageEl.XMLDocument.documentElement.attributes;
38462                 for (var i=attributes.length-1; i>=0; i--) {
38463                         var attr = attributes[i];
38464                         callback(storageEl.getAttribute(attr.name), attr.name);
38465                 }
38466         });
38467 }
38468
38469 function remove$4(unfixedKey) {
38470         var fixedKey = fixKey(unfixedKey);
38471         _withStorageEl(function(storageEl) {
38472                 storageEl.removeAttribute(fixedKey);
38473                 storageEl.save(storageName);
38474         });
38475 }
38476
38477 function clearAll$2() {
38478         _withStorageEl(function(storageEl) {
38479                 var attributes = storageEl.XMLDocument.documentElement.attributes;
38480                 storageEl.load(storageName);
38481                 for (var i=attributes.length-1; i>=0; i--) {
38482                         storageEl.removeAttribute(attributes[i].name);
38483                 }
38484                 storageEl.save(storageName);
38485         });
38486 }
38487
38488 // Helpers
38489 //////////
38490
38491 // In IE7, keys cannot start with a digit or contain certain chars.
38492 // See https://github.com/marcuswestin/store.js/issues/40
38493 // See https://github.com/marcuswestin/store.js/issues/83
38494 var forbiddenCharsRegex = new RegExp("[!\"#$%&'()*+,/\\\\:;<=>?@[\\]^`{|}~]", "g");
38495 function fixKey(key) {
38496         return key.replace(/^\d/, '___$&').replace(forbiddenCharsRegex, '___')
38497 }
38498
38499 function _makeIEStorageElFunction() {
38500         if (!doc || !doc.documentElement || !doc.documentElement.addBehavior) {
38501                 return null
38502         }
38503         var scriptTag = 'script',
38504                 storageOwner,
38505                 storageContainer,
38506                 storageEl;
38507
38508         // Since #userData storage applies only to specific paths, we need to
38509         // somehow link our data to a specific path.  We choose /favicon.ico
38510         // as a pretty safe option, since all browsers already make a request to
38511         // this URL anyway and being a 404 will not hurt us here.  We wrap an
38512         // iframe pointing to the favicon in an ActiveXObject(htmlfile) object
38513         // (see: http://msdn.microsoft.com/en-us/library/aa752574(v=VS.85).aspx)
38514         // since the iframe access rules appear to allow direct access and
38515         // manipulation of the document element, even for a 404 page.  This
38516         // document can be used instead of the current document (which would
38517         // have been limited to the current path) to perform #userData storage.
38518         try {
38519                 /* global ActiveXObject */
38520                 storageContainer = new ActiveXObject('htmlfile');
38521                 storageContainer.open();
38522                 storageContainer.write('<'+scriptTag+'>document.w=window</'+scriptTag+'><iframe src="/favicon.ico"></iframe>');
38523                 storageContainer.close();
38524                 storageOwner = storageContainer.w.frames[0].document;
38525                 storageEl = storageOwner.createElement('div');
38526         } catch(e) {
38527                 // somehow ActiveXObject instantiation failed (perhaps some special
38528                 // security settings or otherwse), fall back to per-path storage
38529                 storageEl = doc.createElement('div');
38530                 storageOwner = doc.body;
38531         }
38532
38533         return function(storeFunction) {
38534                 var args = [].slice.call(arguments, 0);
38535                 args.unshift(storageEl);
38536                 // See http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx
38537                 // and http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx
38538                 storageOwner.appendChild(storageEl);
38539                 storageEl.addBehavior('#default#userData');
38540                 storageEl.load(storageName);
38541                 storeFunction.apply(this, args);
38542                 storageOwner.removeChild(storageEl);
38543                 return
38544         }
38545 }
38546
38547 // cookieStorage is useful Safari private browser mode, where localStorage
38548 // doesn't work but cookies do. This implementation is adopted from
38549 // https://developer.mozilla.org/en-US/docs/Web/API/Storage/LocalStorage
38550
38551
38552 var Global$4 = util.Global;
38553 var trim$1 = util.trim;
38554
38555 var cookieStorage = {
38556         name: 'cookieStorage',
38557         read: read$3,
38558         write: write$3,
38559         each: each$5,
38560         remove: remove$5,
38561         clearAll: clearAll$3,
38562 };
38563
38564 var doc$1 = Global$4.document;
38565
38566 function read$3(key) {
38567         if (!key || !_has(key)) { return null }
38568         var regexpStr = "(?:^|.*;\\s*)" +
38569                 escape(key).replace(/[\-\.\+\*]/g, "\\$&") +
38570                 "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*";
38571         return unescape(doc$1.cookie.replace(new RegExp(regexpStr), "$1"))
38572 }
38573
38574 function each$5(callback) {
38575         var cookies = doc$1.cookie.split(/; ?/g);
38576         for (var i = cookies.length - 1; i >= 0; i--) {
38577                 if (!trim$1(cookies[i])) {
38578                         continue
38579                 }
38580                 var kvp = cookies[i].split('=');
38581                 var key = unescape(kvp[0]);
38582                 var val = unescape(kvp[1]);
38583                 callback(val, key);
38584         }
38585 }
38586
38587 function write$3(key, data) {
38588         if(!key) { return }
38589         doc$1.cookie = escape(key) + "=" + escape(data) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/";
38590 }
38591
38592 function remove$5(key) {
38593         if (!key || !_has(key)) {
38594                 return
38595         }
38596         doc$1.cookie = escape(key) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
38597 }
38598
38599 function clearAll$3() {
38600         each$5(function(_, key) {
38601                 remove$5(key);
38602         });
38603 }
38604
38605 function _has(key) {
38606         return (new RegExp("(?:^|;\\s*)" + escape(key).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(doc$1.cookie)
38607 }
38608
38609 var Global$5 = util.Global;
38610
38611 var sessionStorage_1 = {
38612         name: 'sessionStorage',
38613         read: read$4,
38614         write: write$4,
38615         each: each$6,
38616         remove: remove$6,
38617         clearAll: clearAll$4
38618 };
38619
38620 function sessionStorage() {
38621         return Global$5.sessionStorage
38622 }
38623
38624 function read$4(key) {
38625         return sessionStorage().getItem(key)
38626 }
38627
38628 function write$4(key, data) {
38629         return sessionStorage().setItem(key, data)
38630 }
38631
38632 function each$6(fn) {
38633         for (var i = sessionStorage().length - 1; i >= 0; i--) {
38634                 var key = sessionStorage().key(i);
38635                 fn(read$4(key), key);
38636         }
38637 }
38638
38639 function remove$6(key) {
38640         return sessionStorage().removeItem(key)
38641 }
38642
38643 function clearAll$4() {
38644         return sessionStorage().clear()
38645 }
38646
38647 // memoryStorage is a useful last fallback to ensure that the store
38648 // is functions (meaning store.get(), store.set(), etc will all function).
38649 // However, stored values will not persist when the browser navigates to
38650 // a new page or reloads the current page.
38651
38652 var memoryStorage_1 = {
38653         name: 'memoryStorage',
38654         read: read$5,
38655         write: write$5,
38656         each: each$7,
38657         remove: remove$7,
38658         clearAll: clearAll$5,
38659 };
38660
38661 var memoryStorage = {};
38662
38663 function read$5(key) {
38664         return memoryStorage[key]
38665 }
38666
38667 function write$5(key, data) {
38668         memoryStorage[key] = data;
38669 }
38670
38671 function each$7(callback) {
38672         for (var key in memoryStorage) {
38673                 if (memoryStorage.hasOwnProperty(key)) {
38674                         callback(memoryStorage[key], key);
38675                 }
38676         }
38677 }
38678
38679 function remove$7(key) {
38680         delete memoryStorage[key];
38681 }
38682
38683 function clearAll$5(key) {
38684         memoryStorage = {};
38685 }
38686
38687 var all$3 = [
38688         // Listed in order of usage preference
38689         localStorage_1,
38690         oldFFGlobalStorage,
38691         oldIEUserDataStorage,
38692         cookieStorage,
38693         sessionStorage_1,
38694         memoryStorage_1
38695 ];
38696
38697 /* eslint-disable */
38698
38699 //  json2.js
38700 //  2016-10-28
38701 //  Public Domain.
38702 //  NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
38703 //  See http://www.JSON.org/js.html
38704 //  This code should be minified before deployment.
38705 //  See http://javascript.crockford.com/jsmin.html
38706
38707 //  USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
38708 //  NOT CONTROL.
38709
38710 //  This file creates a global JSON object containing two methods: stringify
38711 //  and parse. This file provides the ES5 JSON capability to ES3 systems.
38712 //  If a project might run on IE8 or earlier, then this file should be included.
38713 //  This file does nothing on ES5 systems.
38714
38715 //      JSON.stringify(value, replacer, space)
38716 //          value       any JavaScript value, usually an object or array.
38717 //          replacer    an optional parameter that determines how object
38718 //                      values are stringified for objects. It can be a
38719 //                      function or an array of strings.
38720 //          space       an optional parameter that specifies the indentation
38721 //                      of nested structures. If it is omitted, the text will
38722 //                      be packed without extra whitespace. If it is a number,
38723 //                      it will specify the number of spaces to indent at each
38724 //                      level. If it is a string (such as "\t" or "&nbsp;"),
38725 //                      it contains the characters used to indent at each level.
38726 //          This method produces a JSON text from a JavaScript value.
38727 //          When an object value is found, if the object contains a toJSON
38728 //          method, its toJSON method will be called and the result will be
38729 //          stringified. A toJSON method does not serialize: it returns the
38730 //          value represented by the name/value pair that should be serialized,
38731 //          or undefined if nothing should be serialized. The toJSON method
38732 //          will be passed the key associated with the value, and this will be
38733 //          bound to the value.
38734
38735 //          For example, this would serialize Dates as ISO strings.
38736
38737 //              Date.prototype.toJSON = function (key) {
38738 //                  function f(n) {
38739 //                      // Format integers to have at least two digits.
38740 //                      return (n < 10)
38741 //                          ? "0" + n
38742 //                          : n;
38743 //                  }
38744 //                  return this.getUTCFullYear()   + "-" +
38745 //                       f(this.getUTCMonth() + 1) + "-" +
38746 //                       f(this.getUTCDate())      + "T" +
38747 //                       f(this.getUTCHours())     + ":" +
38748 //                       f(this.getUTCMinutes())   + ":" +
38749 //                       f(this.getUTCSeconds())   + "Z";
38750 //              };
38751
38752 //          You can provide an optional replacer method. It will be passed the
38753 //          key and value of each member, with this bound to the containing
38754 //          object. The value that is returned from your method will be
38755 //          serialized. If your method returns undefined, then the member will
38756 //          be excluded from the serialization.
38757
38758 //          If the replacer parameter is an array of strings, then it will be
38759 //          used to select the members to be serialized. It filters the results
38760 //          such that only members with keys listed in the replacer array are
38761 //          stringified.
38762
38763 //          Values that do not have JSON representations, such as undefined or
38764 //          functions, will not be serialized. Such values in objects will be
38765 //          dropped; in arrays they will be replaced with null. You can use
38766 //          a replacer function to replace those with JSON values.
38767
38768 //          JSON.stringify(undefined) returns undefined.
38769
38770 //          The optional space parameter produces a stringification of the
38771 //          value that is filled with line breaks and indentation to make it
38772 //          easier to read.
38773
38774 //          If the space parameter is a non-empty string, then that string will
38775 //          be used for indentation. If the space parameter is a number, then
38776 //          the indentation will be that many spaces.
38777
38778 //          Example:
38779
38780 //          text = JSON.stringify(["e", {pluribus: "unum"}]);
38781 //          // text is '["e",{"pluribus":"unum"}]'
38782
38783 //          text = JSON.stringify(["e", {pluribus: "unum"}], null, "\t");
38784 //          // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
38785
38786 //          text = JSON.stringify([new Date()], function (key, value) {
38787 //              return this[key] instanceof Date
38788 //                  ? "Date(" + this[key] + ")"
38789 //                  : value;
38790 //          });
38791 //          // text is '["Date(---current time---)"]'
38792
38793 //      JSON.parse(text, reviver)
38794 //          This method parses a JSON text to produce an object or array.
38795 //          It can throw a SyntaxError exception.
38796
38797 //          The optional reviver parameter is a function that can filter and
38798 //          transform the results. It receives each of the keys and values,
38799 //          and its return value is used instead of the original value.
38800 //          If it returns what it received, then the structure is not modified.
38801 //          If it returns undefined then the member is deleted.
38802
38803 //          Example:
38804
38805 //          // Parse the text. Values that look like ISO date strings will
38806 //          // be converted to Date objects.
38807
38808 //          myData = JSON.parse(text, function (key, value) {
38809 //              var a;
38810 //              if (typeof value === "string") {
38811 //                  a =
38812 //   /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
38813 //                  if (a) {
38814 //                      return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
38815 //                          +a[5], +a[6]));
38816 //                  }
38817 //              }
38818 //              return value;
38819 //          });
38820
38821 //          myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
38822 //              var d;
38823 //              if (typeof value === "string" &&
38824 //                      value.slice(0, 5) === "Date(" &&
38825 //                      value.slice(-1) === ")") {
38826 //                  d = new Date(value.slice(5, -1));
38827 //                  if (d) {
38828 //                      return d;
38829 //                  }
38830 //              }
38831 //              return value;
38832 //          });
38833
38834 //  This is a reference implementation. You are free to copy, modify, or
38835 //  redistribute.
38836
38837 /*jslint
38838     eval, for, this
38839 */
38840
38841 /*property
38842     JSON, apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
38843     getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
38844     lastIndex, length, parse, prototype, push, replace, slice, stringify,
38845     test, toJSON, toString, valueOf
38846 */
38847
38848
38849 // Create a JSON object only if one does not already exist. We create the
38850 // methods in a closure to avoid creating global variables.
38851
38852 if (typeof JSON !== "object") {
38853     JSON = {};
38854 }
38855
38856 (function () {
38857     var rx_one = /^[\],:{}\s]*$/;
38858     var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
38859     var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
38860     var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
38861     var rx_escapable = /[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
38862     var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
38863
38864     function f(n) {
38865         // Format integers to have at least two digits.
38866         return n < 10
38867             ? "0" + n
38868             : n;
38869     }
38870
38871     function this_value() {
38872         return this.valueOf();
38873     }
38874
38875     if (typeof Date.prototype.toJSON !== "function") {
38876
38877         Date.prototype.toJSON = function () {
38878
38879             return isFinite(this.valueOf())
38880                 ? this.getUTCFullYear() + "-" +
38881                         f(this.getUTCMonth() + 1) + "-" +
38882                         f(this.getUTCDate()) + "T" +
38883                         f(this.getUTCHours()) + ":" +
38884                         f(this.getUTCMinutes()) + ":" +
38885                         f(this.getUTCSeconds()) + "Z"
38886                 : null;
38887         };
38888
38889         Boolean.prototype.toJSON = this_value;
38890         Number.prototype.toJSON = this_value;
38891         String.prototype.toJSON = this_value;
38892     }
38893
38894     var gap;
38895     var indent;
38896     var meta;
38897     var rep;
38898
38899
38900     function quote(string) {
38901
38902 // If the string contains no control characters, no quote characters, and no
38903 // backslash characters, then we can safely slap some quotes around it.
38904 // Otherwise we must also replace the offending characters with safe escape
38905 // sequences.
38906
38907         rx_escapable.lastIndex = 0;
38908         return rx_escapable.test(string)
38909             ? "\"" + string.replace(rx_escapable, function (a) {
38910                 var c = meta[a];
38911                 return typeof c === "string"
38912                     ? c
38913                     : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
38914             }) + "\""
38915             : "\"" + string + "\"";
38916     }
38917
38918
38919     function str(key, holder) {
38920
38921 // Produce a string from holder[key].
38922
38923         var i;          // The loop counter.
38924         var k;          // The member key.
38925         var v;          // The member value.
38926         var length;
38927         var mind = gap;
38928         var partial;
38929         var value = holder[key];
38930
38931 // If the value has a toJSON method, call it to obtain a replacement value.
38932
38933         if (value && typeof value === "object" &&
38934                 typeof value.toJSON === "function") {
38935             value = value.toJSON(key);
38936         }
38937
38938 // If we were called with a replacer function, then call the replacer to
38939 // obtain a replacement value.
38940
38941         if (typeof rep === "function") {
38942             value = rep.call(holder, key, value);
38943         }
38944
38945 // What happens next depends on the value's type.
38946
38947         switch (typeof value) {
38948         case "string":
38949             return quote(value);
38950
38951         case "number":
38952
38953 // JSON numbers must be finite. Encode non-finite numbers as null.
38954
38955             return isFinite(value)
38956                 ? String(value)
38957                 : "null";
38958
38959         case "boolean":
38960         case "null":
38961
38962 // If the value is a boolean or null, convert it to a string. Note:
38963 // typeof null does not produce "null". The case is included here in
38964 // the remote chance that this gets fixed someday.
38965
38966             return String(value);
38967
38968 // If the type is "object", we might be dealing with an object or an array or
38969 // null.
38970
38971         case "object":
38972
38973 // Due to a specification blunder in ECMAScript, typeof null is "object",
38974 // so watch out for that case.
38975
38976             if (!value) {
38977                 return "null";
38978             }
38979
38980 // Make an array to hold the partial results of stringifying this object value.
38981
38982             gap += indent;
38983             partial = [];
38984
38985 // Is the value an array?
38986
38987             if (Object.prototype.toString.apply(value) === "[object Array]") {
38988
38989 // The value is an array. Stringify every element. Use null as a placeholder
38990 // for non-JSON values.
38991
38992                 length = value.length;
38993                 for (i = 0; i < length; i += 1) {
38994                     partial[i] = str(i, value) || "null";
38995                 }
38996
38997 // Join all of the elements together, separated with commas, and wrap them in
38998 // brackets.
38999
39000                 v = partial.length === 0
39001                     ? "[]"
39002                     : gap
39003                         ? "[\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "]"
39004                         : "[" + partial.join(",") + "]";
39005                 gap = mind;
39006                 return v;
39007             }
39008
39009 // If the replacer is an array, use it to select the members to be stringified.
39010
39011             if (rep && typeof rep === "object") {
39012                 length = rep.length;
39013                 for (i = 0; i < length; i += 1) {
39014                     if (typeof rep[i] === "string") {
39015                         k = rep[i];
39016                         v = str(k, value);
39017                         if (v) {
39018                             partial.push(quote(k) + (
39019                                 gap
39020                                     ? ": "
39021                                     : ":"
39022                             ) + v);
39023                         }
39024                     }
39025                 }
39026             } else {
39027
39028 // Otherwise, iterate through all of the keys in the object.
39029
39030                 for (k in value) {
39031                     if (Object.prototype.hasOwnProperty.call(value, k)) {
39032                         v = str(k, value);
39033                         if (v) {
39034                             partial.push(quote(k) + (
39035                                 gap
39036                                     ? ": "
39037                                     : ":"
39038                             ) + v);
39039                         }
39040                     }
39041                 }
39042             }
39043
39044 // Join all of the member texts together, separated with commas,
39045 // and wrap them in braces.
39046
39047             v = partial.length === 0
39048                 ? "{}"
39049                 : gap
39050                     ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}"
39051                     : "{" + partial.join(",") + "}";
39052             gap = mind;
39053             return v;
39054         }
39055     }
39056
39057 // If the JSON object does not yet have a stringify method, give it one.
39058
39059     if (typeof JSON.stringify !== "function") {
39060         meta = {    // table of character substitutions
39061             "\b": "\\b",
39062             "\t": "\\t",
39063             "\n": "\\n",
39064             "\f": "\\f",
39065             "\r": "\\r",
39066             "\"": "\\\"",
39067             "\\": "\\\\"
39068         };
39069         JSON.stringify = function (value, replacer, space) {
39070
39071 // The stringify method takes a value and an optional replacer, and an optional
39072 // space parameter, and returns a JSON text. The replacer can be a function
39073 // that can replace values, or an array of strings that will select the keys.
39074 // A default replacer method can be provided. Use of the space parameter can
39075 // produce text that is more easily readable.
39076
39077             var i;
39078             gap = "";
39079             indent = "";
39080
39081 // If the space parameter is a number, make an indent string containing that
39082 // many spaces.
39083
39084             if (typeof space === "number") {
39085                 for (i = 0; i < space; i += 1) {
39086                     indent += " ";
39087                 }
39088
39089 // If the space parameter is a string, it will be used as the indent string.
39090
39091             } else if (typeof space === "string") {
39092                 indent = space;
39093             }
39094
39095 // If there is a replacer, it must be a function or an array.
39096 // Otherwise, throw an error.
39097
39098             rep = replacer;
39099             if (replacer && typeof replacer !== "function" &&
39100                     (typeof replacer !== "object" ||
39101                     typeof replacer.length !== "number")) {
39102                 throw new Error("JSON.stringify");
39103             }
39104
39105 // Make a fake root object containing our value under the key of "".
39106 // Return the result of stringifying the value.
39107
39108             return str("", {"": value});
39109         };
39110     }
39111
39112
39113 // If the JSON object does not yet have a parse method, give it one.
39114
39115     if (typeof JSON.parse !== "function") {
39116         JSON.parse = function (text, reviver) {
39117
39118 // The parse method takes a text and an optional reviver function, and returns
39119 // a JavaScript value if the text is a valid JSON text.
39120
39121             var j;
39122
39123             function walk(holder, key) {
39124
39125 // The walk method is used to recursively walk the resulting structure so
39126 // that modifications can be made.
39127
39128                 var k;
39129                 var v;
39130                 var value = holder[key];
39131                 if (value && typeof value === "object") {
39132                     for (k in value) {
39133                         if (Object.prototype.hasOwnProperty.call(value, k)) {
39134                             v = walk(value, k);
39135                             if (v !== undefined) {
39136                                 value[k] = v;
39137                             } else {
39138                                 delete value[k];
39139                             }
39140                         }
39141                     }
39142                 }
39143                 return reviver.call(holder, key, value);
39144             }
39145
39146
39147 // Parsing happens in four stages. In the first stage, we replace certain
39148 // Unicode characters with escape sequences. JavaScript handles many characters
39149 // incorrectly, either silently deleting them, or treating them as line endings.
39150
39151             text = String(text);
39152             rx_dangerous.lastIndex = 0;
39153             if (rx_dangerous.test(text)) {
39154                 text = text.replace(rx_dangerous, function (a) {
39155                     return "\\u" +
39156                             ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
39157                 });
39158             }
39159
39160 // In the second stage, we run the text against regular expressions that look
39161 // for non-JSON patterns. We are especially concerned with "()" and "new"
39162 // because they can cause invocation, and "=" because it can cause mutation.
39163 // But just to be safe, we want to reject all unexpected forms.
39164
39165 // We split the second stage into 4 regexp operations in order to work around
39166 // crippling inefficiencies in IE's and Safari's regexp engines. First we
39167 // replace the JSON backslash pairs with "@" (a non-JSON character). Second, we
39168 // replace all simple value tokens with "]" characters. Third, we delete all
39169 // open brackets that follow a colon or comma or that begin the text. Finally,
39170 // we look to see that the remaining characters are only whitespace or "]" or
39171 // "," or ":" or "{" or "}". If that is so, then the text is safe for eval.
39172
39173             if (
39174                 rx_one.test(
39175                     text
39176                         .replace(rx_two, "@")
39177                         .replace(rx_three, "]")
39178                         .replace(rx_four, "")
39179                 )
39180             ) {
39181
39182 // In the third stage we use the eval function to compile the text into a
39183 // JavaScript structure. The "{" operator is subject to a syntactic ambiguity
39184 // in JavaScript: it can begin a block or an object literal. We wrap the text
39185 // in parens to eliminate the ambiguity.
39186
39187                 j = eval("(" + text + ")");
39188
39189 // In the optional fourth stage, we recursively walk the new structure, passing
39190 // each name/value pair to a reviver function for possible transformation.
39191
39192                 return (typeof reviver === "function")
39193                     ? walk({"": j}, "")
39194                     : j;
39195             }
39196
39197 // If the text is not JSON parseable, then a SyntaxError is thrown.
39198
39199             throw new SyntaxError("JSON.parse");
39200         };
39201     }
39202 }());
39203
39204 var json2$1 = json2Plugin;
39205
39206 function json2Plugin() {
39207         
39208         return {}
39209 }
39210
39211 var plugins = [json2$1];
39212
39213 var store_legacy = storeEngine.createStore(all$3, plugins);
39214
39215 // # osm-auth
39216 //
39217 // This code is only compatible with IE10+ because the [XDomainRequest](http://bit.ly/LfO7xo)
39218 // object, IE<10's idea of [CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing),
39219 // does not support custom headers, which this uses everywhere.
39220 var osmAuth = function(o) {
39221
39222     var oauth = {};
39223
39224     // authenticated users will also have a request token secret, but it's
39225     // not used in transactions with the server
39226     oauth.authenticated = function() {
39227         return !!(token('oauth_token') && token('oauth_token_secret'));
39228     };
39229
39230     oauth.logout = function() {
39231         token('oauth_token', '');
39232         token('oauth_token_secret', '');
39233         token('oauth_request_token_secret', '');
39234         return oauth;
39235     };
39236
39237     // TODO: detect lack of click event
39238     oauth.authenticate = function(callback) {
39239         if (oauth.authenticated()) return callback();
39240
39241         oauth.logout();
39242
39243         // ## Getting a request token
39244         var params = timenonce(getAuth(o)),
39245             url = o.url + '/oauth/request_token';
39246
39247         params.oauth_signature = ohauth_1.signature(
39248             o.oauth_secret, '',
39249             ohauth_1.baseString('POST', url, params));
39250
39251         if (!o.singlepage) {
39252             // Create a 600x550 popup window in the center of the screen
39253             var w = 600, h = 550,
39254                 settings = [
39255                     ['width', w], ['height', h],
39256                     ['left', screen.width / 2 - w / 2],
39257                     ['top', screen.height / 2 - h / 2]].map(function(x) {
39258                         return x.join('=');
39259                     }).join(','),
39260                 popup = window.open('about:blank', 'oauth_window', settings);
39261         }
39262
39263         // Request a request token. When this is complete, the popup
39264         // window is redirected to OSM's authorization page.
39265         ohauth_1.xhr('POST', url, params, null, {}, reqTokenDone);
39266         o.loading();
39267
39268         function reqTokenDone(err, xhr) {
39269             o.done();
39270             if (err) return callback(err);
39271             var resp = ohauth_1.stringQs(xhr.response);
39272             token('oauth_request_token_secret', resp.oauth_token_secret);
39273             var authorize_url = o.url + '/oauth/authorize?' + ohauth_1.qsString({
39274                 oauth_token: resp.oauth_token,
39275                 oauth_callback: resolveUrl(o.landing)
39276             });
39277
39278             if (o.singlepage) {
39279                 location.href = authorize_url;
39280             } else {
39281                 popup.location = authorize_url;
39282             }
39283         }
39284
39285         // Called by a function in a landing page, in the popup window. The
39286         // window closes itself.
39287         window.authComplete = function(token) {
39288             var oauth_token = ohauth_1.stringQs(token.split('?')[1]);
39289             get_access_token(oauth_token.oauth_token);
39290             delete window.authComplete;
39291         };
39292
39293         // ## Getting an request token
39294         //
39295         // At this point we have an `oauth_token`, brought in from a function
39296         // call on a landing page popup.
39297         function get_access_token(oauth_token) {
39298             var url = o.url + '/oauth/access_token',
39299                 params = timenonce(getAuth(o)),
39300                 request_token_secret = token('oauth_request_token_secret');
39301             params.oauth_token = oauth_token;
39302             params.oauth_signature = ohauth_1.signature(
39303                 o.oauth_secret,
39304                 request_token_secret,
39305                 ohauth_1.baseString('POST', url, params));
39306
39307             // ## Getting an access token
39308             //
39309             // The final token required for authentication. At this point
39310             // we have a `request token secret`
39311             ohauth_1.xhr('POST', url, params, null, {}, accessTokenDone);
39312             o.loading();
39313         }
39314
39315         function accessTokenDone(err, xhr) {
39316             o.done();
39317             if (err) return callback(err);
39318             var access_token = ohauth_1.stringQs(xhr.response);
39319             token('oauth_token', access_token.oauth_token);
39320             token('oauth_token_secret', access_token.oauth_token_secret);
39321             callback(null, oauth);
39322         }
39323     };
39324
39325     oauth.bootstrapToken = function(oauth_token, callback) {
39326         // ## Getting an request token
39327         // At this point we have an `oauth_token`, brought in from a function
39328         // call on a landing page popup.
39329         function get_access_token(oauth_token) {
39330             var url = o.url + '/oauth/access_token',
39331                 params = timenonce(getAuth(o)),
39332                 request_token_secret = token('oauth_request_token_secret');
39333             params.oauth_token = oauth_token;
39334             params.oauth_signature = ohauth_1.signature(
39335                 o.oauth_secret,
39336                 request_token_secret,
39337                 ohauth_1.baseString('POST', url, params));
39338
39339             // ## Getting an access token
39340             // The final token required for authentication. At this point
39341             // we have a `request token secret`
39342             ohauth_1.xhr('POST', url, params, null, {}, accessTokenDone);
39343             o.loading();
39344         }
39345
39346         function accessTokenDone(err, xhr) {
39347             o.done();
39348             if (err) return callback(err);
39349             var access_token = ohauth_1.stringQs(xhr.response);
39350             token('oauth_token', access_token.oauth_token);
39351             token('oauth_token_secret', access_token.oauth_token_secret);
39352             callback(null, oauth);
39353         }
39354
39355         get_access_token(oauth_token);
39356     };
39357
39358     // # xhr
39359     //
39360     // A single XMLHttpRequest wrapper that does authenticated calls if the
39361     // user has logged in.
39362     oauth.xhr = function(options, callback) {
39363         if (!oauth.authenticated()) {
39364             if (o.auto) {
39365                 return oauth.authenticate(run);
39366             } else {
39367                 callback('not authenticated', null);
39368                 return;
39369             }
39370         } else {
39371             return run();
39372         }
39373
39374         function run() {
39375             var params = timenonce(getAuth(o)),
39376                 oauth_token_secret = token('oauth_token_secret'),
39377                 url = (options.prefix !== false) ? o.url + options.path : options.path,
39378                 url_parts = url.replace(/#.*$/, '').split('?', 2),
39379                 base_url = url_parts[0],
39380                 query = (url_parts.length === 2) ? url_parts[1] : '';
39381
39382             // https://tools.ietf.org/html/rfc5849#section-3.4.1.3.1
39383             if ((!options.options || !options.options.header ||
39384                 options.options.header['Content-Type'] === 'application/x-www-form-urlencoded') &&
39385                 options.content) {
39386                 params = immutable(params, ohauth_1.stringQs(options.content));
39387             }
39388
39389             params.oauth_token = token('oauth_token');
39390             params.oauth_signature = ohauth_1.signature(
39391                 o.oauth_secret,
39392                 oauth_token_secret,
39393                 ohauth_1.baseString(options.method, base_url, immutable(params, ohauth_1.stringQs(query)))
39394             );
39395
39396             return ohauth_1.xhr(options.method, url, params, options.content, options.options, done);
39397         }
39398
39399         function done(err, xhr) {
39400             if (err) return callback(err);
39401             else if (xhr.responseXML) return callback(err, xhr.responseXML);
39402             else return callback(err, xhr.response);
39403         }
39404     };
39405
39406     // pre-authorize this object, if we can just get a token and token_secret
39407     // from the start
39408     oauth.preauth = function(c) {
39409         if (!c) return;
39410         if (c.oauth_token) token('oauth_token', c.oauth_token);
39411         if (c.oauth_token_secret) token('oauth_token_secret', c.oauth_token_secret);
39412         return oauth;
39413     };
39414
39415     oauth.options = function(_) {
39416         if (!arguments.length) return o;
39417
39418         o = _;
39419         o.url = o.url || 'https://www.openstreetmap.org';
39420         o.landing = o.landing || 'land.html';
39421         o.singlepage = o.singlepage || false;
39422
39423         // Optional loading and loading-done functions for nice UI feedback.
39424         // by default, no-ops
39425         o.loading = o.loading || function() {};
39426         o.done = o.done || function() {};
39427
39428         return oauth.preauth(o);
39429     };
39430
39431     // 'stamp' an authentication object from `getAuth()`
39432     // with a [nonce](http://en.wikipedia.org/wiki/Cryptographic_nonce)
39433     // and timestamp
39434     function timenonce(o) {
39435         o.oauth_timestamp = ohauth_1.timestamp();
39436         o.oauth_nonce = ohauth_1.nonce();
39437         return o;
39438     }
39439
39440     // get/set tokens. These are prefixed with the base URL so that `osm-auth`
39441     // can be used with multiple APIs and the keys in `localStorage`
39442     // will not clash
39443     var token;
39444
39445     if (store_legacy.enabled) {
39446         token = function (x, y) {
39447             if (arguments.length === 1) return store_legacy.get(o.url + x);
39448             else if (arguments.length === 2) return store_legacy.set(o.url + x, y);
39449         };
39450     } else {
39451         var storage = {};
39452         token = function (x, y) {
39453             if (arguments.length === 1) return storage[o.url + x];
39454             else if (arguments.length === 2) return storage[o.url + x] = y;
39455         };
39456     }
39457
39458     // Get an authentication object. If you just add and remove properties
39459     // from a single object, you'll need to use `delete` to make sure that
39460     // it doesn't contain undesired properties for authentication
39461     function getAuth(o) {
39462         return {
39463             oauth_consumer_key: o.oauth_consumer_key,
39464             oauth_signature_method: 'HMAC-SHA1'
39465         };
39466     }
39467
39468     // potentially pre-authorize
39469     oauth.options(o);
39470
39471     return oauth;
39472 };
39473
39474 var JXON = new (function () {
39475   var
39476     sValueProp = 'keyValue', sAttributesProp = 'keyAttributes', sAttrPref = '@', /* you can customize these values */
39477     aCache = [], rIsNull = /^\s*$/, rIsBool = /^(?:true|false)$/i;
39478
39479   function parseText (sValue) {
39480     if (rIsNull.test(sValue)) { return null; }
39481     if (rIsBool.test(sValue)) { return sValue.toLowerCase() === 'true'; }
39482     if (isFinite(sValue)) { return parseFloat(sValue); }
39483     if (isFinite(Date.parse(sValue))) { return new Date(sValue); }
39484     return sValue;
39485   }
39486
39487   function EmptyTree () { }
39488   EmptyTree.prototype.toString = function () { return 'null'; };
39489   EmptyTree.prototype.valueOf = function () { return null; };
39490
39491   function objectify (vValue) {
39492     return vValue === null ? new EmptyTree() : vValue instanceof Object ? vValue : new vValue.constructor(vValue);
39493   }
39494
39495   function createObjTree (oParentNode, nVerb, bFreeze, bNesteAttr) {
39496     var
39497       nLevelStart = aCache.length, bChildren = oParentNode.hasChildNodes(),
39498       bAttributes = oParentNode.hasAttributes(), bHighVerb = Boolean(nVerb & 2);
39499
39500     var
39501       sProp, vContent, nLength = 0, sCollectedTxt = '',
39502       vResult = bHighVerb ? {} : /* put here the default value for empty nodes: */ true;
39503
39504     if (bChildren) {
39505       for (var oNode, nItem = 0; nItem < oParentNode.childNodes.length; nItem++) {
39506         oNode = oParentNode.childNodes.item(nItem);
39507         if (oNode.nodeType === 4) { sCollectedTxt += oNode.nodeValue; } /* nodeType is 'CDATASection' (4) */
39508         else if (oNode.nodeType === 3) { sCollectedTxt += oNode.nodeValue.trim(); } /* nodeType is 'Text' (3) */
39509         else if (oNode.nodeType === 1 && !oNode.prefix) { aCache.push(oNode); } /* nodeType is 'Element' (1) */
39510       }
39511     }
39512
39513     var nLevelEnd = aCache.length, vBuiltVal = parseText(sCollectedTxt);
39514
39515     if (!bHighVerb && (bChildren || bAttributes)) { vResult = nVerb === 0 ? objectify(vBuiltVal) : {}; }
39516
39517     for (var nElId = nLevelStart; nElId < nLevelEnd; nElId++) {
39518       sProp = aCache[nElId].nodeName.toLowerCase();
39519       vContent = createObjTree(aCache[nElId], nVerb, bFreeze, bNesteAttr);
39520       if (vResult.hasOwnProperty(sProp)) {
39521         if (vResult[sProp].constructor !== Array) { vResult[sProp] = [vResult[sProp]]; }
39522         vResult[sProp].push(vContent);
39523       } else {
39524         vResult[sProp] = vContent;
39525         nLength++;
39526       }
39527     }
39528
39529     if (bAttributes) {
39530       var
39531         nAttrLen = oParentNode.attributes.length,
39532         sAPrefix = bNesteAttr ? '' : sAttrPref, oAttrParent = bNesteAttr ? {} : vResult;
39533
39534       for (var oAttrib, nAttrib = 0; nAttrib < nAttrLen; nLength++, nAttrib++) {
39535         oAttrib = oParentNode.attributes.item(nAttrib);
39536         oAttrParent[sAPrefix + oAttrib.name.toLowerCase()] = parseText(oAttrib.value.trim());
39537       }
39538
39539       if (bNesteAttr) {
39540         if (bFreeze) { Object.freeze(oAttrParent); }
39541         vResult[sAttributesProp] = oAttrParent;
39542         nLength -= nAttrLen - 1;
39543       }
39544     }
39545
39546     if (nVerb === 3 || (nVerb === 2 || nVerb === 1 && nLength > 0) && sCollectedTxt) {
39547       vResult[sValueProp] = vBuiltVal;
39548     } else if (!bHighVerb && nLength === 0 && sCollectedTxt) {
39549       vResult = vBuiltVal;
39550     }
39551
39552     if (bFreeze && (bHighVerb || nLength > 0)) { Object.freeze(vResult); }
39553
39554     aCache.length = nLevelStart;
39555
39556     return vResult;
39557   }
39558
39559   function loadObjTree (oXMLDoc, oParentEl, oParentObj) {
39560     var vValue, oChild;
39561
39562     if (oParentObj instanceof String || oParentObj instanceof Number || oParentObj instanceof Boolean) {
39563       oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toString())); /* verbosity level is 0 */
39564     } else if (oParentObj.constructor === Date) {
39565       oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toGMTString()));    
39566     }
39567
39568     for (var sName in oParentObj) {
39569       vValue = oParentObj[sName];
39570       if (isFinite(sName) || vValue instanceof Function) { continue; } /* verbosity level is 0 */
39571       if (sName === sValueProp) {
39572         if (vValue !== null && vValue !== true) { oParentEl.appendChild(oXMLDoc.createTextNode(vValue.constructor === Date ? vValue.toGMTString() : String(vValue))); }
39573       } else if (sName === sAttributesProp) { /* verbosity level is 3 */
39574         for (var sAttrib in vValue) { oParentEl.setAttribute(sAttrib, vValue[sAttrib]); }
39575       } else if (sName.charAt(0) === sAttrPref) {
39576         oParentEl.setAttribute(sName.slice(1), vValue);
39577       } else if (vValue.constructor === Array) {
39578         for (var nItem = 0; nItem < vValue.length; nItem++) {
39579           oChild = oXMLDoc.createElement(sName);
39580           loadObjTree(oXMLDoc, oChild, vValue[nItem]);
39581           oParentEl.appendChild(oChild);
39582         }
39583       } else {
39584         oChild = oXMLDoc.createElement(sName);
39585         if (vValue instanceof Object) {
39586           loadObjTree(oXMLDoc, oChild, vValue);
39587         } else if (vValue !== null && vValue !== true) {
39588           oChild.appendChild(oXMLDoc.createTextNode(vValue.toString()));
39589         }
39590         oParentEl.appendChild(oChild);
39591      }
39592    }
39593   }
39594
39595   this.build = function (oXMLParent, nVerbosity /* optional */, bFreeze /* optional */, bNesteAttributes /* optional */) {
39596     var _nVerb = arguments.length > 1 && typeof nVerbosity === 'number' ? nVerbosity & 3 : /* put here the default verbosity level: */ 1;
39597     return createObjTree(oXMLParent, _nVerb, bFreeze || false, arguments.length > 3 ? bNesteAttributes : _nVerb === 3);    
39598   };
39599
39600   this.unbuild = function (oObjTree) {    
39601     var oNewDoc = document.implementation.createDocument('', '', null);
39602     loadObjTree(oNewDoc, oNewDoc, oObjTree);
39603     return oNewDoc;
39604   };
39605
39606   this.stringify = function (oObjTree) {
39607     return (new XMLSerializer()).serializeToString(JXON.unbuild(oObjTree));
39608   };
39609 })();
39610
39611 // var myObject = JXON.build(doc);
39612 // we got our javascript object! try: alert(JSON.stringify(myObject));
39613
39614 // var newDoc = JXON.unbuild(myObject);
39615 // we got our Document instance! try: alert((new XMLSerializer()).serializeToString(newDoc));
39616
39617 var dispatch$3 = dispatch('authLoading', 'authDone', 'change', 'loading', 'loaded');
39618 var urlroot = 'https://www.openstreetmap.org';
39619 var oauth = osmAuth({
39620     url: urlroot,
39621     oauth_consumer_key: '5A043yRSEugj4DJ5TljuapfnrflWDte8jTOcWLlT',
39622     oauth_secret: 'aB3jKq1TRsCOUrfOIZ6oQMEDmv2ptV76PA54NGLL',
39623     loading: authLoading,
39624     done: authDone
39625 });
39626
39627 var _blacklists = ['.*\.google(apis)?\..*/(vt|kh)[\?/].*([xyz]=.*){3}.*'];
39628 var _tiles = { loaded: {}, inflight: {} };
39629 var _changeset = {};
39630 var _entityCache = {};
39631 var _connectionID = 1;
39632 var _tileZoom = 16;
39633 var _rateLimitError;
39634 var _userChangesets;
39635 var _userDetails;
39636 var _off;
39637
39638
39639 function authLoading() {
39640     dispatch$3.call('authLoading');
39641 }
39642
39643
39644 function authDone() {
39645     dispatch$3.call('authDone');
39646 }
39647
39648
39649 function abortRequest$2(i) {
39650     if (i) {
39651         i.abort();
39652     }
39653 }
39654
39655
39656 function getLoc(attrs) {
39657     var lon = attrs.lon && attrs.lon.value;
39658     var lat = attrs.lat && attrs.lat.value;
39659     return [parseFloat(lon), parseFloat(lat)];
39660 }
39661
39662
39663 function getNodes(obj) {
39664     var elems = obj.getElementsByTagName('nd');
39665     var nodes = new Array(elems.length);
39666     for (var i = 0, l = elems.length; i < l; i++) {
39667         nodes[i] = 'n' + elems[i].attributes.ref.value;
39668     }
39669     return nodes;
39670 }
39671
39672
39673 function getTags(obj) {
39674     var elems = obj.getElementsByTagName('tag');
39675     var tags = {};
39676     for (var i = 0, l = elems.length; i < l; i++) {
39677         var attrs = elems[i].attributes;
39678         tags[attrs.k.value] = attrs.v.value;
39679     }
39680
39681     return tags;
39682 }
39683
39684
39685 function getMembers(obj) {
39686     var elems = obj.getElementsByTagName('member');
39687     var members = new Array(elems.length);
39688     for (var i = 0, l = elems.length; i < l; i++) {
39689         var attrs = elems[i].attributes;
39690         members[i] = {
39691             id: attrs.type.value[0] + attrs.ref.value,
39692             type: attrs.type.value,
39693             role: attrs.role.value
39694         };
39695     }
39696     return members;
39697 }
39698
39699
39700 function getVisible(attrs) {
39701     return (!attrs.visible || attrs.visible.value !== 'false');
39702 }
39703
39704
39705 var parsers = {
39706     node: function nodeData(obj, uid) {
39707         var attrs = obj.attributes;
39708         return new osmNode({
39709             id:uid,
39710             visible: getVisible(attrs),
39711             version: attrs.version.value,
39712             changeset: attrs.changeset && attrs.changeset.value,
39713             timestamp: attrs.timestamp && attrs.timestamp.value,
39714             user: attrs.user && attrs.user.value,
39715             uid: attrs.uid && attrs.uid.value,
39716             loc: getLoc(attrs),
39717             tags: getTags(obj)
39718         });
39719     },
39720
39721     way: function wayData(obj, uid) {
39722         var attrs = obj.attributes;
39723         return new osmWay({
39724             id: uid,
39725             visible: getVisible(attrs),
39726             version: attrs.version.value,
39727             changeset: attrs.changeset && attrs.changeset.value,
39728             timestamp: attrs.timestamp && attrs.timestamp.value,
39729             user: attrs.user && attrs.user.value,
39730             uid: attrs.uid && attrs.uid.value,
39731             tags: getTags(obj),
39732             nodes: getNodes(obj),
39733         });
39734     },
39735
39736     relation: function relationData(obj, uid) {
39737         var attrs = obj.attributes;
39738         return new osmRelation({
39739             id: uid,
39740             visible: getVisible(attrs),
39741             version: attrs.version.value,
39742             changeset: attrs.changeset && attrs.changeset.value,
39743             timestamp: attrs.timestamp && attrs.timestamp.value,
39744             user: attrs.user && attrs.user.value,
39745             uid: attrs.uid && attrs.uid.value,
39746             tags: getTags(obj),
39747             members: getMembers(obj)
39748         });
39749     }
39750 };
39751
39752
39753 function parse(xml$$1, callback, options) {
39754     options = assignIn({ cache: true }, options);
39755     if (!xml$$1 || !xml$$1.childNodes) return;
39756
39757     var root = xml$$1.childNodes[0];
39758     var children = root.childNodes;
39759
39760     function parseChild(child) {
39761         var parser = parsers[child.nodeName];
39762         if (parser) {
39763             var uid = osmEntity.id.fromOSM(child.nodeName, child.attributes.id.value);
39764             if (options.cache && _entityCache[uid]) {
39765                 return null;
39766             }
39767             return parser(child, uid);
39768         }
39769     }
39770
39771     utilIdleWorker(children, parseChild, callback);
39772 }
39773
39774
39775 var serviceOsm = {
39776
39777     init: function() {
39778         utilRebind(this, dispatch$3, 'on');
39779     },
39780
39781
39782     reset: function() {
39783         _connectionID++;
39784         _userChangesets = undefined;
39785         _userDetails = undefined;
39786         _rateLimitError = undefined;
39787         forEach(_tiles.inflight, abortRequest$2);
39788         if (_changeset.inflight) abortRequest$2(_changeset.inflight);
39789         _tiles = { loaded: {}, inflight: {} };
39790         _changeset = {};
39791         _entityCache = {};
39792         return this;
39793     },
39794
39795
39796     getConnectionId: function() {
39797         return _connectionID;
39798     },
39799
39800
39801     changesetURL: function(changesetId) {
39802         return urlroot + '/changeset/' + changesetId;
39803     },
39804
39805
39806     changesetsURL: function(center, zoom) {
39807         var precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2));
39808         return urlroot + '/history#map=' +
39809             Math.floor(zoom) + '/' +
39810             center[1].toFixed(precision) + '/' +
39811             center[0].toFixed(precision);
39812     },
39813
39814
39815     entityURL: function(entity) {
39816         return urlroot + '/' + entity.type + '/' + entity.osmId();
39817     },
39818
39819
39820     historyURL: function(entity) {
39821         return urlroot + '/' + entity.type + '/' + entity.osmId() + '/history';
39822     },
39823
39824
39825     userURL: function(username) {
39826         return urlroot + '/user/' + username;
39827     },
39828
39829
39830     loadFromAPI: function(path, callback, options) {
39831         options = assignIn({ cache: true }, options);
39832         var that = this;
39833         var cid = _connectionID;
39834
39835         function done(err, xml$$1) {
39836             if (that.getConnectionId() !== cid) {
39837                 if (callback) callback({ message: 'Connection Switched', status: -1 });
39838                 return;
39839             }
39840
39841             var isAuthenticated = that.authenticated();
39842
39843             // 400 Bad Request, 401 Unauthorized, 403 Forbidden
39844             // Logout and retry the request..
39845             if (isAuthenticated && err && (err.status === 400 || err.status === 401 || err.status === 403)) {
39846                 that.logout();
39847                 that.loadFromAPI(path, callback);
39848
39849             // else, no retry..
39850             } else {
39851                 // 509 Bandwidth Limit Exceeded, 429 Too Many Requests
39852                 // Set the rateLimitError flag and trigger a warning..
39853                 if (!isAuthenticated && !_rateLimitError && err &&
39854                         (err.status === 509 || err.status === 429)) {
39855                     _rateLimitError = err;
39856                     dispatch$3.call('change');
39857                 }
39858
39859                 if (callback) {
39860                     if (err) return callback(err, null);
39861                     parse(xml$$1, function (entities) {
39862                         if (options.cache) {
39863                             for (var i in entities) {
39864                                 _entityCache[entities[i].id] = true;
39865                             }
39866                         }
39867                         callback(null, entities);
39868                     }, options);
39869                 }
39870             }
39871         }
39872
39873         if (this.authenticated()) {
39874             return oauth.xhr({ method: 'GET', path: path }, done);
39875         } else {
39876             var url = urlroot + path;
39877             return d3_xml(url).get(done);
39878         }
39879     },
39880
39881
39882     loadEntity: function(id, callback) {
39883         var type = osmEntity.id.type(id);
39884         var osmID = osmEntity.id.toOSM(id);
39885         var options = { cache: false };
39886
39887         this.loadFromAPI(
39888             '/api/0.6/' + type + '/' + osmID + (type !== 'node' ? '/full' : ''),
39889             function(err, entities) {
39890                 if (callback) callback(err, { data: entities });
39891             },
39892             options
39893         );
39894     },
39895
39896
39897     loadEntityVersion: function(id, version, callback) {
39898         var type = osmEntity.id.type(id);
39899         var osmID = osmEntity.id.toOSM(id);
39900         var options = { cache: false };
39901
39902         this.loadFromAPI(
39903             '/api/0.6/' + type + '/' + osmID + '/' + version,
39904             function(err, entities) {
39905                 if (callback) callback(err, { data: entities });
39906             },
39907             options
39908         );
39909     },
39910
39911
39912     loadMultiple: function(ids, callback) {
39913         var that = this;
39914
39915         forEach(groupBy(uniq(ids), osmEntity.id.type), function(v, k) {
39916             var type = k + 's';
39917             var osmIDs = map$4(v, osmEntity.id.toOSM);
39918             var options = { cache: false };
39919
39920             forEach(chunk(osmIDs, 150), function(arr) {
39921                 that.loadFromAPI(
39922                     '/api/0.6/' + type + '?' + type + '=' + arr.join(),
39923                     function(err, entities) {
39924                         if (callback) callback(err, { data: entities });
39925                     },
39926                     options
39927                 );
39928             });
39929         });
39930     },
39931
39932
39933     authenticated: function() {
39934         return oauth.authenticated();
39935     },
39936
39937
39938     putChangeset: function(changeset, changes, callback) {
39939         if (_changeset.inflight) {
39940             return callback({ message: 'Changeset already inflight', status: -2 }, changeset);
39941         }
39942
39943         var that = this;
39944         var cid = _connectionID;
39945
39946         if (_changeset.open) {   // reuse existing open changeset..
39947             createdChangeset(null, _changeset.open);
39948         } else {                 // open a new changeset..
39949             _changeset.inflight = oauth.xhr({
39950                 method: 'PUT',
39951                 path: '/api/0.6/changeset/create',
39952                 options: { header: { 'Content-Type': 'text/xml' } },
39953                 content: JXON.stringify(changeset.asJXON())
39954             }, createdChangeset);
39955         }
39956
39957
39958         function createdChangeset(err, changesetID) {
39959             _changeset.inflight = null;
39960
39961             if (err) {
39962                 // 400 Bad Request, 401 Unauthorized, 403 Forbidden..
39963                 if (err.status === 400 || err.status === 401 || err.status === 403) {
39964                     that.logout();
39965                 }
39966                 return callback(err, changeset);
39967             }
39968             if (that.getConnectionId() !== cid) {
39969                 return callback({ message: 'Connection Switched', status: -1 }, changeset);
39970             }
39971
39972             _changeset.open = changesetID;
39973             changeset = changeset.update({ id: changesetID });
39974
39975             // Upload the changeset..
39976             _changeset.inflight = oauth.xhr({
39977                 method: 'POST',
39978                 path: '/api/0.6/changeset/' + changesetID + '/upload',
39979                 options: { header: { 'Content-Type': 'text/xml' } },
39980                 content: JXON.stringify(changeset.osmChangeJXON(changes))
39981             }, uploadedChangeset);
39982         }
39983
39984
39985         function uploadedChangeset(err) {
39986             _changeset.inflight = null;
39987
39988             if (err) return callback(err, changeset);
39989
39990             // Upload was successful, safe to call the callback.
39991             // Add delay to allow for postgres replication #1646 #2678
39992             window.setTimeout(function() {
39993                 callback(null, changeset);
39994             }, 2500);
39995
39996             _changeset.open = null;
39997
39998             // At this point, we don't really care if the connection was switched..
39999             // Only try to close the changeset if we're still talking to the same server.
40000             if (that.getConnectionId() === cid) {
40001                 // Still attempt to close changeset, but ignore response because #2667
40002                 oauth.xhr({
40003                     method: 'PUT',
40004                     path: '/api/0.6/changeset/' + changeset.id + '/close',
40005                     options: { header: { 'Content-Type': 'text/xml' } }
40006                 }, function() { return true; });
40007             }
40008         }
40009     },
40010
40011
40012     userDetails: function(callback) {
40013         if (_userDetails) {
40014             callback(undefined, _userDetails);
40015             return;
40016         }
40017
40018         var that = this;
40019         var cid = _connectionID;
40020
40021         function done(err, user_details) {
40022             if (err) {
40023                 // 400 Bad Request, 401 Unauthorized, 403 Forbidden..
40024                 if (err.status === 400 || err.status === 401 || err.status === 403) {
40025                     that.logout();
40026                 }
40027                 return callback(err);
40028             }
40029             if (that.getConnectionId() !== cid) {
40030                 return callback({ message: 'Connection Switched', status: -1 });
40031             }
40032
40033
40034             var u = user_details.getElementsByTagName('user')[0];
40035             var img = u.getElementsByTagName('img');
40036             var image_url = '';
40037
40038             if (img && img[0] && img[0].getAttribute('href')) {
40039                 image_url = img[0].getAttribute('href');
40040             }
40041
40042             var changesets = u.getElementsByTagName('changesets');
40043             var changesets_count = 0;
40044
40045             if (changesets && changesets[0] && changesets[0].getAttribute('count')) {
40046                 changesets_count = changesets[0].getAttribute('count');
40047             }
40048
40049             _userDetails = {
40050                 id: u.attributes.id.value,
40051                 display_name: u.attributes.display_name.value,
40052                 image_url: image_url,
40053                 changesets_count: changesets_count
40054             };
40055
40056             callback(undefined, _userDetails);
40057         }
40058
40059         oauth.xhr({ method: 'GET', path: '/api/0.6/user/details' }, done);
40060     },
40061
40062
40063     userChangesets: function(callback) {
40064         if (_userChangesets) {
40065             callback(undefined, _userChangesets);
40066             return;
40067         }
40068
40069         var that = this;
40070         var cid = _connectionID;
40071
40072         this.userDetails(function(err, user) {
40073             if (err) {
40074                 return callback(err);
40075             }
40076             if (that.getConnectionId() !== cid) {
40077                 return callback({ message: 'Connection Switched', status: -1 });
40078             }
40079
40080             function done(err, changesets) {
40081                 if (err) {
40082                     // 400 Bad Request, 401 Unauthorized, 403 Forbidden..
40083                     if (err.status === 400 || err.status === 401 || err.status === 403) {
40084                         that.logout();
40085                     }
40086                     return callback(err);
40087                 }
40088                 if (that.getConnectionId() !== cid) {
40089                     return callback({ message: 'Connection Switched', status: -1 });
40090                 }
40091
40092                 _userChangesets = Array.prototype.map.call(
40093                     changesets.getElementsByTagName('changeset'),
40094                     function (changeset) {
40095                         return { tags: getTags(changeset) };
40096                     }
40097                 ).filter(function (changeset) {
40098                     var comment = changeset.tags.comment;
40099                     return comment && comment !== '';
40100                 });
40101
40102                 callback(undefined, _userChangesets);
40103             }
40104
40105             oauth.xhr({ method: 'GET', path: '/api/0.6/changesets?user=' + user.id }, done);
40106         });
40107     },
40108
40109
40110     status: function(callback) {
40111         var that = this;
40112         var cid = _connectionID;
40113
40114         function done(xml$$1) {
40115             if (that.getConnectionId() !== cid) {
40116                 return callback({ message: 'Connection Switched', status: -1 }, 'connectionSwitched');
40117             }
40118
40119             // update blacklists
40120             var elements = xml$$1.getElementsByTagName('blacklist');
40121             var regexes = [];
40122             for (var i = 0; i < elements.length; i++) {
40123                 var regex = elements[i].getAttribute('regex');  // needs unencode?
40124                 if (regex) {
40125                     regexes.push(regex);
40126                 }
40127             }
40128             if (regexes.length) {
40129                 _blacklists = regexes;
40130             }
40131
40132
40133             if (_rateLimitError) {
40134                 callback(_rateLimitError, 'rateLimited');
40135             } else {
40136                 var apiStatus = xml$$1.getElementsByTagName('status');
40137                 var val = apiStatus[0].getAttribute('api');
40138
40139                 callback(undefined, val);
40140             }
40141         }
40142
40143         d3_xml(urlroot + '/api/capabilities').get()
40144             .on('load', done)
40145             .on('error', callback);
40146     },
40147
40148
40149     imageryBlacklists: function() {
40150         return _blacklists;
40151     },
40152
40153
40154     tileZoom: function(_) {
40155         if (!arguments.length) return _tileZoom;
40156         _tileZoom = _;
40157         return this;
40158     },
40159
40160
40161     loadTiles: function(projection, dimensions, callback) {
40162         if (_off) return;
40163
40164         var that = this;
40165         var s = projection.scale() * 2 * Math.PI;
40166         var z = Math.max(Math.log(s) / Math.log(2) - 8, 0);
40167         var ts = 256 * Math.pow(2, z - _tileZoom);
40168         var origin = [
40169             s / 2 - projection.translate()[0],
40170             s / 2 - projection.translate()[1]
40171         ];
40172
40173         var tiles = d3geoTile()
40174             .scaleExtent([_tileZoom, _tileZoom])
40175             .scale(s)
40176             .size(dimensions)
40177             .translate(projection.translate())()
40178             .map(function(tile) {
40179                 var x = tile[0] * ts - origin[0];
40180                 var y = tile[1] * ts - origin[1];
40181
40182                 return {
40183                     id: tile.toString(),
40184                     extent: geoExtent(
40185                         projection.invert([x, y + ts]),
40186                         projection.invert([x + ts, y]))
40187                 };
40188             });
40189
40190         filter(_tiles.inflight, function(v, i) {
40191             var wanted = find$1(tiles, function(tile) {
40192                 return i === tile.id;
40193             });
40194             if (!wanted) delete _tiles.inflight[i];
40195             return !wanted;
40196         }).map(abortRequest$2);
40197
40198         tiles.forEach(function(tile) {
40199             var id = tile.id;
40200
40201             if (_tiles.loaded[id] || _tiles.inflight[id]) return;
40202
40203             if (isEmpty(_tiles.inflight)) {
40204                 dispatch$3.call('loading');
40205             }
40206
40207             _tiles.inflight[id] = that.loadFromAPI(
40208                 '/api/0.6/map?bbox=' + tile.extent.toParam(),
40209                 function(err, parsed) {
40210                     delete _tiles.inflight[id];
40211                     if (!err) {
40212                         _tiles.loaded[id] = true;
40213                     }
40214
40215                     if (callback) {
40216                         callback(err, assignIn({ data: parsed }, tile));
40217                     }
40218
40219                     if (isEmpty(_tiles.inflight)) {
40220                         dispatch$3.call('loaded');
40221                     }
40222                 }
40223             );
40224         });
40225     },
40226
40227
40228     switch: function(options) {
40229         urlroot = options.urlroot;
40230
40231         oauth.options(assignIn({
40232             url: urlroot,
40233             loading: authLoading,
40234             done: authDone
40235         }, options));
40236
40237         this.reset();
40238         this.userChangesets(function() {});  // eagerly load user details/changesets
40239         dispatch$3.call('change');
40240         return this;
40241     },
40242
40243
40244     toggle: function(_) {
40245         _off = !_;
40246         return this;
40247     },
40248
40249
40250     loadedTiles: function(_) {
40251         if (!arguments.length) return _tiles.loaded;
40252         _tiles.loaded = _;
40253         return this;
40254     },
40255
40256
40257     logout: function() {
40258         _userChangesets = undefined;
40259         _userDetails = undefined;
40260         oauth.logout();
40261         dispatch$3.call('change');
40262         return this;
40263     },
40264
40265
40266     authenticate: function(callback) {
40267         var that = this;
40268         var cid = _connectionID;
40269         _userChangesets = undefined;
40270         _userDetails = undefined;
40271
40272         function done(err, res) {
40273             if (err) {
40274                 if (callback) callback(err);
40275                 return;
40276             }
40277             if (that.getConnectionId() !== cid) {
40278                 if (callback) callback({ message: 'Connection Switched', status: -1 });
40279                 return;
40280             }
40281             _rateLimitError = undefined;
40282             dispatch$3.call('change');
40283             if (callback) callback(err, res);
40284             that.userChangesets(function() {});  // eagerly load user details/changesets
40285         }
40286
40287         return oauth.authenticate(done);
40288     }
40289 };
40290
40291 var apibase$3 = 'https://taginfo.openstreetmap.org/api/4/';
40292 var inflight$1 = {};
40293 var popularKeys = {};
40294 var taginfoCache = {};
40295 var tag_sorts = {
40296         point: 'count_nodes',
40297         vertex: 'count_nodes',
40298         area: 'count_ways',
40299         line: 'count_ways'
40300     };
40301 var tag_sort_members = {
40302         point: 'count_node_members',
40303         vertex: 'count_node_members',
40304         area: 'count_way_members',
40305         line: 'count_way_members',
40306         relation: 'count_relation_members'
40307     };
40308 var tag_filters = {
40309         point: 'nodes',
40310         vertex: 'nodes',
40311         area: 'ways',
40312         line: 'ways'
40313     };
40314 var tag_members_fractions = {
40315         point: 'count_node_members_fraction',
40316         vertex: 'count_node_members_fraction',
40317         area: 'count_way_members_fraction',
40318         line: 'count_way_members_fraction',
40319         relation: 'count_relation_members_fraction'
40320     };
40321
40322
40323 function sets(params, n, o) {
40324     if (params.geometry && o[params.geometry]) {
40325         params[n] = o[params.geometry];
40326     }
40327     return params;
40328 }
40329
40330
40331 function setFilter(params) {
40332     return sets(params, 'filter', tag_filters);
40333 }
40334
40335
40336 function setSort(params) {
40337     return sets(params, 'sortname', tag_sorts);
40338 }
40339
40340
40341 function setSortMembers(params) {
40342     return sets(params, 'sortname', tag_sort_members);
40343 }
40344
40345
40346 function clean(params) {
40347     return omit(params, ['geometry', 'debounce']);
40348 }
40349
40350
40351 function filterKeys(type) {
40352     var count_type = type ? 'count_' + type : 'count_all';
40353     return function(d) {
40354         return parseFloat(d[count_type]) > 2500 || d.in_wiki;
40355     };
40356 }
40357
40358
40359 function filterMultikeys(prefix) {
40360     return function(d) {
40361         // d.key begins with prefix, and d.key contains no additional ':'s
40362         var re = new RegExp('^' + prefix + '(.*)$');
40363         var matches = d.key.match(re) || [];
40364         return (matches.length === 2 && matches[1].indexOf(':') === -1);
40365     };
40366 }
40367
40368
40369 function filterValues(allowUpperCase) {
40370     return function(d) {
40371         if (d.value.match(/[;,]/) !== null) return false;  // exclude some punctuation
40372         if (!allowUpperCase && d.value.match(/[A-Z*]/) !== null) return false;  // exclude uppercase letters
40373         return parseFloat(d.fraction) > 0.0 || d.in_wiki;
40374     };
40375 }
40376
40377
40378 function filterRoles(geometry) {
40379     return function(d) {
40380         if (d.role === '') return false; // exclude empty role
40381         if (d.role.match(/[A-Z*;,]/) !== null) return false;  // exclude uppercase letters and some punctuation
40382         return parseFloat(d[tag_members_fractions[geometry]]) > 0.0;
40383     };
40384 }
40385
40386
40387 function valKey(d) {
40388     return {
40389         value: d.key,
40390         title: d.key
40391     };
40392 }
40393
40394
40395 function valKeyDescription(d) {
40396     return {
40397         value: d.value,
40398         title: d.description || d.value
40399     };
40400 }
40401
40402
40403 function roleKey(d) {
40404     return {
40405         value: d.role,
40406         title: d.role
40407     };
40408 }
40409
40410
40411 // sort keys with ':' lower than keys without ':'
40412 function sortKeys(a, b) {
40413     return (a.key.indexOf(':') === -1 && b.key.indexOf(':') !== -1) ? -1
40414         : (a.key.indexOf(':') !== -1 && b.key.indexOf(':') === -1) ? 1
40415         : 0;
40416 }
40417
40418
40419 var debouncedRequest = debounce(request, 500, { leading: false });
40420
40421 function request(url, params, exactMatch, callback, loaded) {
40422     if (inflight$1[url]) return;
40423
40424     if (checkCache(url, params, exactMatch, callback)) return;
40425
40426     inflight$1[url] = d3_json(url, function (err, data) {
40427         delete inflight$1[url];
40428         loaded(err, data);
40429     });
40430 }
40431
40432
40433 function checkCache(url, params, exactMatch, callback) {
40434     var rp = params.rp || 25,
40435         testQuery = params.query || '',
40436         testUrl = url;
40437
40438     do {
40439         var hit = taginfoCache[testUrl];
40440
40441         // exact match, or shorter match yielding fewer than max results (rp)
40442         if (hit && (url === testUrl || hit.length < rp)) {
40443             callback(null, hit);
40444             return true;
40445         }
40446
40447         // don't try to shorten the query
40448         if (exactMatch || !testQuery.length) return false;
40449
40450         // do shorten the query to see if we already have a cached result
40451         // that has returned fewer than max results (rp)
40452         testQuery = testQuery.slice(0, -1);
40453         testUrl = url.replace(/&query=(.*?)&/, '&query=' + testQuery + '&');
40454     } while (testQuery.length >= 0);
40455
40456     return false;
40457 }
40458
40459
40460 var serviceTaginfo = {
40461
40462     init: function() {
40463         inflight$1 = {};
40464         taginfoCache = {};
40465         popularKeys = {};
40466
40467         // Fetch popular keys.  We'll exclude these from `values`
40468         // lookups because they stress taginfo, and they aren't likely
40469         // to yield meaningful autocomplete results.. see #3955
40470         var params = { rp: 100, sortname: 'values_all', sortorder: 'desc', page: 1, debounce: false };
40471         this.keys(params, function(err, data) {
40472             if (err) return;
40473             data.forEach(function(d) {
40474                 if (d.value === 'opening_hours') return;  // exception
40475                 popularKeys[d.value] = true;
40476             });
40477         });
40478     },
40479
40480
40481     reset: function() {
40482         forEach(inflight$1, function(req) { req.abort(); });
40483         inflight$1 = {};
40484     },
40485
40486
40487     keys: function(params, callback) {
40488         var doRequest = params.debounce ? debouncedRequest : request;
40489         params = clean(setSort(params));
40490         params = assignIn({ rp: 10, sortname: 'count_all', sortorder: 'desc', page: 1 }, params);
40491
40492         var url = apibase$3 + 'keys/all?' + utilQsString(params);
40493         doRequest(url, params, false, callback, function(err, d) {
40494             if (err) {
40495                 callback(err);
40496             } else {
40497                 var f = filterKeys(params.filter);
40498                 var result = d.data.filter(f).sort(sortKeys).map(valKey);
40499                 taginfoCache[url] = result;
40500                 callback(null, result);
40501             }
40502         });
40503     },
40504
40505
40506     multikeys: function(params, callback) {
40507         var doRequest = params.debounce ? debouncedRequest : request;
40508         params = clean(setSort(params));
40509         params = assignIn({ rp: 25, sortname: 'count_all', sortorder: 'desc', page: 1 }, params);
40510         var prefix = params.query;
40511
40512         var url = apibase$3 + 'keys/all?' + utilQsString(params);
40513         doRequest(url, params, true, callback, function(err, d) {
40514             if (err) {
40515                 callback(err);
40516             } else {
40517                 var f = filterMultikeys(prefix);
40518                 var result = d.data.filter(f).map(valKey);
40519                 taginfoCache[url] = result;
40520                 callback(null, result);
40521             }
40522         });
40523     },
40524
40525
40526     values: function(params, callback) {
40527         // Exclude popular keys from values lookups.. see #3955
40528         var key = params.key;
40529         if (key && popularKeys[key]) {
40530             callback(null, []);
40531             return;
40532         }
40533
40534         var doRequest = params.debounce ? debouncedRequest : request;
40535         params = clean(setSort(setFilter(params)));
40536         params = assignIn({ rp: 25, sortname: 'count_all', sortorder: 'desc', page: 1 }, params);
40537
40538         var url = apibase$3 + 'key/values?' + utilQsString(params);
40539         doRequest(url, params, false, callback, function(err, d) {
40540             if (err) {
40541                 callback(err);
40542             } else {
40543                 // In most cases we prefer taginfo value results with lowercase letters.
40544                 // A few OSM keys expect values to contain uppercase values (see #3377).
40545                 // This is not an exhaustive list (e.g. `name` also has uppercase values)
40546                 // but these are the fields where taginfo value lookup is most useful.
40547                 var re = /network|taxon|genus|species|brand|grape_variety|rating|:output|_hours|_times/;
40548                 var allowUpperCase = (params.key.match(re) !== null);
40549                 var f = filterValues(allowUpperCase);
40550
40551                 var result = d.data.filter(f).map(valKeyDescription);
40552                 taginfoCache[url] = result;
40553                 callback(null, result);
40554             }
40555         });
40556     },
40557
40558
40559     roles: function(params, callback) {
40560         var doRequest = params.debounce ? debouncedRequest : request;
40561         var geometry = params.geometry;
40562         params = clean(setSortMembers(params));
40563         params = assignIn({ rp: 25, sortname: 'count_all_members', sortorder: 'desc', page: 1 }, params);
40564
40565         var url = apibase$3 + 'relation/roles?' + utilQsString(params);
40566         doRequest(url, params, true, callback, function(err, d) {
40567             if (err) {
40568                 callback(err);
40569             } else {
40570                 var f = filterRoles(geometry);
40571                 var result = d.data.filter(f).map(roleKey);
40572                 taginfoCache[url] = result;
40573                 callback(null, result);
40574             }
40575         });
40576     },
40577
40578
40579     docs: function(params, callback) {
40580         var doRequest = params.debounce ? debouncedRequest : request;
40581         params = clean(setSort(params));
40582
40583         var path = 'key/wiki_pages?';
40584         if (params.value) path = 'tag/wiki_pages?';
40585         else if (params.rtype) path = 'relation/wiki_pages?';
40586
40587         var url = apibase$3 + path + utilQsString(params);
40588         doRequest(url, params, true, callback, function(err, d) {
40589             if (err) {
40590                 callback(err);
40591             } else {
40592                 taginfoCache[url] = d.data;
40593                 callback(null, d.data);
40594             }
40595         });
40596     },
40597
40598
40599     apibase: function(_) {
40600         if (!arguments.length) return apibase$3;
40601         apibase$3 = _;
40602         return this;
40603     }
40604
40605 };
40606
40607 var jsonpCache = {};
40608 window.jsonpCache = jsonpCache;
40609
40610 function jsonpRequest(url, callback) {
40611
40612   if (window.JSONP_FIX) {
40613     if (window.JSONP_DELAY === 0) {
40614       callback(window.JSONP_FIX);
40615     } else {
40616       setTimeout(function() {
40617         callback(window.JSONP_FIX);
40618       }, window.JSONP_DELAY || 0);
40619     }
40620     return;
40621   }
40622
40623   function rand() {
40624     var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
40625       c = '', i = -1;
40626     while (++i < 15) c += chars.charAt(Math.floor(Math.random() * 52));
40627     return c;
40628   }
40629
40630   function create(url) {
40631     var e = url.match(/callback=(\w+)/),
40632       c = e ? e[1] : rand();
40633     jsonpCache[c] = function(data) {
40634       callback(data);
40635       delete jsonpCache[c];
40636       script.remove();
40637     };
40638     return 'jsonpCache.' + c;
40639   }
40640
40641   var cb = create(url),
40642     script = d3_select('head')
40643     .append('script')
40644     .attr('type', 'text/javascript')
40645     .attr('src', url.replace(/(\{|%7B)callback(\}|%7D)/, cb));
40646 }
40647
40648 var endpoint = 'https://www.wikidata.org/w/api.php?';
40649
40650 var serviceWikidata = {
40651
40652     init: function() {},
40653     reset: function() {},
40654
40655
40656     // Given a Wikipedia language and article title, return an array of
40657     // corresponding Wikidata entities.
40658     itemsByTitle: function(lang, title, callback) {
40659         if (!title) {
40660             callback('', {});
40661             return;
40662         }
40663
40664         lang = lang || 'en';
40665         jsonpRequest(endpoint + utilQsString({
40666             action: 'wbgetentities',
40667             format: 'json',
40668             sites: lang.replace(/-/g, '_') + 'wiki',
40669             titles: title,
40670             languages: 'en', // shrink response by filtering to one language
40671             callback: '{callback}'
40672         }), function(data) {
40673             if (!data || data.error) {
40674                 callback('', {});
40675             } else {
40676                 callback(title, data.entities || {});
40677             }
40678         });
40679     }
40680
40681 };
40682
40683 var endpoint$1 = 'https://en.wikipedia.org/w/api.php?';
40684
40685 var serviceWikipedia = {
40686
40687     init: function() {},
40688     reset: function() {},
40689
40690
40691     search: function(lang, query, callback) {
40692         if (!query) {
40693             callback('', []);
40694             return;
40695         }
40696
40697         lang = lang || 'en';
40698         jsonpRequest(endpoint$1.replace('en', lang) +
40699             utilQsString({
40700                 action: 'query',
40701                 list: 'search',
40702                 srlimit: '10',
40703                 srinfo: 'suggestion',
40704                 format: 'json',
40705                 callback: '{callback}',
40706                 srsearch: query
40707             }), function(data) {
40708                 if (!data || !data.query || !data.query.search || data.error) {
40709                     callback('', []);
40710                 } else {
40711                     var results = data.query.search.map(function(d) { return d.title; });
40712                     callback(query, results);
40713                 }
40714             }
40715         );
40716     },
40717
40718
40719     suggestions: function(lang, query, callback) {
40720         if (!query) {
40721             callback('', []);
40722             return;
40723         }
40724
40725         lang = lang || 'en';
40726         jsonpRequest(endpoint$1.replace('en', lang) +
40727             utilQsString({
40728                 action: 'opensearch',
40729                 namespace: 0,
40730                 suggest: '',
40731                 format: 'json',
40732                 callback: '{callback}',
40733                 search: query
40734             }), function(data) {
40735                 if (!data || data.error) {
40736                     callback('', []);
40737                 } else {
40738                     callback(data[0], data[1] || []);
40739                 }
40740             }
40741         );
40742     },
40743
40744
40745     translations: function(lang, title, callback) {
40746         if (!title) {
40747             callback({});
40748             return;
40749         }
40750
40751         jsonpRequest(endpoint$1.replace('en', lang) +
40752             utilQsString({
40753                 action: 'query',
40754                 prop: 'langlinks',
40755                 format: 'json',
40756                 callback: '{callback}',
40757                 lllimit: 500,
40758                 titles: title
40759             }), function(data) {
40760                 if (!data || !data.query || !data.query.pages || data.error) {
40761                     callback({});
40762                 } else {
40763                     var list = data.query.pages[Object.keys(data.query.pages)[0]],
40764                         translations = {};
40765                     if (list && list.langlinks) {
40766                         list.langlinks.forEach(function(d) {
40767                             translations[d.lang] = d['*'];
40768                         });
40769                     }
40770                     callback(translations);
40771                 }
40772             }
40773         );
40774     }
40775
40776 };
40777
40778 var services = {
40779     geocoder: serviceNominatim,
40780     mapillary: serviceMapillary,
40781     openstreetcam: serviceOpenstreetcam,
40782     osm: serviceOsm,
40783     taginfo: serviceTaginfo,
40784     wikidata: serviceWikidata,
40785     wikipedia: serviceWikipedia
40786 };
40787
40788 function svgAreas(projection, context) {
40789     // Patterns only work in Firefox when set directly on element.
40790     // (This is not a bug: https://bugzilla.mozilla.org/show_bug.cgi?id=750632)
40791     var patterns = {
40792         beach: 'beach',
40793         cemetery: 'cemetery',
40794         construction: 'construction',
40795         farm: 'farmland',
40796         farmland: 'farmland',
40797         grave_yard: 'cemetery',
40798         meadow: 'meadow',
40799         military: 'construction',
40800         orchard: 'orchard',
40801         sand: 'beach',
40802         scrub: 'scrub',
40803         wetland: 'wetland',
40804     };
40805
40806     var patternKeys = ['landuse', 'natural', 'amenity'];
40807
40808
40809     function setPattern(d) {
40810         for (var i = 0; i < patternKeys.length; i++) {
40811             if (d.tags.building && d.tags.building !== 'no') continue;
40812
40813             if (patterns.hasOwnProperty(d.tags[patternKeys[i]])) {
40814                 this.style.fill = this.style.stroke = 'url("#pattern-' + patterns[d.tags[patternKeys[i]]] + '")';
40815                 return;
40816             }
40817         }
40818         this.style.fill = this.style.stroke = '';
40819     }
40820
40821
40822     function drawTargets(selection, graph, entities, filter) {
40823         var targetClass = context.getDebug('target') ? 'pink ' : 'nocolor ';
40824         var nopeClass = context.getDebug('target') ? 'red ' : 'nocolor ';
40825         var getPath = svgPath(projection).geojson;
40826         var activeID = context.activeID();
40827
40828         // The targets and nopes will be MultiLineString sub-segments of the ways
40829         var data = { targets: [], nopes: [] };
40830
40831         entities.forEach(function(way) {
40832             var features = svgSegmentWay(way, graph, activeID);
40833             data.targets.push.apply(data.targets, features.passive);
40834             data.nopes.push.apply(data.nopes, features.active);
40835         });
40836
40837
40838         // Targets allow hover and vertex snapping
40839         var targets = selection.selectAll('.area.target-allowed')
40840             .filter(function(d) { return filter(d.properties.entity); })
40841             .data(data.targets, function key(d) { return d.id; });
40842
40843         // exit
40844         targets.exit()
40845             .remove();
40846
40847         // enter/update
40848         targets.enter()
40849             .append('path')
40850             .merge(targets)
40851             .attr('d', getPath)
40852             .attr('class', function(d) { return 'way area target target-allowed ' + targetClass + d.id; });
40853
40854
40855         // NOPE
40856         var nopes = selection.selectAll('.area.target-nope')
40857             .filter(function(d) { return filter(d.properties.entity); })
40858             .data(data.nopes, function key(d) { return d.id; });
40859
40860         // exit
40861         nopes.exit()
40862             .remove();
40863
40864         // enter/update
40865         nopes.enter()
40866             .append('path')
40867             .merge(nopes)
40868             .attr('d', getPath)
40869             .attr('class', function(d) { return 'way area target target-nope ' + nopeClass + d.id; });
40870     }
40871
40872
40873
40874     function drawAreas(selection, graph, entities, filter) {
40875         var path = svgPath(projection, graph, true),
40876             areas = {},
40877             multipolygon;
40878
40879         for (var i = 0; i < entities.length; i++) {
40880             var entity = entities[i];
40881             if (entity.geometry(graph) !== 'area') continue;
40882
40883             multipolygon = osmIsSimpleMultipolygonOuterMember(entity, graph);
40884             if (multipolygon) {
40885                 areas[multipolygon.id] = {
40886                     entity: multipolygon.mergeTags(entity.tags),
40887                     area: Math.abs(entity.area(graph))
40888                 };
40889             } else if (!areas[entity.id]) {
40890                 areas[entity.id] = {
40891                     entity: entity,
40892                     area: Math.abs(entity.area(graph))
40893                 };
40894             }
40895         }
40896
40897         areas = values$1(areas).filter(function hasPath(a) { return path(a.entity); });
40898         areas.sort(function areaSort(a, b) { return b.area - a.area; });
40899         areas = map$4(areas, 'entity');
40900
40901         var strokes = areas.filter(function(area) {
40902             return area.type === 'way';
40903         });
40904
40905         var data = {
40906             clip: areas,
40907             shadow: strokes,
40908             stroke: strokes,
40909             fill: areas
40910         };
40911
40912         var clipPaths = context.surface().selectAll('defs').selectAll('.clipPath')
40913            .filter(filter)
40914            .data(data.clip, osmEntity.key);
40915
40916         clipPaths.exit()
40917            .remove();
40918
40919         var clipPathsEnter = clipPaths.enter()
40920            .append('clipPath')
40921            .attr('class', 'clipPath')
40922            .attr('id', function(entity) { return entity.id + '-clippath'; });
40923
40924         clipPathsEnter
40925            .append('path');
40926
40927         clipPaths.merge(clipPathsEnter)
40928            .selectAll('path')
40929            .attr('d', path);
40930
40931
40932         var layer = selection.selectAll('.layer-areas .layer-areas-areas');
40933
40934         var areagroup = layer
40935             .selectAll('g.areagroup')
40936             .data(['fill', 'shadow', 'stroke']);
40937
40938         areagroup = areagroup.enter()
40939             .append('g')
40940             .attr('class', function(d) { return 'areagroup area-' + d; })
40941             .merge(areagroup);
40942
40943         var paths = areagroup
40944             .selectAll('path')
40945             .filter(filter)
40946             .data(function(layer) { return data[layer]; }, osmEntity.key);
40947
40948         paths.exit()
40949             .remove();
40950
40951         var fills = selection.selectAll('.area-fill path.area').nodes();
40952
40953         var bisect = d3_bisector(function(node) {
40954             return -node.__data__.area(graph);
40955         }).left;
40956
40957         function sortedByArea(entity) {
40958             if (this._parent.__data__ === 'fill') {
40959                 return fills[bisect(fills, -entity.area(graph))];
40960             }
40961         }
40962
40963         paths = paths.enter()
40964             .insert('path', sortedByArea)
40965             .merge(paths)
40966             .each(function(entity) {
40967                 var layer = this.parentNode.__data__;
40968
40969                 this.setAttribute('class', entity.type + ' area ' + layer + ' ' + entity.id);
40970
40971                 if (layer === 'fill') {
40972                     this.setAttribute('clip-path', 'url(#' + entity.id + '-clippath)');
40973                     setPattern.apply(this, arguments);
40974                 }
40975             })
40976             .call(svgTagClasses())
40977             .attr('d', path);
40978
40979
40980         // touch targets
40981         selection.selectAll('.layer-areas .layer-areas-targets')
40982             .call(drawTargets, graph, data.stroke, filter);
40983     }
40984
40985     return drawAreas;
40986 }
40987
40988 function svgDebug(projection, context) {
40989
40990     function multipolygons(imagery) {
40991         return imagery.map(function(data$$1) {
40992             return {
40993                 type: 'MultiPolygon',
40994                 coordinates: [ data$$1.polygon ]
40995             };
40996         });
40997     }
40998
40999     function drawDebug(selection) {
41000         var showsTile = context.getDebug('tile');
41001         var showsCollision = context.getDebug('collision');
41002         var showsImagery = context.getDebug('imagery');
41003         var showsImperial = context.getDebug('imperial');
41004         var showsDriveLeft = context.getDebug('driveLeft');
41005         var showsTouchTargets = context.getDebug('target');
41006
41007         var debugData = [];
41008         if (showsTile) {
41009             debugData.push({ class: 'red', label: 'tile' });
41010         }
41011         if (showsCollision) {
41012             debugData.push({ class: 'yellow', label: 'collision' });
41013         }
41014         if (showsImagery) {
41015             debugData.push({ class: 'orange', label: 'imagery' });
41016         }
41017         if (showsImperial) {
41018             debugData.push({ class: 'cyan', label: 'imperial' });
41019         }
41020         if (showsDriveLeft) {
41021             debugData.push({ class: 'green', label: 'driveLeft' });
41022         }
41023         if (showsTouchTargets) {
41024             debugData.push({ class: 'pink', label: 'touchTargets' });
41025         }
41026
41027
41028         var legend = d3_select('#content')
41029             .selectAll('.debug-legend')
41030             .data(debugData.length ? [0] : []);
41031
41032         legend.exit()
41033             .remove();
41034
41035         legend = legend.enter()
41036             .append('div')
41037             .attr('class', 'fillD debug-legend')
41038             .merge(legend);
41039
41040
41041         var legendItems = legend.selectAll('.debug-legend-item')
41042             .data(debugData, function(d) { return d.label; });
41043
41044         legendItems.exit()
41045             .remove();
41046
41047         legendItems.enter()
41048             .append('span')
41049             .attr('class', function(d) { return 'debug-legend-item ' + d.class; })
41050             .text(function(d) { return d.label; });
41051
41052
41053         var layer = selection.selectAll('.layer-debug')
41054             .data(showsImagery || showsImperial || showsDriveLeft ? [0] : []);
41055
41056         layer.exit()
41057             .remove();
41058
41059         layer = layer.enter()
41060             .append('g')
41061             .attr('class', 'layer-debug')
41062             .merge(layer);
41063
41064
41065         var extent = context.map().extent();
41066         var dataImagery = data.imagery || [];
41067         var availableImagery = showsImagery && multipolygons(dataImagery.filter(function(source) {
41068             if (!source.polygon) return false;
41069             return source.polygon.some(function(polygon) {
41070                 return geoPolygonIntersectsPolygon(polygon, extent, true);
41071             });
41072         }));
41073
41074         var imagery = layer.selectAll('path.debug-imagery')
41075             .data(showsImagery ? availableImagery : []);
41076
41077         imagery.exit()
41078             .remove();
41079
41080         imagery.enter()
41081             .append('path')
41082             .attr('class', 'debug-imagery debug orange');
41083
41084
41085         var imperial = layer
41086             .selectAll('path.debug-imperial')
41087             .data(showsImperial ? [dataImperial] : []);
41088
41089         imperial.exit()
41090             .remove();
41091
41092         imperial.enter()
41093             .append('path')
41094             .attr('class', 'debug-imperial debug cyan');
41095
41096
41097         var driveLeft = layer
41098             .selectAll('path.debug-drive-left')
41099             .data(showsDriveLeft ? [dataDriveLeft] : []);
41100
41101         driveLeft.exit()
41102             .remove();
41103
41104         driveLeft.enter()
41105             .append('path')
41106             .attr('class', 'debug-drive-left debug green');
41107
41108
41109         // update
41110         layer.selectAll('path')
41111             .attr('d', svgPath(projection).geojson);
41112     }
41113
41114
41115     // This looks strange because `enabled` methods on other layers are
41116     // chainable getter/setters, and this one is just a getter.
41117     drawDebug.enabled = function() {
41118         if (!arguments.length) {
41119             return context.getDebug('tile') ||
41120                 context.getDebug('collision') ||
41121                 context.getDebug('imagery') ||
41122                 context.getDebug('imperial') ||
41123                 context.getDebug('driveLeft') ||
41124                 context.getDebug('target');
41125         } else {
41126             return this;
41127         }
41128     };
41129
41130
41131     return drawDebug;
41132 }
41133
41134 /*
41135     A standalone SVG element that contains only a `defs` sub-element. To be
41136     used once globally, since defs IDs must be unique within a document.
41137 */
41138 function svgDefs(context) {
41139
41140     function SVGSpriteDefinition(id, href) {
41141         return function(defs) {
41142             d3_request(href)
41143                 .mimeType('image/svg+xml')
41144                 .response(function(xhr) { return xhr.responseXML; })
41145                 .get(function(err, svg) {
41146                     if (err) return;
41147                     defs.node().appendChild(
41148                         d3_select(svg.documentElement).attr('id', id).node()
41149                     );
41150                 });
41151         };
41152     }
41153
41154
41155     return function drawDefs(selection) {
41156         var defs = selection.append('defs');
41157
41158         // markers
41159         defs
41160             .append('marker')
41161             .attr('id', 'oneway-marker')
41162             .attr('viewBox', '0 0 10 5')
41163             .attr('refX', 2.5)
41164             .attr('refY', 2.5)
41165             .attr('markerWidth', 2)
41166             .attr('markerHeight', 2)
41167             .attr('markerUnits', 'strokeWidth')
41168             .attr('orient', 'auto')
41169             .append('path')
41170             .attr('class', 'oneway-marker-path')
41171             .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')
41172             .attr('stroke', 'none')
41173             .attr('fill', '#000')
41174             .attr('opacity', '0.75');
41175
41176         defs
41177             .append('marker')
41178             .attr('id', 'viewfield-marker')
41179             .attr('viewBox', '0 0 16 16')
41180             .attr('refX', 8)
41181             .attr('refY', 16)
41182             .attr('markerWidth', 4)
41183             .attr('markerHeight', 4)
41184             .attr('markerUnits', 'strokeWidth')
41185             .attr('orient', 'auto')
41186             .append('path')
41187             .attr('class', 'viewfield-marker-path')
41188             .attr('d', 'M 6,14 C 8,13.4 8,13.4 10,14 L 16,3 C 12,0 4,0 0,3 z')
41189             .attr('fill', '#333')
41190             .attr('fill-opacity', '0.75')
41191             .attr('stroke', '#fff')
41192             .attr('stroke-width', '0.5px')
41193             .attr('stroke-opacity', '0.75');
41194
41195         defs
41196             .append('marker')
41197             .attr('id', 'viewfield-marker-wireframe')
41198             .attr('viewBox', '0 0 16 16')
41199             .attr('refX', 8)
41200             .attr('refY', 16)
41201             .attr('markerWidth', 4)
41202             .attr('markerHeight', 4)
41203             .attr('markerUnits', 'strokeWidth')
41204             .attr('orient', 'auto')
41205             .append('path')
41206             .attr('class', 'viewfield-marker-path')
41207             .attr('d', 'M 6,14 C 8,13.4 8,13.4 10,14 L 16,3 C 12,0 4,0 0,3 z')
41208             .attr('fill', 'none')
41209             .attr('stroke', '#fff')
41210             .attr('stroke-width', '0.5px')
41211             .attr('stroke-opacity', '0.75');
41212
41213         // patterns
41214         var patterns = defs.selectAll('pattern')
41215             .data([
41216                 // pattern name, pattern image name
41217                 ['wetland', 'wetland'],
41218                 ['construction', 'construction'],
41219                 ['cemetery', 'cemetery'],
41220                 ['orchard', 'orchard'],
41221                 ['farmland', 'farmland'],
41222                 ['beach', 'dots'],
41223                 ['scrub', 'dots'],
41224                 ['meadow', 'dots']
41225             ])
41226             .enter()
41227             .append('pattern')
41228             .attr('id', function (d) { return 'pattern-' + d[0]; })
41229             .attr('width', 32)
41230             .attr('height', 32)
41231             .attr('patternUnits', 'userSpaceOnUse');
41232
41233         patterns
41234             .append('rect')
41235             .attr('x', 0)
41236             .attr('y', 0)
41237             .attr('width', 32)
41238             .attr('height', 32)
41239             .attr('class', function (d) { return 'pattern-color-' + d[0]; });
41240
41241         patterns
41242             .append('image')
41243             .attr('x', 0)
41244             .attr('y', 0)
41245             .attr('width', 32)
41246             .attr('height', 32)
41247             .attr('xlink:href', function (d) {
41248                 return context.imagePath('pattern/' + d[1] + '.png');
41249             });
41250
41251         // clip paths
41252         defs.selectAll('clipPath')
41253             .data([12, 18, 20, 32, 45])
41254             .enter()
41255             .append('clipPath')
41256             .attr('id', function (d) { return 'clip-square-' + d; })
41257             .append('rect')
41258             .attr('x', 0)
41259             .attr('y', 0)
41260             .attr('width', function (d) { return d; })
41261             .attr('height', function (d) { return d; });
41262
41263         // symbol spritesheets
41264         defs
41265             .call(SVGSpriteDefinition('iD-sprite', context.imagePath('iD-sprite.svg')))
41266             .call(SVGSpriteDefinition('maki-sprite', context.imagePath('maki-sprite.svg')));
41267     };
41268 }
41269
41270 /**
41271  * Checks if `value` is `undefined`.
41272  *
41273  * @static
41274  * @since 0.1.0
41275  * @memberOf _
41276  * @category Lang
41277  * @param {*} value The value to check.
41278  * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
41279  * @example
41280  *
41281  * _.isUndefined(void 0);
41282  * // => true
41283  *
41284  * _.isUndefined(null);
41285  * // => false
41286  */
41287 function isUndefined(value) {
41288   return value === undefined;
41289 }
41290
41291 //[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]
41292 //[4a]          NameChar           ::=          NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
41293 //[5]           Name       ::=          NameStartChar (NameChar)*
41294 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
41295 var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\\u00B7\\u0300-\\u036F\\u203F-\\u2040]");
41296 var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$');
41297 //var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/
41298 //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(',')
41299
41300 //S_TAG,        S_ATTR, S_EQ,   S_ATTR_NOQUOT_VALUE
41301 //S_ATTR_SPACE, S_ATTR_END,     S_TAG_SPACE, S_TAG_CLOSE
41302 var S_TAG = 0;//tag name offerring
41303 var S_ATTR = 1;//attr name offerring 
41304 var S_ATTR_SPACE=2;//attr name end and space offer
41305 var S_EQ = 3;//=space?
41306 var S_ATTR_NOQUOT_VALUE = 4;//attr value(no quot value only)
41307 var S_ATTR_END = 5;//attr value end and no space(quot end)
41308 var S_TAG_SPACE = 6;//(attr value end || tag end ) && (space offer)
41309 var S_TAG_CLOSE = 7;//closed el<el />
41310
41311 function XMLReader(){
41312         
41313 }
41314
41315 XMLReader.prototype = {
41316         parse:function(source,defaultNSMap,entityMap){
41317                 var domBuilder = this.domBuilder;
41318                 domBuilder.startDocument();
41319                 _copy(defaultNSMap ,defaultNSMap = {});
41320                 parse$1(source,defaultNSMap,entityMap,
41321                                 domBuilder,this.errorHandler);
41322                 domBuilder.endDocument();
41323         }
41324 };
41325 function parse$1(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){
41326         function fixedFromCharCode(code) {
41327                 // String.prototype.fromCharCode does not supports
41328                 // > 2 bytes unicode chars directly
41329                 if (code > 0xffff) {
41330                         code -= 0x10000;
41331                         var surrogate1 = 0xd800 + (code >> 10)
41332                                 , surrogate2 = 0xdc00 + (code & 0x3ff);
41333
41334                         return String.fromCharCode(surrogate1, surrogate2);
41335                 } else {
41336                         return String.fromCharCode(code);
41337                 }
41338         }
41339         function entityReplacer(a){
41340                 var k = a.slice(1,-1);
41341                 if(k in entityMap){
41342                         return entityMap[k]; 
41343                 }else if(k.charAt(0) === '#'){
41344                         return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x')))
41345                 }else{
41346                         errorHandler.error('entity not found:'+a);
41347                         return a;
41348                 }
41349         }
41350         function appendText(end){//has some bugs
41351                 if(end>start){
41352                         var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer);
41353                         locator&&position(start);
41354                         domBuilder.characters(xt,0,end-start);
41355                         start = end;
41356                 }
41357         }
41358         function position(p,m){
41359                 while(p>=lineEnd && (m = linePattern.exec(source))){
41360                         lineStart = m.index;
41361                         lineEnd = lineStart + m[0].length;
41362                         locator.lineNumber++;
41363                         //console.log('line++:',locator,startPos,endPos)
41364                 }
41365                 locator.columnNumber = p-lineStart+1;
41366         }
41367         var lineStart = 0;
41368         var lineEnd = 0;
41369         var linePattern = /.*(?:\r\n?|\n)|.*$/g;
41370         var locator = domBuilder.locator;
41371         
41372         var parseStack = [{currentNSMap:defaultNSMapCopy}];
41373         var closeMap = {};
41374         var start = 0;
41375         while(true){
41376                 try{
41377                         var tagStart = source.indexOf('<',start);
41378                         if(tagStart<0){
41379                                 if(!source.substr(start).match(/^\s*$/)){
41380                                         var doc = domBuilder.doc;
41381                                 var text = doc.createTextNode(source.substr(start));
41382                                 doc.appendChild(text);
41383                                 domBuilder.currentElement = text;
41384                                 }
41385                                 return;
41386                         }
41387                         if(tagStart>start){
41388                                 appendText(tagStart);
41389                         }
41390                         switch(source.charAt(tagStart+1)){
41391                         case '/':
41392                                 var end = source.indexOf('>',tagStart+3);
41393                                 var tagName = source.substring(tagStart+2,end);
41394                                 var config = parseStack.pop();
41395                                 if(end<0){
41396                                         
41397                                 tagName = source.substring(tagStart+2).replace(/[\s<].*/,'');
41398                                 //console.error('#@@@@@@'+tagName)
41399                                 errorHandler.error("end tag name: "+tagName+' is not complete:'+config.tagName);
41400                                 end = tagStart+1+tagName.length;
41401                         }else if(tagName.match(/\s</)){
41402                                 tagName = tagName.replace(/[\s<].*/,'');
41403                                 errorHandler.error("end tag name: "+tagName+' maybe not complete');
41404                                 end = tagStart+1+tagName.length;
41405                                 }
41406                                 //console.error(parseStack.length,parseStack)
41407                                 //console.error(config);
41408                                 var localNSMap = config.localNSMap;
41409                                 var endMatch = config.tagName == tagName;
41410                                 var endIgnoreCaseMach = endMatch || config.tagName&&config.tagName.toLowerCase() == tagName.toLowerCase();
41411                         if(endIgnoreCaseMach){
41412                                 domBuilder.endElement(config.uri,config.localName,tagName);
41413                                         if(localNSMap){
41414                                                 for(var prefix in localNSMap){
41415                                                         domBuilder.endPrefixMapping(prefix) ;
41416                                                 }
41417                                         }
41418                                         if(!endMatch){
41419                                 errorHandler.fatalError("end tag name: "+tagName+' is not match the current start tagName:'+config.tagName );
41420                                         }
41421                         }else{
41422                                 parseStack.push(config);
41423                         }
41424                                 
41425                                 end++;
41426                                 break;
41427                                 // end elment
41428                         case '?':// <?...?>
41429                                 locator&&position(tagStart);
41430                                 end = parseInstruction(source,tagStart,domBuilder);
41431                                 break;
41432                         case '!':// <!doctype,<![CDATA,<!--
41433                                 locator&&position(tagStart);
41434                                 end = parseDCC(source,tagStart,domBuilder,errorHandler);
41435                                 break;
41436                         default:
41437                                 locator&&position(tagStart);
41438                                 var el = new ElementAttributes();
41439                                 var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
41440                                 //elStartEnd
41441                                 var end = parseElementStartPart(source,tagStart,el,currentNSMap,entityReplacer,errorHandler);
41442                                 var len = el.length;
41443                                 
41444                                 
41445                                 if(!el.closed && fixSelfClosed(source,end,el.tagName,closeMap)){
41446                                         el.closed = true;
41447                                         if(!entityMap.nbsp){
41448                                                 errorHandler.warning('unclosed xml attribute');
41449                                         }
41450                                 }
41451                                 if(locator && len){
41452                                         var locator2 = copyLocator(locator,{});
41453                                         //try{//attribute position fixed
41454                                         for(var i = 0;i<len;i++){
41455                                                 var a = el[i];
41456                                                 position(a.offset);
41457                                                 a.locator = copyLocator(locator,{});
41458                                         }
41459                                         //}catch(e){console.error('@@@@@'+e)}
41460                                         domBuilder.locator = locator2;
41461                                         if(appendElement(el,domBuilder,currentNSMap)){
41462                                                 parseStack.push(el);
41463                                         }
41464                                         domBuilder.locator = locator;
41465                                 }else{
41466                                         if(appendElement(el,domBuilder,currentNSMap)){
41467                                                 parseStack.push(el);
41468                                         }
41469                                 }
41470                                 
41471                                 
41472                                 
41473                                 if(el.uri === 'http://www.w3.org/1999/xhtml' && !el.closed){
41474                                         end = parseHtmlSpecialContent(source,end,el.tagName,entityReplacer,domBuilder);
41475                                 }else{
41476                                         end++;
41477                                 }
41478                         }
41479                 }catch(e){
41480                         errorHandler.error('element parse error: '+e);
41481                         //errorHandler.error('element parse error: '+e);
41482                         end = -1;
41483                         //throw e;
41484                 }
41485                 if(end>start){
41486                         start = end;
41487                 }else{
41488                         //TODO: 这里有可能sax回退,有位置错误风险
41489                         appendText(Math.max(tagStart,start)+1);
41490                 }
41491         }
41492 }
41493 function copyLocator(f,t){
41494         t.lineNumber = f.lineNumber;
41495         t.columnNumber = f.columnNumber;
41496         return t;
41497 }
41498
41499 /**
41500  * @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack);
41501  * @return end of the elementStartPart(end of elementEndPart for selfClosed el)
41502  */
41503 function parseElementStartPart(source,start,el,currentNSMap,entityReplacer,errorHandler){
41504         var attrName;
41505         var value;
41506         var p = ++start;
41507         var s = S_TAG;//status
41508         while(true){
41509                 var c = source.charAt(p);
41510                 switch(c){
41511                 case '=':
41512                         if(s === S_ATTR){//attrName
41513                                 attrName = source.slice(start,p);
41514                                 s = S_EQ;
41515                         }else if(s === S_ATTR_SPACE){
41516                                 s = S_EQ;
41517                         }else{
41518                                 //fatalError: equal must after attrName or space after attrName
41519                                 throw new Error('attribute equal must after attrName');
41520                         }
41521                         break;
41522                 case '\'':
41523                 case '"':
41524                         if(s === S_EQ || s === S_ATTR //|| s == S_ATTR_SPACE
41525                                 ){//equal
41526                                 if(s === S_ATTR){
41527                                         errorHandler.warning('attribute value must after "="');
41528                                         attrName = source.slice(start,p);
41529                                 }
41530                                 start = p+1;
41531                                 p = source.indexOf(c,start);
41532                                 if(p>0){
41533                                         value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
41534                                         el.add(attrName,value,start-1);
41535                                         s = S_ATTR_END;
41536                                 }else{
41537                                         //fatalError: no end quot match
41538                                         throw new Error('attribute value no end \''+c+'\' match');
41539                                 }
41540                         }else if(s == S_ATTR_NOQUOT_VALUE){
41541                                 value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
41542                                 //console.log(attrName,value,start,p)
41543                                 el.add(attrName,value,start);
41544                                 //console.dir(el)
41545                                 errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!');
41546                                 start = p+1;
41547                                 s = S_ATTR_END;
41548                         }else{
41549                                 //fatalError: no equal before
41550                                 throw new Error('attribute value must after "="');
41551                         }
41552                         break;
41553                 case '/':
41554                         switch(s){
41555                         case S_TAG:
41556                                 el.setTagName(source.slice(start,p));
41557                         case S_ATTR_END:
41558                         case S_TAG_SPACE:
41559                         case S_TAG_CLOSE:
41560                                 s =S_TAG_CLOSE;
41561                                 el.closed = true;
41562                         case S_ATTR_NOQUOT_VALUE:
41563                         case S_ATTR:
41564                         case S_ATTR_SPACE:
41565                                 break;
41566                         //case S_EQ:
41567                         default:
41568                                 throw new Error("attribute invalid close char('/')")
41569                         }
41570                         break;
41571                 case ''://end document
41572                         //throw new Error('unexpected end of input')
41573                         errorHandler.error('unexpected end of input');
41574                         if(s == S_TAG){
41575                                 el.setTagName(source.slice(start,p));
41576                         }
41577                         return p;
41578                 case '>':
41579                         switch(s){
41580                         case S_TAG:
41581                                 el.setTagName(source.slice(start,p));
41582                         case S_ATTR_END:
41583                         case S_TAG_SPACE:
41584                         case S_TAG_CLOSE:
41585                                 break;//normal
41586                         case S_ATTR_NOQUOT_VALUE://Compatible state
41587                         case S_ATTR:
41588                                 value = source.slice(start,p);
41589                                 if(value.slice(-1) === '/'){
41590                                         el.closed  = true;
41591                                         value = value.slice(0,-1);
41592                                 }
41593                         case S_ATTR_SPACE:
41594                                 if(s === S_ATTR_SPACE){
41595                                         value = attrName;
41596                                 }
41597                                 if(s == S_ATTR_NOQUOT_VALUE){
41598                                         errorHandler.warning('attribute "'+value+'" missed quot(")!!');
41599                                         el.add(attrName,value.replace(/&#?\w+;/g,entityReplacer),start);
41600                                 }else{
41601                                         if(currentNSMap[''] !== 'http://www.w3.org/1999/xhtml' || !value.match(/^(?:disabled|checked|selected)$/i)){
41602                                                 errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!');
41603                                         }
41604                                         el.add(value,value,start);
41605                                 }
41606                                 break;
41607                         case S_EQ:
41608                                 throw new Error('attribute value missed!!');
41609                         }
41610 //                      console.log(tagName,tagNamePattern,tagNamePattern.test(tagName))
41611                         return p;
41612                 /*xml space '\x20' | #x9 | #xD | #xA; */
41613                 case '\u0080':
41614                         c = ' ';
41615                 default:
41616                         if(c<= ' '){//space
41617                                 switch(s){
41618                                 case S_TAG:
41619                                         el.setTagName(source.slice(start,p));//tagName
41620                                         s = S_TAG_SPACE;
41621                                         break;
41622                                 case S_ATTR:
41623                                         attrName = source.slice(start,p);
41624                                         s = S_ATTR_SPACE;
41625                                         break;
41626                                 case S_ATTR_NOQUOT_VALUE:
41627                                         var value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
41628                                         errorHandler.warning('attribute "'+value+'" missed quot(")!!');
41629                                         el.add(attrName,value,start);
41630                                 case S_ATTR_END:
41631                                         s = S_TAG_SPACE;
41632                                         break;
41633                                 //case S_TAG_SPACE:
41634                                 //case S_EQ:
41635                                 //case S_ATTR_SPACE:
41636                                 //      void();break;
41637                                 //case S_TAG_CLOSE:
41638                                         //ignore warning
41639                                 }
41640                         }else{//not space
41641 //S_TAG,        S_ATTR, S_EQ,   S_ATTR_NOQUOT_VALUE
41642 //S_ATTR_SPACE, S_ATTR_END,     S_TAG_SPACE, S_TAG_CLOSE
41643                                 switch(s){
41644                                 //case S_TAG:void();break;
41645                                 //case S_ATTR:void();break;
41646                                 //case S_ATTR_NOQUOT_VALUE:void();break;
41647                                 case S_ATTR_SPACE:
41648                                         var tagName =  el.tagName;
41649                                         if(currentNSMap[''] !== 'http://www.w3.org/1999/xhtml' || !attrName.match(/^(?:disabled|checked|selected)$/i)){
41650                                                 errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead2!!');
41651                                         }
41652                                         el.add(attrName,attrName,start);
41653                                         start = p;
41654                                         s = S_ATTR;
41655                                         break;
41656                                 case S_ATTR_END:
41657                                         errorHandler.warning('attribute space is required"'+attrName+'"!!');
41658                                 case S_TAG_SPACE:
41659                                         s = S_ATTR;
41660                                         start = p;
41661                                         break;
41662                                 case S_EQ:
41663                                         s = S_ATTR_NOQUOT_VALUE;
41664                                         start = p;
41665                                         break;
41666                                 case S_TAG_CLOSE:
41667                                         throw new Error("elements closed character '/' and '>' must be connected to");
41668                                 }
41669                         }
41670                 }//end outer switch
41671                 //console.log('p++',p)
41672                 p++;
41673         }
41674 }
41675 /**
41676  * @return true if has new namespace define
41677  */
41678 function appendElement(el,domBuilder,currentNSMap){
41679         var tagName = el.tagName;
41680         var localNSMap = null;
41681         //var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
41682         var i = el.length;
41683         while(i--){
41684                 var a = el[i];
41685                 var qName = a.qName;
41686                 var value = a.value;
41687                 var nsp = qName.indexOf(':');
41688                 if(nsp>0){
41689                         var prefix = a.prefix = qName.slice(0,nsp);
41690                         var localName = qName.slice(nsp+1);
41691                         var nsPrefix = prefix === 'xmlns' && localName;
41692                 }else{
41693                         localName = qName;
41694                         prefix = null;
41695                         nsPrefix = qName === 'xmlns' && '';
41696                 }
41697                 //can not set prefix,because prefix !== ''
41698                 a.localName = localName ;
41699                 //prefix == null for no ns prefix attribute 
41700                 if(nsPrefix !== false){//hack!!
41701                         if(localNSMap == null){
41702                                 localNSMap = {};
41703                                 //console.log(currentNSMap,0)
41704                                 _copy(currentNSMap,currentNSMap={});
41705                                 //console.log(currentNSMap,1)
41706                         }
41707                         currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
41708                         a.uri = 'http://www.w3.org/2000/xmlns/';
41709                         domBuilder.startPrefixMapping(nsPrefix, value); 
41710                 }
41711         }
41712         var i = el.length;
41713         while(i--){
41714                 a = el[i];
41715                 var prefix = a.prefix;
41716                 if(prefix){//no prefix attribute has no namespace
41717                         if(prefix === 'xml'){
41718                                 a.uri = 'http://www.w3.org/XML/1998/namespace';
41719                         }if(prefix !== 'xmlns'){
41720                                 a.uri = currentNSMap[prefix || ''];
41721                                 
41722                                 //{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)}
41723                         }
41724                 }
41725         }
41726         var nsp = tagName.indexOf(':');
41727         if(nsp>0){
41728                 prefix = el.prefix = tagName.slice(0,nsp);
41729                 localName = el.localName = tagName.slice(nsp+1);
41730         }else{
41731                 prefix = null;//important!!
41732                 localName = el.localName = tagName;
41733         }
41734         //no prefix element has default namespace
41735         var ns = el.uri = currentNSMap[prefix || ''];
41736         domBuilder.startElement(ns,localName,tagName,el);
41737         //endPrefixMapping and startPrefixMapping have not any help for dom builder
41738         //localNSMap = null
41739         if(el.closed){
41740                 domBuilder.endElement(ns,localName,tagName);
41741                 if(localNSMap){
41742                         for(prefix in localNSMap){
41743                                 domBuilder.endPrefixMapping(prefix); 
41744                         }
41745                 }
41746         }else{
41747                 el.currentNSMap = currentNSMap;
41748                 el.localNSMap = localNSMap;
41749                 //parseStack.push(el);
41750                 return true;
41751         }
41752 }
41753 function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){
41754         if(/^(?:script|textarea)$/i.test(tagName)){
41755                 var elEndStart =  source.indexOf('</'+tagName+'>',elStartEnd);
41756                 var text = source.substring(elStartEnd+1,elEndStart);
41757                 if(/[&<]/.test(text)){
41758                         if(/^script$/i.test(tagName)){
41759                                 //if(!/\]\]>/.test(text)){
41760                                         //lexHandler.startCDATA();
41761                                         domBuilder.characters(text,0,text.length);
41762                                         //lexHandler.endCDATA();
41763                                         return elEndStart;
41764                                 //}
41765                         }//}else{//text area
41766                                 text = text.replace(/&#?\w+;/g,entityReplacer);
41767                                 domBuilder.characters(text,0,text.length);
41768                                 return elEndStart;
41769                         //}
41770                         
41771                 }
41772         }
41773         return elStartEnd+1;
41774 }
41775 function fixSelfClosed(source,elStartEnd,tagName,closeMap){
41776         //if(tagName in closeMap){
41777         var pos = closeMap[tagName];
41778         if(pos == null){
41779                 //console.log(tagName)
41780                 pos =  source.lastIndexOf('</'+tagName+'>');
41781                 if(pos<elStartEnd){//忘记闭合
41782                         pos = source.lastIndexOf('</'+tagName);
41783                 }
41784                 closeMap[tagName] =pos;
41785         }
41786         return pos<elStartEnd;
41787         //} 
41788 }
41789 function _copy(source,target){
41790         for(var n in source){target[n] = source[n];}
41791 }
41792 function parseDCC(source,start,domBuilder,errorHandler){//sure start with '<!'
41793         var next= source.charAt(start+2);
41794         switch(next){
41795         case '-':
41796                 if(source.charAt(start + 3) === '-'){
41797                         var end = source.indexOf('-->',start+4);
41798                         //append comment source.substring(4,end)//<!--
41799                         if(end>start){
41800                                 domBuilder.comment(source,start+4,end-start-4);
41801                                 return end+3;
41802                         }else{
41803                                 errorHandler.error("Unclosed comment");
41804                                 return -1;
41805                         }
41806                 }else{
41807                         //error
41808                         return -1;
41809                 }
41810         default:
41811                 if(source.substr(start+3,6) == 'CDATA['){
41812                         var end = source.indexOf(']]>',start+9);
41813                         domBuilder.startCDATA();
41814                         domBuilder.characters(source,start+9,end-start-9);
41815                         domBuilder.endCDATA(); 
41816                         return end+3;
41817                 }
41818                 //<!DOCTYPE
41819                 //startDTD(java.lang.String name, java.lang.String publicId, java.lang.String systemId) 
41820                 var matchs = split(source,start);
41821                 var len = matchs.length;
41822                 if(len>1 && /!doctype/i.test(matchs[0][0])){
41823                         var name = matchs[1][0];
41824                         var pubid = len>3 && /^public$/i.test(matchs[2][0]) && matchs[3][0];
41825                         var sysid = len>4 && matchs[4][0];
41826                         var lastMatch = matchs[len-1];
41827                         domBuilder.startDTD(name,pubid && pubid.replace(/^(['"])(.*?)\1$/,'$2'),
41828                                         sysid && sysid.replace(/^(['"])(.*?)\1$/,'$2'));
41829                         domBuilder.endDTD();
41830                         
41831                         return lastMatch.index+lastMatch[0].length
41832                 }
41833         }
41834         return -1;
41835 }
41836
41837
41838
41839 function parseInstruction(source,start,domBuilder){
41840         var end = source.indexOf('?>',start);
41841         if(end){
41842                 var match = source.substring(start,end).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);
41843                 if(match){
41844                         var len = match[0].length;
41845                         domBuilder.processingInstruction(match[1], match[2]) ;
41846                         return end+2;
41847                 }else{//error
41848                         return -1;
41849                 }
41850         }
41851         return -1;
41852 }
41853
41854 /**
41855  * @param source
41856  */
41857 function ElementAttributes(source){
41858         
41859 }
41860 ElementAttributes.prototype = {
41861         setTagName:function(tagName){
41862                 if(!tagNamePattern.test(tagName)){
41863                         throw new Error('invalid tagName:'+tagName)
41864                 }
41865                 this.tagName = tagName;
41866         },
41867         add:function(qName,value,offset){
41868                 if(!tagNamePattern.test(qName)){
41869                         throw new Error('invalid attribute:'+qName)
41870                 }
41871                 this[this.length++] = {qName:qName,value:value,offset:offset};
41872         },
41873         length:0,
41874         getLocalName:function(i){return this[i].localName},
41875         getLocator:function(i){return this[i].locator},
41876         getQName:function(i){return this[i].qName},
41877         getURI:function(i){return this[i].uri},
41878         getValue:function(i){return this[i].value}
41879 //      ,getIndex:function(uri, localName)){
41880 //              if(localName){
41881 //                      
41882 //              }else{
41883 //                      var qName = uri
41884 //              }
41885 //      },
41886 //      getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))},
41887 //      getType:function(uri,localName){}
41888 //      getType:function(i){},
41889 };
41890
41891
41892
41893
41894 function _set_proto_(thiz,parent){
41895         thiz.__proto__ = parent;
41896         return thiz;
41897 }
41898 if(!(_set_proto_({},_set_proto_.prototype) instanceof _set_proto_)){
41899         _set_proto_ = function(thiz,parent){
41900                 function p(){}
41901                 p.prototype = parent;
41902                 p = new p();
41903                 for(parent in thiz){
41904                         p[parent] = thiz[parent];
41905                 }
41906                 return p;
41907         };
41908 }
41909
41910 function split(source,start){
41911         var match;
41912         var buf = [];
41913         var reg = /'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;
41914         reg.lastIndex = start;
41915         reg.exec(source);//skip <
41916         while(match = reg.exec(source)){
41917                 buf.push(match);
41918                 if(match[1])return buf;
41919         }
41920 }
41921
41922 var XMLReader_1 = XMLReader;
41923
41924 var sax = {
41925         XMLReader: XMLReader_1
41926 };
41927
41928 /*
41929  * DOM Level 2
41930  * Object DOMException
41931  * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html
41932  * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html
41933  */
41934
41935 function copy$1(src,dest){
41936         for(var p in src){
41937                 dest[p] = src[p];
41938         }
41939 }
41940 /**
41941 ^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));?
41942 ^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));?
41943  */
41944 function _extends(Class,Super){
41945         var pt = Class.prototype;
41946         if(Object.create){
41947                 var ppt = Object.create(Super.prototype);
41948                 pt.__proto__ = ppt;
41949         }
41950         if(!(pt instanceof Super)){
41951                 function t(){}
41952                 t.prototype = Super.prototype;
41953                 t = new t();
41954                 copy$1(pt,t);
41955                 Class.prototype = pt = t;
41956         }
41957         if(pt.constructor != Class){
41958                 if(typeof Class != 'function'){
41959                         console.error("unknow Class:"+Class);
41960                 }
41961                 pt.constructor = Class;
41962         }
41963 }
41964 var htmlns = 'http://www.w3.org/1999/xhtml';
41965 // Node Types
41966 var NodeType = {};
41967 var ELEMENT_NODE                = NodeType.ELEMENT_NODE                = 1;
41968 var ATTRIBUTE_NODE              = NodeType.ATTRIBUTE_NODE              = 2;
41969 var TEXT_NODE                   = NodeType.TEXT_NODE                   = 3;
41970 var CDATA_SECTION_NODE          = NodeType.CDATA_SECTION_NODE          = 4;
41971 var ENTITY_REFERENCE_NODE       = NodeType.ENTITY_REFERENCE_NODE       = 5;
41972 var ENTITY_NODE                 = NodeType.ENTITY_NODE                 = 6;
41973 var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7;
41974 var COMMENT_NODE                = NodeType.COMMENT_NODE                = 8;
41975 var DOCUMENT_NODE               = NodeType.DOCUMENT_NODE               = 9;
41976 var DOCUMENT_TYPE_NODE          = NodeType.DOCUMENT_TYPE_NODE          = 10;
41977 var DOCUMENT_FRAGMENT_NODE      = NodeType.DOCUMENT_FRAGMENT_NODE      = 11;
41978 var NOTATION_NODE               = NodeType.NOTATION_NODE               = 12;
41979
41980 // ExceptionCode
41981 var ExceptionCode = {};
41982 var ExceptionMessage = {};
41983 var INDEX_SIZE_ERR              = ExceptionCode.INDEX_SIZE_ERR              = (ExceptionMessage[1]="Index size error", 1);
41984 var DOMSTRING_SIZE_ERR          = ExceptionCode.DOMSTRING_SIZE_ERR          = (ExceptionMessage[2]="DOMString size error", 2);
41985 var HIERARCHY_REQUEST_ERR       = ExceptionCode.HIERARCHY_REQUEST_ERR       = (ExceptionMessage[3]="Hierarchy request error", 3);
41986 var WRONG_DOCUMENT_ERR          = ExceptionCode.WRONG_DOCUMENT_ERR          = (ExceptionMessage[4]="Wrong document", 4);
41987 var INVALID_CHARACTER_ERR       = ExceptionCode.INVALID_CHARACTER_ERR       = (ExceptionMessage[5]="Invalid character", 5);
41988 var NO_DATA_ALLOWED_ERR         = ExceptionCode.NO_DATA_ALLOWED_ERR         = (ExceptionMessage[6]="No data allowed", 6);
41989 var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = (ExceptionMessage[7]="No modification allowed", 7);
41990 var NOT_FOUND_ERR               = ExceptionCode.NOT_FOUND_ERR               = (ExceptionMessage[8]="Not found", 8);
41991 var NOT_SUPPORTED_ERR           = ExceptionCode.NOT_SUPPORTED_ERR           = (ExceptionMessage[9]="Not supported", 9);
41992 var INUSE_ATTRIBUTE_ERR         = ExceptionCode.INUSE_ATTRIBUTE_ERR         = (ExceptionMessage[10]="Attribute in use", 10);
41993 //level2
41994 var INVALID_STATE_ERR           = ExceptionCode.INVALID_STATE_ERR               = (ExceptionMessage[11]="Invalid state", 11);
41995 var SYNTAX_ERR                  = ExceptionCode.SYNTAX_ERR                      = (ExceptionMessage[12]="Syntax error", 12);
41996 var INVALID_MODIFICATION_ERR    = ExceptionCode.INVALID_MODIFICATION_ERR        = (ExceptionMessage[13]="Invalid modification", 13);
41997 var NAMESPACE_ERR               = ExceptionCode.NAMESPACE_ERR                   = (ExceptionMessage[14]="Invalid namespace", 14);
41998 var INVALID_ACCESS_ERR          = ExceptionCode.INVALID_ACCESS_ERR              = (ExceptionMessage[15]="Invalid access", 15);
41999
42000
42001 function DOMException(code, message) {
42002         if(message instanceof Error){
42003                 var error = message;
42004         }else{
42005                 error = this;
42006                 Error.call(this, ExceptionMessage[code]);
42007                 this.message = ExceptionMessage[code];
42008                 if(Error.captureStackTrace) Error.captureStackTrace(this, DOMException);
42009         }
42010         error.code = code;
42011         if(message) this.message = this.message + ": " + message;
42012         return error;
42013 }
42014 DOMException.prototype = Error.prototype;
42015 copy$1(ExceptionCode,DOMException);
42016 /**
42017  * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177
42018  * 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.
42019  * The items in the NodeList are accessible via an integral index, starting from 0.
42020  */
42021 function NodeList() {
42022 }
42023 NodeList.prototype = {
42024         /**
42025          * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive.
42026          * @standard level1
42027          */
42028         length:0, 
42029         /**
42030          * 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.
42031          * @standard level1
42032          * @param index  unsigned long 
42033          *   Index into the collection.
42034          * @return Node
42035          *      The node at the indexth position in the NodeList, or null if that is not a valid index. 
42036          */
42037         item: function(index) {
42038                 return this[index] || null;
42039         },
42040         toString:function(isHTML,nodeFilter){
42041                 for(var buf = [], i = 0;i<this.length;i++){
42042                         serializeToString(this[i],buf,isHTML,nodeFilter);
42043                 }
42044                 return buf.join('');
42045         }
42046 };
42047 function LiveNodeList(node,refresh){
42048         this._node = node;
42049         this._refresh = refresh;
42050         _updateLiveList(this);
42051 }
42052 function _updateLiveList(list){
42053         var inc = list._node._inc || list._node.ownerDocument._inc;
42054         if(list._inc != inc){
42055                 var ls = list._refresh(list._node);
42056                 //console.log(ls.length)
42057                 __set__(list,'length',ls.length);
42058                 copy$1(ls,list);
42059                 list._inc = inc;
42060         }
42061 }
42062 LiveNodeList.prototype.item = function(i){
42063         _updateLiveList(this);
42064         return this[i];
42065 };
42066
42067 _extends(LiveNodeList,NodeList);
42068 /**
42069  * 
42070  * 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.
42071  * NamedNodeMap objects in the DOM are live.
42072  * used for attributes or DocumentType entities 
42073  */
42074 function NamedNodeMap() {
42075 }
42076
42077 function _findNodeIndex(list,node){
42078         var i = list.length;
42079         while(i--){
42080                 if(list[i] === node){return i}
42081         }
42082 }
42083
42084 function _addNamedNode(el,list,newAttr,oldAttr){
42085         if(oldAttr){
42086                 list[_findNodeIndex(list,oldAttr)] = newAttr;
42087         }else{
42088                 list[list.length++] = newAttr;
42089         }
42090         if(el){
42091                 newAttr.ownerElement = el;
42092                 var doc = el.ownerDocument;
42093                 if(doc){
42094                         oldAttr && _onRemoveAttribute(doc,el,oldAttr);
42095                         _onAddAttribute(doc,el,newAttr);
42096                 }
42097         }
42098 }
42099 function _removeNamedNode(el,list,attr){
42100         //console.log('remove attr:'+attr)
42101         var i = _findNodeIndex(list,attr);
42102         if(i>=0){
42103                 var lastIndex = list.length-1;
42104                 while(i<lastIndex){
42105                         list[i] = list[++i];
42106                 }
42107                 list.length = lastIndex;
42108                 if(el){
42109                         var doc = el.ownerDocument;
42110                         if(doc){
42111                                 _onRemoveAttribute(doc,el,attr);
42112                                 attr.ownerElement = null;
42113                         }
42114                 }
42115         }else{
42116                 throw DOMException(NOT_FOUND_ERR,new Error(el.tagName+'@'+attr))
42117         }
42118 }
42119 NamedNodeMap.prototype = {
42120         length:0,
42121         item:NodeList.prototype.item,
42122         getNamedItem: function(key) {
42123 //              if(key.indexOf(':')>0 || key == 'xmlns'){
42124 //                      return null;
42125 //              }
42126                 //console.log()
42127                 var i = this.length;
42128                 while(i--){
42129                         var attr = this[i];
42130                         //console.log(attr.nodeName,key)
42131                         if(attr.nodeName == key){
42132                                 return attr;
42133                         }
42134                 }
42135         },
42136         setNamedItem: function(attr) {
42137                 var el = attr.ownerElement;
42138                 if(el && el!=this._ownerElement){
42139                         throw new DOMException(INUSE_ATTRIBUTE_ERR);
42140                 }
42141                 var oldAttr = this.getNamedItem(attr.nodeName);
42142                 _addNamedNode(this._ownerElement,this,attr,oldAttr);
42143                 return oldAttr;
42144         },
42145         /* returns Node */
42146         setNamedItemNS: function(attr) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR
42147                 var el = attr.ownerElement, oldAttr;
42148                 if(el && el!=this._ownerElement){
42149                         throw new DOMException(INUSE_ATTRIBUTE_ERR);
42150                 }
42151                 oldAttr = this.getNamedItemNS(attr.namespaceURI,attr.localName);
42152                 _addNamedNode(this._ownerElement,this,attr,oldAttr);
42153                 return oldAttr;
42154         },
42155
42156         /* returns Node */
42157         removeNamedItem: function(key) {
42158                 var attr = this.getNamedItem(key);
42159                 _removeNamedNode(this._ownerElement,this,attr);
42160                 return attr;
42161                 
42162                 
42163         },// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR
42164         
42165         //for level2
42166         removeNamedItemNS:function(namespaceURI,localName){
42167                 var attr = this.getNamedItemNS(namespaceURI,localName);
42168                 _removeNamedNode(this._ownerElement,this,attr);
42169                 return attr;
42170         },
42171         getNamedItemNS: function(namespaceURI, localName) {
42172                 var i = this.length;
42173                 while(i--){
42174                         var node = this[i];
42175                         if(node.localName == localName && node.namespaceURI == namespaceURI){
42176                                 return node;
42177                         }
42178                 }
42179                 return null;
42180         }
42181 };
42182 /**
42183  * @see http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490
42184  */
42185 function DOMImplementation(/* Object */ features) {
42186         this._features = {};
42187         if (features) {
42188                 for (var feature in features) {
42189                          this._features = features[feature];
42190                 }
42191         }
42192 }
42193
42194 DOMImplementation.prototype = {
42195         hasFeature: function(/* string */ feature, /* string */ version) {
42196                 var versions = this._features[feature.toLowerCase()];
42197                 if (versions && (!version || version in versions)) {
42198                         return true;
42199                 } else {
42200                         return false;
42201                 }
42202         },
42203         // Introduced in DOM Level 2:
42204         createDocument:function(namespaceURI,  qualifiedName, doctype){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR,WRONG_DOCUMENT_ERR
42205                 var doc = new Document();
42206                 doc.implementation = this;
42207                 doc.childNodes = new NodeList();
42208                 doc.doctype = doctype;
42209                 if(doctype){
42210                         doc.appendChild(doctype);
42211                 }
42212                 if(qualifiedName){
42213                         var root = doc.createElementNS(namespaceURI,qualifiedName);
42214                         doc.appendChild(root);
42215                 }
42216                 return doc;
42217         },
42218         // Introduced in DOM Level 2:
42219         createDocumentType:function(qualifiedName, publicId, systemId){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR
42220                 var node = new DocumentType();
42221                 node.name = qualifiedName;
42222                 node.nodeName = qualifiedName;
42223                 node.publicId = publicId;
42224                 node.systemId = systemId;
42225                 // Introduced in DOM Level 2:
42226                 //readonly attribute DOMString        internalSubset;
42227                 
42228                 //TODO:..
42229                 //  readonly attribute NamedNodeMap     entities;
42230                 //  readonly attribute NamedNodeMap     notations;
42231                 return node;
42232         }
42233 };
42234
42235
42236 /**
42237  * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247
42238  */
42239
42240 function Node$2() {
42241 }
42242
42243 Node$2.prototype = {
42244         firstChild : null,
42245         lastChild : null,
42246         previousSibling : null,
42247         nextSibling : null,
42248         attributes : null,
42249         parentNode : null,
42250         childNodes : null,
42251         ownerDocument : null,
42252         nodeValue : null,
42253         namespaceURI : null,
42254         prefix : null,
42255         localName : null,
42256         // Modified in DOM Level 2:
42257         insertBefore:function(newChild, refChild){//raises 
42258                 return _insertBefore(this,newChild,refChild);
42259         },
42260         replaceChild:function(newChild, oldChild){//raises 
42261                 this.insertBefore(newChild,oldChild);
42262                 if(oldChild){
42263                         this.removeChild(oldChild);
42264                 }
42265         },
42266         removeChild:function(oldChild){
42267                 return _removeChild(this,oldChild);
42268         },
42269         appendChild:function(newChild){
42270                 return this.insertBefore(newChild,null);
42271         },
42272         hasChildNodes:function(){
42273                 return this.firstChild != null;
42274         },
42275         cloneNode:function(deep){
42276                 return cloneNode(this.ownerDocument||this,this,deep);
42277         },
42278         // Modified in DOM Level 2:
42279         normalize:function(){
42280                 var child = this.firstChild;
42281                 while(child){
42282                         var next = child.nextSibling;
42283                         if(next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE){
42284                                 this.removeChild(next);
42285                                 child.appendData(next.data);
42286                         }else{
42287                                 child.normalize();
42288                                 child = next;
42289                         }
42290                 }
42291         },
42292         // Introduced in DOM Level 2:
42293         isSupported:function(feature, version){
42294                 return this.ownerDocument.implementation.hasFeature(feature,version);
42295         },
42296     // Introduced in DOM Level 2:
42297     hasAttributes:function(){
42298         return this.attributes.length>0;
42299     },
42300     lookupPrefix:function(namespaceURI){
42301         var el = this;
42302         while(el){
42303                 var map = el._nsMap;
42304                 //console.dir(map)
42305                 if(map){
42306                         for(var n in map){
42307                                 if(map[n] == namespaceURI){
42308                                         return n;
42309                                 }
42310                         }
42311                 }
42312                 el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode;
42313         }
42314         return null;
42315     },
42316     // Introduced in DOM Level 3:
42317     lookupNamespaceURI:function(prefix){
42318         var el = this;
42319         while(el){
42320                 var map = el._nsMap;
42321                 //console.dir(map)
42322                 if(map){
42323                         if(prefix in map){
42324                                 return map[prefix] ;
42325                         }
42326                 }
42327                 el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode;
42328         }
42329         return null;
42330     },
42331     // Introduced in DOM Level 3:
42332     isDefaultNamespace:function(namespaceURI){
42333         var prefix = this.lookupPrefix(namespaceURI);
42334         return prefix == null;
42335     }
42336 };
42337
42338
42339 function _xmlEncoder(c){
42340         return c == '<' && '&lt;' ||
42341          c == '>' && '&gt;' ||
42342          c == '&' && '&amp;' ||
42343          c == '"' && '&quot;' ||
42344          '&#'+c.charCodeAt()+';'
42345 }
42346
42347
42348 copy$1(NodeType,Node$2);
42349 copy$1(NodeType,Node$2.prototype);
42350
42351 /**
42352  * @param callback return true for continue,false for break
42353  * @return boolean true: break visit;
42354  */
42355 function _visitNode(node,callback){
42356         if(callback(node)){
42357                 return true;
42358         }
42359         if(node = node.firstChild){
42360                 do{
42361                         if(_visitNode(node,callback)){return true}
42362         }while(node=node.nextSibling)
42363     }
42364 }
42365
42366
42367
42368 function Document(){
42369 }
42370 function _onAddAttribute(doc,el,newAttr){
42371         doc && doc._inc++;
42372         var ns = newAttr.namespaceURI;
42373         if(ns == 'http://www.w3.org/2000/xmlns/'){
42374                 //update namespace
42375                 el._nsMap[newAttr.prefix?newAttr.localName:''] = newAttr.value;
42376         }
42377 }
42378 function _onRemoveAttribute(doc,el,newAttr,remove){
42379         doc && doc._inc++;
42380         var ns = newAttr.namespaceURI;
42381         if(ns == 'http://www.w3.org/2000/xmlns/'){
42382                 //update namespace
42383                 delete el._nsMap[newAttr.prefix?newAttr.localName:''];
42384         }
42385 }
42386 function _onUpdateChild(doc,el,newChild){
42387         if(doc && doc._inc){
42388                 doc._inc++;
42389                 //update childNodes
42390                 var cs = el.childNodes;
42391                 if(newChild){
42392                         cs[cs.length++] = newChild;
42393                 }else{
42394                         //console.log(1)
42395                         var child = el.firstChild;
42396                         var i = 0;
42397                         while(child){
42398                                 cs[i++] = child;
42399                                 child =child.nextSibling;
42400                         }
42401                         cs.length = i;
42402                 }
42403         }
42404 }
42405
42406 /**
42407  * attributes;
42408  * children;
42409  * 
42410  * writeable properties:
42411  * nodeValue,Attr:value,CharacterData:data
42412  * prefix
42413  */
42414 function _removeChild(parentNode,child){
42415         var previous = child.previousSibling;
42416         var next = child.nextSibling;
42417         if(previous){
42418                 previous.nextSibling = next;
42419         }else{
42420                 parentNode.firstChild = next;
42421         }
42422         if(next){
42423                 next.previousSibling = previous;
42424         }else{
42425                 parentNode.lastChild = previous;
42426         }
42427         _onUpdateChild(parentNode.ownerDocument,parentNode);
42428         return child;
42429 }
42430 /**
42431  * preformance key(refChild == null)
42432  */
42433 function _insertBefore(parentNode,newChild,nextChild){
42434         var cp = newChild.parentNode;
42435         if(cp){
42436                 cp.removeChild(newChild);//remove and update
42437         }
42438         if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
42439                 var newFirst = newChild.firstChild;
42440                 if (newFirst == null) {
42441                         return newChild;
42442                 }
42443                 var newLast = newChild.lastChild;
42444         }else{
42445                 newFirst = newLast = newChild;
42446         }
42447         var pre = nextChild ? nextChild.previousSibling : parentNode.lastChild;
42448
42449         newFirst.previousSibling = pre;
42450         newLast.nextSibling = nextChild;
42451         
42452         
42453         if(pre){
42454                 pre.nextSibling = newFirst;
42455         }else{
42456                 parentNode.firstChild = newFirst;
42457         }
42458         if(nextChild == null){
42459                 parentNode.lastChild = newLast;
42460         }else{
42461                 nextChild.previousSibling = newLast;
42462         }
42463         do{
42464                 newFirst.parentNode = parentNode;
42465         }while(newFirst !== newLast && (newFirst= newFirst.nextSibling))
42466         _onUpdateChild(parentNode.ownerDocument||parentNode,parentNode);
42467         //console.log(parentNode.lastChild.nextSibling == null)
42468         if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) {
42469                 newChild.firstChild = newChild.lastChild = null;
42470         }
42471         return newChild;
42472 }
42473 function _appendSingleChild(parentNode,newChild){
42474         var cp = newChild.parentNode;
42475         if(cp){
42476                 var pre = parentNode.lastChild;
42477                 cp.removeChild(newChild);//remove and update
42478                 var pre = parentNode.lastChild;
42479         }
42480         var pre = parentNode.lastChild;
42481         newChild.parentNode = parentNode;
42482         newChild.previousSibling = pre;
42483         newChild.nextSibling = null;
42484         if(pre){
42485                 pre.nextSibling = newChild;
42486         }else{
42487                 parentNode.firstChild = newChild;
42488         }
42489         parentNode.lastChild = newChild;
42490         _onUpdateChild(parentNode.ownerDocument,parentNode,newChild);
42491         return newChild;
42492         //console.log("__aa",parentNode.lastChild.nextSibling == null)
42493 }
42494 Document.prototype = {
42495         //implementation : null,
42496         nodeName :  '#document',
42497         nodeType :  DOCUMENT_NODE,
42498         doctype :  null,
42499         documentElement :  null,
42500         _inc : 1,
42501         
42502         insertBefore :  function(newChild, refChild){//raises 
42503                 if(newChild.nodeType == DOCUMENT_FRAGMENT_NODE){
42504                         var child = newChild.firstChild;
42505                         while(child){
42506                                 var next = child.nextSibling;
42507                                 this.insertBefore(child,refChild);
42508                                 child = next;
42509                         }
42510                         return newChild;
42511                 }
42512                 if(this.documentElement == null && newChild.nodeType == ELEMENT_NODE){
42513                         this.documentElement = newChild;
42514                 }
42515                 
42516                 return _insertBefore(this,newChild,refChild), newChild.ownerDocument = this, newChild;
42517         },
42518         removeChild :  function(oldChild){
42519                 if(this.documentElement == oldChild){
42520                         this.documentElement = null;
42521                 }
42522                 return _removeChild(this,oldChild);
42523         },
42524         // Introduced in DOM Level 2:
42525         importNode : function(importedNode,deep){
42526                 return importNode(this,importedNode,deep);
42527         },
42528         // Introduced in DOM Level 2:
42529         getElementById :        function(id){
42530                 var rtv = null;
42531                 _visitNode(this.documentElement,function(node){
42532                         if(node.nodeType == ELEMENT_NODE){
42533                                 if(node.getAttribute('id') == id){
42534                                         rtv = node;
42535                                         return true;
42536                                 }
42537                         }
42538                 });
42539                 return rtv;
42540         },
42541         
42542         //document factory method:
42543         createElement : function(tagName){
42544                 var node = new Element();
42545                 node.ownerDocument = this;
42546                 node.nodeName = tagName;
42547                 node.tagName = tagName;
42548                 node.childNodes = new NodeList();
42549                 var attrs       = node.attributes = new NamedNodeMap();
42550                 attrs._ownerElement = node;
42551                 return node;
42552         },
42553         createDocumentFragment :        function(){
42554                 var node = new DocumentFragment();
42555                 node.ownerDocument = this;
42556                 node.childNodes = new NodeList();
42557                 return node;
42558         },
42559         createTextNode :        function(data){
42560                 var node = new Text();
42561                 node.ownerDocument = this;
42562                 node.appendData(data);
42563                 return node;
42564         },
42565         createComment : function(data){
42566                 var node = new Comment();
42567                 node.ownerDocument = this;
42568                 node.appendData(data);
42569                 return node;
42570         },
42571         createCDATASection :    function(data){
42572                 var node = new CDATASection();
42573                 node.ownerDocument = this;
42574                 node.appendData(data);
42575                 return node;
42576         },
42577         createProcessingInstruction :   function(target,data){
42578                 var node = new ProcessingInstruction();
42579                 node.ownerDocument = this;
42580                 node.tagName = node.target = target;
42581                 node.nodeValue= node.data = data;
42582                 return node;
42583         },
42584         createAttribute :       function(name){
42585                 var node = new Attr();
42586                 node.ownerDocument      = this;
42587                 node.name = name;
42588                 node.nodeName   = name;
42589                 node.localName = name;
42590                 node.specified = true;
42591                 return node;
42592         },
42593         createEntityReference : function(name){
42594                 var node = new EntityReference();
42595                 node.ownerDocument      = this;
42596                 node.nodeName   = name;
42597                 return node;
42598         },
42599         // Introduced in DOM Level 2:
42600         createElementNS :       function(namespaceURI,qualifiedName){
42601                 var node = new Element();
42602                 var pl = qualifiedName.split(':');
42603                 var attrs       = node.attributes = new NamedNodeMap();
42604                 node.childNodes = new NodeList();
42605                 node.ownerDocument = this;
42606                 node.nodeName = qualifiedName;
42607                 node.tagName = qualifiedName;
42608                 node.namespaceURI = namespaceURI;
42609                 if(pl.length == 2){
42610                         node.prefix = pl[0];
42611                         node.localName = pl[1];
42612                 }else{
42613                         //el.prefix = null;
42614                         node.localName = qualifiedName;
42615                 }
42616                 attrs._ownerElement = node;
42617                 return node;
42618         },
42619         // Introduced in DOM Level 2:
42620         createAttributeNS :     function(namespaceURI,qualifiedName){
42621                 var node = new Attr();
42622                 var pl = qualifiedName.split(':');
42623                 node.ownerDocument = this;
42624                 node.nodeName = qualifiedName;
42625                 node.name = qualifiedName;
42626                 node.namespaceURI = namespaceURI;
42627                 node.specified = true;
42628                 if(pl.length == 2){
42629                         node.prefix = pl[0];
42630                         node.localName = pl[1];
42631                 }else{
42632                         //el.prefix = null;
42633                         node.localName = qualifiedName;
42634                 }
42635                 return node;
42636         }
42637 };
42638 _extends(Document,Node$2);
42639
42640
42641 function Element() {
42642         this._nsMap = {};
42643 }
42644 Element.prototype = {
42645         nodeType : ELEMENT_NODE,
42646         hasAttribute : function(name){
42647                 return this.getAttributeNode(name)!=null;
42648         },
42649         getAttribute : function(name){
42650                 var attr = this.getAttributeNode(name);
42651                 return attr && attr.value || '';
42652         },
42653         getAttributeNode : function(name){
42654                 return this.attributes.getNamedItem(name);
42655         },
42656         setAttribute : function(name, value){
42657                 var attr = this.ownerDocument.createAttribute(name);
42658                 attr.value = attr.nodeValue = "" + value;
42659                 this.setAttributeNode(attr);
42660         },
42661         removeAttribute : function(name){
42662                 var attr = this.getAttributeNode(name);
42663                 attr && this.removeAttributeNode(attr);
42664         },
42665         
42666         //four real opeartion method
42667         appendChild:function(newChild){
42668                 if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
42669                         return this.insertBefore(newChild,null);
42670                 }else{
42671                         return _appendSingleChild(this,newChild);
42672                 }
42673         },
42674         setAttributeNode : function(newAttr){
42675                 return this.attributes.setNamedItem(newAttr);
42676         },
42677         setAttributeNodeNS : function(newAttr){
42678                 return this.attributes.setNamedItemNS(newAttr);
42679         },
42680         removeAttributeNode : function(oldAttr){
42681                 //console.log(this == oldAttr.ownerElement)
42682                 return this.attributes.removeNamedItem(oldAttr.nodeName);
42683         },
42684         //get real attribute name,and remove it by removeAttributeNode
42685         removeAttributeNS : function(namespaceURI, localName){
42686                 var old = this.getAttributeNodeNS(namespaceURI, localName);
42687                 old && this.removeAttributeNode(old);
42688         },
42689         
42690         hasAttributeNS : function(namespaceURI, localName){
42691                 return this.getAttributeNodeNS(namespaceURI, localName)!=null;
42692         },
42693         getAttributeNS : function(namespaceURI, localName){
42694                 var attr = this.getAttributeNodeNS(namespaceURI, localName);
42695                 return attr && attr.value || '';
42696         },
42697         setAttributeNS : function(namespaceURI, qualifiedName, value){
42698                 var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
42699                 attr.value = attr.nodeValue = "" + value;
42700                 this.setAttributeNode(attr);
42701         },
42702         getAttributeNodeNS : function(namespaceURI, localName){
42703                 return this.attributes.getNamedItemNS(namespaceURI, localName);
42704         },
42705         
42706         getElementsByTagName : function(tagName){
42707                 return new LiveNodeList(this,function(base){
42708                         var ls = [];
42709                         _visitNode(base,function(node){
42710                                 if(node !== base && node.nodeType == ELEMENT_NODE && (tagName === '*' || node.tagName == tagName)){
42711                                         ls.push(node);
42712                                 }
42713                         });
42714                         return ls;
42715                 });
42716         },
42717         getElementsByTagNameNS : function(namespaceURI, localName){
42718                 return new LiveNodeList(this,function(base){
42719                         var ls = [];
42720                         _visitNode(base,function(node){
42721                                 if(node !== base && node.nodeType === ELEMENT_NODE && (namespaceURI === '*' || node.namespaceURI === namespaceURI) && (localName === '*' || node.localName == localName)){
42722                                         ls.push(node);
42723                                 }
42724                         });
42725                         return ls;
42726                         
42727                 });
42728         }
42729 };
42730 Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName;
42731 Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS;
42732
42733
42734 _extends(Element,Node$2);
42735 function Attr() {
42736 }
42737 Attr.prototype.nodeType = ATTRIBUTE_NODE;
42738 _extends(Attr,Node$2);
42739
42740
42741 function CharacterData() {
42742 }
42743 CharacterData.prototype = {
42744         data : '',
42745         substringData : function(offset, count) {
42746                 return this.data.substring(offset, offset+count);
42747         },
42748         appendData: function(text) {
42749                 text = this.data+text;
42750                 this.nodeValue = this.data = text;
42751                 this.length = text.length;
42752         },
42753         insertData: function(offset,text) {
42754                 this.replaceData(offset,0,text);
42755         
42756         },
42757         appendChild:function(newChild){
42758                 throw new Error(ExceptionMessage[HIERARCHY_REQUEST_ERR])
42759         },
42760         deleteData: function(offset, count) {
42761                 this.replaceData(offset,count,"");
42762         },
42763         replaceData: function(offset, count, text) {
42764                 var start = this.data.substring(0,offset);
42765                 var end = this.data.substring(offset+count);
42766                 text = start + text + end;
42767                 this.nodeValue = this.data = text;
42768                 this.length = text.length;
42769         }
42770 };
42771 _extends(CharacterData,Node$2);
42772 function Text() {
42773 }
42774 Text.prototype = {
42775         nodeName : "#text",
42776         nodeType : TEXT_NODE,
42777         splitText : function(offset) {
42778                 var text = this.data;
42779                 var newText = text.substring(offset);
42780                 text = text.substring(0, offset);
42781                 this.data = this.nodeValue = text;
42782                 this.length = text.length;
42783                 var newNode = this.ownerDocument.createTextNode(newText);
42784                 if(this.parentNode){
42785                         this.parentNode.insertBefore(newNode, this.nextSibling);
42786                 }
42787                 return newNode;
42788         }
42789 };
42790 _extends(Text,CharacterData);
42791 function Comment() {
42792 }
42793 Comment.prototype = {
42794         nodeName : "#comment",
42795         nodeType : COMMENT_NODE
42796 };
42797 _extends(Comment,CharacterData);
42798
42799 function CDATASection() {
42800 }
42801 CDATASection.prototype = {
42802         nodeName : "#cdata-section",
42803         nodeType : CDATA_SECTION_NODE
42804 };
42805 _extends(CDATASection,CharacterData);
42806
42807
42808 function DocumentType() {
42809 }
42810 DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE;
42811 _extends(DocumentType,Node$2);
42812
42813 function Notation() {
42814 }
42815 Notation.prototype.nodeType = NOTATION_NODE;
42816 _extends(Notation,Node$2);
42817
42818 function Entity() {
42819 }
42820 Entity.prototype.nodeType = ENTITY_NODE;
42821 _extends(Entity,Node$2);
42822
42823 function EntityReference() {
42824 }
42825 EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE;
42826 _extends(EntityReference,Node$2);
42827
42828 function DocumentFragment() {
42829 }
42830 DocumentFragment.prototype.nodeName =   "#document-fragment";
42831 DocumentFragment.prototype.nodeType =   DOCUMENT_FRAGMENT_NODE;
42832 _extends(DocumentFragment,Node$2);
42833
42834
42835 function ProcessingInstruction() {
42836 }
42837 ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE;
42838 _extends(ProcessingInstruction,Node$2);
42839 function XMLSerializer$1(){}
42840 XMLSerializer$1.prototype.serializeToString = function(node,isHtml,nodeFilter){
42841         return nodeSerializeToString.call(node,isHtml,nodeFilter);
42842 };
42843 Node$2.prototype.toString = nodeSerializeToString;
42844 function nodeSerializeToString(isHtml,nodeFilter){
42845         var buf = [];
42846         var refNode = this.nodeType == 9?this.documentElement:this;
42847         var prefix = refNode.prefix;
42848         var uri = refNode.namespaceURI;
42849         
42850         if(uri && prefix == null){
42851                 //console.log(prefix)
42852                 var prefix = refNode.lookupPrefix(uri);
42853                 if(prefix == null){
42854                         //isHTML = true;
42855                         var visibleNamespaces=[
42856                         {namespace:uri,prefix:null}
42857                         //{namespace:uri,prefix:''}
42858                         ];
42859                 }
42860         }
42861         serializeToString(this,buf,isHtml,nodeFilter,visibleNamespaces);
42862         //console.log('###',this.nodeType,uri,prefix,buf.join(''))
42863         return buf.join('');
42864 }
42865 function needNamespaceDefine(node,isHTML, visibleNamespaces) {
42866         var prefix = node.prefix||'';
42867         var uri = node.namespaceURI;
42868         if (!prefix && !uri){
42869                 return false;
42870         }
42871         if (prefix === "xml" && uri === "http://www.w3.org/XML/1998/namespace" 
42872                 || uri == 'http://www.w3.org/2000/xmlns/'){
42873                 return false;
42874         }
42875         
42876         var i = visibleNamespaces.length; 
42877         //console.log('@@@@',node.tagName,prefix,uri,visibleNamespaces)
42878         while (i--) {
42879                 var ns = visibleNamespaces[i];
42880                 // get namespace prefix
42881                 //console.log(node.nodeType,node.tagName,ns.prefix,prefix)
42882                 if (ns.prefix == prefix){
42883                         return ns.namespace != uri;
42884                 }
42885         }
42886         //console.log(isHTML,uri,prefix=='')
42887         //if(isHTML && prefix ==null && uri == 'http://www.w3.org/1999/xhtml'){
42888         //      return false;
42889         //}
42890         //node.flag = '11111'
42891         //console.error(3,true,node.flag,node.prefix,node.namespaceURI)
42892         return true;
42893 }
42894 function serializeToString(node,buf,isHTML,nodeFilter,visibleNamespaces){
42895         if(nodeFilter){
42896                 node = nodeFilter(node);
42897                 if(node){
42898                         if(typeof node == 'string'){
42899                                 buf.push(node);
42900                                 return;
42901                         }
42902                 }else{
42903                         return;
42904                 }
42905                 //buf.sort.apply(attrs, attributeSorter);
42906         }
42907         switch(node.nodeType){
42908         case ELEMENT_NODE:
42909                 if (!visibleNamespaces) visibleNamespaces = [];
42910                 var startVisibleNamespaces = visibleNamespaces.length;
42911                 var attrs = node.attributes;
42912                 var len = attrs.length;
42913                 var child = node.firstChild;
42914                 var nodeName = node.tagName;
42915                 
42916                 isHTML =  (htmlns === node.namespaceURI) ||isHTML; 
42917                 buf.push('<',nodeName);
42918                 
42919                 
42920                 
42921                 for(var i=0;i<len;i++){
42922                         // add namespaces for attributes
42923                         var attr = attrs.item(i);
42924                         if (attr.prefix == 'xmlns') {
42925                                 visibleNamespaces.push({ prefix: attr.localName, namespace: attr.value });
42926                         }else if(attr.nodeName == 'xmlns'){
42927                                 visibleNamespaces.push({ prefix: '', namespace: attr.value });
42928                         }
42929                 }
42930                 for(var i=0;i<len;i++){
42931                         var attr = attrs.item(i);
42932                         if (needNamespaceDefine(attr,isHTML, visibleNamespaces)) {
42933                                 var prefix = attr.prefix||'';
42934                                 var uri = attr.namespaceURI;
42935                                 var ns = prefix ? ' xmlns:' + prefix : " xmlns";
42936                                 buf.push(ns, '="' , uri , '"');
42937                                 visibleNamespaces.push({ prefix: prefix, namespace:uri });
42938                         }
42939                         serializeToString(attr,buf,isHTML,nodeFilter,visibleNamespaces);
42940                 }
42941                 // add namespace for current node               
42942                 if (needNamespaceDefine(node,isHTML, visibleNamespaces)) {
42943                         var prefix = node.prefix||'';
42944                         var uri = node.namespaceURI;
42945                         var ns = prefix ? ' xmlns:' + prefix : " xmlns";
42946                         buf.push(ns, '="' , uri , '"');
42947                         visibleNamespaces.push({ prefix: prefix, namespace:uri });
42948                 }
42949                 
42950                 if(child || isHTML && !/^(?:meta|link|img|br|hr|input)$/i.test(nodeName)){
42951                         buf.push('>');
42952                         //if is cdata child node
42953                         if(isHTML && /^script$/i.test(nodeName)){
42954                                 while(child){
42955                                         if(child.data){
42956                                                 buf.push(child.data);
42957                                         }else{
42958                                                 serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces);
42959                                         }
42960                                         child = child.nextSibling;
42961                                 }
42962                         }else
42963                         {
42964                                 while(child){
42965                                         serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces);
42966                                         child = child.nextSibling;
42967                                 }
42968                         }
42969                         buf.push('</',nodeName,'>');
42970                 }else{
42971                         buf.push('/>');
42972                 }
42973                 // remove added visible namespaces
42974                 //visibleNamespaces.length = startVisibleNamespaces;
42975                 return;
42976         case DOCUMENT_NODE:
42977         case DOCUMENT_FRAGMENT_NODE:
42978                 var child = node.firstChild;
42979                 while(child){
42980                         serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces);
42981                         child = child.nextSibling;
42982                 }
42983                 return;
42984         case ATTRIBUTE_NODE:
42985                 return buf.push(' ',node.name,'="',node.value.replace(/[<&"]/g,_xmlEncoder),'"');
42986         case TEXT_NODE:
42987                 return buf.push(node.data.replace(/[<&]/g,_xmlEncoder));
42988         case CDATA_SECTION_NODE:
42989                 return buf.push( '<![CDATA[',node.data,']]>');
42990         case COMMENT_NODE:
42991                 return buf.push( "<!--",node.data,"-->");
42992         case DOCUMENT_TYPE_NODE:
42993                 var pubid = node.publicId;
42994                 var sysid = node.systemId;
42995                 buf.push('<!DOCTYPE ',node.name);
42996                 if(pubid){
42997                         buf.push(' PUBLIC "',pubid);
42998                         if (sysid && sysid!='.') {
42999                                 buf.push( '" "',sysid);
43000                         }
43001                         buf.push('">');
43002                 }else if(sysid && sysid!='.'){
43003                         buf.push(' SYSTEM "',sysid,'">');
43004                 }else{
43005                         var sub = node.internalSubset;
43006                         if(sub){
43007                                 buf.push(" [",sub,"]");
43008                         }
43009                         buf.push(">");
43010                 }
43011                 return;
43012         case PROCESSING_INSTRUCTION_NODE:
43013                 return buf.push( "<?",node.target," ",node.data,"?>");
43014         case ENTITY_REFERENCE_NODE:
43015                 return buf.push( '&',node.nodeName,';');
43016         //case ENTITY_NODE:
43017         //case NOTATION_NODE:
43018         default:
43019                 buf.push('??',node.nodeName);
43020         }
43021 }
43022 function importNode(doc,node,deep){
43023         var node2;
43024         switch (node.nodeType) {
43025         case ELEMENT_NODE:
43026                 node2 = node.cloneNode(false);
43027                 node2.ownerDocument = doc;
43028                 //var attrs = node2.attributes;
43029                 //var len = attrs.length;
43030                 //for(var i=0;i<len;i++){
43031                         //node2.setAttributeNodeNS(importNode(doc,attrs.item(i),deep));
43032                 //}
43033         case DOCUMENT_FRAGMENT_NODE:
43034                 break;
43035         case ATTRIBUTE_NODE:
43036                 deep = true;
43037                 break;
43038         //case ENTITY_REFERENCE_NODE:
43039         //case PROCESSING_INSTRUCTION_NODE:
43040         ////case TEXT_NODE:
43041         //case CDATA_SECTION_NODE:
43042         //case COMMENT_NODE:
43043         //      deep = false;
43044         //      break;
43045         //case DOCUMENT_NODE:
43046         //case DOCUMENT_TYPE_NODE:
43047         //cannot be imported.
43048         //case ENTITY_NODE:
43049         //case NOTATION_NODE:
43050         //can not hit in level3
43051         //default:throw e;
43052         }
43053         if(!node2){
43054                 node2 = node.cloneNode(false);//false
43055         }
43056         node2.ownerDocument = doc;
43057         node2.parentNode = null;
43058         if(deep){
43059                 var child = node.firstChild;
43060                 while(child){
43061                         node2.appendChild(importNode(doc,child,deep));
43062                         child = child.nextSibling;
43063                 }
43064         }
43065         return node2;
43066 }
43067 //
43068 //var _relationMap = {firstChild:1,lastChild:1,previousSibling:1,nextSibling:1,
43069 //                                      attributes:1,childNodes:1,parentNode:1,documentElement:1,doctype,};
43070 function cloneNode(doc,node,deep){
43071         var node2 = new node.constructor();
43072         for(var n in node){
43073                 var v = node[n];
43074                 if(typeof v != 'object' ){
43075                         if(v != node2[n]){
43076                                 node2[n] = v;
43077                         }
43078                 }
43079         }
43080         if(node.childNodes){
43081                 node2.childNodes = new NodeList();
43082         }
43083         node2.ownerDocument = doc;
43084         switch (node2.nodeType) {
43085         case ELEMENT_NODE:
43086                 var attrs       = node.attributes;
43087                 var attrs2      = node2.attributes = new NamedNodeMap();
43088                 var len = attrs.length;
43089                 attrs2._ownerElement = node2;
43090                 for(var i=0;i<len;i++){
43091                         node2.setAttributeNode(cloneNode(doc,attrs.item(i),true));
43092                 }
43093                 break;;
43094         case ATTRIBUTE_NODE:
43095                 deep = true;
43096         }
43097         if(deep){
43098                 var child = node.firstChild;
43099                 while(child){
43100                         node2.appendChild(cloneNode(doc,child,deep));
43101                         child = child.nextSibling;
43102                 }
43103         }
43104         return node2;
43105 }
43106
43107 function __set__(object,key,value){
43108         object[key] = value;
43109 }
43110 //do dynamic
43111 try{
43112         if(Object.defineProperty){
43113                 Object.defineProperty(LiveNodeList.prototype,'length',{
43114                         get:function(){
43115                                 _updateLiveList(this);
43116                                 return this.$$length;
43117                         }
43118                 });
43119                 Object.defineProperty(Node$2.prototype,'textContent',{
43120                         get:function(){
43121                                 return getTextContent(this);
43122                         },
43123                         set:function(data){
43124                                 switch(this.nodeType){
43125                                 case ELEMENT_NODE:
43126                                 case DOCUMENT_FRAGMENT_NODE:
43127                                         while(this.firstChild){
43128                                                 this.removeChild(this.firstChild);
43129                                         }
43130                                         if(data || String(data)){
43131                                                 this.appendChild(this.ownerDocument.createTextNode(data));
43132                                         }
43133                                         break;
43134                                 default:
43135                                         //TODO:
43136                                         this.data = data;
43137                                         this.value = data;
43138                                         this.nodeValue = data;
43139                                 }
43140                         }
43141                 });
43142                 
43143                 function getTextContent(node){
43144                         switch(node.nodeType){
43145                         case ELEMENT_NODE:
43146                         case DOCUMENT_FRAGMENT_NODE:
43147                                 var buf = [];
43148                                 node = node.firstChild;
43149                                 while(node){
43150                                         if(node.nodeType!==7 && node.nodeType !==8){
43151                                                 buf.push(getTextContent(node));
43152                                         }
43153                                         node = node.nextSibling;
43154                                 }
43155                                 return buf.join('');
43156                         default:
43157                                 return node.nodeValue;
43158                         }
43159                 }
43160                 __set__ = function(object,key,value){
43161                         //console.log(value)
43162                         object['$$'+key] = value;
43163                 };
43164         }
43165 }catch(e){//ie8
43166 }
43167
43168 //if(typeof require == 'function'){
43169         var DOMImplementation_1 = DOMImplementation;
43170         var XMLSerializer_1 = XMLSerializer$1;
43171 //}
43172
43173 var dom = {
43174         DOMImplementation: DOMImplementation_1,
43175         XMLSerializer: XMLSerializer_1
43176 };
43177
43178 var domParser = createCommonjsModule(function (module, exports) {
43179 function DOMParser(options){
43180         this.options = options ||{locator:{}};
43181         
43182 }
43183 DOMParser.prototype.parseFromString = function(source,mimeType){
43184         var options = this.options;
43185         var sax$$1 =  new XMLReader();
43186         var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler
43187         var errorHandler = options.errorHandler;
43188         var locator = options.locator;
43189         var defaultNSMap = options.xmlns||{};
43190         var entityMap = {'lt':'<','gt':'>','amp':'&','quot':'"','apos':"'"};
43191         if(locator){
43192                 domBuilder.setDocumentLocator(locator);
43193         }
43194         
43195         sax$$1.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator);
43196         sax$$1.domBuilder = options.domBuilder || domBuilder;
43197         if(/\/x?html?$/.test(mimeType)){
43198                 entityMap.nbsp = '\xa0';
43199                 entityMap.copy = '\xa9';
43200                 defaultNSMap['']= 'http://www.w3.org/1999/xhtml';
43201         }
43202         defaultNSMap.xml = defaultNSMap.xml || 'http://www.w3.org/XML/1998/namespace';
43203         if(source){
43204                 sax$$1.parse(source,defaultNSMap,entityMap);
43205         }else{
43206                 sax$$1.errorHandler.error("invalid doc source");
43207         }
43208         return domBuilder.doc;
43209 };
43210 function buildErrorHandler(errorImpl,domBuilder,locator){
43211         if(!errorImpl){
43212                 if(domBuilder instanceof DOMHandler){
43213                         return domBuilder;
43214                 }
43215                 errorImpl = domBuilder ;
43216         }
43217         var errorHandler = {};
43218         var isCallback = errorImpl instanceof Function;
43219         locator = locator||{};
43220         function build(key){
43221                 var fn = errorImpl[key];
43222                 if(!fn && isCallback){
43223                         fn = errorImpl.length == 2?function(msg){errorImpl(key,msg);}:errorImpl;
43224                 }
43225                 errorHandler[key] = fn && function(msg){
43226                         fn('[xmldom '+key+']\t'+msg+_locator(locator));
43227                 }||function(){};
43228         }
43229         build('warning');
43230         build('error');
43231         build('fatalError');
43232         return errorHandler;
43233 }
43234
43235 //console.log('#\n\n\n\n\n\n\n####')
43236 /**
43237  * +ContentHandler+ErrorHandler
43238  * +LexicalHandler+EntityResolver2
43239  * -DeclHandler-DTDHandler 
43240  * 
43241  * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler
43242  * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2
43243  * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html
43244  */
43245 function DOMHandler() {
43246     this.cdata = false;
43247 }
43248 function position(locator,node){
43249         node.lineNumber = locator.lineNumber;
43250         node.columnNumber = locator.columnNumber;
43251 }
43252 /**
43253  * @see org.xml.sax.ContentHandler#startDocument
43254  * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
43255  */ 
43256 DOMHandler.prototype = {
43257         startDocument : function() {
43258         this.doc = new DOMImplementation().createDocument(null, null, null);
43259         if (this.locator) {
43260                 this.doc.documentURI = this.locator.systemId;
43261         }
43262         },
43263         startElement:function(namespaceURI, localName, qName, attrs) {
43264                 var doc = this.doc;
43265             var el = doc.createElementNS(namespaceURI, qName||localName);
43266             var len = attrs.length;
43267             appendElement(this, el);
43268             this.currentElement = el;
43269             
43270                 this.locator && position(this.locator,el);
43271             for (var i = 0 ; i < len; i++) {
43272                 var namespaceURI = attrs.getURI(i);
43273                 var value = attrs.getValue(i);
43274                 var qName = attrs.getQName(i);
43275                         var attr = doc.createAttributeNS(namespaceURI, qName);
43276                         this.locator &&position(attrs.getLocator(i),attr);
43277                         attr.value = attr.nodeValue = value;
43278                         el.setAttributeNode(attr);
43279             }
43280         },
43281         endElement:function(namespaceURI, localName, qName) {
43282                 var current = this.currentElement;
43283                 var tagName = current.tagName;
43284                 this.currentElement = current.parentNode;
43285         },
43286         startPrefixMapping:function(prefix, uri) {
43287         },
43288         endPrefixMapping:function(prefix) {
43289         },
43290         processingInstruction:function(target, data) {
43291             var ins = this.doc.createProcessingInstruction(target, data);
43292             this.locator && position(this.locator,ins);
43293             appendElement(this, ins);
43294         },
43295         ignorableWhitespace:function(ch, start, length) {
43296         },
43297         characters:function(chars, start, length) {
43298                 chars = _toString.apply(this,arguments);
43299                 //console.log(chars)
43300                 if(chars){
43301                         if (this.cdata) {
43302                                 var charNode = this.doc.createCDATASection(chars);
43303                         } else {
43304                                 var charNode = this.doc.createTextNode(chars);
43305                         }
43306                         if(this.currentElement){
43307                                 this.currentElement.appendChild(charNode);
43308                         }else if(/^\s*$/.test(chars)){
43309                                 this.doc.appendChild(charNode);
43310                                 //process xml
43311                         }
43312                         this.locator && position(this.locator,charNode);
43313                 }
43314         },
43315         skippedEntity:function(name) {
43316         },
43317         endDocument:function() {
43318                 this.doc.normalize();
43319         },
43320         setDocumentLocator:function (locator) {
43321             if(this.locator = locator){// && !('lineNumber' in locator)){
43322                 locator.lineNumber = 0;
43323             }
43324         },
43325         //LexicalHandler
43326         comment:function(chars, start, length) {
43327                 chars = _toString.apply(this,arguments);
43328             var comm = this.doc.createComment(chars);
43329             this.locator && position(this.locator,comm);
43330             appendElement(this, comm);
43331         },
43332         
43333         startCDATA:function() {
43334             //used in characters() methods
43335             this.cdata = true;
43336         },
43337         endCDATA:function() {
43338             this.cdata = false;
43339         },
43340         
43341         startDTD:function(name, publicId, systemId) {
43342                 var impl = this.doc.implementation;
43343             if (impl && impl.createDocumentType) {
43344                 var dt = impl.createDocumentType(name, publicId, systemId);
43345                 this.locator && position(this.locator,dt);
43346                 appendElement(this, dt);
43347             }
43348         },
43349         /**
43350          * @see org.xml.sax.ErrorHandler
43351          * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
43352          */
43353         warning:function(error) {
43354                 console.warn('[xmldom warning]\t'+error,_locator(this.locator));
43355         },
43356         error:function(error) {
43357                 console.error('[xmldom error]\t'+error,_locator(this.locator));
43358         },
43359         fatalError:function(error) {
43360                 console.error('[xmldom fatalError]\t'+error,_locator(this.locator));
43361             throw error;
43362         }
43363 };
43364 function _locator(l){
43365         if(l){
43366                 return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']'
43367         }
43368 }
43369 function _toString(chars,start,length){
43370         if(typeof chars == 'string'){
43371                 return chars.substr(start,length)
43372         }else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)")
43373                 if(chars.length >= start+length || start){
43374                         return new java.lang.String(chars,start,length)+'';
43375                 }
43376                 return chars;
43377         }
43378 }
43379
43380 /*
43381  * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html
43382  * used method of org.xml.sax.ext.LexicalHandler:
43383  *  #comment(chars, start, length)
43384  *  #startCDATA()
43385  *  #endCDATA()
43386  *  #startDTD(name, publicId, systemId)
43387  *
43388  *
43389  * IGNORED method of org.xml.sax.ext.LexicalHandler:
43390  *  #endDTD()
43391  *  #startEntity(name)
43392  *  #endEntity(name)
43393  *
43394  *
43395  * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html
43396  * IGNORED method of org.xml.sax.ext.DeclHandler
43397  *      #attributeDecl(eName, aName, type, mode, value)
43398  *  #elementDecl(name, model)
43399  *  #externalEntityDecl(name, publicId, systemId)
43400  *  #internalEntityDecl(name, value)
43401  * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html
43402  * IGNORED method of org.xml.sax.EntityResolver2
43403  *  #resolveEntity(String name,String publicId,String baseURI,String systemId)
43404  *  #resolveEntity(publicId, systemId)
43405  *  #getExternalSubset(name, baseURI)
43406  * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html
43407  * IGNORED method of org.xml.sax.DTDHandler
43408  *  #notationDecl(name, publicId, systemId) {};
43409  *  #unparsedEntityDecl(name, publicId, systemId, notationName) {};
43410  */
43411 "endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){
43412         DOMHandler.prototype[key] = function(){return null};
43413 });
43414
43415 /* 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 */
43416 function appendElement (hander,node) {
43417     if (!hander.currentElement) {
43418         hander.doc.appendChild(node);
43419     } else {
43420         hander.currentElement.appendChild(node);
43421     }
43422 }//appendChild and setAttributeNS are preformance key
43423
43424 //if(typeof require == 'function'){
43425         var XMLReader = sax.XMLReader;
43426         var DOMImplementation = exports.DOMImplementation = dom.DOMImplementation;
43427         exports.XMLSerializer = dom.XMLSerializer ;
43428         exports.DOMParser = DOMParser;
43429 //}
43430 });
43431
43432 var domParser_1 = domParser.DOMImplementation;
43433 var domParser_2 = domParser.XMLSerializer;
43434 var domParser_3 = domParser.DOMParser;
43435
43436 var togeojson = createCommonjsModule(function (module, exports) {
43437 var toGeoJSON = (function() {
43438     var removeSpace = /\s*/g,
43439         trimSpace = /^\s*|\s*$/g,
43440         splitSpace = /\s+/;
43441     // generate a short, numeric hash of a string
43442     function okhash(x) {
43443         if (!x || !x.length) return 0;
43444         for (var i = 0, h = 0; i < x.length; i++) {
43445             h = ((h << 5) - h) + x.charCodeAt(i) | 0;
43446         } return h;
43447     }
43448     // all Y children of X
43449     function get(x, y) { return x.getElementsByTagName(y); }
43450     function attr(x, y) { return x.getAttribute(y); }
43451     function attrf(x, y) { return parseFloat(attr(x, y)); }
43452     // one Y child of X, if any, otherwise null
43453     function get1(x, y) { var n = get(x, y); return n.length ? n[0] : null; }
43454     // https://developer.mozilla.org/en-US/docs/Web/API/Node.normalize
43455     function norm(el) { if (el.normalize) { el.normalize(); } return el; }
43456     // cast array x into numbers
43457     function numarray(x) {
43458         for (var j = 0, o = []; j < x.length; j++) { o[j] = parseFloat(x[j]); }
43459         return o;
43460     }
43461     // get the content of a text node, if any
43462     function nodeVal(x) {
43463         if (x) { norm(x); }
43464         return (x && x.textContent) || '';
43465     }
43466     // get the contents of multiple text nodes, if present
43467     function getMulti(x, ys) {
43468         var o = {}, n, k;
43469         for (k = 0; k < ys.length; k++) {
43470             n = get1(x, ys[k]);
43471             if (n) o[ys[k]] = nodeVal(n);
43472         }
43473         return o;
43474     }
43475     // add properties of Y to X, overwriting if present in both
43476     function extend(x, y) { for (var k in y) x[k] = y[k]; }
43477     // get one coordinate from a coordinate array, if any
43478     function coord1(v) { return numarray(v.replace(removeSpace, '').split(',')); }
43479     // get all coordinates from a coordinate array as [[],[]]
43480     function coord(v) {
43481         var coords = v.replace(trimSpace, '').split(splitSpace),
43482             o = [];
43483         for (var i = 0; i < coords.length; i++) {
43484             o.push(coord1(coords[i]));
43485         }
43486         return o;
43487     }
43488     function coordPair(x) {
43489         var ll = [attrf(x, 'lon'), attrf(x, 'lat')],
43490             ele = get1(x, 'ele'),
43491             // handle namespaced attribute in browser
43492             heartRate = get1(x, 'gpxtpx:hr') || get1(x, 'hr'),
43493             time = get1(x, 'time'),
43494             e;
43495         if (ele) {
43496             e = parseFloat(nodeVal(ele));
43497             if (!isNaN(e)) {
43498                 ll.push(e);
43499             }
43500         }
43501         return {
43502             coordinates: ll,
43503             time: time ? nodeVal(time) : null,
43504             heartRate: heartRate ? parseFloat(nodeVal(heartRate)) : null
43505         };
43506     }
43507
43508     // create a new feature collection parent object
43509     function fc() {
43510         return {
43511             type: 'FeatureCollection',
43512             features: []
43513         };
43514     }
43515
43516     var serializer;
43517     if (typeof XMLSerializer !== 'undefined') {
43518         /* istanbul ignore next */
43519         serializer = new XMLSerializer();
43520     // only require xmldom in a node environment
43521     } else if ('object' === 'object' && typeof process === 'object' && !process.browser) {
43522         serializer = new (domParser.XMLSerializer)();
43523     }
43524     function xml2str(str) {
43525         // IE9 will create a new XMLSerializer but it'll crash immediately.
43526         // This line is ignored because we don't run coverage tests in IE9
43527         /* istanbul ignore next */
43528         if (str.xml !== undefined) return str.xml;
43529         return serializer.serializeToString(str);
43530     }
43531
43532     var t = {
43533         kml: function(doc) {
43534
43535             var gj = fc(),
43536                 // styleindex keeps track of hashed styles in order to match features
43537                 styleIndex = {}, styleByHash = {},
43538                 // stylemapindex keeps track of style maps to expose in properties
43539                 styleMapIndex = {},
43540                 // atomic geospatial types supported by KML - MultiGeometry is
43541                 // handled separately
43542                 geotypes = ['Polygon', 'LineString', 'Point', 'Track', 'gx:Track'],
43543                 // all root placemarks in the file
43544                 placemarks = get(doc, 'Placemark'),
43545                 styles = get(doc, 'Style'),
43546                 styleMaps = get(doc, 'StyleMap');
43547
43548             for (var k = 0; k < styles.length; k++) {
43549                 var hash = okhash(xml2str(styles[k])).toString(16);
43550                 styleIndex['#' + attr(styles[k], 'id')] = hash;
43551                 styleByHash[hash] = styles[k];
43552             }
43553             for (var l = 0; l < styleMaps.length; l++) {
43554                 styleIndex['#' + attr(styleMaps[l], 'id')] = okhash(xml2str(styleMaps[l])).toString(16);
43555                 var pairs = get(styleMaps[l], 'Pair');
43556                 var pairsMap = {};
43557                 for (var m = 0; m < pairs.length; m++) {
43558                     pairsMap[nodeVal(get1(pairs[m], 'key'))] = nodeVal(get1(pairs[m], 'styleUrl'));
43559                 }
43560                 styleMapIndex['#' + attr(styleMaps[l], 'id')] = pairsMap;
43561
43562             }
43563             for (var j = 0; j < placemarks.length; j++) {
43564                 gj.features = gj.features.concat(getPlacemark(placemarks[j]));
43565             }
43566             function kmlColor(v) {
43567                 var color, opacity;
43568                 v = v || '';
43569                 if (v.substr(0, 1) === '#') { v = v.substr(1); }
43570                 if (v.length === 6 || v.length === 3) { color = v; }
43571                 if (v.length === 8) {
43572                     opacity = parseInt(v.substr(0, 2), 16) / 255;
43573                     color = '#' + v.substr(6, 2) +
43574                         v.substr(4, 2) +
43575                         v.substr(2, 2);
43576                 }
43577                 return [color, isNaN(opacity) ? undefined : opacity];
43578             }
43579             function gxCoord(v) { return numarray(v.split(' ')); }
43580             function gxCoords(root) {
43581                 var elems = get(root, 'coord', 'gx'), coords = [], times = [];
43582                 if (elems.length === 0) elems = get(root, 'gx:coord');
43583                 for (var i = 0; i < elems.length; i++) coords.push(gxCoord(nodeVal(elems[i])));
43584                 var timeElems = get(root, 'when');
43585                 for (var j = 0; j < timeElems.length; j++) times.push(nodeVal(timeElems[j]));
43586                 return {
43587                     coords: coords,
43588                     times: times
43589                 };
43590             }
43591             function getGeometry(root) {
43592                 var geomNode, geomNodes, i, j, k, geoms = [], coordTimes = [];
43593                 if (get1(root, 'MultiGeometry')) { return getGeometry(get1(root, 'MultiGeometry')); }
43594                 if (get1(root, 'MultiTrack')) { return getGeometry(get1(root, 'MultiTrack')); }
43595                 if (get1(root, 'gx:MultiTrack')) { return getGeometry(get1(root, 'gx:MultiTrack')); }
43596                 for (i = 0; i < geotypes.length; i++) {
43597                     geomNodes = get(root, geotypes[i]);
43598                     if (geomNodes) {
43599                         for (j = 0; j < geomNodes.length; j++) {
43600                             geomNode = geomNodes[j];
43601                             if (geotypes[i] === 'Point') {
43602                                 geoms.push({
43603                                     type: 'Point',
43604                                     coordinates: coord1(nodeVal(get1(geomNode, 'coordinates')))
43605                                 });
43606                             } else if (geotypes[i] === 'LineString') {
43607                                 geoms.push({
43608                                     type: 'LineString',
43609                                     coordinates: coord(nodeVal(get1(geomNode, 'coordinates')))
43610                                 });
43611                             } else if (geotypes[i] === 'Polygon') {
43612                                 var rings = get(geomNode, 'LinearRing'),
43613                                     coords = [];
43614                                 for (k = 0; k < rings.length; k++) {
43615                                     coords.push(coord(nodeVal(get1(rings[k], 'coordinates'))));
43616                                 }
43617                                 geoms.push({
43618                                     type: 'Polygon',
43619                                     coordinates: coords
43620                                 });
43621                             } else if (geotypes[i] === 'Track' ||
43622                                 geotypes[i] === 'gx:Track') {
43623                                 var track = gxCoords(geomNode);
43624                                 geoms.push({
43625                                     type: 'LineString',
43626                                     coordinates: track.coords
43627                                 });
43628                                 if (track.times.length) coordTimes.push(track.times);
43629                             }
43630                         }
43631                     }
43632                 }
43633                 return {
43634                     geoms: geoms,
43635                     coordTimes: coordTimes
43636                 };
43637             }
43638             function getPlacemark(root) {
43639                 var geomsAndTimes = getGeometry(root), i, properties = {},
43640                     name = nodeVal(get1(root, 'name')),
43641                     address = nodeVal(get1(root, 'address')),
43642                     styleUrl = nodeVal(get1(root, 'styleUrl')),
43643                     description = nodeVal(get1(root, 'description')),
43644                     timeSpan = get1(root, 'TimeSpan'),
43645                     timeStamp = get1(root, 'TimeStamp'),
43646                     extendedData = get1(root, 'ExtendedData'),
43647                     lineStyle = get1(root, 'LineStyle'),
43648                     polyStyle = get1(root, 'PolyStyle'),
43649                     visibility = get1(root, 'visibility');
43650
43651                 if (!geomsAndTimes.geoms.length) return [];
43652                 if (name) properties.name = name;
43653                 if (address) properties.address = address;
43654                 if (styleUrl) {
43655                     if (styleUrl[0] !== '#') {
43656                         styleUrl = '#' + styleUrl;
43657                     }
43658
43659                     properties.styleUrl = styleUrl;
43660                     if (styleIndex[styleUrl]) {
43661                         properties.styleHash = styleIndex[styleUrl];
43662                     }
43663                     if (styleMapIndex[styleUrl]) {
43664                         properties.styleMapHash = styleMapIndex[styleUrl];
43665                         properties.styleHash = styleIndex[styleMapIndex[styleUrl].normal];
43666                     }
43667                     // Try to populate the lineStyle or polyStyle since we got the style hash
43668                     var style = styleByHash[properties.styleHash];
43669                     if (style) {
43670                         if (!lineStyle) lineStyle = get1(style, 'LineStyle');
43671                         if (!polyStyle) polyStyle = get1(style, 'PolyStyle');
43672                     }
43673                 }
43674                 if (description) properties.description = description;
43675                 if (timeSpan) {
43676                     var begin = nodeVal(get1(timeSpan, 'begin'));
43677                     var end = nodeVal(get1(timeSpan, 'end'));
43678                     properties.timespan = { begin: begin, end: end };
43679                 }
43680                 if (timeStamp) {
43681                     properties.timestamp = nodeVal(get1(timeStamp, 'when'));
43682                 }
43683                 if (lineStyle) {
43684                     var linestyles = kmlColor(nodeVal(get1(lineStyle, 'color'))),
43685                         color = linestyles[0],
43686                         opacity = linestyles[1],
43687                         width = parseFloat(nodeVal(get1(lineStyle, 'width')));
43688                     if (color) properties.stroke = color;
43689                     if (!isNaN(opacity)) properties['stroke-opacity'] = opacity;
43690                     if (!isNaN(width)) properties['stroke-width'] = width;
43691                 }
43692                 if (polyStyle) {
43693                     var polystyles = kmlColor(nodeVal(get1(polyStyle, 'color'))),
43694                         pcolor = polystyles[0],
43695                         popacity = polystyles[1],
43696                         fill = nodeVal(get1(polyStyle, 'fill')),
43697                         outline = nodeVal(get1(polyStyle, 'outline'));
43698                     if (pcolor) properties.fill = pcolor;
43699                     if (!isNaN(popacity)) properties['fill-opacity'] = popacity;
43700                     if (fill) properties['fill-opacity'] = fill === '1' ? properties['fill-opacity'] || 1 : 0;
43701                     if (outline) properties['stroke-opacity'] = outline === '1' ? properties['stroke-opacity'] || 1 : 0;
43702                 }
43703                 if (extendedData) {
43704                     var datas = get(extendedData, 'Data'),
43705                         simpleDatas = get(extendedData, 'SimpleData');
43706
43707                     for (i = 0; i < datas.length; i++) {
43708                         properties[datas[i].getAttribute('name')] = nodeVal(get1(datas[i], 'value'));
43709                     }
43710                     for (i = 0; i < simpleDatas.length; i++) {
43711                         properties[simpleDatas[i].getAttribute('name')] = nodeVal(simpleDatas[i]);
43712                     }
43713                 }
43714                 if (visibility) {
43715                     properties.visibility = nodeVal(visibility);
43716                 }
43717                 if (geomsAndTimes.coordTimes.length) {
43718                     properties.coordTimes = (geomsAndTimes.coordTimes.length === 1) ?
43719                         geomsAndTimes.coordTimes[0] : geomsAndTimes.coordTimes;
43720                 }
43721                 var feature = {
43722                     type: 'Feature',
43723                     geometry: (geomsAndTimes.geoms.length === 1) ? geomsAndTimes.geoms[0] : {
43724                         type: 'GeometryCollection',
43725                         geometries: geomsAndTimes.geoms
43726                     },
43727                     properties: properties
43728                 };
43729                 if (attr(root, 'id')) feature.id = attr(root, 'id');
43730                 return [feature];
43731             }
43732             return gj;
43733         },
43734         gpx: function(doc) {
43735             var i,
43736                 tracks = get(doc, 'trk'),
43737                 routes = get(doc, 'rte'),
43738                 waypoints = get(doc, 'wpt'),
43739                 // a feature collection
43740                 gj = fc(),
43741                 feature;
43742             for (i = 0; i < tracks.length; i++) {
43743                 feature = getTrack(tracks[i]);
43744                 if (feature) gj.features.push(feature);
43745             }
43746             for (i = 0; i < routes.length; i++) {
43747                 feature = getRoute(routes[i]);
43748                 if (feature) gj.features.push(feature);
43749             }
43750             for (i = 0; i < waypoints.length; i++) {
43751                 gj.features.push(getPoint(waypoints[i]));
43752             }
43753             function getPoints(node, pointname) {
43754                 var pts = get(node, pointname),
43755                     line = [],
43756                     times = [],
43757                     heartRates = [],
43758                     l = pts.length;
43759                 if (l < 2) return {};  // Invalid line in GeoJSON
43760                 for (var i = 0; i < l; i++) {
43761                     var c = coordPair(pts[i]);
43762                     line.push(c.coordinates);
43763                     if (c.time) times.push(c.time);
43764                     if (c.heartRate) heartRates.push(c.heartRate);
43765                 }
43766                 return {
43767                     line: line,
43768                     times: times,
43769                     heartRates: heartRates
43770                 };
43771             }
43772             function getTrack(node) {
43773                 var segments = get(node, 'trkseg'),
43774                     track = [],
43775                     times = [],
43776                     heartRates = [],
43777                     line;
43778                 for (var i = 0; i < segments.length; i++) {
43779                     line = getPoints(segments[i], 'trkpt');
43780                     if (line) {
43781                         if (line.line) track.push(line.line);
43782                         if (line.times && line.times.length) times.push(line.times);
43783                         if (line.heartRates && line.heartRates.length) heartRates.push(line.heartRates);
43784                     }
43785                 }
43786                 if (track.length === 0) return;
43787                 var properties = getProperties(node);
43788                 extend(properties, getLineStyle(get1(node, 'extensions')));
43789                 if (times.length) properties.coordTimes = track.length === 1 ? times[0] : times;
43790                 if (heartRates.length) properties.heartRates = track.length === 1 ? heartRates[0] : heartRates;
43791                 return {
43792                     type: 'Feature',
43793                     properties: properties,
43794                     geometry: {
43795                         type: track.length === 1 ? 'LineString' : 'MultiLineString',
43796                         coordinates: track.length === 1 ? track[0] : track
43797                     }
43798                 };
43799             }
43800             function getRoute(node) {
43801                 var line = getPoints(node, 'rtept');
43802                 if (!line.line) return;
43803                 var prop = getProperties(node);
43804                 extend(prop, getLineStyle(get1(node, 'extensions')));
43805                 var routeObj = {
43806                     type: 'Feature',
43807                     properties: prop,
43808                     geometry: {
43809                         type: 'LineString',
43810                         coordinates: line.line
43811                     }
43812                 };
43813                 return routeObj;
43814             }
43815             function getPoint(node) {
43816                 var prop = getProperties(node);
43817                 extend(prop, getMulti(node, ['sym']));
43818                 return {
43819                     type: 'Feature',
43820                     properties: prop,
43821                     geometry: {
43822                         type: 'Point',
43823                         coordinates: coordPair(node).coordinates
43824                     }
43825                 };
43826             }
43827             function getLineStyle(extensions) {
43828                 var style = {};
43829                 if (extensions) {
43830                     var lineStyle = get1(extensions, 'line');
43831                     if (lineStyle) {
43832                         var color = nodeVal(get1(lineStyle, 'color')),
43833                             opacity = parseFloat(nodeVal(get1(lineStyle, 'opacity'))),
43834                             width = parseFloat(nodeVal(get1(lineStyle, 'width')));
43835                         if (color) style.stroke = color;
43836                         if (!isNaN(opacity)) style['stroke-opacity'] = opacity;
43837                         // GPX width is in mm, convert to px with 96 px per inch
43838                         if (!isNaN(width)) style['stroke-width'] = width * 96 / 25.4;
43839                     }
43840                 }
43841                 return style;
43842             }
43843             function getProperties(node) {
43844                 var prop = getMulti(node, ['name', 'cmt', 'desc', 'type', 'time', 'keywords']),
43845                     links = get(node, 'link');
43846                 if (links.length) prop.links = [];
43847                 for (var i = 0, link; i < links.length; i++) {
43848                     link = { href: attr(links[i], 'href') };
43849                     extend(link, getMulti(links[i], ['text', 'type']));
43850                     prop.links.push(link);
43851                 }
43852                 return prop;
43853             }
43854             return gj;
43855         }
43856     };
43857     return t;
43858 })();
43859
43860 module.exports = toGeoJSON;
43861 });
43862
43863 var _initialized = false;
43864 var _enabled = false;
43865 var _geojson;
43866
43867
43868 function svgGpx(projection, context, dispatch) {
43869     var _showLabels = true;
43870     var detected = utilDetect();
43871     var layer;
43872     var _src;
43873
43874
43875     function init() {
43876         if (_initialized) return;  // run once
43877
43878         _geojson = {};
43879         _enabled = true;
43880
43881         function over() {
43882             event.stopPropagation();
43883             event.preventDefault();
43884             event.dataTransfer.dropEffect = 'copy';
43885         }
43886
43887         d3_select('body')
43888             .attr('dropzone', 'copy')
43889             .on('drop.localgpx', function() {
43890                 event.stopPropagation();
43891                 event.preventDefault();
43892                 if (!detected.filedrop) return;
43893                 drawGpx.files(event.dataTransfer.files);
43894             })
43895             .on('dragenter.localgpx', over)
43896             .on('dragexit.localgpx', over)
43897             .on('dragover.localgpx', over);
43898
43899         _initialized = true;
43900     }
43901
43902
43903     function drawGpx(selection) {
43904         var getPath = svgPath(projection).geojson;
43905
43906         layer = selection.selectAll('.layer-gpx')
43907             .data(_enabled ? [0] : []);
43908
43909         layer.exit()
43910             .remove();
43911
43912         layer = layer.enter()
43913             .append('g')
43914             .attr('class', 'layer-gpx')
43915             .merge(layer);
43916
43917
43918         var paths = layer
43919             .selectAll('path')
43920             .data([_geojson]);
43921
43922         paths.exit()
43923             .remove();
43924
43925         paths = paths.enter()
43926             .append('path')
43927             .attr('class', 'gpx')
43928             .merge(paths);
43929
43930         paths
43931             .attr('d', getPath);
43932
43933
43934         var labelData = _showLabels && _geojson.features ? _geojson.features : [];
43935         labelData = labelData.filter(getPath);
43936
43937         layer
43938             .call(drawLabels, 'gpxlabel-halo', labelData)
43939             .call(drawLabels, 'gpxlabel', labelData);
43940
43941
43942         function drawLabels(selection, textClass, data) {
43943             var labels = selection.selectAll('text.' + textClass)
43944                 .data(data);
43945
43946             // exit
43947             labels.exit()
43948                 .remove();
43949
43950             // enter/update
43951             labels = labels.enter()
43952                 .append('text')
43953                 .attr('class', textClass)
43954                 .merge(labels)
43955                 .text(function(d) {
43956                     return d.properties.desc || d.properties.name;
43957                 })
43958                 .attr('x', function(d) {
43959                     var centroid = getPath.centroid(d);
43960                     return centroid[0] + 11;
43961                 })
43962                 .attr('y', function(d) {
43963                     var centroid = getPath.centroid(d);
43964                     return centroid[1];
43965                 });
43966         }
43967     }
43968
43969
43970     function toDom(x) {
43971         return (new DOMParser()).parseFromString(x, 'text/xml');
43972     }
43973
43974
43975     function getExtension(fileName) {
43976         if (isUndefined(fileName)) {
43977             return '';
43978         }
43979
43980         var lastDotIndex = fileName.lastIndexOf('.');
43981         if (lastDotIndex < 0) {
43982             return '';
43983         }
43984
43985         return fileName.substr(lastDotIndex);
43986     }
43987
43988
43989     function parseSaveAndZoom(extension, data) {
43990         switch (extension) {
43991             default:
43992                 drawGpx.geojson(togeojson.gpx(toDom(data))).fitZoom();
43993                 break;
43994             case '.kml':
43995                 drawGpx.geojson(togeojson.kml(toDom(data))).fitZoom();
43996                 break;
43997             case '.geojson':
43998             case '.json':
43999                 drawGpx.geojson(JSON.parse(data)).fitZoom();
44000                 break;
44001         }
44002     }
44003
44004
44005     drawGpx.showLabels = function(_) {
44006         if (!arguments.length) return _showLabels;
44007         _showLabels = _;
44008         return this;
44009     };
44010
44011
44012     drawGpx.enabled = function(_) {
44013         if (!arguments.length) return _enabled;
44014         _enabled = _;
44015         dispatch.call('change');
44016         return this;
44017     };
44018
44019
44020     drawGpx.hasGpx = function() {
44021         return (!(isEmpty(_geojson) || isEmpty(_geojson.features)));
44022     };
44023
44024
44025     drawGpx.geojson = function(gj) {
44026         if (!arguments.length) return _geojson;
44027         if (isEmpty(gj) || isEmpty(gj.features)) return this;
44028         _geojson = gj;
44029         dispatch.call('change');
44030         return this;
44031     };
44032
44033
44034     drawGpx.url = function(url) {
44035         d3_text(url, function(err, data) {
44036             if (!err) {
44037                 _src = url;
44038                 var extension = getExtension(url);
44039                 parseSaveAndZoom(extension, data);
44040             }
44041         });
44042         return this;
44043     };
44044
44045
44046     drawGpx.files = function(fileList) {
44047         if (!fileList.length) return this;
44048         var f = fileList[0],
44049             reader = new FileReader();
44050
44051         reader.onload = (function(file) {
44052             _src = file.name;
44053             var extension = getExtension(file.name);
44054             return function (e) {
44055                 parseSaveAndZoom(extension, e.target.result);
44056             };
44057         })(f);
44058
44059         reader.readAsText(f);
44060         return this;
44061     };
44062
44063
44064     drawGpx.getSrc = function () {
44065         return _src;
44066     };
44067
44068
44069     drawGpx.fitZoom = function() {
44070         if (!this.hasGpx()) return this;
44071
44072         var map = context.map();
44073         var viewport = map.trimmedExtent().polygon();
44074         var coords = reduce(_geojson.features, function(coords, feature) {
44075             var c = feature.geometry.coordinates;
44076
44077             /* eslint-disable no-fallthrough */
44078             switch (feature.geometry.type) {
44079                 case 'Point':
44080                     c = [c];
44081                 case 'MultiPoint':
44082                 case 'LineString':
44083                     break;
44084
44085                 case 'MultiPolygon':
44086                     c = flatten(c);
44087                 case 'Polygon':
44088                 case 'MultiLineString':
44089                     c = flatten(c);
44090                     break;
44091             }
44092             /* eslint-enable no-fallthrough */
44093
44094             return union(coords, c);
44095         }, []);
44096
44097         if (!geoPolygonIntersectsPolygon(viewport, coords, true)) {
44098             var extent = geoExtent(d3_geoBounds({ type: 'LineString', coordinates: coords }));
44099             map.centerZoom(extent.center(), map.trimmedExtentZoom(extent));
44100         }
44101
44102         return this;
44103     };
44104
44105
44106     init();
44107     return drawGpx;
44108 }
44109
44110 function svgIcon(name, svgklass, useklass) {
44111     return function drawIcon(selection) {
44112         selection.selectAll('svg')
44113             .data([0])
44114             .enter()
44115             .append('svg')
44116             .attr('class', 'icon ' + (svgklass || ''))
44117             .append('use')
44118             .attr('xlink:href', name)
44119             .attr('class', useklass);
44120     };
44121 }
44122
44123 function svgLabels(projection, context) {
44124     var path = d3_geoPath(projection);
44125     var detected = utilDetect();
44126     var baselineHack = (detected.ie || detected.browser.toLowerCase() === 'edge');
44127     var _rdrawn = rbush_1();
44128     var _rskipped = rbush_1();
44129     var _textWidthCache = {};
44130     var _entitybboxes = {};
44131
44132     // Listed from highest to lowest priority
44133     var labelStack = [
44134         ['line', 'aeroway', '*', 12],
44135         ['line', 'highway', 'motorway', 12],
44136         ['line', 'highway', 'trunk', 12],
44137         ['line', 'highway', 'primary', 12],
44138         ['line', 'highway', 'secondary', 12],
44139         ['line', 'highway', 'tertiary', 12],
44140         ['line', 'highway', '*', 12],
44141         ['line', 'railway', '*', 12],
44142         ['line', 'waterway', '*', 12],
44143         ['area', 'aeroway', '*', 12],
44144         ['area', 'amenity', '*', 12],
44145         ['area', 'building', '*', 12],
44146         ['area', 'historic', '*', 12],
44147         ['area', 'leisure', '*', 12],
44148         ['area', 'man_made', '*', 12],
44149         ['area', 'natural', '*', 12],
44150         ['area', 'shop', '*', 12],
44151         ['area', 'tourism', '*', 12],
44152         ['area', 'camp_site', '*', 12],
44153         ['point', 'aeroway', '*', 10],
44154         ['point', 'amenity', '*', 10],
44155         ['point', 'building', '*', 10],
44156         ['point', 'historic', '*', 10],
44157         ['point', 'leisure', '*', 10],
44158         ['point', 'man_made', '*', 10],
44159         ['point', 'natural', '*', 10],
44160         ['point', 'shop', '*', 10],
44161         ['point', 'tourism', '*', 10],
44162         ['point', 'camp_site', '*', 10],
44163         ['line', 'name', '*', 12],
44164         ['area', 'name', '*', 12],
44165         ['point', 'name', '*', 10]
44166     ];
44167
44168
44169     function blacklisted(preset) {
44170         var noIcons = ['building', 'landuse', 'natural'];
44171         return some(noIcons, function(s) {
44172             return preset.id.indexOf(s) >= 0;
44173         });
44174     }
44175
44176
44177     function get(array, prop) {
44178         return function(d, i) { return array[i][prop]; };
44179     }
44180
44181
44182     function textWidth(text, size, elem) {
44183         var c = _textWidthCache[size];
44184         if (!c) c = _textWidthCache[size] = {};
44185
44186         if (c[text]) {
44187             return c[text];
44188
44189         } else if (elem) {
44190             c[text] = elem.getComputedTextLength();
44191             return c[text];
44192
44193         } else {
44194             var str = encodeURIComponent(text).match(/%[CDEFcdef]/g);
44195             if (str === null) {
44196                 return size / 3 * 2 * text.length;
44197             } else {
44198                 return size / 3 * (2 * text.length + str.length);
44199             }
44200         }
44201     }
44202
44203
44204     function drawLinePaths(selection, entities, filter, classes, labels) {
44205         var paths = selection.selectAll('path')
44206             .filter(filter)
44207             .data(entities, osmEntity.key);
44208
44209         // exit
44210         paths.exit()
44211             .remove();
44212
44213         // enter/update
44214         paths.enter()
44215             .append('path')
44216             .style('stroke-width', get(labels, 'font-size'))
44217             .attr('id', function(d) { return 'labelpath-' + d.id; })
44218             .attr('class', classes)
44219             .merge(paths)
44220             .attr('d', get(labels, 'lineString'));
44221     }
44222
44223
44224     function drawLineLabels(selection, entities, filter, classes, labels) {
44225         var texts = selection.selectAll('text.' + classes)
44226             .filter(filter)
44227             .data(entities, osmEntity.key);
44228
44229         // exit
44230         texts.exit()
44231             .remove();
44232
44233         // enter
44234         texts.enter()
44235             .append('text')
44236             .attr('class', function(d, i) { return classes + ' ' + labels[i].classes + ' ' + d.id; })
44237             .attr('dy', baselineHack ? '0.35em' : null)
44238             .append('textPath')
44239             .attr('class', 'textpath');
44240
44241         // update
44242         selection.selectAll('text.' + classes).selectAll('.textpath')
44243             .filter(filter)
44244             .data(entities, osmEntity.key)
44245             .attr('startOffset', '50%')
44246             .attr('xlink:href', function(d) { return '#labelpath-' + d.id; })
44247             .text(utilDisplayNameForPath);
44248     }
44249
44250
44251     function drawPointLabels(selection, entities, filter, classes, labels) {
44252         var texts = selection.selectAll('text.' + classes)
44253             .filter(filter)
44254             .data(entities, osmEntity.key);
44255
44256         // exit
44257         texts.exit()
44258             .remove();
44259
44260         // enter/update
44261         texts.enter()
44262             .append('text')
44263             .attr('class', function(d, i) {
44264                 return classes + ' ' + labels[i].classes + ' ' + d.id;
44265             })
44266             .merge(texts)
44267             .attr('x', get(labels, 'x'))
44268             .attr('y', get(labels, 'y'))
44269             .style('text-anchor', get(labels, 'textAnchor'))
44270             .text(utilDisplayName)
44271             .each(function(d, i) {
44272                 textWidth(utilDisplayName(d), labels[i].height, this);
44273             });
44274     }
44275
44276
44277     function drawAreaLabels(selection, entities, filter, classes, labels) {
44278         entities = entities.filter(hasText);
44279         labels = labels.filter(hasText);
44280         drawPointLabels(selection, entities, filter, classes, labels);
44281
44282         function hasText(d, i) {
44283             return labels[i].hasOwnProperty('x') && labels[i].hasOwnProperty('y');
44284         }
44285     }
44286
44287
44288     function drawAreaIcons(selection, entities, filter, classes, labels) {
44289         var icons = selection.selectAll('use.' + classes)
44290             .filter(filter)
44291             .data(entities, osmEntity.key);
44292
44293         // exit
44294         icons.exit()
44295             .remove();
44296
44297         // enter/update
44298         icons.enter()
44299             .append('use')
44300             .attr('class', 'icon ' + classes)
44301             .attr('width', '17px')
44302             .attr('height', '17px')
44303             .merge(icons)
44304             .attr('transform', get(labels, 'transform'))
44305             .attr('xlink:href', function(d) {
44306                 var preset = context.presets().match(d, context.graph());
44307                 var picon = preset && preset.icon;
44308
44309                 if (!picon) {
44310                     return '';
44311                 } else {
44312                     var isMaki = dataFeatureIcons.indexOf(picon) !== -1;
44313                     return '#' + picon + (isMaki ? '-15' : '');
44314                 }
44315             });
44316     }
44317
44318
44319     function drawCollisionBoxes(selection, rtree, which) {
44320         var classes = 'debug ' + which + ' ' + (which === 'debug-skipped' ? 'orange' : 'yellow');
44321
44322         var gj = [];
44323         if (context.getDebug('collision')) {
44324             gj = rtree.all().map(function(d) {
44325                 return { type: 'Polygon', coordinates: [[
44326                     [d.minX, d.minY],
44327                     [d.maxX, d.minY],
44328                     [d.maxX, d.maxY],
44329                     [d.minX, d.maxY],
44330                     [d.minX, d.minY]
44331                 ]]};
44332             });
44333         }
44334
44335         var boxes = selection.selectAll('.' + which)
44336             .data(gj);
44337
44338         // exit
44339         boxes.exit()
44340             .remove();
44341
44342         // enter/update
44343         boxes.enter()
44344             .append('path')
44345             .attr('class', classes)
44346             .merge(boxes)
44347             .attr('d', d3_geoPath());
44348     }
44349
44350
44351     function drawLabels(selection, graph, entities, filter, dimensions, fullRedraw) {
44352         var wireframe = context.surface().classed('fill-wireframe');
44353         var zoom = geoScaleToZoom(projection.scale());
44354
44355         var labelable = [];
44356         var renderNodeAs = {};
44357         var i, j, k, entity, geometry;
44358
44359         for (i = 0; i < labelStack.length; i++) {
44360             labelable.push([]);
44361         }
44362
44363         if (fullRedraw) {
44364             _rdrawn.clear();
44365             _rskipped.clear();
44366             _entitybboxes = {};
44367
44368         } else {
44369             for (i = 0; i < entities.length; i++) {
44370                 entity = entities[i];
44371                 var toRemove = []
44372                     .concat(_entitybboxes[entity.id] || [])
44373                     .concat(_entitybboxes[entity.id + 'I'] || []);
44374
44375                 for (j = 0; j < toRemove.length; j++) {
44376                     _rdrawn.remove(toRemove[j]);
44377                     _rskipped.remove(toRemove[j]);
44378                 }
44379             }
44380         }
44381
44382         // Loop through all the entities to do some preprocessing
44383         for (i = 0; i < entities.length; i++) {
44384             entity = entities[i];
44385             geometry = entity.geometry(graph);
44386
44387             // Insert collision boxes around interesting points/vertices
44388             if (geometry === 'point' || (geometry === 'vertex' && isInterestingVertex(entity))) {
44389                 var hasDirections = entity.directions(graph, projection).length;
44390                 var markerPadding;
44391
44392                 if (!wireframe && geometry === 'point' && !(zoom >= 18 && hasDirections)) {
44393                     renderNodeAs[entity.id] = 'point';
44394                     markerPadding = 20;   // extra y for marker height
44395                 } else {
44396                     renderNodeAs[entity.id] = 'vertex';
44397                     markerPadding = 0;
44398                 }
44399
44400                 var coord = projection(entity.loc);
44401                 var nodePadding = 10;
44402                 var bbox = {
44403                     minX: coord[0] - nodePadding,
44404                     minY: coord[1] - nodePadding - markerPadding,
44405                     maxX: coord[0] + nodePadding,
44406                     maxY: coord[1] + nodePadding
44407                 };
44408
44409                 doInsert(bbox, entity.id + 'P');
44410             }
44411
44412             // From here on, treat vertices like points
44413             if (geometry === 'vertex') {
44414                 geometry = 'point';
44415             }
44416
44417             // Determine which entities are label-able
44418             var preset = geometry === 'area' && context.presets().match(entity, graph);
44419             var icon = preset && !blacklisted(preset) && preset.icon;
44420
44421             if (!icon && !utilDisplayName(entity))
44422                 continue;
44423
44424             for (k = 0; k < labelStack.length; k++) {
44425                 var matchGeom = labelStack[k][0];
44426                 var matchKey = labelStack[k][1];
44427                 var matchVal = labelStack[k][2];
44428                 var hasVal = entity.tags[matchKey];
44429
44430                 if (geometry === matchGeom && hasVal && (matchVal === '*' || matchVal === hasVal)) {
44431                     labelable[k].push(entity);
44432                     break;
44433                 }
44434             }
44435         }
44436
44437         var positions = {
44438             point: [],
44439             line: [],
44440             area: []
44441         };
44442
44443         var labelled = {
44444             point: [],
44445             line: [],
44446             area: []
44447         };
44448
44449         // Try and find a valid label for labellable entities
44450         for (k = 0; k < labelable.length; k++) {
44451             var fontSize = labelStack[k][3];
44452
44453             for (i = 0; i < labelable[k].length; i++) {
44454                 entity = labelable[k][i];
44455                 geometry = entity.geometry(graph);
44456
44457                 var getName = (geometry === 'line') ? utilDisplayNameForPath : utilDisplayName;
44458                 var name = getName(entity);
44459                 var width = name && textWidth(name, fontSize);
44460                 var p = null;
44461
44462                 if (geometry === 'point' || geometry === 'vertex') {
44463                     // no point or vertex labels in wireframe mode
44464                     // no vertex labels at low zooms (vertices have no icons)
44465                     if (wireframe) continue;
44466                     var renderAs = renderNodeAs[entity.id];
44467                     if (renderAs === 'vertex' && zoom < 17) continue;
44468
44469                     p = getPointLabel(entity, width, fontSize, renderAs);
44470
44471                 } else if (geometry === 'line') {
44472                     p = getLineLabel(entity, width, fontSize);
44473
44474                 } else if (geometry === 'area') {
44475                     p = getAreaLabel(entity, width, fontSize);
44476                 }
44477
44478                 if (p) {
44479                     if (geometry === 'vertex') { geometry = 'point'; }  // treat vertex like point
44480                     p.classes = geometry + ' tag-' + labelStack[k][1];
44481                     positions[geometry].push(p);
44482                     labelled[geometry].push(entity);
44483                 }
44484             }
44485         }
44486
44487
44488         function isInterestingVertex(entity) {
44489             var selectedIDs = context.selectedIDs();
44490
44491             return entity.hasInterestingTags() ||
44492                 entity.isEndpoint(graph) ||
44493                 entity.isConnected(graph) ||
44494                 selectedIDs.indexOf(entity.id) !== -1 ||
44495                 some(graph.parentWays(entity), function(parent) {
44496                     return selectedIDs.indexOf(parent.id) !== -1;
44497                 });
44498         }
44499
44500
44501         function getPointLabel(entity, width, height, geometry) {
44502             var y = (geometry === 'point' ? -12 : 0);
44503             var pointOffsets = {
44504                 ltr: [15, y, 'start'],
44505                 rtl: [-15, y, 'end']
44506             };
44507
44508             var coord = projection(entity.loc);
44509             var textPadding = 2;
44510             var offset = pointOffsets[textDirection];
44511             var p = {
44512                 height: height,
44513                 width: width,
44514                 x: coord[0] + offset[0],
44515                 y: coord[1] + offset[1],
44516                 textAnchor: offset[2]
44517             };
44518
44519             // insert a collision box for the text label..
44520             var bbox;
44521             if (textDirection === 'rtl') {
44522                 bbox = {
44523                     minX: p.x - width - textPadding,
44524                     minY: p.y - (height / 2) - textPadding,
44525                     maxX: p.x + textPadding,
44526                     maxY: p.y + (height / 2) + textPadding
44527                 };
44528             } else {
44529                 bbox = {
44530                     minX: p.x - textPadding,
44531                     minY: p.y - (height / 2) - textPadding,
44532                     maxX: p.x + width + textPadding,
44533                     maxY: p.y + (height / 2) + textPadding
44534                 };
44535             }
44536
44537             if (tryInsert([bbox], entity.id, true)) {
44538                 return p;
44539             }
44540         }
44541
44542
44543         function getLineLabel(entity, width, height) {
44544             var viewport = geoExtent(context.projection.clipExtent()).polygon();
44545             var points = map$4(graph.childNodes(entity), 'loc').map(projection);
44546             var length = geoPathLength(points);
44547
44548             if (length < width + 20) return;
44549
44550             // todo: properly clip points to viewport
44551
44552             // % along the line to attempt to place the label
44553             var lineOffsets = [50, 45, 55, 40, 60, 35, 65, 30, 70,
44554                                25, 75, 20, 80, 15, 95, 10, 90, 5, 95];
44555             var padding = 3;
44556
44557             for (var i = 0; i < lineOffsets.length; i++) {
44558                 var offset = lineOffsets[i];
44559                 var middle = offset / 100 * length;
44560                 var start = middle - width / 2;
44561
44562                 if (start < 0 || start + width > length) continue;
44563
44564                 // generate subpath and ignore paths that are invalid or don't cross viewport.
44565                 var sub = subpath(points, start, start + width);
44566                 if (!sub || !geoPolygonIntersectsPolygon(viewport, sub, true)) {
44567                     continue;
44568                 }
44569
44570                 var isReverse = reverse(sub);
44571                 if (isReverse) {
44572                     sub = sub.reverse();
44573                 }
44574
44575                 var bboxes = [];
44576                 var boxsize = (height + 2) / 2;
44577
44578                 for (var j = 0; j < sub.length - 1; j++) {
44579                     var a = sub[j];
44580                     var b = sub[j + 1];
44581
44582                     // split up the text into small collision boxes
44583                     var num = Math.max(1, Math.floor(geoVecLength(a, b) / boxsize / 2));
44584
44585                     for (var box = 0; box < num; box++) {
44586                         var p = geoVecInterp(a, b, box / num);
44587                         var x0 = p[0] - boxsize - padding;
44588                         var y0 = p[1] - boxsize - padding;
44589                         var x1 = p[0] + boxsize + padding;
44590                         var y1 = p[1] + boxsize + padding;
44591
44592                         bboxes.push({
44593                             minX: Math.min(x0, x1),
44594                             minY: Math.min(y0, y1),
44595                             maxX: Math.max(x0, x1),
44596                             maxY: Math.max(y0, y1)
44597                         });
44598                     }
44599                 }
44600
44601                 if (tryInsert(bboxes, entity.id, false)) {   // accept this one
44602                     return {
44603                         'font-size': height + 2,
44604                         lineString: lineString(sub),
44605                         startOffset: offset + '%'
44606                     };
44607                 }
44608             }
44609
44610             function reverse(p) {
44611                 var angle = Math.atan2(p[1][1] - p[0][1], p[1][0] - p[0][0]);
44612                 return !(p[0][0] < p[p.length - 1][0] && angle < Math.PI/2 && angle > -Math.PI/2);
44613             }
44614
44615             function lineString(points) {
44616                 return 'M' + points.join('L');
44617             }
44618
44619             function subpath(points, from, to) {
44620                 var sofar = 0;
44621                 var start, end, i0, i1;
44622
44623                 for (var i = 0; i < points.length - 1; i++) {
44624                     var a = points[i];
44625                     var b = points[i + 1];
44626                     var current = geoVecLength(a, b);
44627                     var portion;
44628                     if (!start && sofar + current >= from) {
44629                         portion = (from - sofar) / current;
44630                         start = [
44631                             a[0] + portion * (b[0] - a[0]),
44632                             a[1] + portion * (b[1] - a[1])
44633                         ];
44634                         i0 = i + 1;
44635                     }
44636                     if (!end && sofar + current >= to) {
44637                         portion = (to - sofar) / current;
44638                         end = [
44639                             a[0] + portion * (b[0] - a[0]),
44640                             a[1] + portion * (b[1] - a[1])
44641                         ];
44642                         i1 = i + 1;
44643                     }
44644                     sofar += current;
44645                 }
44646
44647                 var result = points.slice(i0, i1);
44648                 result.unshift(start);
44649                 result.push(end);
44650                 return result;
44651             }
44652         }
44653
44654
44655         function getAreaLabel(entity, width, height) {
44656             var centroid = path.centroid(entity.asGeoJSON(graph, true));
44657             var extent = entity.extent(graph);
44658             var areaWidth = projection(extent[1])[0] - projection(extent[0])[0];
44659
44660             if (isNaN(centroid[0]) || areaWidth < 20) return;
44661
44662             var preset = context.presets().match(entity, context.graph());
44663             var picon = preset && preset.icon;
44664             var iconSize = 17;
44665             var padding = 2;
44666             var p = {};
44667
44668             if (picon) {  // icon and label..
44669                 if (addIcon()) {
44670                     addLabel(iconSize + padding);
44671                     return p;
44672                 }
44673             } else {   // label only..
44674                 if (addLabel(0)) {
44675                     return p;
44676                 }
44677             }
44678
44679
44680             function addIcon() {
44681                 var iconX = centroid[0] - (iconSize / 2);
44682                 var iconY = centroid[1] - (iconSize / 2);
44683                 var bbox = {
44684                     minX: iconX,
44685                     minY: iconY,
44686                     maxX: iconX + iconSize,
44687                     maxY: iconY + iconSize
44688                 };
44689
44690                 if (tryInsert([bbox], entity.id + 'I', true)) {
44691                     p.transform = 'translate(' + iconX + ',' + iconY + ')';
44692                     return true;
44693                 }
44694                 return false;
44695             }
44696
44697             function addLabel(yOffset) {
44698                 if (width && areaWidth >= width + 20) {
44699                     var labelX = centroid[0];
44700                     var labelY = centroid[1] + yOffset;
44701                     var bbox = {
44702                         minX: labelX - (width / 2) - padding,
44703                         minY: labelY - (height / 2) - padding,
44704                         maxX: labelX + (width / 2) + padding,
44705                         maxY: labelY + (height / 2) + padding
44706                     };
44707
44708                     if (tryInsert([bbox], entity.id, true)) {
44709                         p.x = labelX;
44710                         p.y = labelY;
44711                         p.textAnchor = 'middle';
44712                         p.height = height;
44713                         return true;
44714                     }
44715                 }
44716                 return false;
44717             }
44718         }
44719
44720
44721         // force insert a singular bounding box
44722         // singular box only, no array, id better be unique
44723         function doInsert(bbox, id) {
44724             bbox.id = id;
44725
44726             var oldbox = _entitybboxes[id];
44727             if (oldbox) {
44728                 _rdrawn.remove(oldbox);
44729             }
44730             _entitybboxes[id] = bbox;
44731             _rdrawn.insert(bbox);
44732         }
44733
44734
44735         function tryInsert(bboxes, id, saveSkipped) {
44736             var skipped = false;
44737
44738             for (var i = 0; i < bboxes.length; i++) {
44739                 var bbox = bboxes[i];
44740                 bbox.id = id;
44741
44742                 // Check that label is visible
44743                 if (bbox.minX < 0 || bbox.minY < 0 || bbox.maxX > dimensions[0] || bbox.maxY > dimensions[1]) {
44744                     skipped = true;
44745                     break;
44746                 }
44747                 if (_rdrawn.collides(bbox)) {
44748                     skipped = true;
44749                     break;
44750                 }
44751             }
44752
44753             _entitybboxes[id] = bboxes;
44754
44755             if (skipped) {
44756                 if (saveSkipped) {
44757                     _rskipped.load(bboxes);
44758                 }
44759             } else {
44760                 _rdrawn.load(bboxes);
44761             }
44762
44763             return !skipped;
44764         }
44765
44766
44767         var layer = selection.selectAll('.layer-labels');
44768         var halo = layer.selectAll('.layer-labels-halo');
44769         var label = layer.selectAll('.layer-labels-label');
44770         var debug = layer.selectAll('.layer-labels-debug');
44771
44772         // points
44773         drawPointLabels(label, labelled.point, filter, 'pointlabel', positions.point);
44774         drawPointLabels(halo, labelled.point, filter, 'pointlabel-halo', positions.point);
44775
44776         // lines
44777         drawLinePaths(halo, labelled.line, filter, '', positions.line);
44778         drawLineLabels(label, labelled.line, filter, 'linelabel', positions.line);
44779         drawLineLabels(halo, labelled.line, filter, 'linelabel-halo', positions.line);
44780
44781         // areas
44782         drawAreaLabels(label, labelled.area, filter, 'arealabel', positions.area);
44783         drawAreaLabels(halo, labelled.area, filter, 'arealabel-halo', positions.area);
44784         drawAreaIcons(label, labelled.area, filter, 'areaicon', positions.area);
44785         drawAreaIcons(halo, labelled.area, filter, 'areaicon-halo', positions.area);
44786
44787         // debug
44788         drawCollisionBoxes(debug, _rskipped, 'debug-skipped');
44789         drawCollisionBoxes(debug, _rdrawn, 'debug-drawn');
44790
44791         layer.call(filterLabels);
44792     }
44793
44794
44795     function filterLabels(selection) {
44796         var layers = selection
44797             .selectAll('.layer-labels-label, .layer-labels-halo');
44798
44799         layers.selectAll('.nolabel')
44800             .classed('nolabel', false);
44801
44802         var mouse = context.mouse();
44803         var graph = context.graph();
44804         var selectedIDs = context.selectedIDs();
44805         var ids = [];
44806         var pad, bbox;
44807
44808         // hide labels near the mouse
44809         if (mouse) {
44810             pad = 20;
44811             bbox = { minX: mouse[0] - pad, minY: mouse[1] - pad, maxX: mouse[0] + pad, maxY: mouse[1] + pad };
44812             ids.push.apply(ids, map$4(_rdrawn.search(bbox), 'id'));
44813         }
44814
44815         // hide labels on selected nodes (they look weird when dragging / haloed)
44816         for (var i = 0; i < selectedIDs.length; i++) {
44817             var entity = graph.hasEntity(selectedIDs[i]);
44818             if (entity && entity.type === 'node') {
44819                 ids.push(selectedIDs[i]);
44820             }
44821         }
44822
44823         layers.selectAll(utilEntitySelector(ids))
44824             .classed('nolabel', true);
44825
44826
44827         // draw the mouse bbox if debugging is on..
44828         var debug = selection.selectAll('.layer-labels-debug');
44829         var gj = [];
44830         if (context.getDebug('collision')) {
44831             gj = bbox ? [{
44832                 type: 'Polygon',
44833                 coordinates: [[
44834                     [bbox.minX, bbox.minY],
44835                     [bbox.maxX, bbox.minY],
44836                     [bbox.maxX, bbox.maxY],
44837                     [bbox.minX, bbox.maxY],
44838                     [bbox.minX, bbox.minY]
44839                 ]]
44840             }] : [];
44841         }
44842
44843         var box = debug.selectAll('.debug-mouse')
44844             .data(gj);
44845
44846         // exit
44847         box.exit()
44848             .remove();
44849
44850         // enter/update
44851         box.enter()
44852             .append('path')
44853             .attr('class', 'debug debug-mouse yellow')
44854             .merge(box)
44855             .attr('d', d3_geoPath());
44856     }
44857
44858
44859     var throttleFilterLabels = throttle(utilCallWhenIdle(filterLabels), 100);
44860
44861
44862     drawLabels.observe = function(selection) {
44863         var listener = function() { throttleFilterLabels(selection); };
44864         selection.on('mousemove.hidelabels', listener);
44865         context.on('enter.hidelabels', listener);
44866     };
44867
44868
44869     drawLabels.off = function(selection) {
44870         throttleFilterLabels.cancel();
44871         selection.on('mousemove.hidelabels', null);
44872         context.on('enter.hidelabels', null);
44873     };
44874
44875
44876     return drawLabels;
44877 }
44878
44879 function svgMapillaryImages(projection, context, dispatch) {
44880     var throttledRedraw = throttle(function () { dispatch.call('change'); }, 1000);
44881     var minZoom = 12;
44882     var minMarkerZoom = 16;
44883     var minViewfieldZoom = 18;
44884     var layer = d3_select(null);
44885     var _mapillary;
44886
44887
44888     function init() {
44889         if (svgMapillaryImages.initialized) return;  // run once
44890         svgMapillaryImages.enabled = false;
44891         svgMapillaryImages.initialized = true;
44892     }
44893
44894
44895     function getService() {
44896         if (services.mapillary && !_mapillary) {
44897             _mapillary = services.mapillary;
44898             _mapillary.event.on('loadedImages', throttledRedraw);
44899         } else if (!services.mapillary && _mapillary) {
44900             _mapillary = null;
44901         }
44902
44903         return _mapillary;
44904     }
44905
44906
44907     function showLayer() {
44908         var service = getService();
44909         if (!service) return;
44910
44911         service.loadViewer(context);
44912         editOn();
44913
44914         layer
44915             .style('opacity', 0)
44916             .transition()
44917             .duration(250)
44918             .style('opacity', 1)
44919             .on('end', function () { dispatch.call('change'); });
44920     }
44921
44922
44923     function hideLayer() {
44924         var service = getService();
44925         if (service) {
44926             service.hideViewer();
44927         }
44928
44929         throttledRedraw.cancel();
44930
44931         layer
44932             .transition()
44933             .duration(250)
44934             .style('opacity', 0)
44935             .on('end', editOff);
44936     }
44937
44938
44939     function editOn() {
44940         layer.style('display', 'block');
44941     }
44942
44943
44944     function editOff() {
44945         layer.selectAll('.viewfield-group').remove();
44946         layer.style('display', 'none');
44947     }
44948
44949
44950     function click(d) {
44951         var service = getService();
44952         if (!service) return;
44953
44954         service
44955             .selectImage(d)
44956             .updateViewer(d.key, context)
44957             .showViewer();
44958
44959         context.map().centerEase(d.loc);
44960     }
44961
44962
44963     function mouseover(d) {
44964         var service = getService();
44965         if (service) service.setStyles(d);
44966     }
44967
44968
44969     function mouseout() {
44970         var service = getService();
44971         if (service) service.setStyles(null);
44972     }
44973
44974
44975     function transform(d) {
44976         var t = svgPointTransform(projection)(d);
44977         if (d.ca) {
44978             t += ' rotate(' + Math.floor(d.ca) + ',0,0)';
44979         }
44980         return t;
44981     }
44982
44983
44984     function update() {
44985         var viewer = d3_select('#photoviewer');
44986         var selected = viewer.empty() ? undefined : viewer.datum();
44987
44988         var z = ~~context.map().zoom();
44989         var showMarkers = (z >= minMarkerZoom);
44990         var showViewfields = (z >= minViewfieldZoom);
44991
44992         var service = getService();
44993         var sequences = (service ? service.sequences(projection) : []);
44994         var images = (service && showMarkers ? service.images(projection) : []);
44995
44996         var traces = layer.selectAll('.sequences').selectAll('.sequence')
44997             .data(sequences, function(d) { return d.properties.key; });
44998
44999         // exit
45000         traces.exit()
45001             .remove();
45002
45003         // enter/update
45004         traces = traces.enter()
45005             .append('path')
45006             .attr('class', 'sequence')
45007             .merge(traces)
45008             .attr('d', svgPath(projection).geojson);
45009
45010
45011         var groups = layer.selectAll('.markers').selectAll('.viewfield-group')
45012             .data(images, function(d) { return d.key; });
45013
45014         // exit
45015         groups.exit()
45016             .remove();
45017
45018         // enter
45019         var groupsEnter = groups.enter()
45020             .append('g')
45021             .attr('class', 'viewfield-group')
45022             .on('mouseover', mouseover)
45023             .on('mouseout', mouseout)
45024             .on('click', click);
45025
45026         groupsEnter
45027             .append('g')
45028             .attr('class', 'viewfield-scale');
45029
45030         // update
45031         var markers = groups
45032             .merge(groupsEnter)
45033             .sort(function(a, b) {
45034                 return (a === selected) ? 1
45035                     : (b === selected) ? -1
45036                     : b.loc[1] - a.loc[1];  // sort Y
45037             })
45038             .attr('transform', transform)
45039             .select('.viewfield-scale');
45040
45041
45042         markers.selectAll('circle')
45043             .data([0])
45044             .enter()
45045             .append('circle')
45046             .attr('dx', '0')
45047             .attr('dy', '0')
45048             .attr('r', '6');
45049
45050         var viewfields = markers.selectAll('.viewfield')
45051             .data(showViewfields ? [0] : []);
45052
45053         viewfields.exit()
45054             .remove();
45055
45056         viewfields.enter()               // viewfields may or may not be drawn...
45057             .insert('path', 'circle')    // but if they are, draw below the circles
45058             .attr('class', 'viewfield')
45059             .attr('transform', 'scale(1.5,1.5),translate(-8, -13)')
45060             .attr('d', viewfieldPath);
45061
45062         function viewfieldPath() {
45063             var d = this.parentNode.__data__;
45064             if (d.pano) {
45065                 return 'M 8,13 m -10,0 a 10,10 0 1,0 20,0 a 10,10 0 1,0 -20,0';
45066             } else {
45067                 return 'M 6,9 C 8,8.4 8,8.4 10,9 L 16,-2 C 12,-5 4,-5 0,-2 z';
45068             }
45069         }
45070     }
45071
45072
45073     function drawImages(selection) {
45074         var enabled = svgMapillaryImages.enabled,
45075             service = getService();
45076
45077         layer = selection.selectAll('.layer-mapillary-images')
45078             .data(service ? [0] : []);
45079
45080         layer.exit()
45081             .remove();
45082
45083         var layerEnter = layer.enter()
45084             .append('g')
45085             .attr('class', 'layer-mapillary-images')
45086             .style('display', enabled ? 'block' : 'none');
45087
45088         layerEnter
45089             .append('g')
45090             .attr('class', 'sequences');
45091
45092         layerEnter
45093             .append('g')
45094             .attr('class', 'markers');
45095
45096         layer = layerEnter
45097             .merge(layer);
45098
45099         if (enabled) {
45100             if (service && ~~context.map().zoom() >= minZoom) {
45101                 editOn();
45102                 update();
45103                 service.loadImages(projection);
45104             } else {
45105                 editOff();
45106             }
45107         }
45108     }
45109
45110
45111     drawImages.enabled = function(_) {
45112         if (!arguments.length) return svgMapillaryImages.enabled;
45113         svgMapillaryImages.enabled = _;
45114         if (svgMapillaryImages.enabled) {
45115             showLayer();
45116         } else {
45117             hideLayer();
45118         }
45119         dispatch.call('change');
45120         return this;
45121     };
45122
45123
45124     drawImages.supported = function() {
45125         return !!getService();
45126     };
45127
45128
45129     init();
45130     return drawImages;
45131 }
45132
45133 function svgMapillarySigns(projection, context, dispatch) {
45134     var throttledRedraw = throttle(function () { dispatch.call('change'); }, 1000);
45135     var minZoom = 12;
45136     var layer = d3_select(null);
45137     var _mapillary;
45138
45139
45140     function init() {
45141         if (svgMapillarySigns.initialized) return;  // run once
45142         svgMapillarySigns.enabled = false;
45143         svgMapillarySigns.initialized = true;
45144     }
45145
45146
45147     function getService() {
45148         if (services.mapillary && !_mapillary) {
45149             _mapillary = services.mapillary;
45150             _mapillary.event.on('loadedSigns', throttledRedraw);
45151         } else if (!services.mapillary && _mapillary) {
45152             _mapillary = null;
45153         }
45154         return _mapillary;
45155     }
45156
45157
45158     function showLayer() {
45159         var service = getService();
45160         if (!service) return;
45161
45162         service.loadViewer(context);
45163         editOn();
45164     }
45165
45166
45167     function hideLayer() {
45168         throttledRedraw.cancel();
45169         editOff();
45170     }
45171
45172
45173     function editOn() {
45174         layer.style('display', 'block');
45175     }
45176
45177
45178     function editOff() {
45179         layer.selectAll('.icon-sign').remove();
45180         layer.style('display', 'none');
45181     }
45182
45183
45184     function click(d) {
45185         var service = getService();
45186         if (!service) return;
45187
45188         context.map().centerEase(d.loc);
45189
45190         var selected = service.getSelectedImage();
45191         var selectedImageKey = selected && selected.key;
45192         var imageKey;
45193
45194         // Pick one of the images the sign was detected in,
45195         // preference given to an image already selected.
45196         d.detections.forEach(function(detection) {
45197             if (!imageKey || selectedImageKey === detection.image_key) {
45198                 imageKey = detection.image_key;
45199             }
45200         });
45201
45202         service
45203             .selectImage(null, imageKey)
45204             .updateViewer(imageKey, context)
45205             .showViewer();
45206     }
45207
45208
45209     function update() {
45210         var service = getService();
45211         var data = (service ? service.signs(projection) : []);
45212         var viewer = d3_select('#photoviewer');
45213         var selected = viewer.empty() ? undefined : viewer.datum();
45214         var selectedImageKey = selected && selected.key;
45215
45216         var signs = layer.selectAll('.icon-sign')
45217             .data(data, function(d) { return d.key; });
45218
45219         signs.exit()
45220             .remove();
45221
45222         var enter = signs.enter()
45223             .append('foreignObject')
45224             .attr('class', 'icon-sign')
45225             .attr('width', '24px')      // for Firefox
45226             .attr('height', '24px')     // for Firefox
45227             .classed('selected', function(d) {
45228                 return some(d.detections, function(detection) {
45229                     return detection.image_key === selectedImageKey;
45230                 });
45231             })
45232             .on('click', click);
45233
45234         enter
45235             .append('xhtml:body')
45236             .attr('class', 'icon-sign-body')
45237             .html(service.signHTML);
45238
45239         signs
45240             .merge(enter)
45241             .attr('x', function(d) { return projection(d.loc)[0] - 12; })   // offset by -12px to
45242             .attr('y', function(d) { return projection(d.loc)[1] - 12; });  // center signs on loc
45243     }
45244
45245
45246     function drawSigns(selection) {
45247         var enabled = svgMapillarySigns.enabled,
45248             service = getService();
45249
45250         layer = selection.selectAll('.layer-mapillary-signs')
45251             .data(service ? [0] : []);
45252
45253         layer.exit()
45254             .remove();
45255
45256         layer = layer.enter()
45257             .append('g')
45258             .attr('class', 'layer-mapillary-signs')
45259             .style('display', enabled ? 'block' : 'none')
45260             .merge(layer);
45261
45262         if (enabled) {
45263             if (service && ~~context.map().zoom() >= minZoom) {
45264                 editOn();
45265                 update();
45266                 service.loadSigns(context, projection);
45267             } else {
45268                 editOff();
45269             }
45270         }
45271     }
45272
45273
45274     drawSigns.enabled = function(_) {
45275         if (!arguments.length) return svgMapillarySigns.enabled;
45276         svgMapillarySigns.enabled = _;
45277         if (svgMapillarySigns.enabled) {
45278             showLayer();
45279         } else {
45280             hideLayer();
45281         }
45282         dispatch.call('change');
45283         return this;
45284     };
45285
45286
45287     drawSigns.supported = function() {
45288         var service = getService();
45289         return (service && service.signsSupported());
45290     };
45291
45292
45293     init();
45294     return drawSigns;
45295 }
45296
45297 function svgOpenstreetcamImages(projection, context, dispatch) {
45298     var throttledRedraw = throttle(function () { dispatch.call('change'); }, 1000);
45299     var minZoom = 12;
45300     var minMarkerZoom = 16;
45301     var minViewfieldZoom = 18;
45302     var layer = d3_select(null);
45303     var _openstreetcam;
45304
45305
45306     function init() {
45307         if (svgOpenstreetcamImages.initialized) return;  // run once
45308         svgOpenstreetcamImages.enabled = false;
45309         svgOpenstreetcamImages.initialized = true;
45310     }
45311
45312
45313     function getService() {
45314         if (services.openstreetcam && !_openstreetcam) {
45315             _openstreetcam = services.openstreetcam;
45316             _openstreetcam.event.on('loadedImages', throttledRedraw);
45317         } else if (!services.openstreetcam && _openstreetcam) {
45318             _openstreetcam = null;
45319         }
45320
45321         return _openstreetcam;
45322     }
45323
45324
45325     function showLayer() {
45326         var service = getService();
45327         if (!service) return;
45328
45329         service.loadViewer(context);
45330         editOn();
45331
45332         layer
45333             .style('opacity', 0)
45334             .transition()
45335             .duration(250)
45336             .style('opacity', 1)
45337             .on('end', function () { dispatch.call('change'); });
45338     }
45339
45340
45341     function hideLayer() {
45342         var service = getService();
45343         if (service) {
45344             service.hideViewer();
45345         }
45346
45347         throttledRedraw.cancel();
45348
45349         layer
45350             .transition()
45351             .duration(250)
45352             .style('opacity', 0)
45353             .on('end', editOff);
45354     }
45355
45356
45357     function editOn() {
45358         layer.style('display', 'block');
45359     }
45360
45361
45362     function editOff() {
45363         layer.selectAll('.viewfield-group').remove();
45364         layer.style('display', 'none');
45365     }
45366
45367
45368     function click(d) {
45369         var service = getService();
45370         if (!service) return;
45371
45372         service
45373             .selectImage(d)
45374             .updateViewer(d)
45375             .showViewer();
45376
45377         context.map().centerEase(d.loc);
45378     }
45379
45380
45381     function mouseover(d) {
45382         var service = getService();
45383         if (service) service.setStyles(d);
45384     }
45385
45386
45387     function mouseout() {
45388         var service = getService();
45389         if (service) service.setStyles(null);
45390     }
45391
45392
45393     function transform(d) {
45394         var t = svgPointTransform(projection)(d);
45395         if (d.ca) {
45396             t += ' rotate(' + Math.floor(d.ca) + ',0,0)';
45397         }
45398         return t;
45399     }
45400
45401
45402     function update() {
45403         var viewer = d3_select('#photoviewer');
45404         var selected = viewer.empty() ? undefined : viewer.datum();
45405
45406         var z = ~~context.map().zoom();
45407         var showMarkers = (z >= minMarkerZoom);
45408         var showViewfields = (z >= minViewfieldZoom);
45409
45410         var service = getService();
45411         var sequences = (service ? service.sequences(projection) : []);
45412         var images = (service && showMarkers ? service.images(projection) : []);
45413
45414         var traces = layer.selectAll('.sequences').selectAll('.sequence')
45415             .data(sequences, function(d) { return d.properties.key; });
45416
45417         // exit
45418         traces.exit()
45419             .remove();
45420
45421         // enter/update
45422         traces = traces.enter()
45423             .append('path')
45424             .attr('class', 'sequence')
45425             .merge(traces)
45426             .attr('d', svgPath(projection).geojson);
45427
45428
45429         var groups = layer.selectAll('.markers').selectAll('.viewfield-group')
45430             .data(images, function(d) { return d.key; });
45431
45432         // exit
45433         groups.exit()
45434             .remove();
45435
45436         // enter
45437         var groupsEnter = groups.enter()
45438             .append('g')
45439             .attr('class', 'viewfield-group')
45440             .on('mouseover', mouseover)
45441             .on('mouseout', mouseout)
45442             .on('click', click);
45443
45444         groupsEnter
45445             .append('g')
45446             .attr('class', 'viewfield-scale');
45447
45448         // update
45449         var markers = groups
45450             .merge(groupsEnter)
45451             .sort(function(a, b) {
45452                 return (a === selected) ? 1
45453                     : (b === selected) ? -1
45454                     : b.loc[1] - a.loc[1];  // sort Y
45455             })
45456             .attr('transform', transform)
45457             .select('.viewfield-scale');
45458
45459
45460         markers.selectAll('circle')
45461             .data([0])
45462             .enter()
45463             .append('circle')
45464             .attr('dx', '0')
45465             .attr('dy', '0')
45466             .attr('r', '6');
45467
45468         var viewfields = markers.selectAll('.viewfield')
45469             .data(showViewfields ? [0] : []);
45470
45471         viewfields.exit()
45472             .remove();
45473
45474         viewfields.enter()               // viewfields may or may not be drawn...
45475             .insert('path', 'circle')    // but if they are, draw below the circles
45476             .attr('class', 'viewfield')
45477             .attr('transform', 'scale(1.5,1.5),translate(-8, -13)')
45478             .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');
45479     }
45480
45481
45482     function drawImages(selection) {
45483         var enabled = svgOpenstreetcamImages.enabled,
45484             service = getService();
45485
45486         layer = selection.selectAll('.layer-openstreetcam-images')
45487             .data(service ? [0] : []);
45488
45489         layer.exit()
45490             .remove();
45491
45492         var layerEnter = layer.enter()
45493             .append('g')
45494             .attr('class', 'layer-openstreetcam-images')
45495             .style('display', enabled ? 'block' : 'none');
45496
45497         layerEnter
45498             .append('g')
45499             .attr('class', 'sequences');
45500
45501         layerEnter
45502             .append('g')
45503             .attr('class', 'markers');
45504
45505         layer = layerEnter
45506             .merge(layer);
45507
45508         if (enabled) {
45509             if (service && ~~context.map().zoom() >= minZoom) {
45510                 editOn();
45511                 update();
45512                 service.loadImages(projection);
45513             } else {
45514                 editOff();
45515             }
45516         }
45517     }
45518
45519
45520     drawImages.enabled = function(_) {
45521         if (!arguments.length) return svgOpenstreetcamImages.enabled;
45522         svgOpenstreetcamImages.enabled = _;
45523         if (svgOpenstreetcamImages.enabled) {
45524             showLayer();
45525         } else {
45526             hideLayer();
45527         }
45528         dispatch.call('change');
45529         return this;
45530     };
45531
45532
45533     drawImages.supported = function() {
45534         return !!getService();
45535     };
45536
45537
45538     init();
45539     return drawImages;
45540 }
45541
45542 function svgOsm(projection, context, dispatch) {
45543     var enabled = true;
45544
45545
45546     function drawOsm(selection) {
45547         selection.selectAll('.layer-osm')
45548             .data(['covered', 'areas', 'lines', 'points', 'labels'])
45549             .enter()
45550             .append('g')
45551             .attr('class', function(d) { return 'layer-osm layer-' + d; });
45552
45553         selection.selectAll('.layer-areas').selectAll('.layer-areas-group')
45554             .data(['areas', 'targets'])
45555             .enter()
45556             .append('g')
45557             .attr('class', function(d) { return 'layer-areas-group layer-areas-' + d; });
45558
45559         selection.selectAll('.layer-lines').selectAll('.layer-lines-group')
45560             .data(['lines', 'targets'])
45561             .enter()
45562             .append('g')
45563             .attr('class', function(d) { return 'layer-lines-group layer-lines-' + d; });
45564
45565         selection.selectAll('.layer-points').selectAll('.layer-points-group')
45566             .data(['points', 'midpoints', 'vertices', 'turns', 'targets'])
45567             .enter()
45568             .append('g')
45569             .attr('class', function(d) { return 'layer-points-group layer-points-' + d; });
45570
45571         selection.selectAll('.layer-labels').selectAll('.layer-labels-group')
45572             .data(['halo', 'label', 'debug'])
45573             .enter()
45574             .append('g')
45575             .attr('class', function(d) { return 'layer-labels-group layer-labels-' + d; });
45576     }
45577
45578
45579     function showLayer() {
45580         var layer = context.surface().selectAll('.data-layer-osm');
45581         layer.interrupt();
45582
45583         layer
45584             .classed('disabled', false)
45585             .style('opacity', 0)
45586             .transition()
45587             .duration(250)
45588             .style('opacity', 1)
45589             .on('end interrupt', function () {
45590                 dispatch.call('change');
45591             });
45592     }
45593
45594
45595     function hideLayer() {
45596         var layer = context.surface().selectAll('.data-layer-osm');
45597         layer.interrupt();
45598
45599         layer
45600             .transition()
45601             .duration(250)
45602             .style('opacity', 0)
45603             .on('end interrupt', function () {
45604                 layer.classed('disabled', true);
45605                 dispatch.call('change');
45606             });
45607     }
45608
45609
45610     drawOsm.enabled = function(_) {
45611         if (!arguments.length) return enabled;
45612         enabled = _;
45613
45614         if (enabled) {
45615             showLayer();
45616         } else {
45617             hideLayer();
45618         }
45619
45620         dispatch.call('change');
45621         return this;
45622     };
45623
45624
45625     return drawOsm;
45626 }
45627
45628 function svgLayers(projection, context) {
45629     var dispatch$$1 = dispatch('change'),
45630         svg = d3_select(null),
45631         layers = [
45632             { id: 'osm', layer: svgOsm(projection, context, dispatch$$1) },
45633             { id: 'gpx', layer: svgGpx(projection, context, dispatch$$1) },
45634             { id: 'mapillary-images', layer: svgMapillaryImages(projection, context, dispatch$$1) },
45635             { id: 'mapillary-signs',  layer: svgMapillarySigns(projection, context, dispatch$$1) },
45636             { id: 'openstreetcam-images', layer: svgOpenstreetcamImages(projection, context, dispatch$$1) },
45637             { id: 'debug', layer: svgDebug(projection, context, dispatch$$1) }
45638         ];
45639
45640
45641     function drawLayers(selection) {
45642         svg = selection.selectAll('.surface')
45643             .data([0]);
45644
45645         svg = svg.enter()
45646             .append('svg')
45647             .attr('class', 'surface')
45648             .merge(svg);
45649
45650         var defs = svg.selectAll('.surface-defs')
45651             .data([0]);
45652
45653         defs.enter()
45654             .append('defs')
45655             .attr('class', 'surface-defs');
45656
45657         var groups = svg.selectAll('.data-layer')
45658             .data(layers);
45659
45660         groups.exit()
45661             .remove();
45662
45663         groups.enter()
45664             .append('g')
45665             .attr('class', function(d) { return 'data-layer data-layer-' + d.id; })
45666             .merge(groups)
45667             .each(function(d) { d3_select(this).call(d.layer); });
45668     }
45669
45670
45671     drawLayers.all = function() {
45672         return layers;
45673     };
45674
45675
45676     drawLayers.layer = function(id) {
45677         var obj = find$1(layers, function(o) {return o.id === id;});
45678         return obj && obj.layer;
45679     };
45680
45681
45682     drawLayers.only = function(what) {
45683         var arr = [].concat(what);
45684         drawLayers.remove(difference(map$4(layers, 'id'), arr));
45685         return this;
45686     };
45687
45688
45689     drawLayers.remove = function(what) {
45690         var arr = [].concat(what);
45691         arr.forEach(function(id) {
45692             layers = reject(layers, function(o) {return o.id === id;});
45693         });
45694         dispatch$$1.call('change');
45695         return this;
45696     };
45697
45698
45699     drawLayers.add = function(what) {
45700         var arr = [].concat(what);
45701         arr.forEach(function(obj) {
45702             if ('id' in obj && 'layer' in obj) {
45703                 layers.push(obj);
45704             }
45705         });
45706         dispatch$$1.call('change');
45707         return this;
45708     };
45709
45710
45711     drawLayers.dimensions = function(_) {
45712         if (!arguments.length) return utilGetDimensions(svg);
45713         utilSetDimensions(svg, _);
45714         return this;
45715     };
45716
45717
45718     return utilRebind(drawLayers, dispatch$$1, 'on');
45719 }
45720
45721 function svgLines(projection, context) {
45722     var detected = utilDetect();
45723
45724     var highway_stack = {
45725         motorway: 0,
45726         motorway_link: 1,
45727         trunk: 2,
45728         trunk_link: 3,
45729         primary: 4,
45730         primary_link: 5,
45731         secondary: 6,
45732         tertiary: 7,
45733         unclassified: 8,
45734         residential: 9,
45735         service: 10,
45736         footway: 11
45737     };
45738
45739
45740     function drawTargets(selection, graph, entities, filter$$1) {
45741         var targetClass = context.getDebug('target') ? 'pink ' : 'nocolor ';
45742         var nopeClass = context.getDebug('target') ? 'red ' : 'nocolor ';
45743         var getPath = svgPath(projection).geojson;
45744         var activeID = context.activeID();
45745
45746         // The targets and nopes will be MultiLineString sub-segments of the ways
45747         var data = { targets: [], nopes: [] };
45748
45749         entities.forEach(function(way) {
45750             var features = svgSegmentWay(way, graph, activeID);
45751             data.targets.push.apply(data.targets, features.passive);
45752             data.nopes.push.apply(data.nopes, features.active);
45753         });
45754
45755
45756         // Targets allow hover and vertex snapping
45757         var targets = selection.selectAll('.line.target-allowed')
45758             .filter(function(d) { return filter$$1(d.properties.entity); })
45759             .data(data.targets, function key(d) { return d.id; });
45760
45761         // exit
45762         targets.exit()
45763             .remove();
45764
45765         // enter/update
45766         targets.enter()
45767             .append('path')
45768             .merge(targets)
45769             .attr('d', getPath)
45770             .attr('class', function(d) { return 'way line target target-allowed ' + targetClass + d.id; });
45771
45772
45773         // NOPE
45774         var nopes = selection.selectAll('.line.target-nope')
45775             .filter(function(d) { return filter$$1(d.properties.entity); })
45776             .data(data.nopes, function key(d) { return d.id; });
45777
45778         // exit
45779         nopes.exit()
45780             .remove();
45781
45782         // enter/update
45783         nopes.enter()
45784             .append('path')
45785             .merge(nopes)
45786             .attr('d', getPath)
45787             .attr('class', function(d) { return 'way line target target-nope ' + nopeClass + d.id; });
45788     }
45789
45790
45791     function drawLines(selection, graph, entities, filter$$1) {
45792
45793         function waystack(a, b) {
45794             var selected = context.selectedIDs();
45795             var scoreA = selected.indexOf(a.id) !== -1 ? 20 : 0;
45796             var scoreB = selected.indexOf(b.id) !== -1 ? 20 : 0;
45797
45798             if (a.tags.highway) { scoreA -= highway_stack[a.tags.highway]; }
45799             if (b.tags.highway) { scoreB -= highway_stack[b.tags.highway]; }
45800             return scoreA - scoreB;
45801         }
45802
45803
45804         function drawLineGroup(selection, klass, isSelected) {
45805             // Note: Don't add `.selected` class in draw modes
45806             var mode = context.mode();
45807             var isDrawing = mode && /^draw/.test(mode.id);
45808             var selectedClass = (!isDrawing && isSelected) ? 'selected ' : '';
45809
45810             var lines = selection
45811                 .selectAll('path')
45812                 .filter(filter$$1)
45813                 .data(getPathData(isSelected), osmEntity.key);
45814
45815             lines.exit()
45816                 .remove();
45817
45818             // Optimization: Call expensive TagClasses only on enter selection. This
45819             // works because osmEntity.key is defined to include the entity v attribute.
45820             lines.enter()
45821                 .append('path')
45822                 .attr('class', function(d) {
45823                     var oldMPClass = oldMultiPolygonOuters[d.id] ? 'old-multipolygon ' : '';
45824                     return 'way line ' + klass + ' ' + selectedClass + oldMPClass + d.id;
45825                 })
45826                 .call(svgTagClasses())
45827                 .merge(lines)
45828                 .sort(waystack)
45829                 .attr('d', getPath)
45830                 .call(svgTagClasses().tags(svgRelationMemberTags(graph)));
45831
45832             return selection;
45833         }
45834
45835
45836         function getPathData(isSelected) {
45837             return function() {
45838                 var layer = this.parentNode.__data__;
45839                 var data = pathdata[layer] || [];
45840                 return data.filter(function(d) {
45841                     if (isSelected)
45842                         return context.selectedIDs().indexOf(d.id) !== -1;
45843                     else
45844                         return context.selectedIDs().indexOf(d.id) === -1;
45845                 });
45846             };
45847         }
45848
45849
45850         var getPath = svgPath(projection, graph);
45851         var ways = [];
45852         var pathdata = {};
45853         var onewaydata = {};
45854         var oldMultiPolygonOuters = {};
45855
45856         for (var i = 0; i < entities.length; i++) {
45857             var entity = entities[i];
45858             var outer = osmSimpleMultipolygonOuterMember(entity, graph);
45859             if (outer) {
45860                 ways.push(entity.mergeTags(outer.tags));
45861                 oldMultiPolygonOuters[outer.id] = true;
45862             } else if (entity.geometry(graph) === 'line') {
45863                 ways.push(entity);
45864             }
45865         }
45866
45867         ways = ways.filter(getPath);
45868         pathdata = groupBy(ways, function(way) { return way.layer(); });
45869
45870         forOwn(pathdata, function(v, k) {
45871             var arr = filter(v, function(d) { return d.isOneWay(); });
45872             onewaydata[k] = flatten(map$4(arr, svgOneWaySegments(projection, graph, 35)));
45873         });
45874
45875
45876         var covered = selection.selectAll('.layer-covered');                      // under areas
45877         var uncovered = selection.selectAll('.layer-lines .layer-lines-lines');   // over areas
45878
45879         [covered, uncovered].forEach(function(selection) {
45880             var range$$1 = (selection === covered ? d3_range(-10,0) : d3_range(0,11));
45881             var layergroup = selection
45882                 .selectAll('g.layergroup')
45883                 .data(range$$1);
45884
45885             layergroup = layergroup.enter()
45886                 .append('g')
45887                 .attr('class', function(d) { return 'layergroup layer' + String(d); })
45888                 .merge(layergroup);
45889
45890             layergroup
45891                 .selectAll('g.linegroup')
45892                 .data(['shadow', 'casing', 'stroke', 'shadow-highlighted', 'casing-highlighted', 'stroke-highlighted'])
45893                 .enter()
45894                 .append('g')
45895                 .attr('class', function(d) { return 'linegroup line-' + d; });
45896
45897             layergroup.selectAll('g.line-shadow')
45898                 .call(drawLineGroup, 'shadow', false);
45899             layergroup.selectAll('g.line-casing')
45900                 .call(drawLineGroup, 'casing', false);
45901             layergroup.selectAll('g.line-stroke')
45902                 .call(drawLineGroup, 'stroke', false);
45903
45904             layergroup.selectAll('g.line-shadow-highlighted')
45905                 .call(drawLineGroup, 'shadow', true);
45906             layergroup.selectAll('g.line-casing-highlighted')
45907                 .call(drawLineGroup, 'casing', true);
45908             layergroup.selectAll('g.line-stroke-highlighted')
45909                 .call(drawLineGroup, 'stroke', true);
45910
45911
45912             var onewaygroup = layergroup
45913                 .selectAll('g.onewaygroup')
45914                 .data(['oneway']);
45915
45916             onewaygroup = onewaygroup.enter()
45917                 .append('g')
45918                 .attr('class', 'onewaygroup')
45919                 .merge(onewaygroup);
45920
45921             var oneways = onewaygroup
45922                 .selectAll('path')
45923                 .filter(filter$$1)
45924                 .data(
45925                     function data() { return onewaydata[this.parentNode.__data__] || []; },
45926                     function key(d) { return [d.id, d.index]; }
45927                 );
45928
45929             oneways.exit()
45930                 .remove();
45931
45932             oneways = oneways.enter()
45933                 .append('path')
45934                 .attr('class', 'oneway')
45935                 .attr('marker-mid', 'url(#oneway-marker)')
45936                 .merge(oneways)
45937                 .attr('d', function(d) { return d.d; });
45938
45939             if (detected.ie) {
45940                 oneways.each(function() { this.parentNode.insertBefore(this, this); });
45941             }
45942         });
45943
45944         // touch targets
45945         selection.selectAll('.layer-lines .layer-lines-targets')
45946             .call(drawTargets, graph, ways, filter$$1);
45947     }
45948
45949
45950     return drawLines;
45951 }
45952
45953 function svgMidpoints(projection, context) {
45954     var targetRadius = 8;
45955
45956     function drawTargets(selection, graph, entities, filter) {
45957         var fillClass = context.getDebug('target') ? 'pink ' : 'nocolor ';
45958         var getTransform = svgPointTransform(projection).geojson;
45959
45960         var data = entities.map(function(midpoint) {
45961             return {
45962                 type: 'Feature',
45963                 id: midpoint.id,
45964                 properties: {
45965                     target: true,
45966                     entity: midpoint
45967                 },
45968                 geometry: {
45969                     type: 'Point',
45970                     coordinates: midpoint.loc
45971                 }
45972             };
45973         });
45974
45975         var targets = selection.selectAll('.midpoint.target')
45976             .filter(function(d) { return filter(d.properties.entity); })
45977             .data(data, function key(d) { return d.id; });
45978
45979         // exit
45980         targets.exit()
45981             .remove();
45982
45983         // enter/update
45984         targets.enter()
45985             .append('circle')
45986             .attr('r', targetRadius)
45987             .merge(targets)
45988             .attr('class', function(d) { return 'node midpoint target ' + fillClass + d.id; })
45989             .attr('transform', getTransform);
45990     }
45991
45992
45993     function drawMidpoints(selection, graph, entities, filter, extent) {
45994         var layer = selection.selectAll('.layer-points .layer-points-midpoints');
45995
45996         var mode = context.mode();
45997         if (mode && mode.id !== 'select') {
45998             layer.selectAll('g.midpoint')
45999                 .remove();
46000
46001             selection.selectAll('.layer-points .layer-points-targets .midpoint.target')
46002                 .remove();
46003
46004             return;
46005         }
46006
46007         var poly = extent.polygon();
46008         var midpoints = {};
46009
46010         for (var i = 0; i < entities.length; i++) {
46011             var entity = entities[i];
46012
46013             if (entity.type !== 'way')
46014                 continue;
46015             if (!filter(entity))
46016                 continue;
46017             if (context.selectedIDs().indexOf(entity.id) < 0)
46018                 continue;
46019
46020             var nodes = graph.childNodes(entity);
46021             for (var j = 0; j < nodes.length - 1; j++) {
46022
46023                 var a = nodes[j];
46024                 var b = nodes[j + 1];
46025                 var id = [a.id, b.id].sort().join('-');
46026
46027                 if (midpoints[id]) {
46028                     midpoints[id].parents.push(entity);
46029                 } else {
46030                     if (geoVecLength(projection(a.loc), projection(b.loc)) > 40) {
46031                         var point = geoVecInterp(a.loc, b.loc, 0.5);
46032                         var loc = null;
46033
46034                         if (extent.intersects(point)) {
46035                             loc = point;
46036                         } else {
46037                             for (var k = 0; k < 4; k++) {
46038                                 point = geoLineIntersection([a.loc, b.loc], [poly[k], poly[k + 1]]);
46039                                 if (point &&
46040                                     geoVecLength(projection(a.loc), projection(point)) > 20 &&
46041                                     geoVecLength(projection(b.loc), projection(point)) > 20)
46042                                 {
46043                                     loc = point;
46044                                     break;
46045                                 }
46046                             }
46047                         }
46048
46049                         if (loc) {
46050                             midpoints[id] = {
46051                                 type: 'midpoint',
46052                                 id: id,
46053                                 loc: loc,
46054                                 edge: [a.id, b.id],
46055                                 parents: [entity]
46056                             };
46057                         }
46058                     }
46059                 }
46060             }
46061         }
46062
46063
46064         function midpointFilter(d) {
46065             if (midpoints[d.id])
46066                 return true;
46067
46068             for (var i = 0; i < d.parents.length; i++) {
46069                 if (filter(d.parents[i])) {
46070                     return true;
46071                 }
46072             }
46073
46074             return false;
46075         }
46076
46077
46078         var groups = layer
46079             .selectAll('g.midpoint')
46080             .filter(midpointFilter)
46081             .data(values$1(midpoints), function(d) { return d.id; });
46082
46083         groups.exit()
46084             .remove();
46085
46086         var enter = groups.enter()
46087             .insert('g', ':first-child')
46088             .attr('class', 'midpoint');
46089
46090         enter
46091             .append('polygon')
46092             .attr('points', '-6,8 10,0 -6,-8')
46093             .attr('class', 'shadow');
46094
46095         enter
46096             .append('polygon')
46097             .attr('points', '-3,4 5,0 -3,-4')
46098             .attr('class', 'fill');
46099
46100         groups = groups
46101             .merge(enter)
46102             .attr('transform', function(d) {
46103                 var translate = svgPointTransform(projection);
46104                 var a = graph.entity(d.edge[0]);
46105                 var b = graph.entity(d.edge[1]);
46106                 var angle = geoAngle(a, b, projection) * (180 / Math.PI);
46107                 return translate(d) + ' rotate(' + angle + ')';
46108             })
46109             .call(svgTagClasses().tags(
46110                 function(d) { return d.parents[0].tags; }
46111             ));
46112
46113         // Propagate data bindings.
46114         groups.select('polygon.shadow');
46115         groups.select('polygon.fill');
46116
46117
46118         // Draw touch targets..
46119         selection.selectAll('.layer-points .layer-points-targets')
46120             .call(drawTargets, graph, values$1(midpoints), midpointFilter);
46121     }
46122
46123     return drawMidpoints;
46124 }
46125
46126 // Touch targets control which other vertices we can drag a vertex onto.
46127 //
46128 // - the activeID - nope
46129 // - 1 away (adjacent) to the activeID - yes (vertices will be merged)
46130 // - 2 away from the activeID - nope (would create a self intersecting segment)
46131 // - all others on a linear way - yes
46132 // - all others on a closed way - nope (would create a self intersecting polygon)
46133 //
46134 // returns
46135 // 0 = active vertex - no touch/connect
46136 // 1 = passive vertex - yes touch/connect
46137 // 2 = adjacent vertex - yes but pay attention segmenting a line here
46138 //
46139 function svgPassiveVertex(node, graph, activeID) {
46140     if (!activeID) return 1;
46141     if (activeID === node.id) return 0;
46142
46143     var parents = graph.parentWays(node);
46144
46145     for (var i = 0; i < parents.length; i++) {
46146         var nodes = parents[i].nodes;
46147         var isClosed = parents[i].isClosed();
46148         for (var j = 0; j < nodes.length; j++) {   // find this vertex, look nearby
46149             if (nodes[j] === node.id) {
46150                 var ix1 = j - 2;
46151                 var ix2 = j - 1;
46152                 var ix3 = j + 1;
46153                 var ix4 = j + 2;
46154
46155                 if (isClosed) {  // wraparound if needed
46156                     var max = nodes.length - 1;
46157                     if (ix1 < 0)   ix1 = max + ix1;
46158                     if (ix2 < 0)   ix2 = max + ix2;
46159                     if (ix3 > max) ix3 = ix3 - max;
46160                     if (ix4 > max) ix4 = ix4 - max;
46161                 }
46162
46163                 if (nodes[ix1] === activeID) return 0;        // no - prevent self intersect
46164                 else if (nodes[ix2] === activeID) return 2;   // ok - adjacent
46165                 else if (nodes[ix3] === activeID) return 2;   // ok - adjacent
46166                 else if (nodes[ix4] === activeID) return 0;   // no - prevent self intersect
46167                 else if (isClosed && nodes.indexOf(activeID) !== -1) return 0;  // no - prevent self intersect
46168             }
46169         }
46170     }
46171
46172     return 1;   // ok
46173 }
46174
46175
46176 function svgOneWaySegments(projection, graph, dt) {
46177     return function(entity) {
46178         var i = 0;
46179         var offset = dt;
46180         var segments = [];
46181         var clip = d3_geoIdentity().clipExtent(projection.clipExtent()).stream;
46182         var coordinates = graph.childNodes(entity).map(function(n) { return n.loc; });
46183         var a, b;
46184
46185         if (entity.tags.oneway === '-1') {
46186             coordinates.reverse();
46187         }
46188
46189         var isReversible = (entity.tags.oneway === 'reversible' || entity.tags.oneway === 'alternating');
46190
46191         d3_geoStream({
46192             type: 'LineString',
46193             coordinates: coordinates
46194         }, projection.stream(clip({
46195             lineStart: function() {},
46196             lineEnd: function() { a = null; },
46197             point: function(x, y) {
46198                 b = [x, y];
46199
46200                 if (a) {
46201                     var span = geoVecLength(a, b) - offset;
46202
46203                     if (span >= 0) {
46204                         var heading = geoVecAngle(a, b);
46205                         var dx = dt * Math.cos(heading);
46206                         var dy = dt * Math.sin(heading);
46207                         var p = [
46208                             a[0] + offset * Math.cos(heading),
46209                             a[1] + offset * Math.sin(heading)
46210                         ];
46211
46212                         // gather coordinates
46213                         var coord = [a, p];
46214                         for (span -= dt; span >= 0; span -= dt) {
46215                             p = geoVecAdd(p, [dx, dy]);
46216                             coord.push(p);
46217                         }
46218                         coord.push(b);
46219
46220                         // generate svg paths
46221                         var segment = '';
46222                         var j;
46223
46224                         for (j = 0; j < coord.length; j++) {
46225                             segment += (j === 0 ? 'M' : 'L') + coord[j][0] + ',' + coord[j][1];
46226                         }
46227                         segments.push({ id: entity.id, index: i++, d: segment });
46228
46229                         if (isReversible) {
46230                             segment = '';
46231                             for (j = coord.length - 1; j >= 0; j--) {
46232                                 segment += (j === coord.length - 1 ? 'M' : 'L') + coord[j][0] + ',' + coord[j][1];
46233                             }
46234                             segments.push({ id: entity.id, index: i++, d: segment });
46235                         }
46236                     }
46237
46238                     offset = -span;
46239                 }
46240
46241                 a = b;
46242             }
46243         })));
46244
46245         return segments;
46246     };
46247 }
46248
46249
46250 function svgPath(projection, graph, isArea) {
46251
46252     // Explanation of magic numbers:
46253     // "padding" here allows space for strokes to extend beyond the viewport,
46254     // so that the stroke isn't drawn along the edge of the viewport when
46255     // the shape is clipped.
46256     //
46257     // When drawing lines, pad viewport by 5px.
46258     // When drawing areas, pad viewport by 65px in each direction to allow
46259     // for 60px area fill stroke (see ".fill-partial path.fill" css rule)
46260
46261     var cache = {};
46262     var padding = isArea ? 65 : 5;
46263     var viewport = projection.clipExtent();
46264     var paddedExtent = [
46265         [viewport[0][0] - padding, viewport[0][1] - padding],
46266         [viewport[1][0] + padding, viewport[1][1] + padding]
46267     ];
46268     var clip = d3_geoIdentity().clipExtent(paddedExtent).stream;
46269     var project = projection.stream;
46270     var path = d3_geoPath()
46271         .projection({stream: function(output) { return project(clip(output)); }});
46272
46273     var svgpath = function(entity) {
46274         if (entity.id in cache) {
46275             return cache[entity.id];
46276         } else {
46277             return cache[entity.id] = path(entity.asGeoJSON(graph));
46278         }
46279     };
46280
46281     svgpath.geojson = path;
46282
46283     return svgpath;
46284 }
46285
46286
46287 function svgPointTransform(projection) {
46288     var svgpoint = function(entity) {
46289         // http://jsperf.com/short-array-join
46290         var pt = projection(entity.loc);
46291         return 'translate(' + pt[0] + ',' + pt[1] + ')';
46292     };
46293
46294     svgpoint.geojson = function(d) {
46295         return svgpoint(d.properties.entity);
46296     };
46297
46298     return svgpoint;
46299 }
46300
46301
46302 function svgRelationMemberTags(graph) {
46303     return function(entity) {
46304         var tags = entity.tags;
46305         graph.parentRelations(entity).forEach(function(relation) {
46306             var type = relation.tags.type;
46307             if (type === 'multipolygon' || type === 'boundary') {
46308                 tags = assignIn({}, relation.tags, tags);
46309             }
46310         });
46311         return tags;
46312     };
46313 }
46314
46315
46316 function svgSegmentWay(way, graph, activeID) {
46317     var isActiveWay = (way.nodes.indexOf(activeID) !== -1);
46318     var features = { passive: [], active: [] };
46319     var start = {};
46320     var end = {};
46321     var node, type;
46322
46323     for (var i = 0; i < way.nodes.length; i++) {
46324         node = graph.entity(way.nodes[i]);
46325         type = svgPassiveVertex(node, graph, activeID);
46326         end = { node: node, type: type };
46327
46328         if (start.type !== undefined) {
46329             if (start.node.id === activeID || end.node.id === activeID) {
46330                 // push nothing
46331             } else if (isActiveWay && (start.type === 2 || end.type === 2)) {   // one adjacent vertex
46332                 pushActive(start, end, i);
46333             } else if (start.type === 0 && end.type === 0) {   // both active vertices
46334                 pushActive(start, end, i);
46335             } else {
46336                 pushPassive(start, end, i);
46337             }
46338         }
46339
46340         start = end;
46341     }
46342
46343     return features;
46344
46345
46346     function pushActive(start, end, index) {
46347         features.active.push({
46348             type: 'Feature',
46349             id: way.id + '-' + index + '-nope',
46350             properties: {
46351                 nope: true,
46352                 target: true,
46353                 entity: way,
46354                 nodes: [start.node, end.node],
46355                 index: index
46356             },
46357             geometry: {
46358                 type: 'LineString',
46359                 coordinates: [start.node.loc, end.node.loc]
46360             }
46361         });
46362     }
46363
46364     function pushPassive(start, end, index) {
46365         features.passive.push({
46366             type: 'Feature',
46367             id: way.id + '-' + index,
46368             properties: {
46369                 target: true,
46370                 entity: way,
46371                 nodes: [start.node, end.node],
46372                 index: index
46373             },
46374             geometry: {
46375                 type: 'LineString',
46376                 coordinates: [start.node.loc, end.node.loc]
46377             }
46378         });
46379     }
46380 }
46381
46382 function svgPoints(projection, context) {
46383
46384     function markerPath(selection, klass) {
46385         selection
46386             .attr('class', klass)
46387             .attr('transform', 'translate(-8, -23)')
46388             .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');
46389     }
46390
46391     function sortY(a, b) {
46392         return b.loc[1] - a.loc[1];
46393     }
46394
46395
46396     // Avoid exit/enter if we're just moving stuff around.
46397     // The node will get a new version but we only need to run the update selection.
46398     function fastEntityKey(d) {
46399         var mode = context.mode();
46400         var isMoving = mode && /^(add|draw|drag|move|rotate)/.test(mode.id);
46401         return isMoving ? d.id : osmEntity.key(d);
46402     }
46403
46404
46405     function drawTargets(selection, graph, entities, filter) {
46406         var fillClass = context.getDebug('target') ? 'pink ' : 'nocolor ';
46407         var getTransform = svgPointTransform(projection).geojson;
46408         var activeID = context.activeID();
46409         var data$$1 = [];
46410
46411         entities.forEach(function(node) {
46412             if (activeID === node.id) return;   // draw no target on the activeID
46413
46414             data$$1.push({
46415                 type: 'Feature',
46416                 id: node.id,
46417                 properties: {
46418                     target: true,
46419                     entity: node
46420                 },
46421                 geometry: node.asGeoJSON()
46422             });
46423         });
46424
46425         var targets = selection.selectAll('.point.target')
46426             .filter(function(d) { return filter(d.properties.entity); })
46427             .data(data$$1, function key(d) { return d.id; });
46428
46429         // exit
46430         targets.exit()
46431             .remove();
46432
46433         // enter/update
46434         targets.enter()
46435             .append('rect')
46436             .attr('x', -10)
46437             .attr('y', -26)
46438             .attr('width', 20)
46439             .attr('height', 30)
46440             .merge(targets)
46441             .attr('class', function(d) { return 'node point target ' + fillClass + d.id; })
46442             .attr('transform', getTransform);
46443     }
46444
46445
46446     function drawPoints(selection, graph, entities, filter) {
46447         var wireframe = context.surface().classed('fill-wireframe');
46448         var zoom = geoScaleToZoom(projection.scale());
46449
46450         // points with a direction will render as vertices at higher zooms
46451         function renderAsPoint(entity) {
46452             return entity.geometry(graph) === 'point' &&
46453                 !(zoom >= 18 && entity.directions(graph, projection).length);
46454         }
46455
46456         // all points will render as vertices in wireframe mode too
46457         var points = wireframe ? [] : entities.filter(renderAsPoint);
46458
46459         points.sort(sortY);
46460
46461
46462         var layer = selection.selectAll('.layer-points .layer-points-points');
46463
46464         var groups = layer.selectAll('g.point')
46465             .filter(filter)
46466             .data(points, fastEntityKey);
46467
46468         groups.exit()
46469             .remove();
46470
46471         var enter = groups.enter()
46472             .append('g')
46473             .attr('class', function(d) { return 'node point ' + d.id; })
46474             .order();
46475
46476         enter
46477             .append('path')
46478             .call(markerPath, 'shadow');
46479
46480         enter
46481             .append('ellipse')
46482             .attr('cx', 0.5)
46483             .attr('cy', 1)
46484             .attr('rx', 6.5)
46485             .attr('ry', 3)
46486             .attr('class', 'stroke');
46487
46488         enter
46489             .append('path')
46490             .call(markerPath, 'stroke');
46491
46492         enter
46493             .append('use')
46494             .attr('transform', 'translate(-5, -19)')
46495             .attr('class', 'icon')
46496             .attr('width', '11px')
46497             .attr('height', '11px');
46498
46499         groups = groups
46500             .merge(enter)
46501             .attr('transform', svgPointTransform(projection))
46502             .call(svgTagClasses());
46503
46504         // Selecting the following implicitly
46505         // sets the data (point entity) on the element
46506         groups.select('.shadow');
46507         groups.select('.stroke');
46508         groups.select('.icon')
46509             .attr('xlink:href', function(entity) {
46510                 var preset = context.presets().match(entity, graph);
46511                 var picon = preset && preset.icon;
46512
46513                 if (!picon)
46514                     return '';
46515                 else {
46516                     var isMaki = dataFeatureIcons.indexOf(picon) !== -1;
46517                     return '#' + picon + (isMaki ? '-11' : '');
46518                 }
46519             });
46520
46521
46522         // touch targets
46523         selection.selectAll('.layer-points .layer-points-targets')
46524             .call(drawTargets, graph, points, filter);
46525     }
46526
46527
46528     return drawPoints;
46529 }
46530
46531 function svgTagClasses() {
46532     var primaries = [
46533             'building', 'highway', 'railway', 'waterway', 'aeroway',
46534             'motorway', 'boundary', 'power', 'amenity', 'natural', 'landuse',
46535             'leisure', 'military', 'place'
46536         ],
46537         statuses = [
46538             'proposed', 'construction', 'disused', 'abandoned', 'dismantled',
46539             'razed', 'demolished', 'obliterated', 'intermittent'
46540         ],
46541         secondaries = [
46542             'oneway', 'bridge', 'tunnel', 'embankment', 'cutting', 'barrier',
46543             'surface', 'tracktype', 'crossing', 'service', 'sport'
46544         ],
46545         tagClassRe = /^tag-/,
46546         tags = function(entity) { return entity.tags; };
46547
46548
46549     var tagClasses = function(selection) {
46550         selection.each(function tagClassesEach(entity) {
46551             var value = this.className,
46552                 classes, primary, status;
46553
46554             if (value.baseVal !== undefined) value = value.baseVal;
46555
46556             classes = value.trim().split(/\s+/).filter(function(name) {
46557                 return name.length && !tagClassRe.test(name);
46558             }).join(' ');
46559
46560             var t = tags(entity), i, k, v;
46561
46562             // pick at most one primary classification tag..
46563             for (i = 0; i < primaries.length; i++) {
46564                 k = primaries[i];
46565                 v = t[k];
46566                 if (!v || v === 'no') continue;
46567
46568                 primary = k;
46569                 if (statuses.indexOf(v) !== -1) {   // e.g. `railway=abandoned`
46570                     status = v;
46571                     classes += ' tag-' + k;
46572                 } else {
46573                     classes += ' tag-' + k + ' tag-' + k + '-' + v;
46574                 }
46575
46576                 break;
46577             }
46578
46579             // add at most one status tag, only if relates to primary tag..
46580             if (!status) {
46581                 for (i = 0; i < statuses.length; i++) {
46582                     k = statuses[i];
46583                     v = t[k];
46584                     if (!v || v === 'no') continue;
46585
46586                     if (v === 'yes') {   // e.g. `railway=rail + abandoned=yes`
46587                         status = k;
46588                     }
46589                     else if (primary && primary === v) {  // e.g. `railway=rail + abandoned=railway`
46590                         status = k;
46591                     } else if (!primary && primaries.indexOf(v) !== -1) {  // e.g. `abandoned=railway`
46592                         status = k;
46593                         primary = v;
46594                         classes += ' tag-' + v;
46595                     }  // else ignore e.g.  `highway=path + abandoned=railway`
46596
46597                     if (status) break;
46598                 }
46599             }
46600
46601             if (status) {
46602                 classes += ' tag-status tag-status-' + status;
46603             }
46604
46605             // add any secondary (structure) tags
46606             for (i = 0; i < secondaries.length; i++) {
46607                 k = secondaries[i];
46608                 v = t[k];
46609                 if (!v || v === 'no') continue;
46610                 classes += ' tag-' + k + ' tag-' + k + '-' + v;
46611             }
46612
46613             // For highways, look for surface tagging..
46614             if (primary === 'highway') {
46615                 var paved = (t.highway !== 'track');
46616                 for (k in t) {
46617                     v = t[k];
46618                     if (k in osmPavedTags) {
46619                         paved = !!osmPavedTags[k][v];
46620                         break;
46621                     }
46622                 }
46623                 if (!paved) {
46624                     classes += ' tag-unpaved';
46625                 }
46626             }
46627
46628             classes = classes.trim();
46629
46630             if (classes !== value) {
46631                 d3_select(this).attr('class', classes);
46632             }
46633         });
46634     };
46635
46636
46637     tagClasses.tags = function(_) {
46638         if (!arguments.length) return tags;
46639         tags = _;
46640         return tagClasses;
46641     };
46642
46643     return tagClasses;
46644 }
46645
46646 function svgTurns(projection) {
46647
46648     return function drawTurns(selection, graph, turns) {
46649
46650         function key(turn) {
46651             return [turn.from.node + turn.via.node + turn.to.node].join('-');
46652         }
46653
46654         function icon(turn) {
46655             var u = turn.u ? '-u' : '';
46656             if (!turn.restriction)
46657                 return '#turn-yes' + u;
46658             var restriction = graph.entity(turn.restriction).tags.restriction;
46659             return '#turn-' +
46660                 (!turn.indirect_restriction && /^only_/.test(restriction) ? 'only' : 'no') + u;
46661         }
46662
46663         var layer = selection.selectAll('.layer-points .layer-points-turns');
46664         var groups = layer.selectAll('g.turn')
46665             .data(turns, key);
46666
46667         groups.exit()
46668             .remove();
46669
46670
46671         var enter = groups.enter()
46672             .append('g')
46673             .attr('class', 'turn');
46674
46675         var nEnter = enter
46676             .filter(function (turn) { return !turn.u; });
46677
46678         nEnter.append('rect')
46679             .attr('transform', 'translate(-22, -12)')
46680             .attr('width', '44')
46681             .attr('height', '24');
46682
46683         nEnter.append('use')
46684             .attr('transform', 'translate(-22, -12)')
46685             .attr('width', '44')
46686             .attr('height', '24');
46687
46688
46689         var uEnter = enter
46690             .filter(function (turn) { return turn.u; });
46691
46692         uEnter.append('circle')
46693             .attr('r', '16');
46694
46695         uEnter.append('use')
46696             .attr('transform', 'translate(-16, -16)')
46697             .attr('width', '32')
46698             .attr('height', '32');
46699
46700
46701         groups = groups
46702             .merge(enter);
46703
46704         groups
46705             .attr('transform', function (turn) {
46706                 var v = graph.entity(turn.via.node),
46707                     t = graph.entity(turn.to.node),
46708                     a = geoAngle(v, t, projection),
46709                     p = projection(v.loc),
46710                     r = turn.u ? 0 : 60;
46711
46712                 return 'translate(' + (r * Math.cos(a) + p[0]) + ',' + (r * Math.sin(a) + p[1]) + ') ' +
46713                     'rotate(' + a * 180 / Math.PI + ')';
46714             });
46715
46716         groups.select('use')
46717             .attr('xlink:href', icon);
46718
46719         groups.select('rect');
46720         groups.select('circle');
46721
46722         return this;
46723     };
46724 }
46725
46726 function svgVertices(projection, context) {
46727     var radiuses = {
46728         //       z16-, z17,   z18+,  w/icon
46729         shadow: [6,    7.5,   7.5,   12],
46730         stroke: [2.5,  3.5,   3.5,   8],
46731         fill:   [1,    1.5,   1.5,   1.5]
46732     };
46733
46734     var _currHoverTarget;
46735     var _currPersistent = {};
46736     var _currHover = {};
46737     var _prevHover = {};
46738     var _currSelected = {};
46739     var _prevSelected = {};
46740     var _radii = {};
46741
46742
46743     function sortY(a, b) {
46744         return b.loc[1] - a.loc[1];
46745     }
46746
46747     // Avoid exit/enter if we're just moving stuff around.
46748     // The node will get a new version but we only need to run the update selection.
46749     function fastEntityKey(d) {
46750         var mode = context.mode();
46751         var isMoving = mode && /^(add|draw|drag|move|rotate)/.test(mode.id);
46752         return isMoving ? d.id : osmEntity.key(d);
46753     }
46754
46755
46756     function draw(selection, graph, vertices, sets, filter) {
46757         sets = sets || { selected: {}, important: {}, hovered: {} };
46758
46759         var icons = {};
46760         var directions = {};
46761         var wireframe = context.surface().classed('fill-wireframe');
46762         var zoom = geoScaleToZoom(projection.scale());
46763         var z = (zoom < 17 ? 0 : zoom < 18 ? 1 : 2);
46764
46765
46766         function getIcon(entity) {
46767             if (entity.id in icons) return icons[entity.id];
46768
46769             icons[entity.id] =
46770                 entity.hasInterestingTags() &&
46771                 context.presets().match(entity, graph).icon;
46772             return icons[entity.id];
46773         }
46774
46775
46776         // memoize directions results, return false for empty arrays (for use in filter)
46777         function getDirections(entity) {
46778             if (entity.id in directions) return directions[entity.id];
46779
46780             var angles = entity.directions(graph, projection);
46781             directions[entity.id] = angles.length ? angles : false;
46782             return angles;
46783         }
46784
46785
46786         function updateAttributes(selection) {
46787             ['shadow', 'stroke', 'fill'].forEach(function(klass) {
46788                 var rads = radiuses[klass];
46789                 selection.selectAll('.' + klass)
46790                     .each(function(entity) {
46791                         var i = z && getIcon(entity);
46792                         var r = rads[i ? 3 : z];
46793
46794                         // slightly increase the size of unconnected endpoints #3775
46795                         if (entity.isEndpoint(graph) && !entity.isConnected(graph)) {
46796                             r += 1.5;
46797                         }
46798
46799                         if (klass === 'shadow') {   // remember this value, so we don't need to
46800                             _radii[entity.id] = r;  // recompute it when we draw the touch targets
46801                         }
46802
46803                         d3_select(this)
46804                             .attr('r', r)
46805                             .attr('visibility', (i && klass === 'fill') ? 'hidden' : null);
46806                     });
46807             });
46808
46809             selection.selectAll('use')
46810                 .attr('visibility', (z === 0 ? 'hidden' : null));
46811         }
46812
46813         vertices.sort(sortY);
46814
46815         var groups = selection.selectAll('g.vertex')
46816             .filter(filter)
46817             .data(vertices, fastEntityKey);
46818
46819         // exit
46820         groups.exit()
46821             .remove();
46822
46823         // enter
46824         var enter = groups.enter()
46825             .append('g')
46826             .attr('class', function(d) { return 'node vertex ' + d.id; })
46827             .order();
46828
46829         enter
46830             .append('circle')
46831             .attr('class', 'shadow');
46832
46833         enter
46834             .append('circle')
46835             .attr('class', 'stroke');
46836
46837         // Vertices with icons get a `use`.
46838         enter.filter(function(d) { return getIcon(d); })
46839             .append('use')
46840             .attr('class', 'icon')
46841             .attr('width', '11px')
46842             .attr('height', '11px')
46843             .attr('transform', 'translate(-5.5, -5.5)')
46844             .attr('xlink:href', function(d) {
46845                 var picon = getIcon(d);
46846                 var isMaki = dataFeatureIcons.indexOf(picon) !== -1;
46847                 return '#' + picon + (isMaki ? '-11' : '');
46848             });
46849
46850         // Vertices with tags get a fill.
46851         enter.filter(function(d) { return d.hasInterestingTags(); })
46852             .append('circle')
46853             .attr('class', 'fill');
46854
46855         // update
46856         groups = groups
46857             .merge(enter)
46858             .attr('transform', svgPointTransform(projection))
46859             .classed('sibling', function(d) { return d.id in sets.selected; })
46860             .classed('shared', function(d) { return graph.isShared(d); })
46861             .classed('endpoint', function(d) { return d.isEndpoint(graph); })
46862             .call(updateAttributes);
46863
46864
46865         // Directional vertices get viewfields
46866         var dgroups = groups.filter(function(d) { return getDirections(d); })
46867             .selectAll('.viewfieldgroup')
46868             .data(function data$$1(d) { return zoom >= 18 ? [d] : []; }, osmEntity.key);
46869
46870         // exit
46871         dgroups.exit()
46872             .remove();
46873
46874         // enter/update
46875         dgroups = dgroups.enter()
46876             .insert('g', '.shadow')
46877             .attr('class', 'viewfieldgroup')
46878             .merge(dgroups);
46879
46880         var viewfields = dgroups.selectAll('.viewfield')
46881             .data(getDirections, function key(d) { return d; });
46882
46883         // exit
46884         viewfields.exit()
46885             .remove();
46886
46887         // enter/update
46888         viewfields.enter()
46889             .append('path')
46890             .attr('class', 'viewfield')
46891             .attr('d', 'M0,0H0')
46892             .merge(viewfields)
46893             .attr('marker-start', 'url(#viewfield-marker' + (wireframe ? '-wireframe' : '') + ')')
46894             .attr('transform', function(d) { return 'rotate(' + d + ')'; });
46895     }
46896
46897
46898     function drawTargets(selection, graph, entities, filter) {
46899         var targetClass = context.getDebug('target') ? 'pink ' : 'nocolor ';
46900         var nopeClass = context.getDebug('target') ? 'red ' : 'nocolor ';
46901         var getTransform = svgPointTransform(projection).geojson;
46902         var activeID = context.activeID();
46903         var data$$1 = { targets: [], nopes: [] };
46904
46905         entities.forEach(function(node) {
46906             if (activeID === node.id) return;   // draw no target on the activeID
46907
46908             var vertexType = svgPassiveVertex(node, graph, activeID);
46909             if (vertexType !== 0) {     // passive or adjacent - allow to connect
46910                 data$$1.targets.push({
46911                     type: 'Feature',
46912                     id: node.id,
46913                     properties: {
46914                         target: true,
46915                         entity: node
46916                     },
46917                     geometry: node.asGeoJSON()
46918                 });
46919             } else {
46920                 data$$1.nopes.push({
46921                     type: 'Feature',
46922                     id: node.id + '-nope',
46923                     properties: {
46924                         nope: true,
46925                         target: true,
46926                         entity: node
46927                     },
46928                     geometry: node.asGeoJSON()
46929                 });
46930             }
46931         });
46932
46933
46934         // Targets allow hover and vertex snapping
46935         var targets = selection.selectAll('.vertex.target-allowed')
46936             .filter(function(d) { return filter(d.properties.entity); })
46937             .data(data$$1.targets, function key(d) { return d.id; });
46938
46939         // exit
46940         targets.exit()
46941             .remove();
46942
46943         // enter/update
46944         targets.enter()
46945             .append('circle')
46946             .attr('r', function(d) { return (_radii[d.id] || radiuses.shadow[3]); })
46947             .merge(targets)
46948             .attr('class', function(d) { return 'node vertex target target-allowed ' + targetClass + d.id; })
46949             .attr('transform', getTransform);
46950
46951
46952         // NOPE
46953         var nopes = selection.selectAll('.vertex.target-nope')
46954             .filter(function(d) { return filter(d.properties.entity); })
46955             .data(data$$1.nopes, function key(d) { return d.id; });
46956
46957         // exit
46958         nopes.exit()
46959             .remove();
46960
46961         // enter/update
46962         nopes.enter()
46963             .append('circle')
46964             .attr('r', function(d) { return (_radii[d.properties.entity.id] || radiuses.shadow[3]); })
46965             .merge(nopes)
46966             .attr('class', function(d) { return 'node vertex target target-nope ' + nopeClass + d.id; })
46967             .attr('transform', getTransform);
46968     }
46969
46970
46971     // Points can also render as vertices:
46972     // 1. in wireframe mode or
46973     // 2. at higher zooms if they have a direction
46974     function renderAsVertex(entity, graph, wireframe, zoom) {
46975         var geometry = entity.geometry(graph);
46976         return geometry === 'vertex' || (geometry === 'point' && (
46977             wireframe || (zoom >= 18 && entity.directions(graph, projection).length)
46978         ));
46979     }
46980
46981
46982     function getSiblingAndChildVertices(ids, graph, wireframe, zoom) {
46983         var results = {};
46984
46985         function addChildVertices(entity) {
46986             var geometry = entity.geometry(graph);
46987             if (!context.features().isHiddenFeature(entity, graph, geometry)) {
46988                 var i;
46989                 if (entity.type === 'way') {
46990                     for (i = 0; i < entity.nodes.length; i++) {
46991                         var child = graph.hasEntity(entity.nodes[i]);
46992                         if (child) {
46993                             addChildVertices(child);
46994                         }
46995                     }
46996                 } else if (entity.type === 'relation') {
46997                     for (i = 0; i < entity.members.length; i++) {
46998                         var member = graph.hasEntity(entity.members[i].id);
46999                         if (member) {
47000                             addChildVertices(member);
47001                         }
47002                     }
47003                 } else if (renderAsVertex(entity, graph, wireframe, zoom)) {
47004                     results[entity.id] = entity;
47005                 }
47006             }
47007         }
47008
47009         ids.forEach(function(id) {
47010             var entity = graph.hasEntity(id);
47011             if (!entity) return;
47012
47013             if (entity.type === 'node') {
47014                 if (renderAsVertex(entity, graph, wireframe, zoom)) {
47015                     results[entity.id] = entity;
47016                     graph.parentWays(entity).forEach(function(entity) {
47017                         addChildVertices(entity);
47018                     });
47019                 }
47020             } else {  // way, relation
47021                 addChildVertices(entity);
47022             }
47023         });
47024
47025         return results;
47026     }
47027
47028
47029     function drawVertices(selection, graph, entities, filter, extent, fullRedraw) {
47030         var wireframe = context.surface().classed('fill-wireframe');
47031         var zoom = geoScaleToZoom(projection.scale());
47032         var mode = context.mode();
47033         var isMoving = mode && /^(add|draw|drag|move|rotate)/.test(mode.id);
47034
47035         if (fullRedraw) {
47036             _currPersistent = {};
47037             _radii = {};
47038         }
47039
47040         // Collect important vertices from the `entities` list..
47041         // (during a paritial redraw, it will not contain everything)
47042         for (var i = 0; i < entities.length; i++) {
47043             var entity = entities[i];
47044             var geometry = entity.geometry(graph);
47045             var keep = false;
47046
47047             // a point that looks like a vertex..
47048             if ((geometry === 'point') && renderAsVertex(entity, graph, wireframe, zoom)) {
47049                 _currPersistent[entity.id] = entity;
47050                 keep = true;
47051
47052             // a vertex of some importance..
47053             } else if (geometry === 'vertex' &&
47054                 (entity.hasInterestingTags() || entity.isEndpoint(graph) || entity.isConnected(graph))) {
47055                 _currPersistent[entity.id] = entity;
47056                 keep = true;
47057             }
47058
47059             // whatever this is, it's not a persistent vertex..
47060             if (!keep && !fullRedraw) {
47061                 delete _currPersistent[entity.id];
47062             }
47063         }
47064
47065         // 3 sets of vertices to consider:
47066         var sets = {
47067             persistent: _currPersistent,  // persistent = important vertices (render always)
47068             selected: _currSelected,      // selected + siblings of selected (render always)
47069             hovered: _currHover           // hovered + siblings of hovered (render only in draw modes)
47070         };
47071
47072         var all = assign({}, (isMoving ? _currHover : {}), _currSelected, _currPersistent);
47073
47074         // Draw the vertices..
47075         // The filter function controls the scope of what objects d3 will touch (exit/enter/update)
47076         // Adjust the filter function to expand the scope beyond whatever entities were passed in.
47077         var filterRendered = function(d) {
47078             return d.id in _currPersistent || d.id in _currSelected || d.id in _currHover || filter(d);
47079         };
47080         selection.selectAll('.layer-points .layer-points-vertices')
47081             .call(draw, graph, currentVisible(all), sets, filterRendered);
47082
47083         // Draw touch targets..
47084         // When drawing, render all targets (not just those affected by a partial redraw)
47085         var filterTouch = function(d) {
47086             return isMoving ? true : filterRendered(d);
47087         };
47088         selection.selectAll('.layer-points .layer-points-targets')
47089             .call(drawTargets, graph, currentVisible(all), filterTouch);
47090
47091
47092         function currentVisible(which) {
47093             return Object.keys(which)
47094                 .map(graph.hasEntity, graph)     // the current version of this entity
47095                 .filter(function (entity) { return entity && entity.intersects(extent, graph); });
47096         }
47097     }
47098
47099
47100     // partial redraw - only update the selected items..
47101     drawVertices.drawSelected = function(selection, graph, extent) {
47102         var wireframe = context.surface().classed('fill-wireframe');
47103         var zoom = geoScaleToZoom(projection.scale());
47104
47105         _prevSelected = _currSelected || {};
47106         _currSelected = getSiblingAndChildVertices(context.selectedIDs(), graph, wireframe, zoom);
47107
47108         // note that drawVertices will add `_currSelected` automatically if needed..
47109         var filter = function(d) { return d.id in _prevSelected; };
47110         drawVertices(selection, graph, values$1(_prevSelected), filter, extent, false);
47111     };
47112
47113
47114     // partial redraw - only update the hovered items..
47115     drawVertices.drawHover = function(selection, graph, target, extent) {
47116         if (target === _currHoverTarget) return;  // continue only if something changed
47117
47118         var wireframe = context.surface().classed('fill-wireframe');
47119         var zoom = geoScaleToZoom(projection.scale());
47120
47121         _prevHover = _currHover || {};
47122         _currHoverTarget = target;
47123         var entity = target && target.properties && target.properties.entity;
47124
47125         if (entity) {
47126             _currHover = getSiblingAndChildVertices([entity.id], graph, wireframe, zoom);
47127         } else {
47128             _currHover = {};
47129         }
47130
47131         // note that drawVertices will add `_currHover` automatically if needed..
47132         var filter = function(d) { return d.id in _prevHover; };
47133         drawVertices(selection, graph, values$1(_prevHover), filter, extent, false);
47134     };
47135
47136     return drawVertices;
47137 }
47138
47139 function uiAccount(context) {
47140     var osm = context.connection();
47141
47142
47143     function update(selection) {
47144         if (!osm) return;
47145
47146         if (!osm.authenticated()) {
47147             selection.selectAll('#userLink, #logoutLink')
47148                 .classed('hide', true);
47149             return;
47150         }
47151
47152         osm.userDetails(function(err, details) {
47153             var userLink = selection.select('#userLink'),
47154                 logoutLink = selection.select('#logoutLink');
47155
47156             userLink.html('');
47157             logoutLink.html('');
47158
47159             if (err) return;
47160
47161             selection.selectAll('#userLink, #logoutLink')
47162                 .classed('hide', false);
47163
47164             // Link
47165             userLink.append('a')
47166                 .attr('href', osm.userURL(details.display_name))
47167                 .attr('target', '_blank');
47168
47169             // Add thumbnail or dont
47170             if (details.image_url) {
47171                 userLink.append('img')
47172                     .attr('class', 'icon pre-text user-icon')
47173                     .attr('src', details.image_url);
47174             } else {
47175                 userLink
47176                     .call(svgIcon('#icon-avatar', 'pre-text light'));
47177             }
47178
47179             // Add user name
47180             userLink.append('span')
47181                 .attr('class', 'label')
47182                 .text(details.display_name);
47183
47184             logoutLink.append('a')
47185                 .attr('class', 'logout')
47186                 .attr('href', '#')
47187                 .text(t('logout'))
47188                 .on('click.logout', function() {
47189                     event.preventDefault();
47190                     osm.logout();
47191                 });
47192         });
47193     }
47194
47195
47196     return function(selection) {
47197         selection.append('li')
47198             .attr('id', 'logoutLink')
47199             .classed('hide', true);
47200
47201         selection.append('li')
47202             .attr('id', 'userLink')
47203             .classed('hide', true);
47204
47205         if (osm) {
47206             osm.on('change.account', function() { update(selection); });
47207             update(selection);
47208         }
47209     };
47210 }
47211
47212 function uiAttribution(context) {
47213     var selection;
47214
47215
47216     function attribution(data, klass) {
47217         var div = selection.selectAll('.' + klass)
47218             .data([0]);
47219
47220         div = div.enter()
47221             .append('div')
47222             .attr('class', klass)
47223             .merge(div);
47224
47225
47226         var background = div.selectAll('.attribution')
47227             .data(data, function(d) { return d.name(); });
47228
47229         background.exit()
47230             .remove();
47231
47232         background = background.enter()
47233             .append('span')
47234             .attr('class', 'attribution')
47235             .each(function(d) {
47236                 if (d.terms_html) {
47237                     d3_select(this)
47238                         .html(d.terms_html);
47239                     return;
47240                 }
47241
47242                 var selection;
47243                 if (d.terms_url) {
47244                     selection = d3_select(this)
47245                         .append('a')
47246                         .attr('href', d.terms_url)
47247                         .attr('target', '_blank');
47248                 } else {
47249                     selection = d3_select(this);
47250                 }
47251
47252
47253                 var id_safe = d.id.replace('.', '<TX_DOT>');
47254                 var terms_text = t('imagery.' + id_safe + '.attribution.text',
47255                     { default: d.terms_text || d.id || d.name() }
47256                 );
47257
47258                 if (d.icon && !d.overlay) {
47259                     selection
47260                         .append('img')
47261                         .attr('class', 'source-image')
47262                         .attr('src', d.icon);
47263                 }
47264
47265                 selection
47266                     .append('span')
47267                     .attr('class', 'attribution-text')
47268                     .text(terms_text);
47269             })
47270             .merge(background);
47271
47272
47273         var copyright = background.selectAll('.copyright-notice')
47274             .data(function(d) {
47275                 var notice = d.copyrightNotices(context.map().zoom(), context.map().extent());
47276                 return notice ? [notice] : [];
47277             });
47278
47279         copyright.exit()
47280             .remove();
47281
47282         copyright = copyright.enter()
47283             .append('span')
47284             .attr('class', 'copyright-notice')
47285             .merge(copyright);
47286
47287         copyright
47288             .text(String);
47289     }
47290
47291
47292     function update() {
47293         attribution([context.background().baseLayerSource()], 'base-layer-attribution');
47294         attribution(context.background().overlayLayerSources().filter(function (s) {
47295             return s.validZoom(context.map().zoom());
47296         }), 'overlay-layer-attribution');
47297     }
47298
47299
47300     return function(select$$1) {
47301         selection = select$$1;
47302
47303         context.background()
47304             .on('change.attribution', update);
47305
47306         context.map()
47307             .on('move.attribution', throttle(update, 400, {leading: false}));
47308
47309         update();
47310     };
47311 }
47312
47313 // toggles the visibility of ui elements, using a combination of the
47314 // hide class, which sets display=none, and a d3 transition for opacity.
47315 // this will cause blinking when called repeatedly, so check that the
47316 // value actually changes between calls.
47317 function uiToggle(show, callback) {
47318     return function(selection) {
47319         selection
47320             .style('opacity', show ? 0 : 1)
47321             .classed('hide', false)
47322             .transition()
47323             .style('opacity', show ? 1 : 0)
47324             .on('end', function() {
47325                 d3_select(this)
47326                     .classed('hide', !show)
47327                     .style('opacity', null);
47328                 if (callback) callback.apply(this);
47329             });
47330     };
47331 }
47332
47333 function uiDisclosure(context, key, expandedDefault) {
47334     var dispatch$$1 = dispatch('toggled'),
47335         _preference = (context.storage('disclosure.' + key + '.expanded')),
47336         _expanded = (_preference === null ? !!expandedDefault : (_preference === 'true')),
47337         _title,
47338         _updatePreference = true,
47339         _content = function () {};
47340
47341
47342     var disclosure = function(selection) {
47343         var hideToggle = selection.selectAll('.hide-toggle-' + key)
47344             .data([0]);
47345
47346         // enter
47347         var hideToggleEnter = hideToggle.enter()
47348             .append('a')
47349             .attr('href', '#')
47350             .attr('class', 'hide-toggle hide-toggle-' + key)
47351             .call(svgIcon('', 'pre-text', 'hide-toggle-icon'));
47352
47353         hideToggleEnter
47354             .append('span')
47355             .attr('class', 'hide-toggle-text');
47356
47357         // update
47358         hideToggle = hideToggleEnter
47359             .merge(hideToggle);
47360
47361         hideToggle
47362             .on('click', toggle)
47363             .classed('expanded', _expanded);
47364
47365         hideToggle.selectAll('.hide-toggle-text')
47366             .text(_title);
47367
47368         hideToggle.selectAll('.hide-toggle-icon')
47369             .attr('xlink:href', _expanded ? '#icon-down'
47370                 : (textDirection === 'rtl') ? '#icon-backward' : '#icon-forward'
47371             );
47372
47373
47374         var wrap = selection.selectAll('.disclosure-wrap')
47375             .data([0]);
47376
47377         wrap = wrap.enter()
47378             .append('div')
47379             .attr('class', 'disclosure-wrap disclosure-wrap-' + key)
47380             .merge(wrap);
47381
47382         wrap
47383             .classed('hide', !_expanded)
47384             .call(_content);
47385
47386
47387         function toggle() {
47388             event.preventDefault();
47389
47390             _expanded = !_expanded;
47391
47392             if (_updatePreference) {
47393                 context.storage('disclosure.' + key + '.expanded', _expanded);
47394             }
47395
47396             hideToggle
47397                 .classed('expanded', _expanded);
47398
47399             hideToggle.selectAll('.hide-toggle-icon')
47400                 .attr('xlink:href', _expanded ? '#icon-down'
47401                     : (textDirection === 'rtl') ? '#icon-backward' : '#icon-forward'
47402                 );
47403
47404             wrap
47405                 .call(uiToggle(_expanded));
47406
47407             dispatch$$1.call('toggled', this, _expanded);
47408         }
47409     };
47410
47411
47412     disclosure.title = function(_) {
47413         if (!arguments.length) return _title;
47414         _title = _;
47415         return disclosure;
47416     };
47417
47418
47419     disclosure.expanded = function(_) {
47420         if (!arguments.length) return _expanded;
47421         _expanded = _;
47422         return disclosure;
47423     };
47424
47425
47426     disclosure.updatePreference = function(_) {
47427         if (!arguments.length) return _updatePreference;
47428         _updatePreference = _;
47429         return disclosure;
47430     };
47431
47432
47433     disclosure.content = function(_) {
47434         if (!arguments.length) return _content;
47435         _content = _;
47436         return disclosure;
47437     };
47438
47439
47440     return utilRebind(disclosure, dispatch$$1, 'on');
47441 }
47442
47443 function uiBackgroundDisplayOptions(context) {
47444     var detected = utilDetect();
47445     var storedOpacity = context.storage('background-opacity');
47446     var minVal = 0.25;
47447     var maxVal = detected.cssfilters ? 2 : 1;
47448
47449     var sliders = detected.cssfilters
47450         ? ['brightness', 'contrast', 'saturation', 'sharpness']
47451         : ['brightness'];
47452
47453     var _options = {
47454         brightness: (storedOpacity !== null ? (+storedOpacity) : 1),
47455         contrast: 1,
47456         saturation: 1,
47457         sharpness: 1
47458     };
47459
47460     var _selection = d3_select(null);
47461
47462
47463     function clamp(x, min, max) {
47464         return Math.max(min, Math.min(x, max));
47465     }
47466
47467
47468     function updateValue(d, val) {
47469         if (!val && event && event.target) {
47470             val = event.target.value;
47471         }
47472
47473         val = clamp(val, minVal, maxVal);
47474
47475         _options[d] = val;
47476         context.background()[d](val);
47477
47478         if (d === 'brightness') {
47479             context.storage('background-opacity', val);
47480         }
47481
47482         _selection
47483             .call(render);
47484     }
47485
47486
47487     function render(selection) {
47488         var container = selection.selectAll('.display-options-container')
47489             .data([0]);
47490
47491         var containerEnter = container.enter()
47492             .append('div')
47493             .attr('class', 'display-options-container controls-list');
47494
47495         // add slider controls
47496         var slidersEnter = containerEnter.selectAll('.display-control')
47497             .data(sliders)
47498             .enter()
47499             .append('div')
47500             .attr('class', function(d) { return 'display-control display-control-' + d; });
47501
47502         slidersEnter
47503             .append('h5')
47504             .text(function(d) { return t('background.' + d); })
47505             .append('span')
47506             .attr('class', function(d) { return 'display-option-value display-option-value-' + d; });
47507
47508         slidersEnter
47509             .append('input')
47510             .attr('class', function(d) { return 'display-option-input display-option-input-' + d; })
47511             .attr('type', 'range')
47512             .attr('min', minVal)
47513             .attr('max', maxVal)
47514             .attr('step', '0.05')
47515             .on('input', function(d) {
47516                 var val = d3_select(this).property('value');
47517                 updateValue(d, val);
47518             });
47519
47520         slidersEnter
47521             .append('button')
47522             .attr('title', t('background.reset'))
47523             .attr('class', function(d) { return 'display-option-reset display-option-reset-' + d; })
47524             .on('click', function(d) {
47525                 if (event.button !== 0) return;
47526                 updateValue(d, 1);
47527             })
47528             .call(svgIcon('#icon-' + (textDirection === 'rtl' ? 'redo' : 'undo')));
47529
47530
47531         // update
47532         container = containerEnter
47533             .merge(container);
47534
47535         container.selectAll('.display-option-input')
47536             .property('value', function(d) { return _options[d]; });
47537
47538         container.selectAll('.display-option-value')
47539             .text(function(d) { return Math.floor(_options[d] * 100) + '%'; });
47540
47541         container.selectAll('.display-option-reset')
47542             .classed('disabled', function(d) { return _options[d] === 1; });
47543
47544         // first time only, set brightness if needed
47545         if (containerEnter.size() && _options.brightness !== 1) {
47546             context.background().brightness(_options.brightness);
47547         }
47548     }
47549
47550
47551     function backgroundDisplayOptions(selection) {
47552         _selection = selection;
47553
47554         selection
47555             .call(uiDisclosure(context, 'background_display_options', true)
47556                 .title(t('background.display_options'))
47557                 .content(render)
47558             );
47559     }
47560
47561
47562     return backgroundDisplayOptions;
47563 }
47564
47565 function uiBackgroundOffset(context) {
47566     var directions = [
47567         ['right', [0.5, 0]],
47568         ['top', [0, -0.5]],
47569         ['left', [-0.5, 0]],
47570         ['bottom', [0, 0.5]]
47571     ];
47572
47573
47574     function d3_eventCancel() {
47575         event.stopPropagation();
47576         event.preventDefault();
47577     }
47578
47579
47580     function updateValue() {
47581         var meters = geoOffsetToMeters(context.background().offset());
47582         var x = +meters[0].toFixed(2);
47583         var y = +meters[1].toFixed(2);
47584
47585         d3_selectAll('.nudge-inner-rect')
47586             .select('input')
47587             .classed('error', false)
47588             .property('value', x + ', ' + y);
47589
47590         d3_selectAll('.nudge-reset')
47591             .classed('disabled', function() {
47592                 return (x === 0 && y === 0);
47593             });
47594     }
47595
47596
47597     function resetOffset() {
47598         context.background().offset([0, 0]);
47599         updateValue();
47600     }
47601
47602
47603     function nudge(d) {
47604         context.background().nudge(d, context.map().zoom());
47605         updateValue();
47606     }
47607
47608
47609     function clickNudgeButton(d) {
47610         var interval;
47611         var timeout = window.setTimeout(function() {
47612                 interval = window.setInterval(nudge.bind(null, d), 100);
47613             }, 500);
47614
47615         function doneNudge() {
47616             window.clearTimeout(timeout);
47617             window.clearInterval(interval);
47618             d3_select(window)
47619                 .on('mouseup.buttonoffset', null, true)
47620                 .on('mousedown.buttonoffset', null, true);
47621         }
47622
47623         d3_select(window)
47624             .on('mouseup.buttonoffset', doneNudge, true)
47625             .on('mousedown.buttonoffset', doneNudge, true);
47626
47627         nudge(d);
47628     }
47629
47630
47631     function inputOffset() {
47632         var input = d3_select(this);
47633         var d = input.node().value;
47634
47635         if (d === '') return resetOffset();
47636
47637         d = d.replace(/;/g, ',').split(',').map(function(n) {
47638             // if n is NaN, it will always get mapped to false.
47639             return !isNaN(n) && n;
47640         });
47641
47642         if (d.length !== 2 || !d[0] || !d[1]) {
47643             input.classed('error', true);
47644             return;
47645         }
47646
47647         context.background().offset(geoMetersToOffset(d));
47648         updateValue();
47649     }
47650
47651
47652     function dragOffset() {
47653         event.preventDefault();
47654         if (event.button !== 0) return;
47655
47656         var origin = [event.clientX, event.clientY];
47657
47658         context.container()
47659             .append('div')
47660             .attr('class', 'nudge-surface');
47661
47662         d3_select(window)
47663             .on('mousemove.offset', function() {
47664                 var latest = [event.clientX, event.clientY];
47665                 var d = [
47666                     -(origin[0] - latest[0]) / 4,
47667                     -(origin[1] - latest[1]) / 4
47668                 ];
47669
47670                 origin = latest;
47671                 nudge(d);
47672             })
47673             .on('mouseup.offset', function() {
47674                 if (event.button !== 0) return;
47675                 d3_selectAll('.nudge-surface')
47676                     .remove();
47677
47678                 d3_select(window)
47679                     .on('mousemove.offset', null)
47680                     .on('mouseup.offset', null);
47681             });
47682     }
47683
47684
47685     function render(selection) {
47686         var container = selection.selectAll('.nudge-container')
47687             .data([0]);
47688
47689         var containerEnter = container.enter()
47690             .append('div')
47691             .attr('class', 'nudge-container cf');
47692
47693         containerEnter
47694             .append('div')
47695             .attr('class', 'nudge-instructions')
47696             .text(t('background.offset'));
47697
47698         var nudgeEnter = containerEnter
47699             .append('div')
47700             .attr('class', 'nudge-outer-rect')
47701             .on('mousedown', dragOffset);
47702
47703         nudgeEnter
47704             .append('div')
47705             .attr('class', 'nudge-inner-rect')
47706             .append('input')
47707             .on('change', inputOffset);
47708
47709         containerEnter
47710             .append('div')
47711             .selectAll('button')
47712             .data(directions).enter()
47713             .append('button')
47714             .attr('class', function(d) { return d[0] + ' nudge'; })
47715             .on('contextmenu', d3_eventCancel)
47716             .on('mousedown', function(d) {
47717                 if (event.button !== 0) return;
47718                 clickNudgeButton(d[1]);
47719             });
47720
47721         containerEnter
47722             .append('button')
47723             .attr('title', t('background.reset'))
47724             .attr('class', 'nudge-reset disabled')
47725             .on('contextmenu', d3_eventCancel)
47726             .on('click', function() {
47727                 if (event.button !== 0) return;
47728                 resetOffset();
47729             })
47730             .call(svgIcon('#icon-' + (textDirection === 'rtl' ? 'redo' : 'undo')));
47731
47732         updateValue();
47733     }
47734
47735
47736     function backgroundOffset(selection) {
47737         selection
47738             .call(uiDisclosure(context, 'background_offset', false)
47739                 .title(t('background.fix_misalignment'))
47740                 .content(render)
47741             );
47742     }
47743
47744
47745     context.background()
47746         .on('change.backgroundOffset-update', updateValue);
47747
47748     return backgroundOffset;
47749 }
47750
47751 var marked = createCommonjsModule(function (module, exports) {
47752 /**
47753  * marked - a markdown parser
47754  * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
47755  * https://github.com/chjj/marked
47756  */
47757
47758 (function() {
47759 var block = {
47760   newline: /^\n+/,
47761   code: /^( {4}[^\n]+\n*)+/,
47762   fences: noop,
47763   hr: /^( *[-*_]){3,} *(?:\n+|$)/,
47764   heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
47765   nptable: noop,
47766   lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
47767   blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
47768   list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
47769   html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
47770   def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
47771   table: noop,
47772   paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
47773   text: /^[^\n]+/
47774 };
47775
47776 block.bullet = /(?:[*+-]|\d+\.)/;
47777 block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
47778 block.item = replace(block.item, 'gm')
47779   (/bull/g, block.bullet)
47780   ();
47781
47782 block.list = replace(block.list)
47783   (/bull/g, block.bullet)
47784   ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
47785   ('def', '\\n+(?=' + block.def.source + ')')
47786   ();
47787
47788 block.blockquote = replace(block.blockquote)
47789   ('def', block.def)
47790   ();
47791
47792 block._tag = '(?!(?:'
47793   + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
47794   + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
47795   + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b';
47796
47797 block.html = replace(block.html)
47798   ('comment', /<!--[\s\S]*?-->/)
47799   ('closed', /<(tag)[\s\S]+?<\/\1>/)
47800   ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
47801   (/tag/g, block._tag)
47802   ();
47803
47804 block.paragraph = replace(block.paragraph)
47805   ('hr', block.hr)
47806   ('heading', block.heading)
47807   ('lheading', block.lheading)
47808   ('blockquote', block.blockquote)
47809   ('tag', '<' + block._tag)
47810   ('def', block.def)
47811   ();
47812
47813 /**
47814  * Normal Block Grammar
47815  */
47816
47817 block.normal = merge({}, block);
47818
47819 /**
47820  * GFM Block Grammar
47821  */
47822
47823 block.gfm = merge({}, block.normal, {
47824   fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,
47825   paragraph: /^/,
47826   heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/
47827 });
47828
47829 block.gfm.paragraph = replace(block.paragraph)
47830   ('(?!', '(?!'
47831     + block.gfm.fences.source.replace('\\1', '\\2') + '|'
47832     + block.list.source.replace('\\1', '\\3') + '|')
47833   ();
47834
47835 /**
47836  * GFM + Tables Block Grammar
47837  */
47838
47839 block.tables = merge({}, block.gfm, {
47840   nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
47841   table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
47842 });
47843
47844 /**
47845  * Block Lexer
47846  */
47847
47848 function Lexer(options) {
47849   this.tokens = [];
47850   this.tokens.links = {};
47851   this.options = options || marked.defaults;
47852   this.rules = block.normal;
47853
47854   if (this.options.gfm) {
47855     if (this.options.tables) {
47856       this.rules = block.tables;
47857     } else {
47858       this.rules = block.gfm;
47859     }
47860   }
47861 }
47862
47863 /**
47864  * Expose Block Rules
47865  */
47866
47867 Lexer.rules = block;
47868
47869 /**
47870  * Static Lex Method
47871  */
47872
47873 Lexer.lex = function(src, options) {
47874   var lexer = new Lexer(options);
47875   return lexer.lex(src);
47876 };
47877
47878 /**
47879  * Preprocessing
47880  */
47881
47882 Lexer.prototype.lex = function(src) {
47883   src = src
47884     .replace(/\r\n|\r/g, '\n')
47885     .replace(/\t/g, '    ')
47886     .replace(/\u00a0/g, ' ')
47887     .replace(/\u2424/g, '\n');
47888
47889   return this.token(src, true);
47890 };
47891
47892 /**
47893  * Lexing
47894  */
47895
47896 Lexer.prototype.token = function(src, top, bq) {
47897   var src = src.replace(/^ +$/gm, '')
47898     , next
47899     , loose
47900     , cap
47901     , bull
47902     , b
47903     , item
47904     , space
47905     , i
47906     , l;
47907
47908   while (src) {
47909     // newline
47910     if (cap = this.rules.newline.exec(src)) {
47911       src = src.substring(cap[0].length);
47912       if (cap[0].length > 1) {
47913         this.tokens.push({
47914           type: 'space'
47915         });
47916       }
47917     }
47918
47919     // code
47920     if (cap = this.rules.code.exec(src)) {
47921       src = src.substring(cap[0].length);
47922       cap = cap[0].replace(/^ {4}/gm, '');
47923       this.tokens.push({
47924         type: 'code',
47925         text: !this.options.pedantic
47926           ? cap.replace(/\n+$/, '')
47927           : cap
47928       });
47929       continue;
47930     }
47931
47932     // fences (gfm)
47933     if (cap = this.rules.fences.exec(src)) {
47934       src = src.substring(cap[0].length);
47935       this.tokens.push({
47936         type: 'code',
47937         lang: cap[2],
47938         text: cap[3] || ''
47939       });
47940       continue;
47941     }
47942
47943     // heading
47944     if (cap = this.rules.heading.exec(src)) {
47945       src = src.substring(cap[0].length);
47946       this.tokens.push({
47947         type: 'heading',
47948         depth: cap[1].length,
47949         text: cap[2]
47950       });
47951       continue;
47952     }
47953
47954     // table no leading pipe (gfm)
47955     if (top && (cap = this.rules.nptable.exec(src))) {
47956       src = src.substring(cap[0].length);
47957
47958       item = {
47959         type: 'table',
47960         header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
47961         align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
47962         cells: cap[3].replace(/\n$/, '').split('\n')
47963       };
47964
47965       for (i = 0; i < item.align.length; i++) {
47966         if (/^ *-+: *$/.test(item.align[i])) {
47967           item.align[i] = 'right';
47968         } else if (/^ *:-+: *$/.test(item.align[i])) {
47969           item.align[i] = 'center';
47970         } else if (/^ *:-+ *$/.test(item.align[i])) {
47971           item.align[i] = 'left';
47972         } else {
47973           item.align[i] = null;
47974         }
47975       }
47976
47977       for (i = 0; i < item.cells.length; i++) {
47978         item.cells[i] = item.cells[i].split(/ *\| */);
47979       }
47980
47981       this.tokens.push(item);
47982
47983       continue;
47984     }
47985
47986     // lheading
47987     if (cap = this.rules.lheading.exec(src)) {
47988       src = src.substring(cap[0].length);
47989       this.tokens.push({
47990         type: 'heading',
47991         depth: cap[2] === '=' ? 1 : 2,
47992         text: cap[1]
47993       });
47994       continue;
47995     }
47996
47997     // hr
47998     if (cap = this.rules.hr.exec(src)) {
47999       src = src.substring(cap[0].length);
48000       this.tokens.push({
48001         type: 'hr'
48002       });
48003       continue;
48004     }
48005
48006     // blockquote
48007     if (cap = this.rules.blockquote.exec(src)) {
48008       src = src.substring(cap[0].length);
48009
48010       this.tokens.push({
48011         type: 'blockquote_start'
48012       });
48013
48014       cap = cap[0].replace(/^ *> ?/gm, '');
48015
48016       // Pass `top` to keep the current
48017       // "toplevel" state. This is exactly
48018       // how markdown.pl works.
48019       this.token(cap, top, true);
48020
48021       this.tokens.push({
48022         type: 'blockquote_end'
48023       });
48024
48025       continue;
48026     }
48027
48028     // list
48029     if (cap = this.rules.list.exec(src)) {
48030       src = src.substring(cap[0].length);
48031       bull = cap[2];
48032
48033       this.tokens.push({
48034         type: 'list_start',
48035         ordered: bull.length > 1
48036       });
48037
48038       // Get each top-level item.
48039       cap = cap[0].match(this.rules.item);
48040
48041       next = false;
48042       l = cap.length;
48043       i = 0;
48044
48045       for (; i < l; i++) {
48046         item = cap[i];
48047
48048         // Remove the list item's bullet
48049         // so it is seen as the next token.
48050         space = item.length;
48051         item = item.replace(/^ *([*+-]|\d+\.) +/, '');
48052
48053         // Outdent whatever the
48054         // list item contains. Hacky.
48055         if (~item.indexOf('\n ')) {
48056           space -= item.length;
48057           item = !this.options.pedantic
48058             ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
48059             : item.replace(/^ {1,4}/gm, '');
48060         }
48061
48062         // Determine whether the next list item belongs here.
48063         // Backpedal if it does not belong in this list.
48064         if (this.options.smartLists && i !== l - 1) {
48065           b = block.bullet.exec(cap[i + 1])[0];
48066           if (bull !== b && !(bull.length > 1 && b.length > 1)) {
48067             src = cap.slice(i + 1).join('\n') + src;
48068             i = l - 1;
48069           }
48070         }
48071
48072         // Determine whether item is loose or not.
48073         // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
48074         // for discount behavior.
48075         loose = next || /\n\n(?!\s*$)/.test(item);
48076         if (i !== l - 1) {
48077           next = item.charAt(item.length - 1) === '\n';
48078           if (!loose) loose = next;
48079         }
48080
48081         this.tokens.push({
48082           type: loose
48083             ? 'loose_item_start'
48084             : 'list_item_start'
48085         });
48086
48087         // Recurse.
48088         this.token(item, false, bq);
48089
48090         this.tokens.push({
48091           type: 'list_item_end'
48092         });
48093       }
48094
48095       this.tokens.push({
48096         type: 'list_end'
48097       });
48098
48099       continue;
48100     }
48101
48102     // html
48103     if (cap = this.rules.html.exec(src)) {
48104       src = src.substring(cap[0].length);
48105       this.tokens.push({
48106         type: this.options.sanitize
48107           ? 'paragraph'
48108           : 'html',
48109         pre: !this.options.sanitizer
48110           && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
48111         text: cap[0]
48112       });
48113       continue;
48114     }
48115
48116     // def
48117     if ((!bq && top) && (cap = this.rules.def.exec(src))) {
48118       src = src.substring(cap[0].length);
48119       this.tokens.links[cap[1].toLowerCase()] = {
48120         href: cap[2],
48121         title: cap[3]
48122       };
48123       continue;
48124     }
48125
48126     // table (gfm)
48127     if (top && (cap = this.rules.table.exec(src))) {
48128       src = src.substring(cap[0].length);
48129
48130       item = {
48131         type: 'table',
48132         header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
48133         align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
48134         cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
48135       };
48136
48137       for (i = 0; i < item.align.length; i++) {
48138         if (/^ *-+: *$/.test(item.align[i])) {
48139           item.align[i] = 'right';
48140         } else if (/^ *:-+: *$/.test(item.align[i])) {
48141           item.align[i] = 'center';
48142         } else if (/^ *:-+ *$/.test(item.align[i])) {
48143           item.align[i] = 'left';
48144         } else {
48145           item.align[i] = null;
48146         }
48147       }
48148
48149       for (i = 0; i < item.cells.length; i++) {
48150         item.cells[i] = item.cells[i]
48151           .replace(/^ *\| *| *\| *$/g, '')
48152           .split(/ *\| */);
48153       }
48154
48155       this.tokens.push(item);
48156
48157       continue;
48158     }
48159
48160     // top-level paragraph
48161     if (top && (cap = this.rules.paragraph.exec(src))) {
48162       src = src.substring(cap[0].length);
48163       this.tokens.push({
48164         type: 'paragraph',
48165         text: cap[1].charAt(cap[1].length - 1) === '\n'
48166           ? cap[1].slice(0, -1)
48167           : cap[1]
48168       });
48169       continue;
48170     }
48171
48172     // text
48173     if (cap = this.rules.text.exec(src)) {
48174       // Top-level should never reach here.
48175       src = src.substring(cap[0].length);
48176       this.tokens.push({
48177         type: 'text',
48178         text: cap[0]
48179       });
48180       continue;
48181     }
48182
48183     if (src) {
48184       throw new
48185         Error('Infinite loop on byte: ' + src.charCodeAt(0));
48186     }
48187   }
48188
48189   return this.tokens;
48190 };
48191
48192 /**
48193  * Inline-Level Grammar
48194  */
48195
48196 var inline = {
48197   escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
48198   autolink: /^<([^ <>]+(@|:\/)[^ <>]+)>/,
48199   url: noop,
48200   tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^<'">])*?>/,
48201   link: /^!?\[(inside)\]\(href\)/,
48202   reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
48203   nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
48204   strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
48205   em: /^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
48206   code: /^(`+)([\s\S]*?[^`])\1(?!`)/,
48207   br: /^ {2,}\n(?!\s*$)/,
48208   del: noop,
48209   text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
48210 };
48211
48212 inline._inside = /(?:\[[^\]]*\]|\\[\[\]]|[^\[\]]|\](?=[^\[]*\]))*/;
48213 inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
48214
48215 inline.link = replace(inline.link)
48216   ('inside', inline._inside)
48217   ('href', inline._href)
48218   ();
48219
48220 inline.reflink = replace(inline.reflink)
48221   ('inside', inline._inside)
48222   ();
48223
48224 /**
48225  * Normal Inline Grammar
48226  */
48227
48228 inline.normal = merge({}, inline);
48229
48230 /**
48231  * Pedantic Inline Grammar
48232  */
48233
48234 inline.pedantic = merge({}, inline.normal, {
48235   strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
48236   em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
48237 });
48238
48239 /**
48240  * GFM Inline Grammar
48241  */
48242
48243 inline.gfm = merge({}, inline.normal, {
48244   escape: replace(inline.escape)('])', '~|])')(),
48245   url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
48246   del: /^~~(?=\S)([\s\S]*?\S)~~/,
48247   text: replace(inline.text)
48248     (']|', '~]|')
48249     ('|', '|https?://|')
48250     ()
48251 });
48252
48253 /**
48254  * GFM + Line Breaks Inline Grammar
48255  */
48256
48257 inline.breaks = merge({}, inline.gfm, {
48258   br: replace(inline.br)('{2,}', '*')(),
48259   text: replace(inline.gfm.text)('{2,}', '*')()
48260 });
48261
48262 /**
48263  * Inline Lexer & Compiler
48264  */
48265
48266 function InlineLexer(links, options) {
48267   this.options = options || marked.defaults;
48268   this.links = links;
48269   this.rules = inline.normal;
48270   this.renderer = this.options.renderer || new Renderer;
48271   this.renderer.options = this.options;
48272
48273   if (!this.links) {
48274     throw new
48275       Error('Tokens array requires a `links` property.');
48276   }
48277
48278   if (this.options.gfm) {
48279     if (this.options.breaks) {
48280       this.rules = inline.breaks;
48281     } else {
48282       this.rules = inline.gfm;
48283     }
48284   } else if (this.options.pedantic) {
48285     this.rules = inline.pedantic;
48286   }
48287 }
48288
48289 /**
48290  * Expose Inline Rules
48291  */
48292
48293 InlineLexer.rules = inline;
48294
48295 /**
48296  * Static Lexing/Compiling Method
48297  */
48298
48299 InlineLexer.output = function(src, links, options) {
48300   var inline = new InlineLexer(links, options);
48301   return inline.output(src);
48302 };
48303
48304 /**
48305  * Lexing/Compiling
48306  */
48307
48308 InlineLexer.prototype.output = function(src) {
48309   var out = ''
48310     , link
48311     , text
48312     , href
48313     , cap;
48314
48315   while (src) {
48316     // escape
48317     if (cap = this.rules.escape.exec(src)) {
48318       src = src.substring(cap[0].length);
48319       out += cap[1];
48320       continue;
48321     }
48322
48323     // autolink
48324     if (cap = this.rules.autolink.exec(src)) {
48325       src = src.substring(cap[0].length);
48326       if (cap[2] === '@') {
48327         text = escape(
48328           cap[1].charAt(6) === ':'
48329           ? this.mangle(cap[1].substring(7))
48330           : this.mangle(cap[1])
48331         );
48332         href = this.mangle('mailto:') + text;
48333       } else {
48334         text = escape(cap[1]);
48335         href = text;
48336       }
48337       out += this.renderer.link(href, null, text);
48338       continue;
48339     }
48340
48341     // url (gfm)
48342     if (!this.inLink && (cap = this.rules.url.exec(src))) {
48343       src = src.substring(cap[0].length);
48344       text = escape(cap[1]);
48345       href = text;
48346       out += this.renderer.link(href, null, text);
48347       continue;
48348     }
48349
48350     // tag
48351     if (cap = this.rules.tag.exec(src)) {
48352       if (!this.inLink && /^<a /i.test(cap[0])) {
48353         this.inLink = true;
48354       } else if (this.inLink && /^<\/a>/i.test(cap[0])) {
48355         this.inLink = false;
48356       }
48357       src = src.substring(cap[0].length);
48358       out += this.options.sanitize
48359         ? this.options.sanitizer
48360           ? this.options.sanitizer(cap[0])
48361           : escape(cap[0])
48362         : cap[0];
48363       continue;
48364     }
48365
48366     // link
48367     if (cap = this.rules.link.exec(src)) {
48368       src = src.substring(cap[0].length);
48369       this.inLink = true;
48370       out += this.outputLink(cap, {
48371         href: cap[2],
48372         title: cap[3]
48373       });
48374       this.inLink = false;
48375       continue;
48376     }
48377
48378     // reflink, nolink
48379     if ((cap = this.rules.reflink.exec(src))
48380         || (cap = this.rules.nolink.exec(src))) {
48381       src = src.substring(cap[0].length);
48382       link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
48383       link = this.links[link.toLowerCase()];
48384       if (!link || !link.href) {
48385         out += cap[0].charAt(0);
48386         src = cap[0].substring(1) + src;
48387         continue;
48388       }
48389       this.inLink = true;
48390       out += this.outputLink(cap, link);
48391       this.inLink = false;
48392       continue;
48393     }
48394
48395     // strong
48396     if (cap = this.rules.strong.exec(src)) {
48397       src = src.substring(cap[0].length);
48398       out += this.renderer.strong(this.output(cap[2] || cap[1]));
48399       continue;
48400     }
48401
48402     // em
48403     if (cap = this.rules.em.exec(src)) {
48404       src = src.substring(cap[0].length);
48405       out += this.renderer.em(this.output(cap[2] || cap[1]));
48406       continue;
48407     }
48408
48409     // code
48410     if (cap = this.rules.code.exec(src)) {
48411       src = src.substring(cap[0].length);
48412       out += this.renderer.codespan(escape(cap[2].trim(), true));
48413       continue;
48414     }
48415
48416     // br
48417     if (cap = this.rules.br.exec(src)) {
48418       src = src.substring(cap[0].length);
48419       out += this.renderer.br();
48420       continue;
48421     }
48422
48423     // del (gfm)
48424     if (cap = this.rules.del.exec(src)) {
48425       src = src.substring(cap[0].length);
48426       out += this.renderer.del(this.output(cap[1]));
48427       continue;
48428     }
48429
48430     // text
48431     if (cap = this.rules.text.exec(src)) {
48432       src = src.substring(cap[0].length);
48433       out += this.renderer.text(escape(this.smartypants(cap[0])));
48434       continue;
48435     }
48436
48437     if (src) {
48438       throw new
48439         Error('Infinite loop on byte: ' + src.charCodeAt(0));
48440     }
48441   }
48442
48443   return out;
48444 };
48445
48446 /**
48447  * Compile Link
48448  */
48449
48450 InlineLexer.prototype.outputLink = function(cap, link) {
48451   var href = escape(link.href)
48452     , title = link.title ? escape(link.title) : null;
48453
48454   return cap[0].charAt(0) !== '!'
48455     ? this.renderer.link(href, title, this.output(cap[1]))
48456     : this.renderer.image(href, title, escape(cap[1]));
48457 };
48458
48459 /**
48460  * Smartypants Transformations
48461  */
48462
48463 InlineLexer.prototype.smartypants = function(text) {
48464   if (!this.options.smartypants) return text;
48465   return text
48466     // em-dashes
48467     .replace(/---/g, '\u2014')
48468     // en-dashes
48469     .replace(/--/g, '\u2013')
48470     // opening singles
48471     .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
48472     // closing singles & apostrophes
48473     .replace(/'/g, '\u2019')
48474     // opening doubles
48475     .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
48476     // closing doubles
48477     .replace(/"/g, '\u201d')
48478     // ellipses
48479     .replace(/\.{3}/g, '\u2026');
48480 };
48481
48482 /**
48483  * Mangle Links
48484  */
48485
48486 InlineLexer.prototype.mangle = function(text) {
48487   if (!this.options.mangle) return text;
48488   var out = ''
48489     , l = text.length
48490     , i = 0
48491     , ch;
48492
48493   for (; i < l; i++) {
48494     ch = text.charCodeAt(i);
48495     if (Math.random() > 0.5) {
48496       ch = 'x' + ch.toString(16);
48497     }
48498     out += '&#' + ch + ';';
48499   }
48500
48501   return out;
48502 };
48503
48504 /**
48505  * Renderer
48506  */
48507
48508 function Renderer(options) {
48509   this.options = options || {};
48510 }
48511
48512 Renderer.prototype.code = function(code, lang, escaped) {
48513   if (this.options.highlight) {
48514     var out = this.options.highlight(code, lang);
48515     if (out != null && out !== code) {
48516       escaped = true;
48517       code = out;
48518     }
48519   }
48520
48521   if (!lang) {
48522     return '<pre><code>'
48523       + (escaped ? code : escape(code, true))
48524       + '\n</code></pre>';
48525   }
48526
48527   return '<pre><code class="'
48528     + this.options.langPrefix
48529     + escape(lang, true)
48530     + '">'
48531     + (escaped ? code : escape(code, true))
48532     + '\n</code></pre>\n';
48533 };
48534
48535 Renderer.prototype.blockquote = function(quote) {
48536   return '<blockquote>\n' + quote + '</blockquote>\n';
48537 };
48538
48539 Renderer.prototype.html = function(html) {
48540   return html;
48541 };
48542
48543 Renderer.prototype.heading = function(text, level, raw) {
48544   return '<h'
48545     + level
48546     + ' id="'
48547     + this.options.headerPrefix
48548     + raw.toLowerCase().replace(/[^\w]+/g, '-')
48549     + '">'
48550     + text
48551     + '</h'
48552     + level
48553     + '>\n';
48554 };
48555
48556 Renderer.prototype.hr = function() {
48557   return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
48558 };
48559
48560 Renderer.prototype.list = function(body, ordered) {
48561   var type = ordered ? 'ol' : 'ul';
48562   return '<' + type + '>\n' + body + '</' + type + '>\n';
48563 };
48564
48565 Renderer.prototype.listitem = function(text) {
48566   return '<li>' + text + '</li>\n';
48567 };
48568
48569 Renderer.prototype.paragraph = function(text) {
48570   return '<p>' + text + '</p>\n';
48571 };
48572
48573 Renderer.prototype.table = function(header, body) {
48574   return '<table>\n'
48575     + '<thead>\n'
48576     + header
48577     + '</thead>\n'
48578     + '<tbody>\n'
48579     + body
48580     + '</tbody>\n'
48581     + '</table>\n';
48582 };
48583
48584 Renderer.prototype.tablerow = function(content) {
48585   return '<tr>\n' + content + '</tr>\n';
48586 };
48587
48588 Renderer.prototype.tablecell = function(content, flags) {
48589   var type = flags.header ? 'th' : 'td';
48590   var tag = flags.align
48591     ? '<' + type + ' style="text-align:' + flags.align + '">'
48592     : '<' + type + '>';
48593   return tag + content + '</' + type + '>\n';
48594 };
48595
48596 // span level renderer
48597 Renderer.prototype.strong = function(text) {
48598   return '<strong>' + text + '</strong>';
48599 };
48600
48601 Renderer.prototype.em = function(text) {
48602   return '<em>' + text + '</em>';
48603 };
48604
48605 Renderer.prototype.codespan = function(text) {
48606   return '<code>' + text + '</code>';
48607 };
48608
48609 Renderer.prototype.br = function() {
48610   return this.options.xhtml ? '<br/>' : '<br>';
48611 };
48612
48613 Renderer.prototype.del = function(text) {
48614   return '<del>' + text + '</del>';
48615 };
48616
48617 Renderer.prototype.link = function(href, title, text) {
48618   if (this.options.sanitize) {
48619     try {
48620       var prot = decodeURIComponent(unescape(href))
48621         .replace(/[^\w:]/g, '')
48622         .toLowerCase();
48623     } catch (e) {
48624       return text;
48625     }
48626     if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
48627       return text;
48628     }
48629   }
48630   if (this.options.baseUrl && !originIndependentUrl.test(href)) {
48631     href = resolveUrl(this.options.baseUrl, href);
48632   }
48633   var out = '<a href="' + href + '"';
48634   if (title) {
48635     out += ' title="' + title + '"';
48636   }
48637   out += '>' + text + '</a>';
48638   return out;
48639 };
48640
48641 Renderer.prototype.image = function(href, title, text) {
48642   if (this.options.baseUrl && !originIndependentUrl.test(href)) {
48643     href = resolveUrl(this.options.baseUrl, href);
48644   }
48645   var out = '<img src="' + href + '" alt="' + text + '"';
48646   if (title) {
48647     out += ' title="' + title + '"';
48648   }
48649   out += this.options.xhtml ? '/>' : '>';
48650   return out;
48651 };
48652
48653 Renderer.prototype.text = function(text) {
48654   return text;
48655 };
48656
48657 /**
48658  * Parsing & Compiling
48659  */
48660
48661 function Parser(options) {
48662   this.tokens = [];
48663   this.token = null;
48664   this.options = options || marked.defaults;
48665   this.options.renderer = this.options.renderer || new Renderer;
48666   this.renderer = this.options.renderer;
48667   this.renderer.options = this.options;
48668 }
48669
48670 /**
48671  * Static Parse Method
48672  */
48673
48674 Parser.parse = function(src, options, renderer) {
48675   var parser = new Parser(options, renderer);
48676   return parser.parse(src);
48677 };
48678
48679 /**
48680  * Parse Loop
48681  */
48682
48683 Parser.prototype.parse = function(src) {
48684   this.inline = new InlineLexer(src.links, this.options, this.renderer);
48685   this.tokens = src.reverse();
48686
48687   var out = '';
48688   while (this.next()) {
48689     out += this.tok();
48690   }
48691
48692   return out;
48693 };
48694
48695 /**
48696  * Next Token
48697  */
48698
48699 Parser.prototype.next = function() {
48700   return this.token = this.tokens.pop();
48701 };
48702
48703 /**
48704  * Preview Next Token
48705  */
48706
48707 Parser.prototype.peek = function() {
48708   return this.tokens[this.tokens.length - 1] || 0;
48709 };
48710
48711 /**
48712  * Parse Text Tokens
48713  */
48714
48715 Parser.prototype.parseText = function() {
48716   var body = this.token.text;
48717
48718   while (this.peek().type === 'text') {
48719     body += '\n' + this.next().text;
48720   }
48721
48722   return this.inline.output(body);
48723 };
48724
48725 /**
48726  * Parse Current Token
48727  */
48728
48729 Parser.prototype.tok = function() {
48730   switch (this.token.type) {
48731     case 'space': {
48732       return '';
48733     }
48734     case 'hr': {
48735       return this.renderer.hr();
48736     }
48737     case 'heading': {
48738       return this.renderer.heading(
48739         this.inline.output(this.token.text),
48740         this.token.depth,
48741         this.token.text);
48742     }
48743     case 'code': {
48744       return this.renderer.code(this.token.text,
48745         this.token.lang,
48746         this.token.escaped);
48747     }
48748     case 'table': {
48749       var header = ''
48750         , body = ''
48751         , i
48752         , row
48753         , cell
48754         , flags
48755         , j;
48756
48757       // header
48758       cell = '';
48759       for (i = 0; i < this.token.header.length; i++) {
48760         flags = { header: true, align: this.token.align[i] };
48761         cell += this.renderer.tablecell(
48762           this.inline.output(this.token.header[i]),
48763           { header: true, align: this.token.align[i] }
48764         );
48765       }
48766       header += this.renderer.tablerow(cell);
48767
48768       for (i = 0; i < this.token.cells.length; i++) {
48769         row = this.token.cells[i];
48770
48771         cell = '';
48772         for (j = 0; j < row.length; j++) {
48773           cell += this.renderer.tablecell(
48774             this.inline.output(row[j]),
48775             { header: false, align: this.token.align[j] }
48776           );
48777         }
48778
48779         body += this.renderer.tablerow(cell);
48780       }
48781       return this.renderer.table(header, body);
48782     }
48783     case 'blockquote_start': {
48784       var body = '';
48785
48786       while (this.next().type !== 'blockquote_end') {
48787         body += this.tok();
48788       }
48789
48790       return this.renderer.blockquote(body);
48791     }
48792     case 'list_start': {
48793       var body = ''
48794         , ordered = this.token.ordered;
48795
48796       while (this.next().type !== 'list_end') {
48797         body += this.tok();
48798       }
48799
48800       return this.renderer.list(body, ordered);
48801     }
48802     case 'list_item_start': {
48803       var body = '';
48804
48805       while (this.next().type !== 'list_item_end') {
48806         body += this.token.type === 'text'
48807           ? this.parseText()
48808           : this.tok();
48809       }
48810
48811       return this.renderer.listitem(body);
48812     }
48813     case 'loose_item_start': {
48814       var body = '';
48815
48816       while (this.next().type !== 'list_item_end') {
48817         body += this.tok();
48818       }
48819
48820       return this.renderer.listitem(body);
48821     }
48822     case 'html': {
48823       var html = !this.token.pre && !this.options.pedantic
48824         ? this.inline.output(this.token.text)
48825         : this.token.text;
48826       return this.renderer.html(html);
48827     }
48828     case 'paragraph': {
48829       return this.renderer.paragraph(this.inline.output(this.token.text));
48830     }
48831     case 'text': {
48832       return this.renderer.paragraph(this.parseText());
48833     }
48834   }
48835 };
48836
48837 /**
48838  * Helpers
48839  */
48840
48841 function escape(html, encode) {
48842   return html
48843     .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&amp;')
48844     .replace(/</g, '&lt;')
48845     .replace(/>/g, '&gt;')
48846     .replace(/"/g, '&quot;')
48847     .replace(/'/g, '&#39;');
48848 }
48849
48850 function unescape(html) {
48851         // explicitly match decimal, hex, and named HTML entities
48852   return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig, function(_, n) {
48853     n = n.toLowerCase();
48854     if (n === 'colon') return ':';
48855     if (n.charAt(0) === '#') {
48856       return n.charAt(1) === 'x'
48857         ? String.fromCharCode(parseInt(n.substring(2), 16))
48858         : String.fromCharCode(+n.substring(1));
48859     }
48860     return '';
48861   });
48862 }
48863
48864 function replace(regex, opt) {
48865   regex = regex.source;
48866   opt = opt || '';
48867   return function self(name, val) {
48868     if (!name) return new RegExp(regex, opt);
48869     val = val.source || val;
48870     val = val.replace(/(^|[^\[])\^/g, '$1');
48871     regex = regex.replace(name, val);
48872     return self;
48873   };
48874 }
48875
48876 function resolveUrl(base, href) {
48877   if (!baseUrls[' ' + base]) {
48878     // we can ignore everything in base after the last slash of its path component,
48879     // but we might need to add _that_
48880     // https://tools.ietf.org/html/rfc3986#section-3
48881     if (/^[^:]+:\/*[^/]*$/.test(base)) {
48882       baseUrls[' ' + base] = base + '/';
48883     } else {
48884       baseUrls[' ' + base] = base.replace(/[^/]*$/, '');
48885     }
48886   }
48887   base = baseUrls[' ' + base];
48888
48889   if (href.slice(0, 2) === '//') {
48890     return base.replace(/:[\s\S]*/, ':') + href;
48891   } else if (href.charAt(0) === '/') {
48892     return base.replace(/(:\/*[^/]*)[\s\S]*/, '$1') + href;
48893   } else {
48894     return base + href;
48895   }
48896 }
48897 var baseUrls = {};
48898 var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
48899
48900 function noop() {}
48901 noop.exec = noop;
48902
48903 function merge(obj) {
48904   var i = 1
48905     , target
48906     , key;
48907
48908   for (; i < arguments.length; i++) {
48909     target = arguments[i];
48910     for (key in target) {
48911       if (Object.prototype.hasOwnProperty.call(target, key)) {
48912         obj[key] = target[key];
48913       }
48914     }
48915   }
48916
48917   return obj;
48918 }
48919
48920
48921 /**
48922  * Marked
48923  */
48924
48925 function marked(src, opt, callback) {
48926   if (callback || typeof opt === 'function') {
48927     if (!callback) {
48928       callback = opt;
48929       opt = null;
48930     }
48931
48932     opt = merge({}, marked.defaults, opt || {});
48933
48934     var highlight = opt.highlight
48935       , tokens
48936       , pending
48937       , i = 0;
48938
48939     try {
48940       tokens = Lexer.lex(src, opt);
48941     } catch (e) {
48942       return callback(e);
48943     }
48944
48945     pending = tokens.length;
48946
48947     var done = function(err) {
48948       if (err) {
48949         opt.highlight = highlight;
48950         return callback(err);
48951       }
48952
48953       var out;
48954
48955       try {
48956         out = Parser.parse(tokens, opt);
48957       } catch (e) {
48958         err = e;
48959       }
48960
48961       opt.highlight = highlight;
48962
48963       return err
48964         ? callback(err)
48965         : callback(null, out);
48966     };
48967
48968     if (!highlight || highlight.length < 3) {
48969       return done();
48970     }
48971
48972     delete opt.highlight;
48973
48974     if (!pending) return done();
48975
48976     for (; i < tokens.length; i++) {
48977       (function(token) {
48978         if (token.type !== 'code') {
48979           return --pending || done();
48980         }
48981         return highlight(token.text, token.lang, function(err, code) {
48982           if (err) return done(err);
48983           if (code == null || code === token.text) {
48984             return --pending || done();
48985           }
48986           token.text = code;
48987           token.escaped = true;
48988           --pending || done();
48989         });
48990       })(tokens[i]);
48991     }
48992
48993     return;
48994   }
48995   try {
48996     if (opt) opt = merge({}, marked.defaults, opt);
48997     return Parser.parse(Lexer.lex(src, opt), opt);
48998   } catch (e) {
48999     e.message += '\nPlease report this to https://github.com/chjj/marked.';
49000     if ((opt || marked.defaults).silent) {
49001       return '<p>An error occurred:</p><pre>'
49002         + escape(e.message + '', true)
49003         + '</pre>';
49004     }
49005     throw e;
49006   }
49007 }
49008
49009 /**
49010  * Options
49011  */
49012
49013 marked.options =
49014 marked.setOptions = function(opt) {
49015   merge(marked.defaults, opt);
49016   return marked;
49017 };
49018
49019 marked.defaults = {
49020   gfm: true,
49021   tables: true,
49022   breaks: false,
49023   pedantic: false,
49024   sanitize: false,
49025   sanitizer: null,
49026   mangle: true,
49027   smartLists: false,
49028   silent: false,
49029   highlight: null,
49030   langPrefix: 'lang-',
49031   smartypants: false,
49032   headerPrefix: '',
49033   renderer: new Renderer,
49034   xhtml: false,
49035   baseUrl: null
49036 };
49037
49038 /**
49039  * Expose
49040  */
49041
49042 marked.Parser = Parser;
49043 marked.parser = Parser.parse;
49044
49045 marked.Renderer = Renderer;
49046
49047 marked.Lexer = Lexer;
49048 marked.lexer = Lexer.lex;
49049
49050 marked.InlineLexer = InlineLexer;
49051 marked.inlineLexer = InlineLexer.output;
49052
49053 marked.parse = marked;
49054
49055 {
49056   module.exports = marked;
49057 }
49058
49059 }).call(function() {
49060   return this || (typeof window !== 'undefined' ? window : commonjsGlobal);
49061 }());
49062 });
49063
49064 function pointBox(loc, context) {
49065     var rect = context.surfaceRect();
49066     var point = context.curtainProjection(loc);
49067     return {
49068         left: point[0] + rect.left - 40,
49069         top: point[1] + rect.top - 60,
49070         width: 80,
49071         height: 90
49072     };
49073 }
49074
49075
49076 function pad$1(locOrBox, padding, context) {
49077     var box;
49078     if (locOrBox instanceof Array) {
49079         var rect = context.surfaceRect();
49080         var point = context.curtainProjection(locOrBox);
49081         box = {
49082             left: point[0] + rect.left,
49083             top: point[1] + rect.top
49084         };
49085     } else {
49086         box = locOrBox;
49087     }
49088
49089     return {
49090         left: box.left - padding,
49091         top: box.top - padding,
49092         width: (box.width || 0) + 2 * padding,
49093         height: (box.width || 0) + 2 * padding
49094     };
49095 }
49096
49097
49098 function icon(name, svgklass, useklass) {
49099     return '<svg class="icon ' + (svgklass || '') + '">' +
49100          '<use xlink:href="' + name + '"' +
49101          (useklass ? ' class="' + useklass + '"' : '') + '></use></svg>';
49102 }
49103
49104
49105 function slugify(text) {
49106     return text.toString().toLowerCase()
49107         .replace(/\s+/g, '-')           // Replace spaces with -
49108         .replace(/[^\w\-]+/g, '')       // Remove all non-word chars
49109         .replace(/\-\-+/g, '-')         // Replace multiple - with single -
49110         .replace(/^-+/, '')             // Trim - from start of text
49111         .replace(/-+$/, '');            // Trim - from end of text
49112 }
49113
49114
49115 // console warning for missing walkthrough names
49116 var missingStrings = {};
49117 function checkKey(key, text) {
49118     if (t(key, { default: undefined}) === undefined) {
49119         if (missingStrings.hasOwnProperty(key)) return;  // warn once
49120         missingStrings[key] = text;
49121         var missing = key + ': ' + text;
49122         if (typeof console !== 'undefined') console.log(missing); // eslint-disable-line
49123     }
49124 }
49125
49126
49127 function localize(obj) {
49128     var key;
49129
49130     // Assign name if entity has one..
49131     var name = obj.tags && obj.tags.name;
49132     if (name) {
49133         key = 'intro.graph.name.' + slugify(name);
49134         obj.tags.name = t(key, { default: name });
49135         checkKey(key, name);
49136     }
49137
49138     // Assign street name if entity has one..
49139     var street = obj.tags && obj.tags['addr:street'];
49140     if (street) {
49141         key = 'intro.graph.name.' + slugify(street);
49142         obj.tags['addr:street'] = t(key, { default: street });
49143         checkKey(key, street);
49144
49145         // Add address details common across walkthrough..
49146         var addrTags = [
49147             'block_number', 'city', 'county', 'district', 'hamlet', 'neighbourhood',
49148             'postcode', 'province', 'quarter', 'state', 'subdistrict', 'suburb'
49149         ];
49150         addrTags.forEach(function(k) {
49151             var key = 'intro.graph.' + k,
49152                 tag = 'addr:' + k,
49153                 val = obj.tags && obj.tags[tag],
49154                 str = t(key, { default: val });
49155
49156             if (str) {
49157                 if (str.match(/^<.*>$/) !== null) {
49158                     delete obj.tags[tag];
49159                 } else {
49160                     obj.tags[tag] = str;
49161                 }
49162             }
49163         });
49164     }
49165
49166     return obj;
49167 }
49168
49169
49170 // Used to detect squareness.. some duplicataion of code from actionOrthogonalize.
49171 function isMostlySquare(points) {
49172     // note: uses 15 here instead of the 12 from actionOrthogonalize because
49173     // actionOrthogonalize can actually straighten some larger angles as it iterates
49174     var threshold = 15, // degrees within right or straight
49175         lowerBound = Math.cos((90 - threshold) * Math.PI / 180),  // near right
49176         upperBound = Math.cos(threshold * Math.PI / 180),         // near straight
49177         mag;
49178
49179     for (var i = 0; i < points.length; i++) {
49180         mag = Math.abs(normalizedDotProduct(i, points));
49181         if (mag > lowerBound && mag < upperBound) {
49182             return false;
49183         }
49184     }
49185
49186     return true;
49187
49188
49189     function normalizedDotProduct(i, points) {
49190         var a = points[(i - 1 + points.length) % points.length],
49191             b = points[i],
49192             c = points[(i + 1) % points.length],
49193             p = subtractPoints(a, b),
49194             q = subtractPoints(c, b);
49195
49196         p = normalizePoint(p);
49197         q = normalizePoint(q);
49198
49199         return p[0] * q[0] + p[1] * q[1];
49200
49201
49202         function subtractPoints(a, b) {
49203             return [a[0] - b[0], a[1] - b[1]];
49204         }
49205
49206         function normalizePoint(point) {
49207             var vector = [0, 0];
49208             var length = Math.sqrt(point[0] * point[0] + point[1] * point[1]);
49209             if (length !== 0) {
49210                 vector[0] = point[0] / length;
49211                 vector[1] = point[1] / length;
49212             }
49213             return vector;
49214         }
49215     }
49216 }
49217
49218
49219 function selectMenuItem(operation) {
49220     var selector = '.edit-menu .edit-menu-item-' + operation +
49221         ', .radial-menu .radial-menu-item-' + operation;
49222     return d3_select(selector);
49223 }
49224
49225
49226 function transitionTime(point1, point2) {
49227     var distance = geoSphericalDistance(point1, point2);
49228     if (distance === 0)
49229         return 0;
49230     else if (distance < 80)
49231         return 500;
49232     else
49233         return 1000;
49234 }
49235
49236 var dataIntroGraph = {"n1":{"id":"n1","loc":[-85.631039,41.948829]},"n10":{"id":"n10","loc":[-85.634733,41.941588]},"n100":{"id":"n100","loc":[-85.637395,41.942252]},"n1000":{"id":"n1000","loc":[-85.632699,41.944763]},"n1001":{"id":"n1001","loc":[-85.632685,41.944763]},"n1002":{"id":"n1002","loc":[-85.632673,41.944755]},"n1003":{"id":"n1003","loc":[-85.632595,41.944682]},"n1004":{"id":"n1004","loc":[-85.632576,41.944673]},"n1005":{"id":"n1005","loc":[-85.632551,41.944667]},"n1006":{"id":"n1006","loc":[-85.63253,41.944667]},"n1007":{"id":"n1007","loc":[-85.632502,41.944669]},"n1008":{"id":"n1008","loc":[-85.632483,41.944677]},"n1009":{"id":"n1009","loc":[-85.632383,41.944731]},"n101":{"id":"n101","loc":[-85.637357,41.942252]},"n1010":{"id":"n1010","loc":[-85.63349,41.944976],"tags":{"addr:city":"Three Rivers","addr:housenumber":"31","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","name":"Sherwin-Williams","shop":"paint"}},"n1011":{"id":"n1011","loc":[-85.633548,41.945034],"tags":{"addr:city":"Three Rivers","addr:housenumber":"33","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","name":"Unique Jewelry","shop":"jewelry"}},"n1012":{"id":"n1012","loc":[-85.633683,41.945129],"tags":{"addr:city":"Three Rivers","addr:housenumber":"37","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","name":"World Fare","shop":"gift"}},"n1013":{"id":"n1013","loc":[-85.634563,41.945469],"tags":{"addr:city":"Three Rivers","addr:housenumber":"62","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","name":"Golden Finch Framing","shop":"frame"}},"n1014":{"id":"n1014","loc":[-85.634469,41.945379],"tags":{"addr:city":"Three Rivers","addr:housenumber":"58","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","name":"Dollar Tree","shop":"second_hand"}},"n1015":{"id":"n1015","loc":[-85.634227,41.945159],"tags":{"addr:city":"Three Rivers","addr:housenumber":"48","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","amenity":"theatre","name":"Riviera Theatre"}},"n1016":{"id":"n1016","loc":[-85.634057,41.945012],"tags":{"addr:city":"Three Rivers","addr:housenumber":"42","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","name":"River City Appliance","shop":"appliance"}},"n1017":{"id":"n1017","loc":[-85.633879,41.945325],"tags":{"addr:city":"Three Rivers","addr:housenumber":"45","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","name":"Paparazzi Tattoo","shop":"tattoo"}},"n1018":{"id":"n1018","loc":[-85.634914,41.945839],"tags":{"addr:city":"Three Rivers","addr:housenumber":"88","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","amenity":"bank","name":"Southern Michigan Bank"}},"n1019":{"id":"n1019","loc":[-85.634514,41.946176]},"n102":{"id":"n102","loc":[-85.637357,41.942216]},"n1020":{"id":"n1020","loc":[-85.634087,41.946178]},"n1021":{"id":"n1021","loc":[-85.634357,41.945805]},"n1022":{"id":"n1022","loc":[-85.634389,41.945788]},"n1023":{"id":"n1023","loc":[-85.634491,41.94581]},"n1024":{"id":"n1024","loc":[-85.634513,41.945853]},"n1025":{"id":"n1025","loc":[-85.634506,41.94583]},"n1026":{"id":"n1026","loc":[-85.634762,41.946056],"tags":{"crossing":"zebra","highway":"crossing"}},"n1027":{"id":"n1027","loc":[-85.634767,41.946172]},"n1028":{"id":"n1028","loc":[-85.634622,41.946175],"tags":{"crossing":"zebra","highway":"crossing"}},"n1029":{"id":"n1029","loc":[-85.640655,41.942057]},"n103":{"id":"n103","loc":[-85.637386,41.942054]},"n1030":{"id":"n1030","loc":[-85.640947,41.942057]},"n1031":{"id":"n1031","loc":[-85.640957,41.942593]},"n1032":{"id":"n1032","loc":[-85.630953,41.960873]},"n1033":{"id":"n1033","loc":[-85.632174,41.960679]},"n1034":{"id":"n1034","loc":[-85.638785,41.943066]},"n1035":{"id":"n1035","loc":[-85.638853,41.943065]},"n1036":{"id":"n1036","loc":[-85.638855,41.943183]},"n1037":{"id":"n1037","loc":[-85.638552,41.943189]},"n1038":{"id":"n1038","loc":[-85.63855,41.943149]},"n1039":{"id":"n1039","loc":[-85.638638,41.943068]},"n104":{"id":"n104","loc":[-85.637387,41.942125]},"n1040":{"id":"n1040","loc":[-85.638638,41.943078]},"n1041":{"id":"n1041","loc":[-85.638813,41.943163]},"n1042":{"id":"n1042","loc":[-85.638684,41.943165]},"n1043":{"id":"n1043","loc":[-85.638682,41.943105]},"n1044":{"id":"n1044","loc":[-85.638706,41.943105]},"n1045":{"id":"n1045","loc":[-85.638707,41.943117]},"n1046":{"id":"n1046","loc":[-85.638812,41.943115]},"n1047":{"id":"n1047","loc":[-85.638769,41.943407]},"n1048":{"id":"n1048","loc":[-85.638549,41.943407]},"n1049":{"id":"n1049","loc":[-85.638567,41.943555]},"n105":{"id":"n105","loc":[-85.637319,41.942125]},"n1050":{"id":"n1050","loc":[-85.638426,41.943554]},"n1051":{"id":"n1051","loc":[-85.638427,41.94346]},"n1052":{"id":"n1052","loc":[-85.638568,41.943461]},"n1053":{"id":"n1053","loc":[-85.639264,41.943415]},"n1054":{"id":"n1054","loc":[-85.639082,41.943417]},"n1055":{"id":"n1055","loc":[-85.63908,41.943331]},"n1056":{"id":"n1056","loc":[-85.639136,41.94333]},"n1057":{"id":"n1057","loc":[-85.639158,41.943312]},"n1058":{"id":"n1058","loc":[-85.639188,41.943313]},"n1059":{"id":"n1059","loc":[-85.639211,41.943331]},"n106":{"id":"n106","loc":[-85.637319,41.942137]},"n1060":{"id":"n1060","loc":[-85.639262,41.943331]},"n1061":{"id":"n1061","loc":[-85.638986,41.943515]},"n1062":{"id":"n1062","loc":[-85.63888,41.943521]},"n1063":{"id":"n1063","loc":[-85.638871,41.943436]},"n1064":{"id":"n1064","loc":[-85.638958,41.943431]},"n1065":{"id":"n1065","loc":[-85.638979,41.943443]},"n1066":{"id":"n1066","loc":[-85.63926,41.943703]},"n1067":{"id":"n1067","loc":[-85.639152,41.943704]},"n1068":{"id":"n1068","loc":[-85.639152,41.943691]},"n1069":{"id":"n1069","loc":[-85.639063,41.943691]},"n107":{"id":"n107","loc":[-85.637259,41.942137]},"n1070":{"id":"n1070","loc":[-85.639062,41.943613]},"n1071":{"id":"n1071","loc":[-85.639259,41.943611]},"n1072":{"id":"n1072","loc":[-85.639117,41.943726]},"n1073":{"id":"n1073","loc":[-85.639118,41.943767]},"n1074":{"id":"n1074","loc":[-85.639051,41.943768]},"n1075":{"id":"n1075","loc":[-85.63905,41.943727]},"n1076":{"id":"n1076","loc":[-85.638627,41.943716]},"n1077":{"id":"n1077","loc":[-85.63863,41.943634]},"n1078":{"id":"n1078","loc":[-85.63844,41.943631]},"n1079":{"id":"n1079","loc":[-85.638437,41.943729]},"n108":{"id":"n108","loc":[-85.637259,41.942126]},"n1080":{"id":"n1080","loc":[-85.638533,41.94373]},"n1081":{"id":"n1081","loc":[-85.638534,41.943715]},"n1082":{"id":"n1082","loc":[-85.638678,41.943941]},"n1083":{"id":"n1083","loc":[-85.638522,41.943944]},"n1084":{"id":"n1084","loc":[-85.63852,41.943864]},"n1085":{"id":"n1085","loc":[-85.638676,41.943861]},"n1086":{"id":"n1086","loc":[-85.638663,41.944059]},"n1087":{"id":"n1087","loc":[-85.638513,41.944061]},"n1088":{"id":"n1088","loc":[-85.638511,41.943991]},"n1089":{"id":"n1089","loc":[-85.638661,41.943989]},"n109":{"id":"n109","loc":[-85.637193,41.942126]},"n1090":{"id":"n1090","loc":[-85.63865,41.944134]},"n1091":{"id":"n1091","loc":[-85.638429,41.944144]},"n1092":{"id":"n1092","loc":[-85.638426,41.944106]},"n1093":{"id":"n1093","loc":[-85.638476,41.944104]},"n1094":{"id":"n1094","loc":[-85.638475,41.94409]},"n1095":{"id":"n1095","loc":[-85.638594,41.944084]},"n1096":{"id":"n1096","loc":[-85.638595,41.944101]},"n1097":{"id":"n1097","loc":[-85.638647,41.944099]},"n1098":{"id":"n1098","loc":[-85.63829,41.944154]},"n1099":{"id":"n1099","loc":[-85.638558,41.944155]},"n11":{"id":"n11","loc":[-85.634602,41.941523]},"n110":{"id":"n110","loc":[-85.637192,41.942053]},"n1100":{"id":"n1100","loc":[-85.638558,41.944338]},"n1101":{"id":"n1101","loc":[-85.638851,41.944408]},"n1102":{"id":"n1102","loc":[-85.637771,41.943989]},"n1103":{"id":"n1103","loc":[-85.639345,41.943964]},"n1104":{"id":"n1104","loc":[-85.638515,41.94397]},"n1105":{"id":"n1105","loc":[-85.639256,41.943928]},"n1106":{"id":"n1106","loc":[-85.639157,41.943929]},"n1107":{"id":"n1107","loc":[-85.639156,41.9439]},"n1108":{"id":"n1108","loc":[-85.639118,41.9439]},"n1109":{"id":"n1109","loc":[-85.639116,41.94382]},"n111":{"id":"n111","loc":[-85.637248,41.942053]},"n1110":{"id":"n1110","loc":[-85.639202,41.943819]},"n1111":{"id":"n1111","loc":[-85.639202,41.943837]},"n1112":{"id":"n1112","loc":[-85.639293,41.943836]},"n1113":{"id":"n1113","loc":[-85.639295,41.943898]},"n1114":{"id":"n1114","loc":[-85.639255,41.943898]},"n1115":{"id":"n1115","loc":[-85.639296,41.944083]},"n1116":{"id":"n1116","loc":[-85.639144,41.944084]},"n1117":{"id":"n1117","loc":[-85.639143,41.944026]},"n1118":{"id":"n1118","loc":[-85.639162,41.944026]},"n1119":{"id":"n1119","loc":[-85.639162,41.944]},"n112":{"id":"n112","loc":[-85.637248,41.942042]},"n1120":{"id":"n1120","loc":[-85.639295,41.943999]},"n1121":{"id":"n1121","loc":[-85.639131,41.944139]},"n1122":{"id":"n1122","loc":[-85.63901,41.94414]},"n1123":{"id":"n1123","loc":[-85.63901,41.944076]},"n1124":{"id":"n1124","loc":[-85.63913,41.944075]},"n1125":{"id":"n1125","loc":[-85.639092,41.944155]},"n1126":{"id":"n1126","loc":[-85.639093,41.944308]},"n1127":{"id":"n1127","loc":[-85.639225,41.944308]},"n1128":{"id":"n1128","loc":[-85.639225,41.94429]},"n1129":{"id":"n1129","loc":[-85.639253,41.944289]},"n113":{"id":"n113","loc":[-85.637338,41.942041]},"n1130":{"id":"n1130","loc":[-85.639253,41.944269]},"n1131":{"id":"n1131","loc":[-85.639243,41.944269]},"n1132":{"id":"n1132","loc":[-85.639243,41.944229]},"n1133":{"id":"n1133","loc":[-85.639224,41.944229]},"n1134":{"id":"n1134","loc":[-85.639224,41.944196]},"n1135":{"id":"n1135","loc":[-85.639195,41.944196]},"n1136":{"id":"n1136","loc":[-85.639195,41.944155]},"n1137":{"id":"n1137","loc":[-85.639072,41.944154]},"n1138":{"id":"n1138","loc":[-85.638865,41.944154]},"n1139":{"id":"n1139","loc":[-85.638863,41.943967]},"n114":{"id":"n114","loc":[-85.637338,41.942055]},"n1140":{"id":"n1140","loc":[-85.6386,41.942698]},"n1141":{"id":"n1141","loc":[-85.639348,41.942698]},"n1142":{"id":"n1142","loc":[-85.639377,41.944984]},"n1143":{"id":"n1143","loc":[-85.63937,41.945013]},"n1144":{"id":"n1144","loc":[-85.639357,41.945033]},"n1145":{"id":"n1145","loc":[-85.639353,41.945053]},"n1146":{"id":"n1146","loc":[-85.639352,41.945084]},"n1147":{"id":"n1147","loc":[-85.638278,41.945516]},"n1148":{"id":"n1148","loc":[-85.637505,41.945801]},"n1149":{"id":"n1149","loc":[-85.637327,41.945857]},"n115":{"id":"n115","loc":[-85.637583,41.941943]},"n1150":{"id":"n1150","loc":[-85.637168,41.945899]},"n1151":{"id":"n1151","loc":[-85.637017,41.94593]},"n1152":{"id":"n1152","loc":[-85.637185,41.945938]},"n1153":{"id":"n1153","loc":[-85.63682,41.945963]},"n1154":{"id":"n1154","loc":[-85.636639,41.945984]},"n1155":{"id":"n1155","loc":[-85.636439,41.945999]},"n1156":{"id":"n1156","loc":[-85.635801,41.945999]},"n1157":{"id":"n1157","loc":[-85.635769,41.945908]},"n1158":{"id":"n1158","loc":[-85.635953,41.946154]},"n1159":{"id":"n1159","loc":[-85.635472,41.94598]},"n116":{"id":"n116","loc":[-85.637584,41.941983]},"n1160":{"id":"n1160","loc":[-85.635409,41.945981]},"n1161":{"id":"n1161","loc":[-85.635583,41.945987]},"n1162":{"id":"n1162","loc":[-85.636452,41.945805]},"n1163":{"id":"n1163","loc":[-85.636425,41.94582]},"n1164":{"id":"n1164","loc":[-85.636396,41.945817]},"n1165":{"id":"n1165","loc":[-85.636368,41.945797]},"n1166":{"id":"n1166","loc":[-85.636346,41.945767]},"n1167":{"id":"n1167","loc":[-85.636307,41.945745]},"n1168":{"id":"n1168","loc":[-85.636194,41.94565]},"n1169":{"id":"n1169","loc":[-85.636121,41.945579]},"n117":{"id":"n117","loc":[-85.63751,41.941983]},"n1170":{"id":"n1170","loc":[-85.635995,41.945432]},"n1171":{"id":"n1171","loc":[-85.637564,41.943538]},"n1172":{"id":"n1172","loc":[-85.63756,41.943505]},"n1173":{"id":"n1173","loc":[-85.637435,41.943489]},"n1174":{"id":"n1174","loc":[-85.637093,41.943556]},"n1175":{"id":"n1175","loc":[-85.634836,41.941574]},"n1176":{"id":"n1176","loc":[-85.634692,41.9415]},"n1177":{"id":"n1177","loc":[-85.634261,41.941337]},"n1178":{"id":"n1178","loc":[-85.634208,41.940962]},"n1179":{"id":"n1179","loc":[-85.635247,41.940968]},"n118":{"id":"n118","loc":[-85.637509,41.941944]},"n1180":{"id":"n1180","loc":[-85.63514,41.941205]},"n1181":{"id":"n1181","loc":[-85.634858,41.941511]},"n1182":{"id":"n1182","loc":[-85.630725,41.943465]},"n1183":{"id":"n1183","loc":[-85.632591,41.942826]},"n1184":{"id":"n1184","loc":[-85.634487,41.941928]},"n1185":{"id":"n1185","loc":[-85.634499,41.942056]},"n1186":{"id":"n1186","loc":[-85.63433,41.943102]},"n1187":{"id":"n1187","loc":[-85.634158,41.943151]},"n1188":{"id":"n1188","loc":[-85.634107,41.94305]},"n1189":{"id":"n1189","loc":[-85.634279,41.943002]},"n119":{"id":"n119","loc":[-85.637724,41.941973]},"n1190":{"id":"n1190","loc":[-85.634362,41.943762]},"n1191":{"id":"n1191","loc":[-85.634331,41.943731]},"n1192":{"id":"n1192","loc":[-85.634396,41.943695]},"n1193":{"id":"n1193","loc":[-85.634426,41.943726]},"n1194":{"id":"n1194","loc":[-85.621569,41.956021]},"n1195":{"id":"n1195","loc":[-85.621574,41.956164]},"n1196":{"id":"n1196","loc":[-85.621489,41.956165]},"n1197":{"id":"n1197","loc":[-85.621488,41.956136]},"n1198":{"id":"n1198","loc":[-85.621372,41.956139]},"n1199":{"id":"n1199","loc":[-85.621369,41.956049]},"n12":{"id":"n12","loc":[-85.63359,41.941093]},"n120":{"id":"n120","loc":[-85.637633,41.941973]},"n1200":{"id":"n1200","loc":[-85.621493,41.956047]},"n1201":{"id":"n1201","loc":[-85.621492,41.956022]},"n1202":{"id":"n1202","loc":[-85.619744,41.953192]},"n1203":{"id":"n1203","loc":[-85.619059,41.953902]},"n1204":{"id":"n1204","loc":[-85.623984,41.95469]},"n1205":{"id":"n1205","loc":[-85.630159,41.958208]},"n1206":{"id":"n1206","loc":[-85.63002,41.958208]},"n1207":{"id":"n1207","loc":[-85.630021,41.95814]},"n1208":{"id":"n1208","loc":[-85.63,41.95814]},"n1209":{"id":"n1209","loc":[-85.63,41.958043]},"n121":{"id":"n121","loc":[-85.637633,41.941853]},"n1210":{"id":"n1210","loc":[-85.630159,41.958043]},"n1211":{"id":"n1211","loc":[-85.630304,41.957566]},"n1212":{"id":"n1212","loc":[-85.630303,41.957684]},"n1213":{"id":"n1213","loc":[-85.630073,41.957683]},"n1214":{"id":"n1214","loc":[-85.630072,41.957721]},"n1215":{"id":"n1215","loc":[-85.629993,41.95772]},"n1216":{"id":"n1216","loc":[-85.629993,41.95768]},"n1217":{"id":"n1217","loc":[-85.629968,41.95768]},"n1218":{"id":"n1218","loc":[-85.629969,41.957588]},"n1219":{"id":"n1219","loc":[-85.630219,41.95759]},"n122":{"id":"n122","loc":[-85.637724,41.941853]},"n1220":{"id":"n1220","loc":[-85.630219,41.957566]},"n1221":{"id":"n1221","loc":[-85.630717,41.957744]},"n1222":{"id":"n1222","loc":[-85.630596,41.957745]},"n1223":{"id":"n1223","loc":[-85.630598,41.957553]},"n1224":{"id":"n1224","loc":[-85.630717,41.957555]},"n1225":{"id":"n1225","loc":[-85.630609,41.957745]},"n1226":{"id":"n1226","loc":[-85.63061,41.957789]},"n1227":{"id":"n1227","loc":[-85.630327,41.957791]},"n1228":{"id":"n1228","loc":[-85.630324,41.95752]},"n1229":{"id":"n1229","loc":[-85.630325,41.95756]},"n123":{"id":"n123","loc":[-85.637773,41.941988]},"n1230":{"id":"n1230","loc":[-85.63057,41.95756]},"n1231":{"id":"n1231","loc":[-85.63069,41.958016]},"n1232":{"id":"n1232","loc":[-85.630586,41.958017]},"n1233":{"id":"n1233","loc":[-85.630584,41.957956]},"n1234":{"id":"n1234","loc":[-85.630614,41.957956]},"n1235":{"id":"n1235","loc":[-85.630611,41.957835]},"n1236":{"id":"n1236","loc":[-85.630737,41.957833]},"n1237":{"id":"n1237","loc":[-85.630739,41.957921]},"n1238":{"id":"n1238","loc":[-85.630688,41.957922]},"n1239":{"id":"n1239","loc":[-85.630719,41.958291]},"n124":{"id":"n124","loc":[-85.637773,41.942046]},"n1240":{"id":"n1240","loc":[-85.630592,41.958291]},"n1241":{"id":"n1241","loc":[-85.630593,41.958108]},"n1242":{"id":"n1242","loc":[-85.630701,41.958109]},"n1243":{"id":"n1243","loc":[-85.6307,41.958173]},"n1244":{"id":"n1244","loc":[-85.630711,41.958173]},"n1245":{"id":"n1245","loc":[-85.630711,41.958233]},"n1246":{"id":"n1246","loc":[-85.630719,41.958233]},"n1247":{"id":"n1247","loc":[-85.630523,41.958329]},"n1248":{"id":"n1248","loc":[-85.630388,41.958329]},"n1249":{"id":"n1249","loc":[-85.630387,41.958262]},"n125":{"id":"n125","loc":[-85.637693,41.942047]},"n1250":{"id":"n1250","loc":[-85.630523,41.958261]},"n1251":{"id":"n1251","loc":[-85.63072,41.958636]},"n1252":{"id":"n1252","loc":[-85.630721,41.958709]},"n1253":{"id":"n1253","loc":[-85.630503,41.958712]},"n1254":{"id":"n1254","loc":[-85.630498,41.958511]},"n1255":{"id":"n1255","loc":[-85.630635,41.95851]},"n1256":{"id":"n1256","loc":[-85.630638,41.958636]},"n1257":{"id":"n1257","loc":[-85.630437,41.958822]},"n1258":{"id":"n1258","loc":[-85.630437,41.958849]},"n1259":{"id":"n1259","loc":[-85.630393,41.958849]},"n126":{"id":"n126","loc":[-85.637692,41.941988]},"n1260":{"id":"n1260","loc":[-85.630393,41.958822]},"n1261":{"id":"n1261","loc":[-85.630605,41.959102]},"n1262":{"id":"n1262","loc":[-85.63049,41.959104]},"n1263":{"id":"n1263","loc":[-85.630487,41.958996]},"n1264":{"id":"n1264","loc":[-85.630462,41.958996]},"n1265":{"id":"n1265","loc":[-85.63046,41.958922]},"n1266":{"id":"n1266","loc":[-85.630562,41.958921]},"n1267":{"id":"n1267","loc":[-85.630564,41.958992]},"n1268":{"id":"n1268","loc":[-85.630602,41.958992]},"n1269":{"id":"n1269","loc":[-85.630126,41.957096]},"n127":{"id":"n127","loc":[-85.637604,41.941994]},"n1270":{"id":"n1270","loc":[-85.630129,41.957283]},"n1271":{"id":"n1271","loc":[-85.629993,41.957284]},"n1272":{"id":"n1272","loc":[-85.629992,41.957216]},"n1273":{"id":"n1273","loc":[-85.630015,41.957215]},"n1274":{"id":"n1274","loc":[-85.630013,41.957097]},"n1275":{"id":"n1275","loc":[-85.630211,41.956592]},"n1276":{"id":"n1276","loc":[-85.630211,41.956676]},"n1277":{"id":"n1277","loc":[-85.630162,41.956676]},"n1278":{"id":"n1278","loc":[-85.630162,41.95676]},"n1279":{"id":"n1279","loc":[-85.630037,41.956761]},"n128":{"id":"n128","loc":[-85.637604,41.942057]},"n1280":{"id":"n1280","loc":[-85.630037,41.956592]},"n1281":{"id":"n1281","loc":[-85.630309,41.95653]},"n1282":{"id":"n1282","loc":[-85.630326,41.957065]},"n1283":{"id":"n1283","loc":[-85.630118,41.957065]},"n1284":{"id":"n1284","loc":[-85.630119,41.957096]},"n1285":{"id":"n1285","loc":[-85.63067,41.957307]},"n1286":{"id":"n1286","loc":[-85.630536,41.957308]},"n1287":{"id":"n1287","loc":[-85.630533,41.957111]},"n1288":{"id":"n1288","loc":[-85.630667,41.95711]},"n1289":{"id":"n1289","loc":[-85.630676,41.956808]},"n129":{"id":"n129","loc":[-85.63748,41.942057]},"n1290":{"id":"n1290","loc":[-85.630551,41.956808]},"n1291":{"id":"n1291","loc":[-85.630552,41.956982]},"n1292":{"id":"n1292","loc":[-85.63059,41.956982]},"n1293":{"id":"n1293","loc":[-85.63059,41.957001]},"n1294":{"id":"n1294","loc":[-85.630692,41.957001]},"n1295":{"id":"n1295","loc":[-85.630692,41.956936]},"n1296":{"id":"n1296","loc":[-85.630676,41.956936]},"n1297":{"id":"n1297","loc":[-85.630496,41.956889]},"n1298":{"id":"n1298","loc":[-85.630501,41.956947]},"n1299":{"id":"n1299","loc":[-85.630377,41.956953]},"n13":{"id":"n13","loc":[-85.633643,41.941143]},"n130":{"id":"n130","loc":[-85.63748,41.941994]},"n1300":{"id":"n1300","loc":[-85.630359,41.956938]},"n1301":{"id":"n1301","loc":[-85.630359,41.956912]},"n1302":{"id":"n1302","loc":[-85.63038,41.956894]},"n1303":{"id":"n1303","loc":[-85.630679,41.956747]},"n1304":{"id":"n1304","loc":[-85.630572,41.956748]},"n1305":{"id":"n1305","loc":[-85.63057,41.956668]},"n1306":{"id":"n1306","loc":[-85.630501,41.956669]},"n1307":{"id":"n1307","loc":[-85.630499,41.95659]},"n1308":{"id":"n1308","loc":[-85.630565,41.956589]},"n1309":{"id":"n1309","loc":[-85.630564,41.956541]},"n131":{"id":"n131","loc":[-85.637431,41.941832]},"n1310":{"id":"n1310","loc":[-85.630686,41.956539]},"n1311":{"id":"n1311","loc":[-85.630688,41.956631]},"n1312":{"id":"n1312","loc":[-85.630676,41.956631]},"n1313":{"id":"n1313","loc":[-85.630686,41.956487]},"n1314":{"id":"n1314","loc":[-85.63059,41.956487]},"n1315":{"id":"n1315","loc":[-85.63059,41.956396]},"n1316":{"id":"n1316","loc":[-85.630686,41.956396]},"n1317":{"id":"n1317","loc":[-85.630643,41.9563]},"n1318":{"id":"n1318","loc":[-85.630548,41.956301]},"n1319":{"id":"n1319","loc":[-85.630545,41.956217]},"n132":{"id":"n132","loc":[-85.637432,41.94189]},"n1320":{"id":"n1320","loc":[-85.630529,41.956214]},"n1321":{"id":"n1321","loc":[-85.630521,41.956202]},"n1322":{"id":"n1322","loc":[-85.63052,41.95618]},"n1323":{"id":"n1323","loc":[-85.630527,41.956169]},"n1324":{"id":"n1324","loc":[-85.630544,41.956163]},"n1325":{"id":"n1325","loc":[-85.630543,41.956094]},"n1326":{"id":"n1326","loc":[-85.630641,41.956093]},"n1327":{"id":"n1327","loc":[-85.630642,41.956134]},"n1328":{"id":"n1328","loc":[-85.630656,41.956134]},"n1329":{"id":"n1329","loc":[-85.630657,41.956252]},"n133":{"id":"n133","loc":[-85.637412,41.94189]},"n1330":{"id":"n1330","loc":[-85.630643,41.956252]},"n1331":{"id":"n1331","loc":[-85.630409,41.956044]},"n1332":{"id":"n1332","loc":[-85.630409,41.956075]},"n1333":{"id":"n1333","loc":[-85.630195,41.956078]},"n1334":{"id":"n1334","loc":[-85.630195,41.9561]},"n1335":{"id":"n1335","loc":[-85.630088,41.956101]},"n1336":{"id":"n1336","loc":[-85.630087,41.956048]},"n1337":{"id":"n1337","loc":[-85.630345,41.956114]},"n1338":{"id":"n1338","loc":[-85.630328,41.956113]},"n1339":{"id":"n1339","loc":[-85.63034,41.956189]},"n134":{"id":"n134","loc":[-85.637413,41.941938]},"n1340":{"id":"n1340","loc":[-85.630355,41.956185]},"n1341":{"id":"n1341","loc":[-85.630311,41.956117]},"n1342":{"id":"n1342","loc":[-85.630297,41.956125]},"n1343":{"id":"n1343","loc":[-85.630287,41.956136]},"n1344":{"id":"n1344","loc":[-85.630283,41.956149]},"n1345":{"id":"n1345","loc":[-85.630285,41.956162]},"n1346":{"id":"n1346","loc":[-85.630293,41.956174]},"n1347":{"id":"n1347","loc":[-85.630306,41.956183]},"n1348":{"id":"n1348","loc":[-85.630322,41.956188]},"n1349":{"id":"n1349","loc":[-85.630368,41.956179]},"n135":{"id":"n135","loc":[-85.637342,41.941939]},"n1350":{"id":"n1350","loc":[-85.630378,41.95617]},"n1351":{"id":"n1351","loc":[-85.630384,41.956159]},"n1352":{"id":"n1352","loc":[-85.630385,41.956147]},"n1353":{"id":"n1353","loc":[-85.630381,41.956136]},"n1354":{"id":"n1354","loc":[-85.630372,41.956126]},"n1355":{"id":"n1355","loc":[-85.63036,41.956118]},"n1356":{"id":"n1356","loc":[-85.630776,41.956041]},"n1357":{"id":"n1357","loc":[-85.630195,41.956036]},"n1358":{"id":"n1358","loc":[-85.630137,41.956037]},"n1359":{"id":"n1359","loc":[-85.630136,41.956006]},"n136":{"id":"n136","loc":[-85.637342,41.941914]},"n1360":{"id":"n1360","loc":[-85.630194,41.956005]},"n1361":{"id":"n1361","loc":[-85.629864,41.956039]},"n1362":{"id":"n1362","loc":[-85.629864,41.955862]},"n1363":{"id":"n1363","loc":[-85.629541,41.958291]},"n1364":{"id":"n1364","loc":[-85.629419,41.958292]},"n1365":{"id":"n1365","loc":[-85.629417,41.958168]},"n1366":{"id":"n1366","loc":[-85.629445,41.958168]},"n1367":{"id":"n1367","loc":[-85.629444,41.958109]},"n1368":{"id":"n1368","loc":[-85.629537,41.958108]},"n1369":{"id":"n1369","loc":[-85.629351,41.958136]},"n137":{"id":"n137","loc":[-85.637212,41.941916]},"n1370":{"id":"n1370","loc":[-85.629352,41.958202]},"n1371":{"id":"n1371","loc":[-85.629365,41.958202]},"n1372":{"id":"n1372","loc":[-85.629365,41.958223]},"n1373":{"id":"n1373","loc":[-85.629291,41.958224]},"n1374":{"id":"n1374","loc":[-85.62929,41.958137]},"n1375":{"id":"n1375","loc":[-85.629443,41.958073]},"n1376":{"id":"n1376","loc":[-85.629252,41.958075]},"n1377":{"id":"n1377","loc":[-85.629253,41.95827]},"n1378":{"id":"n1378","loc":[-85.629566,41.957585]},"n1379":{"id":"n1379","loc":[-85.629566,41.957692]},"n138":{"id":"n138","loc":[-85.637211,41.941835]},"n1380":{"id":"n1380","loc":[-85.629281,41.957693]},"n1381":{"id":"n1381","loc":[-85.62928,41.957585]},"n1382":{"id":"n1382","loc":[-85.629004,41.957599]},"n1383":{"id":"n1383","loc":[-85.629004,41.957682]},"n1384":{"id":"n1384","loc":[-85.628902,41.957682]},"n1385":{"id":"n1385","loc":[-85.628902,41.957723]},"n1386":{"id":"n1386","loc":[-85.628731,41.957724]},"n1387":{"id":"n1387","loc":[-85.628731,41.9576]},"n1388":{"id":"n1388","loc":[-85.62836,41.957679]},"n1389":{"id":"n1389","loc":[-85.628359,41.957759]},"n139":{"id":"n139","loc":[-85.637293,41.941834]},"n1390":{"id":"n1390","loc":[-85.628062,41.957757]},"n1391":{"id":"n1391","loc":[-85.628063,41.957657]},"n1392":{"id":"n1392","loc":[-85.628198,41.957657]},"n1393":{"id":"n1393","loc":[-85.628198,41.957678]},"n1394":{"id":"n1394","loc":[-85.627775,41.958095]},"n1395":{"id":"n1395","loc":[-85.627608,41.958095]},"n1396":{"id":"n1396","loc":[-85.627606,41.957829]},"n1397":{"id":"n1397","loc":[-85.627774,41.957829]},"n1398":{"id":"n1398","loc":[-85.626816,41.957636]},"n1399":{"id":"n1399","loc":[-85.626787,41.957681]},"n14":{"id":"n14","loc":[-85.633643,41.940122]},"n140":{"id":"n140","loc":[-85.637293,41.941823]},"n1400":{"id":"n1400","loc":[-85.626673,41.95764]},"n1401":{"id":"n1401","loc":[-85.626703,41.957594]},"n1402":{"id":"n1402","loc":[-85.62694,41.95752]},"n1403":{"id":"n1403","loc":[-85.62688,41.957611]},"n1404":{"id":"n1404","loc":[-85.626798,41.957582]},"n1405":{"id":"n1405","loc":[-85.626793,41.95759]},"n1406":{"id":"n1406","loc":[-85.626657,41.95754]},"n1407":{"id":"n1407","loc":[-85.626666,41.957526]},"n1408":{"id":"n1408","loc":[-85.626584,41.957497]},"n1409":{"id":"n1409","loc":[-85.626638,41.957415]},"n141":{"id":"n141","loc":[-85.637363,41.941822]},"n1410":{"id":"n1410","loc":[-85.626731,41.957449]},"n1411":{"id":"n1411","loc":[-85.626725,41.957457]},"n1412":{"id":"n1412","loc":[-85.626843,41.9575]},"n1413":{"id":"n1413","loc":[-85.626851,41.957487]},"n1414":{"id":"n1414","loc":[-85.626579,41.957521]},"n1415":{"id":"n1415","loc":[-85.626537,41.957587]},"n1416":{"id":"n1416","loc":[-85.626427,41.957551]},"n1417":{"id":"n1417","loc":[-85.626468,41.957483]},"n1418":{"id":"n1418","loc":[-85.626592,41.957639]},"n1419":{"id":"n1419","loc":[-85.626807,41.957713]},"n142":{"id":"n142","loc":[-85.637364,41.941833]},"n1420":{"id":"n1420","loc":[-85.627129,41.957401]},"n1421":{"id":"n1421","loc":[-85.627209,41.95742]},"n1422":{"id":"n1422","loc":[-85.627302,41.957435]},"n1423":{"id":"n1423","loc":[-85.629566,41.957048]},"n1424":{"id":"n1424","loc":[-85.629568,41.957215]},"n1425":{"id":"n1425","loc":[-85.629383,41.957216]},"n1426":{"id":"n1426","loc":[-85.629384,41.95727]},"n1427":{"id":"n1427","loc":[-85.629231,41.957271]},"n1428":{"id":"n1428","loc":[-85.62923,41.957198]},"n1429":{"id":"n1429","loc":[-85.629322,41.957198]},"n143":{"id":"n143","loc":[-85.637559,41.942448]},"n1430":{"id":"n1430","loc":[-85.629321,41.957108]},"n1431":{"id":"n1431","loc":[-85.629441,41.957108]},"n1432":{"id":"n1432","loc":[-85.62944,41.957049]},"n1433":{"id":"n1433","loc":[-85.629337,41.957018]},"n1434":{"id":"n1434","loc":[-85.629366,41.957028]},"n1435":{"id":"n1435","loc":[-85.629375,41.957044]},"n1436":{"id":"n1436","loc":[-85.629354,41.957071]},"n1437":{"id":"n1437","loc":[-85.629317,41.957071]},"n1438":{"id":"n1438","loc":[-85.62929,41.957074]},"n1439":{"id":"n1439","loc":[-85.62927,41.957084]},"n144":{"id":"n144","loc":[-85.637036,41.942454]},"n1440":{"id":"n1440","loc":[-85.629232,41.957081]},"n1441":{"id":"n1441","loc":[-85.629222,41.957057]},"n1442":{"id":"n1442","loc":[-85.629259,41.957025]},"n1443":{"id":"n1443","loc":[-85.629293,41.957017]},"n1444":{"id":"n1444","loc":[-85.629251,41.957085]},"n1445":{"id":"n1445","loc":[-85.629235,41.957041]},"n1446":{"id":"n1446","loc":[-85.62937,41.95706]},"n1447":{"id":"n1447","loc":[-85.629531,41.956909]},"n1448":{"id":"n1448","loc":[-85.629408,41.956909]},"n1449":{"id":"n1449","loc":[-85.629402,41.956681]},"n145":{"id":"n145","loc":[-85.636692,41.942828]},"n1450":{"id":"n1450","loc":[-85.62953,41.956681]},"n1451":{"id":"n1451","loc":[-85.629402,41.956728]},"n1452":{"id":"n1452","loc":[-85.629408,41.956845]},"n1453":{"id":"n1453","loc":[-85.629385,41.956845]},"n1454":{"id":"n1454","loc":[-85.629384,41.956728]},"n1455":{"id":"n1455","loc":[-85.629063,41.956973]},"n1456":{"id":"n1456","loc":[-85.629064,41.957009]},"n1457":{"id":"n1457","loc":[-85.62902,41.957009]},"n1458":{"id":"n1458","loc":[-85.629019,41.956973]},"n1459":{"id":"n1459","loc":[-85.629136,41.956633]},"n146":{"id":"n146","loc":[-85.635929,41.942826]},"n1460":{"id":"n1460","loc":[-85.629084,41.956632]},"n1461":{"id":"n1461","loc":[-85.629084,41.956605]},"n1462":{"id":"n1462","loc":[-85.629136,41.956605]},"n1463":{"id":"n1463","loc":[-85.629153,41.956657]},"n1464":{"id":"n1464","loc":[-85.627914,41.956661]},"n1465":{"id":"n1465","loc":[-85.630096,41.956101]},"n1466":{"id":"n1466","loc":[-85.630097,41.95612]},"n1467":{"id":"n1467","loc":[-85.630011,41.956121]},"n1468":{"id":"n1468","loc":[-85.630015,41.956374]},"n1469":{"id":"n1469","loc":[-85.629148,41.95626]},"n147":{"id":"n147","loc":[-85.636433,41.942828]},"n1470":{"id":"n1470","loc":[-85.629527,41.956591]},"n1471":{"id":"n1471","loc":[-85.629405,41.956591]},"n1472":{"id":"n1472","loc":[-85.629405,41.956459]},"n1473":{"id":"n1473","loc":[-85.629369,41.956459]},"n1474":{"id":"n1474","loc":[-85.629369,41.956424]},"n1475":{"id":"n1475","loc":[-85.629413,41.956424]},"n1476":{"id":"n1476","loc":[-85.629414,41.956326]},"n1477":{"id":"n1477","loc":[-85.629522,41.956326]},"n1478":{"id":"n1478","loc":[-85.629522,41.956487]},"n1479":{"id":"n1479","loc":[-85.629527,41.956487]},"n148":{"id":"n148","loc":[-85.636435,41.942864],"tags":{"entrance":"yes"}},"n1480":{"id":"n1480","loc":[-85.629414,41.95634]},"n1481":{"id":"n1481","loc":[-85.629149,41.956338]},"n1482":{"id":"n1482","loc":[-85.62931,41.956531]},"n1483":{"id":"n1483","loc":[-85.629291,41.95655]},"n1484":{"id":"n1484","loc":[-85.629255,41.95655]},"n1485":{"id":"n1485","loc":[-85.629236,41.956533]},"n1486":{"id":"n1486","loc":[-85.629237,41.956461]},"n1487":{"id":"n1487","loc":[-85.629257,41.956445]},"n1488":{"id":"n1488","loc":[-85.629257,41.956428]},"n1489":{"id":"n1489","loc":[-85.629287,41.956428]},"n149":{"id":"n149","loc":[-85.637235,41.942622]},"n1490":{"id":"n1490","loc":[-85.629287,41.956445]},"n1491":{"id":"n1491","loc":[-85.62931,41.95646]},"n1492":{"id":"n1492","loc":[-85.629049,41.956425]},"n1493":{"id":"n1493","loc":[-85.628907,41.956427]},"n1494":{"id":"n1494","loc":[-85.628907,41.956455]},"n1495":{"id":"n1495","loc":[-85.628841,41.956455]},"n1496":{"id":"n1496","loc":[-85.62884,41.956424]},"n1497":{"id":"n1497","loc":[-85.628764,41.956425]},"n1498":{"id":"n1498","loc":[-85.628762,41.956323]},"n1499":{"id":"n1499","loc":[-85.628808,41.956323]},"n15":{"id":"n15","loc":[-85.633477,41.940187]},"n150":{"id":"n150","loc":[-85.637247,41.943116]},"n1500":{"id":"n1500","loc":[-85.628808,41.956314]},"n1501":{"id":"n1501","loc":[-85.628911,41.956313]},"n1502":{"id":"n1502","loc":[-85.628911,41.956322]},"n1503":{"id":"n1503","loc":[-85.62896,41.956322]},"n1504":{"id":"n1504","loc":[-85.62896,41.956348]},"n1505":{"id":"n1505","loc":[-85.629047,41.956347]},"n1506":{"id":"n1506","loc":[-85.628893,41.957263]},"n1507":{"id":"n1507","loc":[-85.628788,41.957264]},"n1508":{"id":"n1508","loc":[-85.628786,41.95711]},"n1509":{"id":"n1509","loc":[-85.628894,41.957109]},"n151":{"id":"n151","loc":[-85.637564,41.943116]},"n1510":{"id":"n1510","loc":[-85.628893,41.957075]},"n1511":{"id":"n1511","loc":[-85.628965,41.957075]},"n1512":{"id":"n1512","loc":[-85.628965,41.957111]},"n1513":{"id":"n1513","loc":[-85.629035,41.95711]},"n1514":{"id":"n1514","loc":[-85.629036,41.957209]},"n1515":{"id":"n1515","loc":[-85.628893,41.95721]},"n1516":{"id":"n1516","loc":[-85.631348,41.95773]},"n1517":{"id":"n1517","loc":[-85.631101,41.957732]},"n1518":{"id":"n1518","loc":[-85.631099,41.957558]},"n1519":{"id":"n1519","loc":[-85.63123,41.957557]},"n152":{"id":"n152","loc":[-85.637552,41.942619]},"n1520":{"id":"n1520","loc":[-85.631231,41.957618]},"n1521":{"id":"n1521","loc":[-85.63129,41.957618]},"n1522":{"id":"n1522","loc":[-85.63129,41.957651]},"n1523":{"id":"n1523","loc":[-85.631346,41.957651]},"n1524":{"id":"n1524","loc":[-85.631366,41.95802]},"n1525":{"id":"n1525","loc":[-85.631141,41.958021]},"n1526":{"id":"n1526","loc":[-85.63114,41.957943]},"n1527":{"id":"n1527","loc":[-85.631167,41.957943]},"n1528":{"id":"n1528","loc":[-85.631166,41.957808]},"n1529":{"id":"n1529","loc":[-85.631301,41.957807]},"n153":{"id":"n153","loc":[-85.63763,41.942528]},"n1530":{"id":"n1530","loc":[-85.631302,41.95789]},"n1531":{"id":"n1531","loc":[-85.631364,41.95789]},"n1532":{"id":"n1532","loc":[-85.631539,41.957754]},"n1533":{"id":"n1533","loc":[-85.631069,41.957756]},"n1534":{"id":"n1534","loc":[-85.631536,41.957518]},"n1535":{"id":"n1535","loc":[-85.631543,41.957995]},"n1536":{"id":"n1536","loc":[-85.631531,41.957748]},"n1537":{"id":"n1537","loc":[-85.631485,41.957748]},"n1538":{"id":"n1538","loc":[-85.631484,41.957698]},"n1539":{"id":"n1539","loc":[-85.631531,41.957698]},"n154":{"id":"n154","loc":[-85.637151,41.94253]},"n1540":{"id":"n1540","loc":[-85.631586,41.957742]},"n1541":{"id":"n1541","loc":[-85.63155,41.957742]},"n1542":{"id":"n1542","loc":[-85.631551,41.957702]},"n1543":{"id":"n1543","loc":[-85.631587,41.957702]},"n1544":{"id":"n1544","loc":[-85.631534,41.95807]},"n1545":{"id":"n1545","loc":[-85.631534,41.958097]},"n1546":{"id":"n1546","loc":[-85.631491,41.958097]},"n1547":{"id":"n1547","loc":[-85.631491,41.95807]},"n1548":{"id":"n1548","loc":[-85.631304,41.958861]},"n1549":{"id":"n1549","loc":[-85.631186,41.958862]},"n155":{"id":"n155","loc":[-85.63715,41.942424]},"n1550":{"id":"n1550","loc":[-85.631182,41.958653]},"n1551":{"id":"n1551","loc":[-85.6313,41.958651]},"n1552":{"id":"n1552","loc":[-85.631293,41.95854]},"n1553":{"id":"n1553","loc":[-85.631176,41.958539]},"n1554":{"id":"n1554","loc":[-85.631176,41.958377]},"n1555":{"id":"n1555","loc":[-85.631297,41.958377]},"n1556":{"id":"n1556","loc":[-85.631297,41.958422]},"n1557":{"id":"n1557","loc":[-85.631333,41.958422]},"n1558":{"id":"n1558","loc":[-85.631333,41.958479]},"n1559":{"id":"n1559","loc":[-85.631293,41.958479]},"n156":{"id":"n156","loc":[-85.637629,41.942422]},"n1560":{"id":"n1560","loc":[-85.631951,41.958908]},"n1561":{"id":"n1561","loc":[-85.631838,41.958909]},"n1562":{"id":"n1562","loc":[-85.631837,41.958847]},"n1563":{"id":"n1563","loc":[-85.631859,41.958847]},"n1564":{"id":"n1564","loc":[-85.631858,41.958746]},"n1565":{"id":"n1565","loc":[-85.631961,41.958745]},"n1566":{"id":"n1566","loc":[-85.631962,41.958812]},"n1567":{"id":"n1567","loc":[-85.631949,41.958813]},"n1568":{"id":"n1568","loc":[-85.631579,41.958913]},"n1569":{"id":"n1569","loc":[-85.631567,41.95864]},"n157":{"id":"n157","loc":[-85.638232,41.942477]},"n1570":{"id":"n1570","loc":[-85.631942,41.958639]},"n1571":{"id":"n1571","loc":[-85.631543,41.958594]},"n1572":{"id":"n1572","loc":[-85.631543,41.958065]},"n1573":{"id":"n1573","loc":[-85.631888,41.958546]},"n1574":{"id":"n1574","loc":[-85.631804,41.958546]},"n1575":{"id":"n1575","loc":[-85.631803,41.95841]},"n1576":{"id":"n1576","loc":[-85.631886,41.958409]},"n1577":{"id":"n1577","loc":[-85.631897,41.958125]},"n1578":{"id":"n1578","loc":[-85.631755,41.958126]},"n1579":{"id":"n1579","loc":[-85.631756,41.958174]},"n158":{"id":"n158","loc":[-85.637775,41.942483]},"n1580":{"id":"n1580","loc":[-85.63178,41.958174]},"n1581":{"id":"n1581","loc":[-85.631782,41.958272]},"n1582":{"id":"n1582","loc":[-85.631922,41.958271]},"n1583":{"id":"n1583","loc":[-85.631922,41.958244]},"n1584":{"id":"n1584","loc":[-85.631883,41.958245]},"n1585":{"id":"n1585","loc":[-85.631882,41.958175]},"n1586":{"id":"n1586","loc":[-85.631898,41.958175]},"n1587":{"id":"n1587","loc":[-85.631924,41.958032]},"n1588":{"id":"n1588","loc":[-85.631762,41.958032]},"n1589":{"id":"n1589","loc":[-85.63176,41.957827]},"n159":{"id":"n159","loc":[-85.638107,41.942512]},"n1590":{"id":"n1590","loc":[-85.631888,41.957826]},"n1591":{"id":"n1591","loc":[-85.631888,41.957892]},"n1592":{"id":"n1592","loc":[-85.631871,41.957892]},"n1593":{"id":"n1593","loc":[-85.631872,41.957949]},"n1594":{"id":"n1594","loc":[-85.631923,41.957949]},"n1595":{"id":"n1595","loc":[-85.631695,41.95795]},"n1596":{"id":"n1596","loc":[-85.631666,41.957975]},"n1597":{"id":"n1597","loc":[-85.63163,41.957975]},"n1598":{"id":"n1598","loc":[-85.6316,41.957951]},"n1599":{"id":"n1599","loc":[-85.6316,41.95785]},"n16":{"id":"n16","loc":[-85.63341,41.94032]},"n160":{"id":"n160","loc":[-85.637763,41.942514]},"n1600":{"id":"n1600","loc":[-85.63166,41.95785]},"n1601":{"id":"n1601","loc":[-85.631696,41.957873]},"n1602":{"id":"n1602","loc":[-85.631924,41.957762]},"n1603":{"id":"n1603","loc":[-85.631762,41.957762]},"n1604":{"id":"n1604","loc":[-85.631762,41.957708]},"n1605":{"id":"n1605","loc":[-85.631785,41.957708]},"n1606":{"id":"n1606","loc":[-85.631785,41.957606]},"n1607":{"id":"n1607","loc":[-85.631734,41.957606]},"n1608":{"id":"n1608","loc":[-85.631734,41.957538]},"n1609":{"id":"n1609","loc":[-85.631821,41.957538]},"n161":{"id":"n161","loc":[-85.637763,41.942445]},"n1610":{"id":"n1610","loc":[-85.631935,41.957545]},"n1611":{"id":"n1611","loc":[-85.631821,41.957544]},"n1612":{"id":"n1612","loc":[-85.631935,41.957645]},"n1613":{"id":"n1613","loc":[-85.631924,41.957645]},"n1614":{"id":"n1614","loc":[-85.627135,41.953828]},"n1615":{"id":"n1615","loc":[-85.633517,41.941353],"tags":{"man_made":"lighthouse"}},"n1616":{"id":"n1616","loc":[-85.633659,41.942041],"tags":{"amenity":"bbq"}},"n1617":{"id":"n1617","loc":[-85.63662,41.942911],"tags":{"amenity":"toilets"}},"n1618":{"id":"n1618","loc":[-85.637487,41.943876],"tags":{"amenity":"toilets"}},"n1619":{"id":"n1619","loc":[-85.634938,41.941917],"tags":{"amenity":"toilets"}},"n162":{"id":"n162","loc":[-85.638107,41.942443]},"n1620":{"id":"n1620","loc":[-85.632427,41.941678],"tags":{"amenity":"bbq"}},"n1621":{"id":"n1621","loc":[-85.638033,41.944568],"tags":{"amenity":"bbq"}},"n1622":{"id":"n1622","loc":[-85.638052,41.944522],"tags":{"amenity":"bbq"}},"n1623":{"id":"n1623","loc":[-85.635001,41.941965]},"n1624":{"id":"n1624","loc":[-85.634635,41.941884]},"n1625":{"id":"n1625","loc":[-85.634667,41.941894]},"n1626":{"id":"n1626","loc":[-85.634791,41.942011]},"n1627":{"id":"n1627","loc":[-85.634749,41.941938]},"n1628":{"id":"n1628","loc":[-85.627295,41.953946],"tags":{"barrier":"gate"}},"n1629":{"id":"n1629","loc":[-85.629076,41.954689]},"n163":{"id":"n163","loc":[-85.638813,41.942475]},"n1630":{"id":"n1630","loc":[-85.640667,41.942595]},"n1631":{"id":"n1631","loc":[-85.639455,41.94261]},"n1632":{"id":"n1632","loc":[-85.643407,41.942336]},"n1633":{"id":"n1633","loc":[-85.641845,41.941316]},"n1634":{"id":"n1634","loc":[-85.643322,41.942224]},"n1635":{"id":"n1635","loc":[-85.643301,41.942124]},"n1636":{"id":"n1636","loc":[-85.640639,41.941326]},"n1637":{"id":"n1637","loc":[-85.640614,41.940058]},"n1638":{"id":"n1638","loc":[-85.639428,41.941335]},"n1639":{"id":"n1639","loc":[-85.643078,41.941293]},"n164":{"id":"n164","loc":[-85.63883,41.942422]},"n1640":{"id":"n1640","loc":[-85.64371,41.942302]},"n1641":{"id":"n1641","loc":[-85.643056,41.94001]},"n1642":{"id":"n1642","loc":[-85.643097,41.942575],"tags":{"highway":"traffic_signals","traffic_signals":"signal","traffic_signals:direction":"both"}},"n1643":{"id":"n1643","loc":[-85.641855,41.942586]},"n1644":{"id":"n1644","loc":[-85.643549,41.942209]},"n1645":{"id":"n1645","loc":[-85.639359,41.94007]},"n1646":{"id":"n1646","loc":[-85.642797,41.940522]},"n1647":{"id":"n1647","loc":[-85.642589,41.940523]},"n1648":{"id":"n1648","loc":[-85.642587,41.940287]},"n1649":{"id":"n1649","loc":[-85.642797,41.940286]},"n165":{"id":"n165","loc":[-85.63883,41.942508]},"n1650":{"id":"n1650","loc":[-85.642571,41.940523]},"n1651":{"id":"n1651","loc":[-85.642568,41.940286]},"n1652":{"id":"n1652","loc":[-85.642316,41.940289]},"n1653":{"id":"n1653","loc":[-85.642321,41.940436]},"n1654":{"id":"n1654","loc":[-85.642292,41.940458]},"n1655":{"id":"n1655","loc":[-85.642287,41.940483]},"n1656":{"id":"n1656","loc":[-85.642323,41.940509]},"n1657":{"id":"n1657","loc":[-85.642385,41.940511]},"n1658":{"id":"n1658","loc":[-85.642408,41.940526]},"n1659":{"id":"n1659","loc":[-85.641962,41.94109]},"n166":{"id":"n166","loc":[-85.638364,41.942508]},"n1660":{"id":"n1660","loc":[-85.642753,41.941084]},"n1661":{"id":"n1661","loc":[-85.642752,41.941004]},"n1662":{"id":"n1662","loc":[-85.642806,41.941003]},"n1663":{"id":"n1663","loc":[-85.642803,41.940731]},"n1664":{"id":"n1664","loc":[-85.642741,41.940732]},"n1665":{"id":"n1665","loc":[-85.64274,41.940645]},"n1666":{"id":"n1666","loc":[-85.641957,41.940651]},"n1667":{"id":"n1667","loc":[-85.642937,41.941241]},"n1668":{"id":"n1668","loc":[-85.641776,41.941253]},"n1669":{"id":"n1669","loc":[-85.641766,41.940598]},"n167":{"id":"n167","loc":[-85.638836,41.942167]},"n1670":{"id":"n1670","loc":[-85.64198,41.940598]},"n1671":{"id":"n1671","loc":[-85.641961,41.940137]},"n1672":{"id":"n1672","loc":[-85.642934,41.94012]},"n1673":{"id":"n1673","loc":[-85.643074,41.941173]},"n1674":{"id":"n1674","loc":[-85.642841,41.940997]},"n1675":{"id":"n1675","loc":[-85.642839,41.940721]},"n1676":{"id":"n1676","loc":[-85.643065,41.940552]},"n1677":{"id":"n1677","loc":[-85.642732,41.94124]},"n1678":{"id":"n1678","loc":[-85.641815,41.941246]},"n1679":{"id":"n1679","loc":[-85.641813,41.941132]},"n168":{"id":"n168","loc":[-85.638836,41.94229]},"n1680":{"id":"n1680","loc":[-85.641839,41.941111]},"n1681":{"id":"n1681","loc":[-85.641884,41.941098]},"n1682":{"id":"n1682","loc":[-85.642732,41.941092]},"n1683":{"id":"n1683","loc":[-85.642776,41.941302]},"n1684":{"id":"n1684","loc":[-85.632788,41.946236]},"n1685":{"id":"n1685","loc":[-85.622342,41.953127]},"n1686":{"id":"n1686","loc":[-85.641848,41.941167]},"n1687":{"id":"n1687","loc":[-85.643753,41.941503]},"n1688":{"id":"n1688","loc":[-85.643762,41.942119]},"n1689":{"id":"n1689","loc":[-85.64238,41.942262]},"n169":{"id":"n169","loc":[-85.638594,41.94229]},"n1690":{"id":"n1690","loc":[-85.642374,41.941944]},"n1691":{"id":"n1691","loc":[-85.642518,41.941943]},"n1692":{"id":"n1692","loc":[-85.642519,41.94198]},"n1693":{"id":"n1693","loc":[-85.642831,41.941977]},"n1694":{"id":"n1694","loc":[-85.642837,41.942312]},"n1695":{"id":"n1695","loc":[-85.642495,41.942315]},"n1696":{"id":"n1696","loc":[-85.642494,41.942261]},"n1697":{"id":"n1697","loc":[-85.641087,41.942433]},"n1698":{"id":"n1698","loc":[-85.641081,41.942006]},"n1699":{"id":"n1699","loc":[-85.641244,41.942005]},"n17":{"id":"n17","loc":[-85.633478,41.94081]},"n170":{"id":"n170","loc":[-85.638594,41.942422]},"n1700":{"id":"n1700","loc":[-85.64125,41.942431]},"n1701":{"id":"n1701","loc":[-85.641331,41.942968]},"n1702":{"id":"n1702","loc":[-85.641328,41.942713]},"n1703":{"id":"n1703","loc":[-85.641521,41.942712]},"n1704":{"id":"n1704","loc":[-85.641523,41.942924]},"n1705":{"id":"n1705","loc":[-85.641504,41.942924]},"n1706":{"id":"n1706","loc":[-85.641505,41.942967]},"n1707":{"id":"n1707","loc":[-85.638612,41.942408]},"n1708":{"id":"n1708","loc":[-85.638612,41.942327]},"n1709":{"id":"n1709","loc":[-85.638775,41.942327]},"n171":{"id":"n171","loc":[-85.638364,41.942356]},"n1710":{"id":"n1710","loc":[-85.638775,41.942299]},"n1711":{"id":"n1711","loc":[-85.638835,41.942298]},"n1712":{"id":"n1712","loc":[-85.638835,41.942407]},"n1713":{"id":"n1713","loc":[-85.639116,41.942444]},"n1714":{"id":"n1714","loc":[-85.639114,41.942362]},"n1715":{"id":"n1715","loc":[-85.639294,41.94236]},"n1716":{"id":"n1716","loc":[-85.639296,41.942442]},"n1717":{"id":"n1717","loc":[-85.639808,41.942385]},"n1718":{"id":"n1718","loc":[-85.639805,41.942285]},"n1719":{"id":"n1719","loc":[-85.639988,41.942283]},"n172":{"id":"n172","loc":[-85.638364,41.942167]},"n1720":{"id":"n1720","loc":[-85.63999,41.942383]},"n1721":{"id":"n1721","loc":[-85.639633,41.943023]},"n1722":{"id":"n1722","loc":[-85.639867,41.943019]},"n1723":{"id":"n1723","loc":[-85.639866,41.942964]},"n1724":{"id":"n1724","loc":[-85.639888,41.942963]},"n1725":{"id":"n1725","loc":[-85.639883,41.942779]},"n1726":{"id":"n1726","loc":[-85.639851,41.94278]},"n1727":{"id":"n1727","loc":[-85.63985,41.94274]},"n1728":{"id":"n1728","loc":[-85.639789,41.942741]},"n1729":{"id":"n1729","loc":[-85.639789,41.942753]},"n173":{"id":"n173","loc":[-85.639038,41.942463]},"n1730":{"id":"n1730","loc":[-85.639698,41.942754]},"n1731":{"id":"n1731","loc":[-85.639699,41.942788]},"n1732":{"id":"n1732","loc":[-85.639675,41.942789]},"n1733":{"id":"n1733","loc":[-85.639676,41.94283]},"n1734":{"id":"n1734","loc":[-85.639701,41.942829]},"n1735":{"id":"n1735","loc":[-85.639702,41.942869]},"n1736":{"id":"n1736","loc":[-85.639629,41.94287]},"n1737":{"id":"n1737","loc":[-85.643568,41.942946]},"n1738":{"id":"n1738","loc":[-85.643568,41.942777]},"n1739":{"id":"n1739","loc":[-85.643401,41.942777]},"n174":{"id":"n174","loc":[-85.638897,41.942464]},"n1740":{"id":"n1740","loc":[-85.643401,41.942863]},"n1741":{"id":"n1741","loc":[-85.643448,41.942863]},"n1742":{"id":"n1742","loc":[-85.643448,41.942946]},"n1743":{"id":"n1743","loc":[-85.642836,41.942981]},"n1744":{"id":"n1744","loc":[-85.642917,41.942979]},"n1745":{"id":"n1745","loc":[-85.642914,41.942904]},"n1746":{"id":"n1746","loc":[-85.642938,41.942903]},"n1747":{"id":"n1747","loc":[-85.642935,41.942813]},"n1748":{"id":"n1748","loc":[-85.642775,41.942816]},"n1749":{"id":"n1749","loc":[-85.642778,41.942906]},"n175":{"id":"n175","loc":[-85.638897,41.942423]},"n1750":{"id":"n1750","loc":[-85.642833,41.942905]},"n1751":{"id":"n1751","loc":[-85.642302,41.942886]},"n1752":{"id":"n1752","loc":[-85.642299,41.942721]},"n1753":{"id":"n1753","loc":[-85.642422,41.94272]},"n1754":{"id":"n1754","loc":[-85.642425,41.942868]},"n1755":{"id":"n1755","loc":[-85.642385,41.942869]},"n1756":{"id":"n1756","loc":[-85.642385,41.942885]},"n1757":{"id":"n1757","loc":[-85.641533,41.942939]},"n1758":{"id":"n1758","loc":[-85.64161,41.942877]},"n1759":{"id":"n1759","loc":[-85.641676,41.942922]},"n176":{"id":"n176","loc":[-85.638853,41.942423]},"n1760":{"id":"n1760","loc":[-85.6416,41.942985]},"n1761":{"id":"n1761","loc":[-85.64206,41.942802]},"n1762":{"id":"n1762","loc":[-85.642059,41.942741]},"n1763":{"id":"n1763","loc":[-85.642196,41.942741]},"n1764":{"id":"n1764","loc":[-85.642196,41.942818]},"n1765":{"id":"n1765","loc":[-85.642128,41.942819]},"n1766":{"id":"n1766","loc":[-85.642128,41.942801]},"n1767":{"id":"n1767","loc":[-85.640943,41.942934]},"n1768":{"id":"n1768","loc":[-85.641035,41.942933]},"n1769":{"id":"n1769","loc":[-85.641032,41.942797]},"n177":{"id":"n177","loc":[-85.638852,41.94237]},"n1770":{"id":"n1770","loc":[-85.640997,41.942798]},"n1771":{"id":"n1771","loc":[-85.640996,41.942764]},"n1772":{"id":"n1772","loc":[-85.640861,41.942766]},"n1773":{"id":"n1773","loc":[-85.640862,41.942848]},"n1774":{"id":"n1774","loc":[-85.640941,41.942847]},"n1775":{"id":"n1775","loc":[-85.643766,41.942226]},"n1776":{"id":"n1776","loc":[-85.643768,41.942407]},"n1777":{"id":"n1777","loc":[-85.643218,41.94177]},"n1778":{"id":"n1778","loc":[-85.64321,41.941327]},"n1779":{"id":"n1779","loc":[-85.643649,41.941323]},"n178":{"id":"n178","loc":[-85.638892,41.94237]},"n1780":{"id":"n1780","loc":[-85.643656,41.941716]},"n1781":{"id":"n1781","loc":[-85.64358,41.941717]},"n1782":{"id":"n1782","loc":[-85.64358,41.941767]},"n1783":{"id":"n1783","loc":[-85.64382,41.941495]},"n1784":{"id":"n1784","loc":[-85.643817,41.941317]},"n1785":{"id":"n1785","loc":[-85.643235,41.941833]},"n1786":{"id":"n1786","loc":[-85.64335,41.941842]},"n1787":{"id":"n1787","loc":[-85.643504,41.941903]},"n1788":{"id":"n1788","loc":[-85.643554,41.941946]},"n1789":{"id":"n1789","loc":[-85.643618,41.942015]},"n179":{"id":"n179","loc":[-85.638891,41.942334]},"n1790":{"id":"n1790","loc":[-85.64346,41.941971]},"n1791":{"id":"n1791","loc":[-85.643528,41.942468]},"n1792":{"id":"n1792","loc":[-85.643621,41.942363]},"n1793":{"id":"n1793","loc":[-85.643496,41.942297]},"n1794":{"id":"n1794","loc":[-85.643446,41.942246]},"n1795":{"id":"n1795","loc":[-85.643398,41.942177]},"n1796":{"id":"n1796","loc":[-85.643398,41.942031]},"n1797":{"id":"n1797","loc":[-85.621531,41.952693]},"n1798":{"id":"n1798","loc":[-85.643221,41.942028]},"n1799":{"id":"n1799","loc":[-85.643225,41.942276]},"n18":{"id":"n18","loc":[-85.63345,41.94071]},"n180":{"id":"n180","loc":[-85.639037,41.942334]},"n1800":{"id":"n1800","loc":[-85.643265,41.942347]},"n1801":{"id":"n1801","loc":[-85.643323,41.942413]},"n1802":{"id":"n1802","loc":[-85.643411,41.94247]},"n1803":{"id":"n1803","loc":[-85.643459,41.942435]},"n1804":{"id":"n1804","loc":[-85.643767,41.942307]},"n1805":{"id":"n1805","loc":[-85.643661,41.942293]},"n1806":{"id":"n1806","loc":[-85.643578,41.942247]},"n1807":{"id":"n1807","loc":[-85.643522,41.942125]},"n1808":{"id":"n1808","loc":[-85.643515,41.942061]},"n1809":{"id":"n1809","loc":[-85.643346,41.941924]},"n181":{"id":"n181","loc":[-85.638074,41.941839]},"n1810":{"id":"n1810","loc":[-85.643086,41.94192]},"n1811":{"id":"n1811","loc":[-85.643529,41.94217]},"n1812":{"id":"n1812","loc":[-85.643489,41.942003]},"n1813":{"id":"n1813","loc":[-85.643295,41.941919]},"n1814":{"id":"n1814","loc":[-85.643305,41.942163]},"n1815":{"id":"n1815","loc":[-85.643354,41.942285]},"n1816":{"id":"n1816","loc":[-85.643472,41.942389]},"n1817":{"id":"n1817","loc":[-85.643608,41.942271]},"n1818":{"id":"n1818","loc":[-85.643876,41.941402]},"n1819":{"id":"n1819","loc":[-85.643818,41.941369]},"n182":{"id":"n182","loc":[-85.638076,41.941942]},"n1820":{"id":"n1820","loc":[-85.643682,41.941304]},"n1821":{"id":"n1821","loc":[-85.64359,41.941286]},"n1822":{"id":"n1822","loc":[-85.643317,41.941727]},"n1823":{"id":"n1823","loc":[-85.643301,41.941286]},"n1824":{"id":"n1824","loc":[-85.643553,41.941698]},"n1825":{"id":"n1825","loc":[-85.643543,41.941286]},"n1826":{"id":"n1826","loc":[-85.636967,41.940118]},"n1827":{"id":"n1827","loc":[-85.63378,41.940114]},"n1828":{"id":"n1828","loc":[-85.637254,41.940075]},"n1829":{"id":"n1829","loc":[-85.637002,41.941355]},"n183":{"id":"n183","loc":[-85.637955,41.941944]},"n1830":{"id":"n1830","loc":[-85.643532,41.94204]},"n1831":{"id":"n1831","loc":[-85.638235,41.942615]},"n1832":{"id":"n1832","loc":[-85.637039,41.942624]},"n1833":{"id":"n1833","loc":[-85.636369,41.94266]},"n1834":{"id":"n1834","loc":[-85.63582,41.942771],"tags":{"highway":"traffic_signals","traffic_signals":"emergency","traffic_signals:direction":"both"}},"n1835":{"id":"n1835","loc":[-85.634873,41.943044]},"n1836":{"id":"n1836","loc":[-85.643482,41.941976]},"n1837":{"id":"n1837","loc":[-85.64345,41.941945]},"n1838":{"id":"n1838","loc":[-85.641885,41.943851]},"n1839":{"id":"n1839","loc":[-85.641915,41.945121]},"n184":{"id":"n184","loc":[-85.637953,41.94184]},"n1840":{"id":"n1840","loc":[-85.639454,41.943871]},"n1841":{"id":"n1841","loc":[-85.639491,41.945191]},"n1842":{"id":"n1842","loc":[-85.635768,41.940113]},"n1843":{"id":"n1843","loc":[-85.638206,41.941345]},"n1844":{"id":"n1844","loc":[-85.640721,41.94513]},"n1845":{"id":"n1845","loc":[-85.643137,41.945103]},"n1846":{"id":"n1846","loc":[-85.638199,41.940079]},"n1847":{"id":"n1847","loc":[-85.640688,41.943861]},"n1848":{"id":"n1848","loc":[-85.643397,41.941924]},"n1849":{"id":"n1849","loc":[-85.643117,41.943841]},"n185":{"id":"n185","loc":[-85.637953,41.941866]},"n1850":{"id":"n1850","loc":[-85.636731,41.94263]},"n1851":{"id":"n1851","loc":[-85.63518,41.942955],"tags":{"highway":"crossing"}},"n1852":{"id":"n1852","loc":[-85.636152,41.942695]},"n1853":{"id":"n1853","loc":[-85.644202,41.941499]},"n1854":{"id":"n1854","loc":[-85.644211,41.942116]},"n1855":{"id":"n1855","loc":[-85.644233,41.942404]},"n1856":{"id":"n1856","loc":[-85.644231,41.942223]},"n1857":{"id":"n1857","loc":[-85.644133,41.941315]},"n1858":{"id":"n1858","loc":[-85.644136,41.941493]},"n1859":{"id":"n1859","loc":[-85.644345,41.942307]},"n186":{"id":"n186","loc":[-85.637873,41.941867]},"n1860":{"id":"n1860","loc":[-85.644232,41.942304]},"n1861":{"id":"n1861","loc":[-85.644134,41.941403]},"n1862":{"id":"n1862","loc":[-85.63607,41.943005],"tags":{"addr:city":"Three Rivers","addr:housenumber":"333","addr:postcode":"49093","addr:state":"MI","addr:street":"Michigan Avenue","amenity":"fire_station","name":"Three Rivers Fire Department"}},"n1863":{"id":"n1863","loc":[-85.637,41.941236]},"n1864":{"id":"n1864","loc":[-85.634476,41.941475]},"n1865":{"id":"n1865","loc":[-85.635036,41.941858]},"n1866":{"id":"n1866","loc":[-85.635362,41.941962]},"n1867":{"id":"n1867","loc":[-85.635796,41.941962]},"n1868":{"id":"n1868","loc":[-85.63295,41.943006]},"n1869":{"id":"n1869","loc":[-85.634692,41.943098]},"n187":{"id":"n187","loc":[-85.637877,41.941975]},"n1870":{"id":"n1870","loc":[-85.633128,41.940484]},"n1871":{"id":"n1871","loc":[-85.633117,41.942798]},"n1872":{"id":"n1872","loc":[-85.633303,41.942412]},"n1873":{"id":"n1873","loc":[-85.633482,41.941912]},"n1874":{"id":"n1874","loc":[-85.633455,41.941359]},"n1875":{"id":"n1875","loc":[-85.633162,41.942679]},"n1876":{"id":"n1876","loc":[-85.634274,41.943479]},"n1877":{"id":"n1877","loc":[-85.634678,41.942909]},"n1878":{"id":"n1878","loc":[-85.6339,41.941453]},"n1879":{"id":"n1879","loc":[-85.634571,41.942774]},"n188":{"id":"n188","loc":[-85.636855,41.942488]},"n1880":{"id":"n1880","loc":[-85.63419,41.941732]},"n1881":{"id":"n1881","loc":[-85.634067,41.941565]},"n1882":{"id":"n1882","loc":[-85.63436,41.942358]},"n1883":{"id":"n1883","loc":[-85.634327,41.942247]},"n1884":{"id":"n1884","loc":[-85.633391,41.941231]},"n1885":{"id":"n1885","loc":[-85.634303,41.941972]},"n1886":{"id":"n1886","loc":[-85.633541,41.940147]},"n1887":{"id":"n1887","loc":[-85.633433,41.940252]},"n1888":{"id":"n1888","loc":[-85.633402,41.940411]},"n1889":{"id":"n1889","loc":[-85.633551,41.941023]},"n189":{"id":"n189","loc":[-85.636702,41.942488]},"n1890":{"id":"n1890","loc":[-85.633719,41.941186]},"n1891":{"id":"n1891","loc":[-85.633067,41.941845]},"n1892":{"id":"n1892","loc":[-85.634902,41.942766]},"n1893":{"id":"n1893","loc":[-85.634603,41.942202]},"n1894":{"id":"n1894","loc":[-85.634858,41.942152]},"n1895":{"id":"n1895","loc":[-85.634842,41.942269]},"n1896":{"id":"n1896","loc":[-85.634907,41.942313]},"n1897":{"id":"n1897","loc":[-85.635049,41.942331]},"n1898":{"id":"n1898","loc":[-85.635101,41.942281]},"n1899":{"id":"n1899","loc":[-85.635129,41.942144]},"n19":{"id":"n19","loc":[-85.633009,41.942229]},"n190":{"id":"n190","loc":[-85.636702,41.942434]},"n1900":{"id":"n1900","loc":[-85.635531,41.942143]},"n1901":{"id":"n1901","loc":[-85.635534,41.942577]},"n1902":{"id":"n1902","loc":[-85.635158,41.942656]},"n1903":{"id":"n1903","loc":[-85.635121,41.942703]},"n1904":{"id":"n1904","loc":[-85.635087,41.941508]},"n1905":{"id":"n1905","loc":[-85.63536,41.941106]},"n1906":{"id":"n1906","loc":[-85.635442,41.941094]},"n1907":{"id":"n1907","loc":[-85.635508,41.941104]},"n1908":{"id":"n1908","loc":[-85.635569,41.941125]},"n1909":{"id":"n1909","loc":[-85.635583,41.941106]},"n191":{"id":"n191","loc":[-85.636761,41.942434]},"n1910":{"id":"n1910","loc":[-85.635555,41.940976]},"n1911":{"id":"n1911","loc":[-85.635501,41.940915]},"n1912":{"id":"n1912","loc":[-85.635392,41.940922]},"n1913":{"id":"n1913","loc":[-85.635276,41.940974]},"n1914":{"id":"n1914","loc":[-85.63517,41.941204]},"n1915":{"id":"n1915","loc":[-85.634888,41.941517]},"n1916":{"id":"n1916","loc":[-85.634897,41.941576]},"n1917":{"id":"n1917","loc":[-85.634961,41.94164]},"n1918":{"id":"n1918","loc":[-85.635028,41.941659]},"n1919":{"id":"n1919","loc":[-85.635118,41.941621]},"n192":{"id":"n192","loc":[-85.636761,41.942369]},"n1920":{"id":"n1920","loc":[-85.635085,41.941558]},"n1921":{"id":"n1921","loc":[-85.63504,41.94136]},"n1922":{"id":"n1922","loc":[-85.635221,41.941077]},"n1923":{"id":"n1923","loc":[-85.634387,41.941559]},"n1924":{"id":"n1924","loc":[-85.634351,41.941587]},"n1925":{"id":"n1925","loc":[-85.634416,41.941756]},"n1926":{"id":"n1926","loc":[-85.634461,41.941797]},"n1927":{"id":"n1927","loc":[-85.634501,41.941819]},"n1928":{"id":"n1928","loc":[-85.634597,41.941816]},"n1929":{"id":"n1929","loc":[-85.634732,41.941724]},"n193":{"id":"n193","loc":[-85.636855,41.942369]},"n1930":{"id":"n1930","loc":[-85.634672,41.941775]},"n1931":{"id":"n1931","loc":[-85.633403,41.939101]},"n1932":{"id":"n1932","loc":[-85.633297,41.939397]},"n1933":{"id":"n1933","loc":[-85.633205,41.939674]},"n1934":{"id":"n1934","loc":[-85.63322,41.939777]},"n1935":{"id":"n1935","loc":[-85.633345,41.939936]},"n1936":{"id":"n1936","loc":[-85.633376,41.940002]},"n1937":{"id":"n1937","loc":[-85.633266,41.940228]},"n1938":{"id":"n1938","loc":[-85.633236,41.940352]},"n1939":{"id":"n1939","loc":[-85.633282,41.94063]},"n194":{"id":"n194","loc":[-85.636645,41.94249]},"n1940":{"id":"n1940","loc":[-85.633364,41.940874]},"n1941":{"id":"n1941","loc":[-85.633439,41.941052]},"n1942":{"id":"n1942","loc":[-85.633582,41.941172]},"n1943":{"id":"n1943","loc":[-85.633748,41.941273]},"n1944":{"id":"n1944","loc":[-85.634317,41.941527]},"n1945":{"id":"n1945","loc":[-85.634389,41.94174]},"n1946":{"id":"n1946","loc":[-85.634441,41.941801]},"n1947":{"id":"n1947","loc":[-85.634514,41.941837]},"n1948":{"id":"n1948","loc":[-85.634485,41.942005]},"n1949":{"id":"n1949","loc":[-85.63457,41.942202]},"n195":{"id":"n195","loc":[-85.636565,41.94249]},"n1950":{"id":"n1950","loc":[-85.634869,41.942769]},"n1951":{"id":"n1951","loc":[-85.634943,41.942792]},"n1952":{"id":"n1952","loc":[-85.635139,41.942882]},"n1953":{"id":"n1953","loc":[-85.634962,41.943161]},"n1954":{"id":"n1954","loc":[-85.635002,41.943131]},"n1955":{"id":"n1955","loc":[-85.635005,41.943091]},"n1956":{"id":"n1956","loc":[-85.635216,41.943033]},"n1957":{"id":"n1957","loc":[-85.634817,41.94267]},"n1958":{"id":"n1958","loc":[-85.634614,41.942599]},"n1959":{"id":"n1959","loc":[-85.634494,41.942381]},"n196":{"id":"n196","loc":[-85.636565,41.942474]},"n1960":{"id":"n1960","loc":[-85.634486,41.9423]},"n1961":{"id":"n1961","loc":[-85.634671,41.941795]},"n1962":{"id":"n1962","loc":[-85.634595,41.941831]},"n1963":{"id":"n1963","loc":[-85.634332,41.941866]},"n1964":{"id":"n1964","loc":[-85.634207,41.941885]},"n1965":{"id":"n1965","loc":[-85.634133,41.941892]},"n1966":{"id":"n1966","loc":[-85.634131,41.942203]},"n1967":{"id":"n1967","loc":[-85.634047,41.942327]},"n1968":{"id":"n1968","loc":[-85.634219,41.942793]},"n1969":{"id":"n1969","loc":[-85.634061,41.942392]},"n197":{"id":"n197","loc":[-85.636514,41.942474]},"n1970":{"id":"n1970","loc":[-85.633989,41.942407]},"n1971":{"id":"n1971","loc":[-85.633971,41.942356]},"n1972":{"id":"n1972","loc":[-85.63361,41.942423]},"n1973":{"id":"n1973","loc":[-85.633714,41.942682]},"n1974":{"id":"n1974","loc":[-85.633698,41.942863]},"n1975":{"id":"n1975","loc":[-85.633882,41.942865]},"n1976":{"id":"n1976","loc":[-85.633941,41.943007]},"n1977":{"id":"n1977","loc":[-85.633887,41.943035]},"n1978":{"id":"n1978","loc":[-85.633768,41.942815]},"n1979":{"id":"n1979","loc":[-85.633682,41.942351]},"n198":{"id":"n198","loc":[-85.636514,41.942326]},"n1980":{"id":"n1980","loc":[-85.634037,41.942273]},"n1981":{"id":"n1981","loc":[-85.634029,41.942252]},"n1982":{"id":"n1982","loc":[-85.633673,41.942331]},"n1983":{"id":"n1983","loc":[-85.634219,41.942571]},"n1984":{"id":"n1984","loc":[-85.634252,41.942565]},"n1985":{"id":"n1985","loc":[-85.634144,41.942299]},"n1986":{"id":"n1986","loc":[-85.634115,41.942306]},"n1987":{"id":"n1987","loc":[-85.634059,41.943094]},"n1988":{"id":"n1988","loc":[-85.633944,41.942903]},"n1989":{"id":"n1989","loc":[-85.634311,41.942821]},"n199":{"id":"n199","loc":[-85.636561,41.942326]},"n1990":{"id":"n1990","loc":[-85.634351,41.94277]},"n1991":{"id":"n1991","loc":[-85.634153,41.942254]},"n1992":{"id":"n1992","loc":[-85.634092,41.94222]},"n1993":{"id":"n1993","loc":[-85.633571,41.942336]},"n1994":{"id":"n1994","loc":[-85.633513,41.942387]},"n1995":{"id":"n1995","loc":[-85.633509,41.942455]},"n1996":{"id":"n1996","loc":[-85.63363,41.942665]},"n1997":{"id":"n1997","loc":[-85.63414,41.94286]},"n1998":{"id":"n1998","loc":[-85.63397,41.942449]},"n1999":{"id":"n1999","loc":[-85.633551,41.942529]},"n2":{"id":"n2","loc":[-85.627421,41.953877]},"n20":{"id":"n20","loc":[-85.633013,41.941438]},"n200":{"id":"n200","loc":[-85.636561,41.942311]},"n2000":{"id":"n2000","loc":[-85.633741,41.942493]},"n2001":{"id":"n2001","loc":[-85.633894,41.942869]},"n2002":{"id":"n2002","loc":[-85.634132,41.941954]},"n2003":{"id":"n2003","loc":[-85.634032,41.942038]},"n2004":{"id":"n2004","loc":[-85.633765,41.942238]},"n2005":{"id":"n2005","loc":[-85.63376,41.942268]},"n2006":{"id":"n2006","loc":[-85.633768,41.942293]},"n2007":{"id":"n2007","loc":[-85.633808,41.942386]},"n2008":{"id":"n2008","loc":[-85.634946,41.941663]},"n2009":{"id":"n2009","loc":[-85.63511,41.941697]},"n201":{"id":"n201","loc":[-85.636621,41.942311]},"n2010":{"id":"n2010","loc":[-85.635337,41.94168]},"n2011":{"id":"n2011","loc":[-85.634997,41.942251]},"n2012":{"id":"n2012","loc":[-85.635013,41.942173]},"n2013":{"id":"n2013","loc":[-85.634876,41.942157]},"n2014":{"id":"n2014","loc":[-85.634859,41.942235]},"n2015":{"id":"n2015","loc":[-85.634992,41.941951]},"n2016":{"id":"n2016","loc":[-85.634952,41.941877]},"n2017":{"id":"n2017","loc":[-85.634844,41.94191]},"n2018":{"id":"n2018","loc":[-85.634884,41.941983]},"n2019":{"id":"n2019","loc":[-85.635189,41.941691]},"n202":{"id":"n202","loc":[-85.636621,41.942351]},"n2020":{"id":"n2020","loc":[-85.635089,41.941896]},"n2021":{"id":"n2021","loc":[-85.635077,41.941964]},"n2022":{"id":"n2022","loc":[-85.635058,41.942147]},"n2023":{"id":"n2023","loc":[-85.635099,41.942161]},"n2024":{"id":"n2024","loc":[-85.635099,41.942213]},"n2025":{"id":"n2025","loc":[-85.635079,41.942285]},"n2026":{"id":"n2026","loc":[-85.635047,41.942316]},"n2027":{"id":"n2027","loc":[-85.634925,41.9423]},"n2028":{"id":"n2028","loc":[-85.634911,41.942276]},"n2029":{"id":"n2029","loc":[-85.634917,41.942242]},"n203":{"id":"n203","loc":[-85.63666,41.942351]},"n2030":{"id":"n2030","loc":[-85.634698,41.941898]},"n2031":{"id":"n2031","loc":[-85.634964,41.941878]},"n2032":{"id":"n2032","loc":[-85.635025,41.941929]},"n2033":{"id":"n2033","loc":[-85.634862,41.941887]},"n2034":{"id":"n2034","loc":[-85.634811,41.94181]},"n2035":{"id":"n2035","loc":[-85.634731,41.941745]},"n2036":{"id":"n2036","loc":[-85.634933,41.94176]},"n2037":{"id":"n2037","loc":[-85.634942,41.942145]},"n2038":{"id":"n2038","loc":[-85.634944,41.942065]},"n2039":{"id":"n2039","loc":[-85.634914,41.941996]},"n204":{"id":"n204","loc":[-85.63666,41.942453]},"n2040":{"id":"n2040","loc":[-85.634981,41.941979]},"n2041":{"id":"n2041","loc":[-85.633419,41.942172]},"n2042":{"id":"n2042","loc":[-85.633509,41.941631]},"n2043":{"id":"n2043","loc":[-85.633686,41.942937]},"n2044":{"id":"n2044","loc":[-85.633371,41.942722]},"n2045":{"id":"n2045","loc":[-85.633291,41.942538]},"n2046":{"id":"n2046","loc":[-85.633902,41.940941]},"n2047":{"id":"n2047","loc":[-85.635254,41.940939]},"n2048":{"id":"n2048","loc":[-85.635686,41.940829]},"n2049":{"id":"n2049","loc":[-85.635712,41.942681]},"n205":{"id":"n205","loc":[-85.636645,41.942453]},"n2050":{"id":"n2050","loc":[-85.633721,41.942118]},"n2051":{"id":"n2051","loc":[-85.633698,41.942057]},"n2052":{"id":"n2052","loc":[-85.633591,41.942079]},"n2053":{"id":"n2053","loc":[-85.633614,41.94214]},"n2054":{"id":"n2054","loc":[-85.633968,41.941099]},"n2055":{"id":"n2055","loc":[-85.633907,41.941138]},"n2056":{"id":"n2056","loc":[-85.633968,41.941197]},"n2057":{"id":"n2057","loc":[-85.63404,41.941162]},"n2058":{"id":"n2058","loc":[-85.634839,41.941665]},"n2059":{"id":"n2059","loc":[-85.635314,41.943035]},"n206":{"id":"n206","loc":[-85.636394,41.942471]},"n2060":{"id":"n2060","loc":[-85.634919,41.943142]},"n2061":{"id":"n2061","loc":[-85.636433,41.942959],"tags":{"addr:city":"Three Rivers","addr:housenumber":"333","addr:postcode":"49093","addr:state":"MI","addr:street":"Michigan Avenue","amenity":"townhall","name":"Three Rivers City Hall"}},"n2062":{"id":"n2062","loc":[-85.637039,41.942789]},"n2063":{"id":"n2063","loc":[-85.636333,41.94279]},"n2064":{"id":"n2064","loc":[-85.634484,41.940726]},"n2065":{"id":"n2065","loc":[-85.634483,41.940603]},"n2066":{"id":"n2066","loc":[-85.634908,41.940601]},"n2067":{"id":"n2067","loc":[-85.634908,41.94053]},"n2068":{"id":"n2068","loc":[-85.634934,41.94053]},"n2069":{"id":"n2069","loc":[-85.634934,41.940496]},"n207":{"id":"n207","loc":[-85.636262,41.942472]},"n2070":{"id":"n2070","loc":[-85.63504,41.940495]},"n2071":{"id":"n2071","loc":[-85.63504,41.940531]},"n2072":{"id":"n2072","loc":[-85.635068,41.940531]},"n2073":{"id":"n2073","loc":[-85.635071,41.940794]},"n2074":{"id":"n2074","loc":[-85.635183,41.940793]},"n2075":{"id":"n2075","loc":[-85.635185,41.940916]},"n2076":{"id":"n2076","loc":[-85.634799,41.940919]},"n2077":{"id":"n2077","loc":[-85.634798,41.940798]},"n2078":{"id":"n2078","loc":[-85.634925,41.940797]},"n2079":{"id":"n2079","loc":[-85.634924,41.940724]},"n208":{"id":"n208","loc":[-85.636261,41.94233]},"n2080":{"id":"n2080","loc":[-85.637448,41.938233]},"n2081":{"id":"n2081","loc":[-85.634168,41.943279]},"n2082":{"id":"n2082","loc":[-85.635744,41.938248]},"n2083":{"id":"n2083","loc":[-85.638744,41.951211]},"n2084":{"id":"n2084","loc":[-85.636421,41.946392]},"n2085":{"id":"n2085","loc":[-85.635965,41.945809]},"n2086":{"id":"n2086","loc":[-85.635683,41.945449]},"n2087":{"id":"n2087","loc":[-85.635281,41.945025]},"n2088":{"id":"n2088","loc":[-85.632443,41.942574]},"n2089":{"id":"n2089","loc":[-85.638243,41.943674]},"n209":{"id":"n209","loc":[-85.636353,41.942329]},"n2090":{"id":"n2090","loc":[-85.638228,41.943747]},"n2091":{"id":"n2091","loc":[-85.638163,41.943797]},"n2092":{"id":"n2092","loc":[-85.638089,41.943832]},"n2093":{"id":"n2093","loc":[-85.637969,41.943841]},"n2094":{"id":"n2094","loc":[-85.637841,41.943833]},"n2095":{"id":"n2095","loc":[-85.637342,41.943734]},"n2096":{"id":"n2096","loc":[-85.637232,41.943707]},"n2097":{"id":"n2097","loc":[-85.637163,41.943668]},"n2098":{"id":"n2098","loc":[-85.637118,41.943615]},"n2099":{"id":"n2099","loc":[-85.637078,41.943494]},"n21":{"id":"n21","loc":[-85.634126,41.942228]},"n210":{"id":"n210","loc":[-85.636354,41.94239]},"n2100":{"id":"n2100","loc":[-85.632903,41.998429],"tags":{"railway":"level_crossing"}},"n2101":{"id":"n2101","loc":[-85.633616,41.943581],"tags":{"railway":"level_crossing"}},"n2102":{"id":"n2102","loc":[-85.636943,41.947311]},"n2103":{"id":"n2103","loc":[-85.6376,41.94854]},"n2104":{"id":"n2104","loc":[-85.634565,41.93631]},"n2105":{"id":"n2105","loc":[-85.629597,41.942562]},"n2106":{"id":"n2106","loc":[-85.630821,41.943077]},"n2107":{"id":"n2107","loc":[-85.627473,41.940659]},"n2108":{"id":"n2108","loc":[-85.629708,41.942872]},"n2109":{"id":"n2109","loc":[-85.634093,41.935448]},"n211":{"id":"n211","loc":[-85.636393,41.94239]},"n2110":{"id":"n2110","loc":[-85.630413,41.94366]},"n2111":{"id":"n2111","loc":[-85.630488,41.942662]},"n2112":{"id":"n2112","loc":[-85.63361,41.936749]},"n2113":{"id":"n2113","loc":[-85.630038,41.941808]},"n2114":{"id":"n2114","loc":[-85.632016,41.942922]},"n2115":{"id":"n2115","loc":[-85.631525,41.944303]},"n2116":{"id":"n2116","loc":[-85.626862,41.94022]},"n2117":{"id":"n2117","loc":[-85.629673,41.94121]},"n2118":{"id":"n2118","loc":[-85.632752,41.943101]},"n2119":{"id":"n2119","loc":[-85.631147,41.943201]},"n212":{"id":"n212","loc":[-85.63444,41.943176]},"n2120":{"id":"n2120","loc":[-85.624974,41.940579]},"n2121":{"id":"n2121","loc":[-85.629518,41.941783]},"n2122":{"id":"n2122","loc":[-85.632349,41.942699]},"n2123":{"id":"n2123","loc":[-85.628418,41.940356]},"n2124":{"id":"n2124","loc":[-85.629147,41.94129]},"n2125":{"id":"n2125","loc":[-85.631111,41.943979]},"n2126":{"id":"n2126","loc":[-85.632087,41.940013]},"n2127":{"id":"n2127","loc":[-85.634469,41.935057]},"n2128":{"id":"n2128","loc":[-85.630097,41.943449]},"n2129":{"id":"n2129","loc":[-85.6331,41.937878]},"n213":{"id":"n213","loc":[-85.63375,41.942814]},"n2130":{"id":"n2130","loc":[-85.625274,41.941114]},"n2131":{"id":"n2131","loc":[-85.632632,41.941217]},"n2132":{"id":"n2132","loc":[-85.632739,41.941926]},"n2133":{"id":"n2133","loc":[-85.631647,41.94366]},"n2134":{"id":"n2134","loc":[-85.635059,41.935456]},"n2135":{"id":"n2135","loc":[-85.631259,41.944349]},"n2136":{"id":"n2136","loc":[-85.626336,41.940811]},"n2137":{"id":"n2137","loc":[-85.631507,41.943875]},"n2138":{"id":"n2138","loc":[-85.625081,41.940859]},"n2139":{"id":"n2139","loc":[-85.625778,41.940093]},"n214":{"id":"n214","loc":[-85.633674,41.942869]},"n2140":{"id":"n2140","loc":[-85.632641,41.942436]},"n2141":{"id":"n2141","loc":[-85.628825,41.941034]},"n2142":{"id":"n2142","loc":[-85.627913,41.940292]},"n2143":{"id":"n2143","loc":[-85.628943,41.940516]},"n2144":{"id":"n2144","loc":[-85.63139,41.943941]},"n2145":{"id":"n2145","loc":[-85.630081,41.94204]},"n2146":{"id":"n2146","loc":[-85.632194,41.93963]},"n2147":{"id":"n2147","loc":[-85.632913,41.93939]},"n2148":{"id":"n2148","loc":[-85.632001,41.943492]},"n2149":{"id":"n2149","loc":[-85.63149,41.943154]},"n215":{"id":"n215","loc":[-85.633542,41.942768]},"n2150":{"id":"n2150","loc":[-85.625167,41.940117]},"n2151":{"id":"n2151","loc":[-85.63287,41.939941]},"n2152":{"id":"n2152","loc":[-85.630789,41.943732]},"n2153":{"id":"n2153","loc":[-85.632173,41.940348]},"n2154":{"id":"n2154","loc":[-85.626587,41.940113]},"n2155":{"id":"n2155","loc":[-85.62684,41.940667]},"n2156":{"id":"n2156","loc":[-85.632527,41.938904]},"n2157":{"id":"n2157","loc":[-85.624866,41.94018]},"n2158":{"id":"n2158","loc":[-85.633267,41.93872]},"n2159":{"id":"n2159","loc":[-85.62934,41.940843]},"n216":{"id":"n216","loc":[-85.633618,41.942714]},"n2160":{"id":"n2160","loc":[-85.62272,41.953817]},"n2161":{"id":"n2161","loc":[-85.622555,41.954453]},"n2162":{"id":"n2162","loc":[-85.637225,41.944128]},"n2163":{"id":"n2163","loc":[-85.622628,41.953683]},"n2164":{"id":"n2164","loc":[-85.635441,41.943989]},"n2165":{"id":"n2165","loc":[-85.622629,41.953807]},"n2166":{"id":"n2166","loc":[-85.62262,41.953807]},"n2167":{"id":"n2167","loc":[-85.62262,41.953837]},"n2168":{"id":"n2168","loc":[-85.622532,41.953838]},"n2169":{"id":"n2169","loc":[-85.637469,41.944579]},"n217":{"id":"n217","loc":[-85.634001,41.942336]},"n2170":{"id":"n2170","loc":[-85.63688,41.943935]},"n2171":{"id":"n2171","loc":[-85.638263,41.946367]},"n2172":{"id":"n2172","loc":[-85.622532,41.953807]},"n2173":{"id":"n2173","loc":[-85.622353,41.953808]},"n2174":{"id":"n2174","loc":[-85.622352,41.953685]},"n2175":{"id":"n2175","loc":[-85.622464,41.953684]},"n2176":{"id":"n2176","loc":[-85.622464,41.953648]},"n2177":{"id":"n2177","loc":[-85.637136,41.94576]},"n2178":{"id":"n2178","loc":[-85.622521,41.953648]},"n2179":{"id":"n2179","loc":[-85.637129,41.945415]},"n218":{"id":"n218","loc":[-85.633825,41.942376]},"n2180":{"id":"n2180","loc":[-85.637473,41.94607]},"n2181":{"id":"n2181","loc":[-85.622521,41.953683]},"n2182":{"id":"n2182","loc":[-85.622717,41.954104]},"n2183":{"id":"n2183","loc":[-85.637769,41.946095]},"n2184":{"id":"n2184","loc":[-85.623872,41.953515]},"n2185":{"id":"n2185","loc":[-85.623851,41.953588]},"n2186":{"id":"n2186","loc":[-85.631385,41.94433]},"n2187":{"id":"n2187","loc":[-85.623608,41.953543]},"n2188":{"id":"n2188","loc":[-85.637308,41.944882]},"n2189":{"id":"n2189","loc":[-85.634898,41.944041]},"n219":{"id":"n219","loc":[-85.633807,41.942334]},"n2190":{"id":"n2190","loc":[-85.623604,41.953442]},"n2191":{"id":"n2191","loc":[-85.623705,41.953442]},"n2192":{"id":"n2192","loc":[-85.623708,41.953493]},"n2193":{"id":"n2193","loc":[-85.624064,41.952655]},"n2194":{"id":"n2194","loc":[-85.62395,41.952654]},"n2195":{"id":"n2195","loc":[-85.623951,41.952579]},"n2196":{"id":"n2196","loc":[-85.637435,41.944342]},"n2197":{"id":"n2197","loc":[-85.624064,41.952579]},"n2198":{"id":"n2198","loc":[-85.623812,41.952648]},"n2199":{"id":"n2199","loc":[-85.623813,41.952705]},"n22":{"id":"n22","loc":[-85.633531,41.942357]},"n220":{"id":"n220","loc":[-85.633983,41.942294]},"n2200":{"id":"n2200","loc":[-85.637169,41.945098]},"n2201":{"id":"n2201","loc":[-85.623552,41.952707]},"n2202":{"id":"n2202","loc":[-85.623551,41.95263]},"n2203":{"id":"n2203","loc":[-85.623701,41.952629]},"n2204":{"id":"n2204","loc":[-85.635894,41.943719]},"n2205":{"id":"n2205","loc":[-85.637297,41.945992]},"n2206":{"id":"n2206","loc":[-85.623724,41.952648]},"n2207":{"id":"n2207","loc":[-85.623812,41.952438]},"n2208":{"id":"n2208","loc":[-85.625239,41.952197]},"n2209":{"id":"n2209","loc":[-85.625232,41.952257]},"n221":{"id":"n221","loc":[-85.634182,41.942495]},"n2210":{"id":"n2210","loc":[-85.635175,41.94408]},"n2211":{"id":"n2211","loc":[-85.636381,41.943761]},"n2212":{"id":"n2212","loc":[-85.625115,41.952249]},"n2213":{"id":"n2213","loc":[-85.638578,41.946644]},"n2214":{"id":"n2214","loc":[-85.625122,41.952189]},"n2215":{"id":"n2215","loc":[-85.625085,41.952031]},"n2216":{"id":"n2216","loc":[-85.636126,41.943713]},"n2217":{"id":"n2217","loc":[-85.635005,41.944041]},"n2218":{"id":"n2218","loc":[-85.63714,41.945328]},"n2219":{"id":"n2219","loc":[-85.634871,41.943292]},"n222":{"id":"n222","loc":[-85.634149,41.942503]},"n2220":{"id":"n2220","loc":[-85.635705,41.943799]},"n2221":{"id":"n2221","loc":[-85.634995,41.943576]},"n2222":{"id":"n2222","loc":[-85.635026,41.943829]},"n2223":{"id":"n2223","loc":[-85.632874,41.941031]},"n2224":{"id":"n2224","loc":[-85.632531,41.940233]},"n2225":{"id":"n2225","loc":[-85.634247,41.936003]},"n2226":{"id":"n2226","loc":[-85.62929,41.941127]},"n2227":{"id":"n2227","loc":[-85.630428,41.943266]},"n2228":{"id":"n2228","loc":[-85.631608,41.943425]},"n2229":{"id":"n2229","loc":[-85.632316,41.943042]},"n223":{"id":"n223","loc":[-85.634098,41.942373]},"n2230":{"id":"n2230","loc":[-85.628711,41.940744]},"n2231":{"id":"n2231","loc":[-85.627831,41.940536]},"n2232":{"id":"n2232","loc":[-85.625514,41.94052]},"n2233":{"id":"n2233","loc":[-85.631127,41.943545]},"n2234":{"id":"n2234","loc":[-85.632909,41.942531]},"n2235":{"id":"n2235","loc":[-85.632917,41.938796]},"n2236":{"id":"n2236","loc":[-85.626716,41.94044]},"n2237":{"id":"n2237","loc":[-85.630122,41.942852]},"n2238":{"id":"n2238","loc":[-85.632509,41.939674]},"n2239":{"id":"n2239","loc":[-85.634762,41.935237]},"n224":{"id":"n224","loc":[-85.634131,41.942366]},"n2240":{"id":"n2240","loc":[-85.63384,41.937025]},"n2241":{"id":"n2241","loc":[-85.629741,41.941909]},"n2242":{"id":"n2242","loc":[-85.635254,41.945001],"tags":{"railway":"level_crossing"}},"n2243":{"id":"n2243","loc":[-85.634005,41.938168]},"n2244":{"id":"n2244","loc":[-85.63393,41.938335]},"n2245":{"id":"n2245","loc":[-85.633859,41.93846]},"n2246":{"id":"n2246","loc":[-85.633663,41.938776]},"n2247":{"id":"n2247","loc":[-85.633513,41.938936]},"n2248":{"id":"n2248","loc":[-85.635295,41.943225]},"n2249":{"id":"n2249","loc":[-85.635393,41.943293]},"n225":{"id":"n225","loc":[-85.635986,41.94177]},"n2250":{"id":"n2250","loc":[-85.635645,41.94332]},"n2251":{"id":"n2251","loc":[-85.63629,41.943328]},"n2252":{"id":"n2252","loc":[-85.636554,41.943372]},"n2253":{"id":"n2253","loc":[-85.636869,41.943526]},"n2254":{"id":"n2254","loc":[-85.637099,41.943704]},"n2255":{"id":"n2255","loc":[-85.637268,41.943773]},"n2256":{"id":"n2256","loc":[-85.637483,41.943821]},"n2257":{"id":"n2257","loc":[-85.637616,41.943929]},"n2258":{"id":"n2258","loc":[-85.637752,41.944114]},"n2259":{"id":"n2259","loc":[-85.638399,41.944308]},"n226":{"id":"n226","loc":[-85.635982,41.941523]},"n2260":{"id":"n2260","loc":[-85.638573,41.944451]},"n2261":{"id":"n2261","loc":[-85.638702,41.944574]},"n2262":{"id":"n2262","loc":[-85.638718,41.944652]},"n2263":{"id":"n2263","loc":[-85.638715,41.944809]},"n2264":{"id":"n2264","loc":[-85.638766,41.944988]},"n2265":{"id":"n2265","loc":[-85.638773,41.945136]},"n2266":{"id":"n2266","loc":[-85.638705,41.945251]},"n2267":{"id":"n2267","loc":[-85.638335,41.944291]},"n2268":{"id":"n2268","loc":[-85.638474,41.944352]},"n2269":{"id":"n2269","loc":[-85.635408,41.943429]},"n227":{"id":"n227","loc":[-85.636108,41.941521]},"n2270":{"id":"n2270","loc":[-85.635271,41.943654]},"n2271":{"id":"n2271","loc":[-85.635266,41.943744]},"n2272":{"id":"n2272","loc":[-85.635271,41.943819]},"n2273":{"id":"n2273","loc":[-85.635192,41.943876]},"n2274":{"id":"n2274","loc":[-85.635129,41.943857]},"n2275":{"id":"n2275","loc":[-85.635122,41.943764]},"n2276":{"id":"n2276","loc":[-85.635124,41.943664]},"n2277":{"id":"n2277","loc":[-85.63515,41.943611]},"n2278":{"id":"n2278","loc":[-85.635106,41.943534]},"n2279":{"id":"n2279","loc":[-85.634972,41.943197]},"n228":{"id":"n228","loc":[-85.636109,41.941559]},"n2280":{"id":"n2280","loc":[-85.633978,41.938227]},"n2281":{"id":"n2281","loc":[-85.634216,41.943255]},"n2282":{"id":"n2282","loc":[-85.634434,41.943622]},"n2283":{"id":"n2283","loc":[-85.632406,41.940854]},"n2284":{"id":"n2284","loc":[-85.632488,41.941063],"tags":{"leisure":"slipway"}},"n2285":{"id":"n2285","loc":[-85.632726,41.941537]},"n2286":{"id":"n2286","loc":[-85.632639,41.94136]},"n2287":{"id":"n2287","loc":[-85.632704,41.941439]},"n2288":{"id":"n2288","loc":[-85.632289,41.940601]},"n2289":{"id":"n2289","loc":[-85.632541,41.942526]},"n229":{"id":"n229","loc":[-85.636145,41.941559]},"n2290":{"id":"n2290","loc":[-85.634058,41.943173]},"n2291":{"id":"n2291","loc":[-85.636175,41.945974]},"n2292":{"id":"n2292","loc":[-85.636528,41.945975]},"n2293":{"id":"n2293","loc":[-85.637092,41.945893]},"n2294":{"id":"n2294","loc":[-85.637881,41.945647]},"n2295":{"id":"n2295","loc":[-85.639329,41.945162]},"n2296":{"id":"n2296","loc":[-85.639323,41.945026]},"n2297":{"id":"n2297","loc":[-85.638826,41.945032]},"n2298":{"id":"n2298","loc":[-85.638817,41.944174]},"n2299":{"id":"n2299","loc":[-85.638291,41.94418]},"n23":{"id":"n23","loc":[-85.633504,41.942418]},"n230":{"id":"n230","loc":[-85.636145,41.941551]},"n2300":{"id":"n2300","loc":[-85.63828,41.943811]},"n2301":{"id":"n2301","loc":[-85.638195,41.943601]},"n2302":{"id":"n2302","loc":[-85.63719,41.943592]},"n2303":{"id":"n2303","loc":[-85.636697,41.943273]},"n2304":{"id":"n2304","loc":[-85.635375,41.943274]},"n2305":{"id":"n2305","loc":[-85.635091,41.943547]},"n2306":{"id":"n2306","loc":[-85.63442,41.944117]},"n2307":{"id":"n2307","loc":[-85.635117,41.943717]},"n2308":{"id":"n2308","loc":[-85.635601,41.945177]},"n2309":{"id":"n2309","loc":[-85.635819,41.945494]},"n231":{"id":"n231","loc":[-85.636312,41.941549]},"n2310":{"id":"n2310","loc":[-85.635303,41.944891]},"n2311":{"id":"n2311","loc":[-85.637674,41.943802]},"n2312":{"id":"n2312","loc":[-85.638263,41.944272]},"n2313":{"id":"n2313","loc":[-85.634267,41.935266]},"n2314":{"id":"n2314","loc":[-85.639788,41.945152]},"n2315":{"id":"n2315","loc":[-85.639645,41.945167]},"n2316":{"id":"n2316","loc":[-85.639362,41.945233]},"n2317":{"id":"n2317","loc":[-85.638616,41.945163]},"n2318":{"id":"n2318","loc":[-85.638514,41.944936]},"n2319":{"id":"n2319","loc":[-85.638578,41.94503]},"n232":{"id":"n232","loc":[-85.636314,41.941649]},"n2320":{"id":"n2320","loc":[-85.638578,41.945215]},"n2321":{"id":"n2321","loc":[-85.640495,41.947015]},"n2322":{"id":"n2322","loc":[-85.639577,41.946495]},"n2323":{"id":"n2323","loc":[-85.638935,41.946087]},"n2324":{"id":"n2324","loc":[-85.637535,41.94584]},"n2325":{"id":"n2325","loc":[-85.638357,41.945404]},"n2326":{"id":"n2326","loc":[-85.638051,41.94553]},"n2327":{"id":"n2327","loc":[-85.637732,41.945555]},"n2328":{"id":"n2328","loc":[-85.637657,41.945524]},"n2329":{"id":"n2329","loc":[-85.637598,41.945467]},"n233":{"id":"n233","loc":[-85.636152,41.94165]},"n2330":{"id":"n2330","loc":[-85.637669,41.945318]},"n2331":{"id":"n2331","loc":[-85.637894,41.945171]},"n2332":{"id":"n2332","loc":[-85.637923,41.945082]},"n2333":{"id":"n2333","loc":[-85.63793,41.944756]},"n2334":{"id":"n2334","loc":[-85.637976,41.944696]},"n2335":{"id":"n2335","loc":[-85.638044,41.944671]},"n2336":{"id":"n2336","loc":[-85.638129,41.944597]},"n2337":{"id":"n2337","loc":[-85.638252,41.944413]},"n2338":{"id":"n2338","loc":[-85.638092,41.945442]},"n2339":{"id":"n2339","loc":[-85.638409,41.945315]},"n234":{"id":"n234","loc":[-85.636152,41.941628]},"n2340":{"id":"n2340","loc":[-85.638325,41.944771]},"n2341":{"id":"n2341","loc":[-85.638103,41.944744]},"n2342":{"id":"n2342","loc":[-85.637976,41.944781]},"n2343":{"id":"n2343","loc":[-85.637983,41.944865]},"n2344":{"id":"n2344","loc":[-85.638063,41.945074]},"n2345":{"id":"n2345","loc":[-85.638041,41.945206]},"n2346":{"id":"n2346","loc":[-85.637907,41.945309]},"n2347":{"id":"n2347","loc":[-85.637925,41.94539]},"n2348":{"id":"n2348","loc":[-85.637998,41.94545]},"n2349":{"id":"n2349","loc":[-85.637135,41.946254]},"n235":{"id":"n235","loc":[-85.63611,41.941628]},"n2350":{"id":"n2350","loc":[-85.636837,41.946615]},"n2351":{"id":"n2351","loc":[-85.637954,41.948909]},"n2352":{"id":"n2352","loc":[-85.638382,41.949786]},"n2353":{"id":"n2353","loc":[-85.639367,41.951242]},"n2354":{"id":"n2354","loc":[-85.640554,41.951777]},"n2355":{"id":"n2355","loc":[-85.6411,41.952234]},"n2356":{"id":"n2356","loc":[-85.641742,41.952657]},"n2357":{"id":"n2357","loc":[-85.642321,41.952941]},"n2358":{"id":"n2358","loc":[-85.64277,41.953228]},"n2359":{"id":"n2359","loc":[-85.643333,41.953825]},"n236":{"id":"n236","loc":[-85.636113,41.941768]},"n2360":{"id":"n2360","loc":[-85.643579,41.954365]},"n2361":{"id":"n2361","loc":[-85.644439,41.954105]},"n2362":{"id":"n2362","loc":[-85.64506,41.954]},"n2363":{"id":"n2363","loc":[-85.645483,41.953911]},"n2364":{"id":"n2364","loc":[-85.646046,41.953853]},"n2365":{"id":"n2365","loc":[-85.646318,41.953717]},"n2366":{"id":"n2366","loc":[-85.646276,41.953414]},"n2367":{"id":"n2367","loc":[-85.631063,41.957478],"tags":{"emergency":"fire_hydrant"}},"n2368":{"id":"n2368","loc":[-85.630996,41.955857],"tags":{"emergency":"fire_hydrant"}},"n2369":{"id":"n2369","loc":[-85.630976,41.954608],"tags":{"emergency":"fire_hydrant"}},"n237":{"id":"n237","loc":[-85.635983,41.941589],"tags":{"entrance":"yes"}},"n2370":{"id":"n2370","loc":[-85.646,41.953154]},"n2371":{"id":"n2371","loc":[-85.645222,41.953193]},"n2372":{"id":"n2372","loc":[-85.644732,41.953181]},"n2373":{"id":"n2373","loc":[-85.644064,41.953298]},"n2374":{"id":"n2374","loc":[-85.643818,41.953177]},"n2375":{"id":"n2375","loc":[-85.644001,41.95284]},"n2376":{"id":"n2376","loc":[-85.628174,41.95456],"tags":{"emergency":"fire_hydrant"}},"n2377":{"id":"n2377","loc":[-85.644267,41.952591]},"n2378":{"id":"n2378","loc":[-85.644288,41.952328]},"n2379":{"id":"n2379","loc":[-85.627276,41.953987],"tags":{"emergency":"fire_hydrant"}},"n238":{"id":"n238","loc":[-85.635906,41.94159]},"n2380":{"id":"n2380","loc":[-85.644262,41.952153]},"n2381":{"id":"n2381","loc":[-85.644168,41.95204]},"n2382":{"id":"n2382","loc":[-85.64421,41.951749]},"n2383":{"id":"n2383","loc":[-85.64385,41.951586]},"n2384":{"id":"n2384","loc":[-85.62736,41.955964],"tags":{"emergency":"fire_hydrant"}},"n2385":{"id":"n2385","loc":[-85.626307,41.957198],"tags":{"emergency":"fire_hydrant"}},"n2386":{"id":"n2386","loc":[-85.643589,41.951323]},"n2387":{"id":"n2387","loc":[-85.62747,41.957509],"tags":{"emergency":"fire_hydrant"}},"n2388":{"id":"n2388","loc":[-85.628665,41.957492],"tags":{"emergency":"fire_hydrant"}},"n2389":{"id":"n2389","loc":[-85.642535,41.951031]},"n239":{"id":"n239","loc":[-85.635883,41.940182]},"n2390":{"id":"n2390","loc":[-85.642269,41.95088]},"n2391":{"id":"n2391","loc":[-85.641878,41.950814]},"n2392":{"id":"n2392","loc":[-85.641549,41.950806]},"n2393":{"id":"n2393","loc":[-85.641103,41.950549]},"n2394":{"id":"n2394","loc":[-85.630864,41.959046],"tags":{"emergency":"fire_hydrant"}},"n2395":{"id":"n2395","loc":[-85.632249,41.958969],"tags":{"emergency":"fire_hydrant"}},"n2396":{"id":"n2396","loc":[-85.641037,41.949821]},"n2397":{"id":"n2397","loc":[-85.641006,41.949433]},"n2398":{"id":"n2398","loc":[-85.632232,41.95859],"tags":{"emergency":"fire_hydrant"}},"n2399":{"id":"n2399","loc":[-85.632071,41.958345],"tags":{"emergency":"fire_hydrant"}},"n24":{"id":"n24","loc":[-85.634346,41.942792]},"n240":{"id":"n240","loc":[-85.635916,41.94264]},"n2400":{"id":"n2400","loc":[-85.632228,41.9573],"tags":{"emergency":"fire_hydrant"}},"n2401":{"id":"n2401","loc":[-85.641152,41.948257]},"n2402":{"id":"n2402","loc":[-85.641055,41.947304]},"n2403":{"id":"n2403","loc":[-85.638022,41.945897]},"n2404":{"id":"n2404","loc":[-85.638672,41.950778]},"n2405":{"id":"n2405","loc":[-85.63666,41.944492],"tags":{"name":"Memory Isle","place":"island"}},"n2406":{"id":"n2406","loc":[-85.635,41.946389],"tags":{"amenity":"post_office","name":"Three Rivers Post Office"}},"n2407":{"id":"n2407","loc":[-85.633676,41.946036]},"n2408":{"id":"n2408","loc":[-85.633736,41.946078]},"n2409":{"id":"n2409","loc":[-85.633997,41.946185]},"n241":{"id":"n241","loc":[-85.635795,41.941906]},"n2410":{"id":"n2410","loc":[-85.634448,41.945626],"tags":{"highway":"traffic_signals","traffic_signals":"signal"}},"n2411":{"id":"n2411","loc":[-85.63456,41.945731],"tags":{"crossing":"zebra","highway":"crossing"}},"n2412":{"id":"n2412","loc":[-85.634592,41.94578]},"n2413":{"id":"n2413","loc":[-85.634607,41.945815]},"n2414":{"id":"n2414","loc":[-85.634614,41.945864]},"n2415":{"id":"n2415","loc":[-85.636066,41.946185]},"n2416":{"id":"n2416","loc":[-85.636128,41.946352]},"n2417":{"id":"n2417","loc":[-85.636142,41.946452]},"n2418":{"id":"n2418","loc":[-85.635327,41.945292]},"n2419":{"id":"n2419","loc":[-85.635648,41.94558]},"n242":{"id":"n242","loc":[-85.635909,41.941906]},"n2420":{"id":"n2420","loc":[-85.635769,41.945729]},"n2421":{"id":"n2421","loc":[-85.637349,41.945897]},"n2422":{"id":"n2422","loc":[-85.632211,41.95596],"tags":{"emergency":"fire_hydrant"}},"n2423":{"id":"n2423","loc":[-85.635942,41.94598]},"n2424":{"id":"n2424","loc":[-85.636443,41.946042]},"n2425":{"id":"n2425","loc":[-85.635819,41.946052]},"n2426":{"id":"n2426","loc":[-85.636669,41.946025]},"n2427":{"id":"n2427","loc":[-85.636832,41.946005]},"n2428":{"id":"n2428","loc":[-85.637039,41.945968]},"n2429":{"id":"n2429","loc":[-85.636291,41.946046]},"n243":{"id":"n243","loc":[-85.636359,41.941904]},"n2430":{"id":"n2430","loc":[-85.634005,41.943367]},"n2431":{"id":"n2431","loc":[-85.633366,41.943724]},"n2432":{"id":"n2432","loc":[-85.634617,41.946057]},"n2433":{"id":"n2433","loc":[-85.636534,41.944793]},"n2434":{"id":"n2434","loc":[-85.637055,41.945188]},"n2435":{"id":"n2435","loc":[-85.636153,41.944618]},"n2436":{"id":"n2436","loc":[-85.636803,41.944944]},"n2437":{"id":"n2437","loc":[-85.633389,41.945735]},"n2438":{"id":"n2438","loc":[-85.633536,41.94585]},"n2439":{"id":"n2439","loc":[-85.63363,41.945993]},"n244":{"id":"n244","loc":[-85.636351,41.941438]},"n2440":{"id":"n2440","loc":[-85.633268,41.94568]},"n2441":{"id":"n2441","loc":[-85.635947,41.94546]},"n2442":{"id":"n2442","loc":[-85.636277,41.945268]},"n2443":{"id":"n2443","loc":[-85.635203,41.944287]},"n2444":{"id":"n2444","loc":[-85.634876,41.944477]},"n2445":{"id":"n2445","loc":[-85.634975,41.944419]},"n2446":{"id":"n2446","loc":[-85.633877,41.943438]},"n2447":{"id":"n2447","loc":[-85.63508,41.945113]},"n2448":{"id":"n2448","loc":[-85.635372,41.944932]},"n2449":{"id":"n2449","loc":[-85.636594,41.945935]},"n245":{"id":"n245","loc":[-85.635903,41.941436]},"n2450":{"id":"n2450","loc":[-85.636901,41.945747]},"n2451":{"id":"n2451","loc":[-85.636329,41.945228]},"n2452":{"id":"n2452","loc":[-85.636025,41.945417]},"n2453":{"id":"n2453","loc":[-85.634002,41.944644]},"n2454":{"id":"n2454","loc":[-85.63407,41.944692]},"n2455":{"id":"n2455","loc":[-85.634114,41.944756]},"n2456":{"id":"n2456","loc":[-85.633762,41.944809]},"n2457":{"id":"n2457","loc":[-85.634184,41.944807]},"n2458":{"id":"n2458","loc":[-85.634291,41.944819]},"n2459":{"id":"n2459","loc":[-85.634639,41.944845]},"n246":{"id":"n246","loc":[-85.635788,41.941436]},"n2460":{"id":"n2460","loc":[-85.633822,41.944861]},"n2461":{"id":"n2461","loc":[-85.63411,41.944855]},"n2462":{"id":"n2462","loc":[-85.63435,41.944872]},"n2463":{"id":"n2463","loc":[-85.63441,41.944903]},"n2464":{"id":"n2464","loc":[-85.633883,41.944913]},"n2465":{"id":"n2465","loc":[-85.634164,41.944896]},"n2466":{"id":"n2466","loc":[-85.633487,41.944926]},"n2467":{"id":"n2467","loc":[-85.634736,41.944929]},"n2468":{"id":"n2468","loc":[-85.633944,41.944965]},"n2469":{"id":"n2469","loc":[-85.633555,41.944983]},"n247":{"id":"n247","loc":[-85.635929,41.941511]},"n2470":{"id":"n2470","loc":[-85.633995,41.945013]},"n2471":{"id":"n2471","loc":[-85.633614,41.945037]},"n2472":{"id":"n2472","loc":[-85.634848,41.945031]},"n2473":{"id":"n2473","loc":[-85.634049,41.945061]},"n2474":{"id":"n2474","loc":[-85.633678,41.945094]},"n2475":{"id":"n2475","loc":[-85.63317,41.945111]},"n2476":{"id":"n2476","loc":[-85.633357,41.945103]},"n2477":{"id":"n2477","loc":[-85.633728,41.945136]},"n2478":{"id":"n2478","loc":[-85.634146,41.945148]},"n2479":{"id":"n2479","loc":[-85.633416,41.945157]},"n248":{"id":"n248","loc":[-85.635929,41.941317]},"n2480":{"id":"n2480","loc":[-85.634625,41.945172]},"n2481":{"id":"n2481","loc":[-85.633239,41.945174]},"n2482":{"id":"n2482","loc":[-85.63469,41.945185]},"n2483":{"id":"n2483","loc":[-85.634661,41.945203]},"n2484":{"id":"n2484","loc":[-85.63348,41.945214]},"n2485":{"id":"n2485","loc":[-85.633578,41.945221]},"n2486":{"id":"n2486","loc":[-85.634742,41.945231]},"n2487":{"id":"n2487","loc":[-85.634251,41.94525]},"n2488":{"id":"n2488","loc":[-85.633524,41.945254]},"n2489":{"id":"n2489","loc":[-85.63468,41.945271]},"n249":{"id":"n249","loc":[-85.636414,41.941316]},"n2490":{"id":"n2490","loc":[-85.633885,41.945272]},"n2491":{"id":"n2491","loc":[-85.634795,41.945288]},"n2492":{"id":"n2492","loc":[-85.634742,41.94532]},"n2493":{"id":"n2493","loc":[-85.633946,41.945327]},"n2494":{"id":"n2494","loc":[-85.634844,41.945331]},"n2495":{"id":"n2495","loc":[-85.63435,41.945349]},"n2496":{"id":"n2496","loc":[-85.633733,41.945357]},"n2497":{"id":"n2497","loc":[-85.633987,41.945375]},"n2498":{"id":"n2498","loc":[-85.634911,41.945419]},"n2499":{"id":"n2499","loc":[-85.634049,41.945431]},"n25":{"id":"n25","loc":[-85.634333,41.942809]},"n250":{"id":"n250","loc":[-85.636414,41.941511]},"n2500":{"id":"n2500","loc":[-85.633705,41.945461]},"n2501":{"id":"n2501","loc":[-85.633642,41.945408]},"n2502":{"id":"n2502","loc":[-85.634493,41.945475]},"n2503":{"id":"n2503","loc":[-85.634106,41.945484]},"n2504":{"id":"n2504","loc":[-85.635008,41.945505]},"n2505":{"id":"n2505","loc":[-85.633757,41.945506]},"n2506":{"id":"n2506","loc":[-85.634542,41.945519]},"n2507":{"id":"n2507","loc":[-85.634162,41.945536]},"n2508":{"id":"n2508","loc":[-85.633843,41.945547]},"n2509":{"id":"n2509","loc":[-85.634919,41.94556]},"n251":{"id":"n251","loc":[-85.636819,41.941617]},"n2510":{"id":"n2510","loc":[-85.633818,41.945561]},"n2511":{"id":"n2511","loc":[-85.634638,41.94559]},"n2512":{"id":"n2512","loc":[-85.633901,41.945598]},"n2513":{"id":"n2513","loc":[-85.634257,41.945626]},"n2514":{"id":"n2514","loc":[-85.633967,41.945652]},"n2515":{"id":"n2515","loc":[-85.634735,41.945676]},"n2516":{"id":"n2516","loc":[-85.635057,41.945683]},"n2517":{"id":"n2517","loc":[-85.635296,41.945703]},"n2518":{"id":"n2518","loc":[-85.635112,41.945703]},"n2519":{"id":"n2519","loc":[-85.634782,41.945729]},"n252":{"id":"n252","loc":[-85.636718,41.941619]},"n2520":{"id":"n2520","loc":[-85.634052,41.945747]},"n2521":{"id":"n2521","loc":[-85.635296,41.945757]},"n2522":{"id":"n2522","loc":[-85.635314,41.945757]},"n2523":{"id":"n2523","loc":[-85.635112,41.945761]},"n2524":{"id":"n2524","loc":[-85.63484,41.945778]},"n2525":{"id":"n2525","loc":[-85.635314,41.945938]},"n2526":{"id":"n2526","loc":[-85.63484,41.945922]},"n2527":{"id":"n2527","loc":[-85.635461,41.944879]},"n2528":{"id":"n2528","loc":[-85.636024,41.945384]},"n2529":{"id":"n2529","loc":[-85.636145,41.945312]},"n253":{"id":"n253","loc":[-85.636716,41.941509]},"n2530":{"id":"n2530","loc":[-85.6356,41.944797]},"n2531":{"id":"n2531","loc":[-85.635135,41.944354]},"n2532":{"id":"n2532","loc":[-85.632988,41.945369]},"n2533":{"id":"n2533","loc":[-85.633376,41.94563]},"n2534":{"id":"n2534","loc":[-85.633539,41.945534]},"n2535":{"id":"n2535","loc":[-85.633238,41.945248]},"n2536":{"id":"n2536","loc":[-85.633166,41.945216]},"n2537":{"id":"n2537","loc":[-85.633114,41.945188]},"n2538":{"id":"n2538","loc":[-85.633078,41.945127]},"n2539":{"id":"n2539","loc":[-85.633066,41.94508]},"n254":{"id":"n254","loc":[-85.636732,41.941509]},"n2540":{"id":"n2540","loc":[-85.633222,41.945358]},"n2541":{"id":"n2541","loc":[-85.633425,41.945541]},"n2542":{"id":"n2542","loc":[-85.63299,41.9455]},"n2543":{"id":"n2543","loc":[-85.634374,41.944327]},"n2544":{"id":"n2544","loc":[-85.633648,41.943697]},"n2545":{"id":"n2545","loc":[-85.633533,41.943764]},"n2546":{"id":"n2546","loc":[-85.634239,41.944417]},"n2547":{"id":"n2547","loc":[-85.634122,41.944395]},"n2548":{"id":"n2548","loc":[-85.634235,41.944326]},"n2549":{"id":"n2549","loc":[-85.633613,41.943787]},"n255":{"id":"n255","loc":[-85.636731,41.941461]},"n2550":{"id":"n2550","loc":[-85.633915,41.943613]},"n2551":{"id":"n2551","loc":[-85.634015,41.943555]},"n2552":{"id":"n2552","loc":[-85.63433,41.943839]},"n2553":{"id":"n2553","loc":[-85.634236,41.943894]},"n2554":{"id":"n2554","loc":[-85.635413,41.946052]},"n2555":{"id":"n2555","loc":[-85.635405,41.94569]},"n2556":{"id":"n2556","loc":[-85.635684,41.945925]},"n2557":{"id":"n2557","loc":[-85.635614,41.945742]},"n2558":{"id":"n2558","loc":[-85.635401,41.945745]},"n2559":{"id":"n2559","loc":[-85.635406,41.945928]},"n256":{"id":"n256","loc":[-85.636799,41.941461]},"n2560":{"id":"n2560","loc":[-85.633478,41.943663]},"n2561":{"id":"n2561","loc":[-85.633291,41.943526]},"n2562":{"id":"n2562","loc":[-85.633094,41.943541]},"n2563":{"id":"n2563","loc":[-85.633302,41.943492]},"n2564":{"id":"n2564","loc":[-85.633047,41.943623]},"n2565":{"id":"n2565","loc":[-85.633275,41.943562]},"n2566":{"id":"n2566","loc":[-85.633351,41.943518]},"n2567":{"id":"n2567","loc":[-85.633224,41.9434]},"n2568":{"id":"n2568","loc":[-85.633235,41.943369]},"n2569":{"id":"n2569","loc":[-85.635179,41.943911]},"n257":{"id":"n257","loc":[-85.6368,41.9415]},"n2570":{"id":"n2570","loc":[-85.635146,41.943918]},"n2571":{"id":"n2571","loc":[-85.634888,41.943905]},"n2572":{"id":"n2572","loc":[-85.634832,41.943911]},"n2573":{"id":"n2573","loc":[-85.634638,41.944007]},"n2574":{"id":"n2574","loc":[-85.634568,41.94405]},"n2575":{"id":"n2575","loc":[-85.635994,41.94501]},"n2576":{"id":"n2576","loc":[-85.636388,41.944608]},"n2577":{"id":"n2577","loc":[-85.636215,41.944787]},"n2578":{"id":"n2578","loc":[-85.637948,41.944587]},"n2579":{"id":"n2579","loc":[-85.637849,41.944567]},"n258":{"id":"n258","loc":[-85.636814,41.9415]},"n2580":{"id":"n2580","loc":[-85.637895,41.944455]},"n2581":{"id":"n2581","loc":[-85.637996,41.944477]},"n2582":{"id":"n2582","loc":[-85.635525,41.94337]},"n2583":{"id":"n2583","loc":[-85.637847,41.943923]},"n2584":{"id":"n2584","loc":[-85.637891,41.944124]},"n2585":{"id":"n2585","loc":[-85.638167,41.944229]},"n2586":{"id":"n2586","loc":[-85.638236,41.944097]},"n2587":{"id":"n2587","loc":[-85.638207,41.944025]},"n2588":{"id":"n2588","loc":[-85.638141,41.943997]},"n2589":{"id":"n2589","loc":[-85.638057,41.944015]},"n259":{"id":"n259","loc":[-85.636815,41.941538]},"n2590":{"id":"n2590","loc":[-85.637902,41.944231]},"n2591":{"id":"n2591","loc":[-85.638134,41.944307]},"n2592":{"id":"n2592","loc":[-85.638242,41.944294]},"n2593":{"id":"n2593","loc":[-85.638274,41.944222]},"n2594":{"id":"n2594","loc":[-85.638236,41.944174]},"n2595":{"id":"n2595","loc":[-85.638207,41.944157]},"n2596":{"id":"n2596","loc":[-85.637818,41.943984]},"n2597":{"id":"n2597","loc":[-85.634996,41.944439]},"n2598":{"id":"n2598","loc":[-85.633946,41.945804]},"n2599":{"id":"n2599","loc":[-85.634102,41.945864]},"n26":{"id":"n26","loc":[-85.634346,41.942744]},"n260":{"id":"n260","loc":[-85.636827,41.941538]},"n2600":{"id":"n2600","loc":[-85.633819,41.945756]},"n2601":{"id":"n2601","loc":[-85.634025,41.945975]},"n2602":{"id":"n2602","loc":[-85.633742,41.945867]},"n2603":{"id":"n2603","loc":[-85.63373,41.946004]},"n2604":{"id":"n2604","loc":[-85.633947,41.946081]},"n2605":{"id":"n2605","loc":[-85.633872,41.945917]},"n2606":{"id":"n2606","loc":[-85.633825,41.945985]},"n2607":{"id":"n2607","loc":[-85.633762,41.94596]},"n2608":{"id":"n2608","loc":[-85.634224,41.946037]},"n2609":{"id":"n2609","loc":[-85.634357,41.945851]},"n261":{"id":"n261","loc":[-85.636828,41.941584]},"n2610":{"id":"n2610","loc":[-85.634398,41.945813]},"n2611":{"id":"n2611","loc":[-85.634461,41.945812]},"n2612":{"id":"n2612","loc":[-85.634501,41.945852]},"n2613":{"id":"n2613","loc":[-85.634503,41.94597]},"n2614":{"id":"n2614","loc":[-85.634462,41.945971]},"n2615":{"id":"n2615","loc":[-85.634465,41.946036]},"n2616":{"id":"n2616","loc":[-85.634235,41.946072]},"n2617":{"id":"n2617","loc":[-85.634447,41.946036]},"n2618":{"id":"n2618","loc":[-85.634448,41.946052]},"n2619":{"id":"n2619","loc":[-85.634494,41.946051]},"n262":{"id":"n262","loc":[-85.636819,41.941585]},"n2620":{"id":"n2620","loc":[-85.634497,41.946144]},"n2621":{"id":"n2621","loc":[-85.634453,41.946144]},"n2622":{"id":"n2622","loc":[-85.634454,41.94616]},"n2623":{"id":"n2623","loc":[-85.634393,41.946161]},"n2624":{"id":"n2624","loc":[-85.634394,41.94618]},"n2625":{"id":"n2625","loc":[-85.634345,41.94618]},"n2626":{"id":"n2626","loc":[-85.634344,41.946162]},"n2627":{"id":"n2627","loc":[-85.63427,41.946163]},"n2628":{"id":"n2628","loc":[-85.634266,41.946071]},"n2629":{"id":"n2629","loc":[-85.634148,41.946163]},"n263":{"id":"n263","loc":[-85.636854,41.941714]},"n2630":{"id":"n2630","loc":[-85.634213,41.946072]},"n2631":{"id":"n2631","loc":[-85.633293,41.946309]},"n2632":{"id":"n2632","loc":[-85.633122,41.946239]},"n2633":{"id":"n2633","loc":[-85.633295,41.946005]},"n2634":{"id":"n2634","loc":[-85.633395,41.946047]},"n2635":{"id":"n2635","loc":[-85.633404,41.946035]},"n2636":{"id":"n2636","loc":[-85.633459,41.946057]},"n2637":{"id":"n2637","loc":[-85.633387,41.946154]},"n2638":{"id":"n2638","loc":[-85.633403,41.946161]},"n2639":{"id":"n2639","loc":[-85.634176,41.946415]},"n264":{"id":"n264","loc":[-85.636855,41.941774]},"n2640":{"id":"n2640","loc":[-85.634179,41.946339]},"n2641":{"id":"n2641","loc":[-85.634455,41.946345]},"n2642":{"id":"n2642","loc":[-85.634452,41.946422]},"n2643":{"id":"n2643","loc":[-85.63437,41.946421]},"n2644":{"id":"n2644","loc":[-85.634367,41.946497]},"n2645":{"id":"n2645","loc":[-85.634289,41.946495]},"n2646":{"id":"n2646","loc":[-85.634291,41.946448]},"n2647":{"id":"n2647","loc":[-85.634269,41.946448]},"n2648":{"id":"n2648","loc":[-85.63427,41.946417]},"n2649":{"id":"n2649","loc":[-85.63484,41.946328]},"n265":{"id":"n265","loc":[-85.636822,41.941774]},"n2650":{"id":"n2650","loc":[-85.634839,41.946187]},"n2651":{"id":"n2651","loc":[-85.635148,41.946186]},"n2652":{"id":"n2652","loc":[-85.635148,41.946216]},"n2653":{"id":"n2653","loc":[-85.63521,41.946216]},"n2654":{"id":"n2654","loc":[-85.63521,41.946348]},"n2655":{"id":"n2655","loc":[-85.635154,41.946348]},"n2656":{"id":"n2656","loc":[-85.635153,41.946327]},"n2657":{"id":"n2657","loc":[-85.634037,41.946957]},"n2658":{"id":"n2658","loc":[-85.634253,41.946953]},"n2659":{"id":"n2659","loc":[-85.63481,41.946543]},"n266":{"id":"n266","loc":[-85.636822,41.941778]},"n2660":{"id":"n2660","loc":[-85.634809,41.946459]},"n2661":{"id":"n2661","loc":[-85.635154,41.946458]},"n2662":{"id":"n2662","loc":[-85.635155,41.946554]},"n2663":{"id":"n2663","loc":[-85.635022,41.946547]},"n2664":{"id":"n2664","loc":[-85.635022,41.946573]},"n2665":{"id":"n2665","loc":[-85.634909,41.946574]},"n2666":{"id":"n2666","loc":[-85.634909,41.946561]},"n2667":{"id":"n2667","loc":[-85.634896,41.947159]},"n2668":{"id":"n2668","loc":[-85.634894,41.947032]},"n2669":{"id":"n2669","loc":[-85.635024,41.947031]},"n267":{"id":"n267","loc":[-85.636756,41.941779]},"n2670":{"id":"n2670","loc":[-85.635026,41.947158]},"n2671":{"id":"n2671","loc":[-85.635233,41.947105]},"n2672":{"id":"n2672","loc":[-85.635236,41.946991]},"n2673":{"id":"n2673","loc":[-85.635369,41.946993]},"n2674":{"id":"n2674","loc":[-85.635366,41.947107]},"n2675":{"id":"n2675","loc":[-85.634824,41.946929]},"n2676":{"id":"n2676","loc":[-85.634825,41.946818]},"n2677":{"id":"n2677","loc":[-85.63512,41.946819]},"n2678":{"id":"n2678","loc":[-85.635119,41.94693]},"n2679":{"id":"n2679","loc":[-85.634796,41.946806]},"n268":{"id":"n268","loc":[-85.636756,41.941774]},"n2680":{"id":"n2680","loc":[-85.634792,41.946604]},"n2681":{"id":"n2681","loc":[-85.634948,41.946602]},"n2682":{"id":"n2682","loc":[-85.634949,41.946645]},"n2683":{"id":"n2683","loc":[-85.634975,41.946644]},"n2684":{"id":"n2684","loc":[-85.634974,41.946599]},"n2685":{"id":"n2685","loc":[-85.635117,41.946598]},"n2686":{"id":"n2686","loc":[-85.635122,41.946801]},"n2687":{"id":"n2687","loc":[-85.634981,41.946803]},"n2688":{"id":"n2688","loc":[-85.634979,41.946752]},"n2689":{"id":"n2689","loc":[-85.634952,41.946752]},"n269":{"id":"n269","loc":[-85.636721,41.941774]},"n2690":{"id":"n2690","loc":[-85.634953,41.946804]},"n2691":{"id":"n2691","loc":[-85.634649,41.946841]},"n2692":{"id":"n2692","loc":[-85.634331,41.94684]},"n2693":{"id":"n2693","loc":[-85.634183,41.946809]},"n2694":{"id":"n2694","loc":[-85.633699,41.946607]},"n2695":{"id":"n2695","loc":[-85.634487,41.946664]},"n2696":{"id":"n2696","loc":[-85.634486,41.946598]},"n2697":{"id":"n2697","loc":[-85.63423,41.946599]},"n2698":{"id":"n2698","loc":[-85.634231,41.946662]},"n2699":{"id":"n2699","loc":[-85.634284,41.946662]},"n27":{"id":"n27","loc":[-85.634136,41.943183]},"n270":{"id":"n270","loc":[-85.63672,41.941714]},"n2700":{"id":"n2700","loc":[-85.634284,41.946679]},"n2701":{"id":"n2701","loc":[-85.634365,41.946679]},"n2702":{"id":"n2702","loc":[-85.634365,41.946664]},"n2703":{"id":"n2703","loc":[-85.635443,41.947015]},"n2704":{"id":"n2704","loc":[-85.635442,41.946801]},"n2705":{"id":"n2705","loc":[-85.63603,41.9468]},"n2706":{"id":"n2706","loc":[-85.636028,41.947016]},"n2707":{"id":"n2707","loc":[-85.635457,41.946582]},"n2708":{"id":"n2708","loc":[-85.635455,41.946211]},"n2709":{"id":"n2709","loc":[-85.635636,41.946579]},"n271":{"id":"n271","loc":[-85.636767,41.941713]},"n2710":{"id":"n2710","loc":[-85.635716,41.9468]},"n2711":{"id":"n2711","loc":[-85.635969,41.9468]},"n2712":{"id":"n2712","loc":[-85.635973,41.946295]},"n2713":{"id":"n2713","loc":[-85.636019,41.946484]},"n2714":{"id":"n2714","loc":[-85.636022,41.946388]},"n2715":{"id":"n2715","loc":[-85.635961,41.946493]},"n2716":{"id":"n2716","loc":[-85.635713,41.94621]},"n2717":{"id":"n2717","loc":[-85.635416,41.946142]},"n2718":{"id":"n2718","loc":[-85.635759,41.946203]},"n2719":{"id":"n2719","loc":[-85.636153,41.946747]},"n272":{"id":"n272","loc":[-85.636767,41.941706]},"n2720":{"id":"n2720","loc":[-85.635417,41.946915]},"n2721":{"id":"n2721","loc":[-85.636154,41.946915]},"n2722":{"id":"n2722","loc":[-85.635866,41.946473]},"n2723":{"id":"n2723","loc":[-85.635717,41.946633]},"n2724":{"id":"n2724","loc":[-85.635556,41.946166]},"n2725":{"id":"n2725","loc":[-85.63556,41.946556]},"n2726":{"id":"n2726","loc":[-85.635731,41.946594]},"n2727":{"id":"n2727","loc":[-85.635866,41.946595]},"n2728":{"id":"n2728","loc":[-85.635456,41.947028]},"n2729":{"id":"n2729","loc":[-85.635796,41.947023]},"n273":{"id":"n273","loc":[-85.636779,41.941698]},"n2730":{"id":"n2730","loc":[-85.635798,41.947091]},"n2731":{"id":"n2731","loc":[-85.63573,41.947092]},"n2732":{"id":"n2732","loc":[-85.635733,41.947233]},"n2733":{"id":"n2733","loc":[-85.636283,41.946863]},"n2734":{"id":"n2734","loc":[-85.63628,41.946706]},"n2735":{"id":"n2735","loc":[-85.636341,41.946705]},"n2736":{"id":"n2736","loc":[-85.636273,41.946584]},"n2737":{"id":"n2737","loc":[-85.636396,41.946545]},"n2738":{"id":"n2738","loc":[-85.636474,41.946684]},"n2739":{"id":"n2739","loc":[-85.636511,41.946861]},"n274":{"id":"n274","loc":[-85.636798,41.941697]},"n2740":{"id":"n2740","loc":[-85.633713,41.947184]},"n2741":{"id":"n2741","loc":[-85.633651,41.94716]},"n2742":{"id":"n2742","loc":[-85.633704,41.947085]},"n2743":{"id":"n2743","loc":[-85.6336,41.947044]},"n2744":{"id":"n2744","loc":[-85.633506,41.947177]},"n2745":{"id":"n2745","loc":[-85.629586,41.952469]},"n2746":{"id":"n2746","loc":[-85.634723,41.953681]},"n2747":{"id":"n2747","loc":[-85.63478,41.959007]},"n2748":{"id":"n2748","loc":[-85.632793,41.94405],"tags":{"highway":"traffic_signals","traffic_signals":"signal","traffic_signals:direction":"both"}},"n2749":{"id":"n2749","loc":[-85.634648,41.947325]},"n275":{"id":"n275","loc":[-85.63681,41.941705]},"n2750":{"id":"n2750","loc":[-85.625078,41.952097]},"n2751":{"id":"n2751","loc":[-85.633195,41.94734]},"n2752":{"id":"n2752","loc":[-85.626447,41.957168]},"n2753":{"id":"n2753","loc":[-85.632023,41.949012]},"n2754":{"id":"n2754","loc":[-85.630835,41.950656]},"n2755":{"id":"n2755","loc":[-85.634655,41.948612]},"n2756":{"id":"n2756","loc":[-85.636182,41.948605]},"n2757":{"id":"n2757","loc":[-85.634729,41.954667]},"n2758":{"id":"n2758","loc":[-85.634686,41.951159]},"n2759":{"id":"n2759","loc":[-85.636206,41.951146]},"n276":{"id":"n276","loc":[-85.63681,41.941714]},"n2760":{"id":"n2760","loc":[-85.634668,41.949891]},"n2761":{"id":"n2761","loc":[-85.634701,41.952422]},"n2762":{"id":"n2762","loc":[-85.634747,41.955907]},"n2763":{"id":"n2763","loc":[-85.627975,41.954695]},"n2764":{"id":"n2764","loc":[-85.626832,41.954698]},"n2765":{"id":"n2765","loc":[-85.632278,41.948624]},"n2766":{"id":"n2766","loc":[-85.628639,41.953725]},"n2767":{"id":"n2767","loc":[-85.636233,41.95241]},"n2768":{"id":"n2768","loc":[-85.631385,41.949913]},"n2769":{"id":"n2769","loc":[-85.630486,41.951194]},"n277":{"id":"n277","loc":[-85.636861,41.942041]},"n2770":{"id":"n2770","loc":[-85.624937,41.952088]},"n2771":{"id":"n2771","loc":[-85.624945,41.952022]},"n2772":{"id":"n2772","loc":[-85.636162,41.94731]},"n2773":{"id":"n2773","loc":[-85.636188,41.949881]},"n2774":{"id":"n2774","loc":[-85.631422,41.948294]},"n2775":{"id":"n2775","loc":[-85.632844,41.945547]},"n2776":{"id":"n2776","loc":[-85.632484,41.945344]},"n2777":{"id":"n2777","loc":[-85.631775,41.944636]},"n2778":{"id":"n2778","loc":[-85.632656,41.945471]},"n2779":{"id":"n2779","loc":[-85.631959,41.944827]},"n278":{"id":"n278","loc":[-85.636862,41.942099]},"n2780":{"id":"n2780","loc":[-85.631679,41.94438]},"n2781":{"id":"n2781","loc":[-85.625129,41.959272]},"n2782":{"id":"n2782","loc":[-85.632446,41.944861]},"n2783":{"id":"n2783","loc":[-85.632804,41.945477]},"n2784":{"id":"n2784","loc":[-85.632255,41.944962]},"n2785":{"id":"n2785","loc":[-85.632736,41.944757]},"n2786":{"id":"n2786","loc":[-85.632543,41.94486]},"n2787":{"id":"n2787","loc":[-85.632889,41.945561]},"n2788":{"id":"n2788","loc":[-85.632091,41.944949]},"n2789":{"id":"n2789","loc":[-85.632537,41.944713]},"n279":{"id":"n279","loc":[-85.636807,41.942099]},"n2790":{"id":"n2790","loc":[-85.632279,41.94485]},"n2791":{"id":"n2791","loc":[-85.632749,41.943247]},"n2792":{"id":"n2792","loc":[-85.632824,41.943152]},"n2793":{"id":"n2793","loc":[-85.632929,41.94317]},"n2794":{"id":"n2794","loc":[-85.632897,41.943078]},"n2795":{"id":"n2795","loc":[-85.632626,41.943231]},"n2796":{"id":"n2796","loc":[-85.634048,41.947257]},"n2797":{"id":"n2797","loc":[-85.634264,41.947252]},"n2798":{"id":"n2798","loc":[-85.635418,41.947317]},"n2799":{"id":"n2799","loc":[-85.635461,41.947237]},"n28":{"id":"n28","loc":[-85.63821,41.944308]},"n280":{"id":"n280","loc":[-85.636807,41.942126]},"n2800":{"id":"n2800","loc":[-85.632868,41.946229]},"n2801":{"id":"n2801","loc":[-85.633673,41.947242]},"n2802":{"id":"n2802","loc":[-85.623604,41.945881],"tags":{"amenity":"school","name":"Barrows School"}},"n2803":{"id":"n2803","loc":[-85.627401,41.943496]},"n2804":{"id":"n2804","loc":[-85.627403,41.943625]},"n2805":{"id":"n2805","loc":[-85.626409,41.943215]},"n2806":{"id":"n2806","loc":[-85.624884,41.943508]},"n2807":{"id":"n2807","loc":[-85.625191,41.943509]},"n2808":{"id":"n2808","loc":[-85.624882,41.94382]},"n2809":{"id":"n2809","loc":[-85.624893,41.945618]},"n281":{"id":"n281","loc":[-85.636726,41.942126]},"n2810":{"id":"n2810","loc":[-85.624912,41.946524]},"n2811":{"id":"n2811","loc":[-85.622721,41.946535]},"n2812":{"id":"n2812","loc":[-85.627399,41.94469]},"n2813":{"id":"n2813","loc":[-85.622716,41.945622]},"n2814":{"id":"n2814","loc":[-85.624886,41.944724]},"n2815":{"id":"n2815","loc":[-85.622674,41.944737]},"n2816":{"id":"n2816","loc":[-85.625092,41.945063]},"n2817":{"id":"n2817","loc":[-85.625233,41.945064]},"n2818":{"id":"n2818","loc":[-85.625229,41.944871]},"n2819":{"id":"n2819","loc":[-85.625066,41.944871]},"n282":{"id":"n282","loc":[-85.636726,41.942098]},"n2820":{"id":"n2820","loc":[-85.625024,41.944901]},"n2821":{"id":"n2821","loc":[-85.625025,41.944924]},"n2822":{"id":"n2822","loc":[-85.625087,41.944926]},"n2823":{"id":"n2823","loc":[-85.625349,41.944506]},"n2824":{"id":"n2824","loc":[-85.625347,41.944388]},"n2825":{"id":"n2825","loc":[-85.625152,41.94439]},"n2826":{"id":"n2826","loc":[-85.625152,41.944431]},"n2827":{"id":"n2827","loc":[-85.625134,41.944431]},"n2828":{"id":"n2828","loc":[-85.625136,41.944508]},"n2829":{"id":"n2829","loc":[-85.623236,41.946341]},"n283":{"id":"n283","loc":[-85.636708,41.942098]},"n2830":{"id":"n2830","loc":[-85.623241,41.946067]},"n2831":{"id":"n2831","loc":[-85.623207,41.946067]},"n2832":{"id":"n2832","loc":[-85.623212,41.945827]},"n2833":{"id":"n2833","loc":[-85.622981,41.945825]},"n2834":{"id":"n2834","loc":[-85.622976,41.946063]},"n2835":{"id":"n2835","loc":[-85.623006,41.946063]},"n2836":{"id":"n2836","loc":[-85.623002,41.946256]},"n2837":{"id":"n2837","loc":[-85.623075,41.946256]},"n2838":{"id":"n2838","loc":[-85.623074,41.946339]},"n2839":{"id":"n2839","loc":[-85.624574,41.951755]},"n284":{"id":"n284","loc":[-85.636708,41.942041]},"n2840":{"id":"n2840","loc":[-85.62498,41.951844]},"n2841":{"id":"n2841","loc":[-85.625086,41.95188]},"n2842":{"id":"n2842","loc":[-85.625135,41.951922]},"n2843":{"id":"n2843","loc":[-85.615273,41.945637]},"n2844":{"id":"n2844","loc":[-85.620172,41.945627]},"n2845":{"id":"n2845","loc":[-85.625167,41.951985]},"n2846":{"id":"n2846","loc":[-85.622741,41.947437]},"n2847":{"id":"n2847","loc":[-85.624907,41.947428]},"n2848":{"id":"n2848","loc":[-85.627046,41.940995]},"n2849":{"id":"n2849","loc":[-85.627295,41.941304]},"n285":{"id":"n285","loc":[-85.635618,41.941852]},"n2850":{"id":"n2850","loc":[-85.627352,41.94148]},"n2851":{"id":"n2851","loc":[-85.62737,41.942261]},"n2852":{"id":"n2852","loc":[-85.6264,41.942263]},"n2853":{"id":"n2853","loc":[-85.622769,41.949228]},"n2854":{"id":"n2854","loc":[-85.624937,41.949218]},"n2855":{"id":"n2855","loc":[-85.630001,41.944664]},"n2856":{"id":"n2856","loc":[-85.624873,41.942022]},"n2857":{"id":"n2857","loc":[-85.622761,41.948333]},"n2858":{"id":"n2858","loc":[-85.624924,41.948334]},"n2859":{"id":"n2859","loc":[-85.620051,41.94383]},"n286":{"id":"n286","loc":[-85.635621,41.94202]},"n2860":{"id":"n2860","loc":[-85.627629,41.946498]},"n2861":{"id":"n2861","loc":[-85.622757,41.950111]},"n2862":{"id":"n2862","loc":[-85.623685,41.954624]},"n2863":{"id":"n2863","loc":[-85.621459,41.944756]},"n2864":{"id":"n2864","loc":[-85.628637,41.944676]},"n2865":{"id":"n2865","loc":[-85.630125,41.944654]},"n2866":{"id":"n2866","loc":[-85.625196,41.952097]},"n2867":{"id":"n2867","loc":[-85.630257,41.944637]},"n2868":{"id":"n2868","loc":[-85.631247,41.944459]},"n2869":{"id":"n2869","loc":[-85.624867,41.94159]},"n287":{"id":"n287","loc":[-85.63524,41.942023]},"n2870":{"id":"n2870","loc":[-85.624958,41.950343]},"n2871":{"id":"n2871","loc":[-85.624948,41.950484]},"n2872":{"id":"n2872","loc":[-85.624813,41.950983]},"n2873":{"id":"n2873","loc":[-85.624723,41.951789]},"n2874":{"id":"n2874","loc":[-85.624262,41.9512]},"n2875":{"id":"n2875","loc":[-85.62414,41.951201]},"n2876":{"id":"n2876","loc":[-85.624139,41.95112]},"n2877":{"id":"n2877","loc":[-85.628481,41.945611]},"n2878":{"id":"n2878","loc":[-85.620072,41.946538]},"n2879":{"id":"n2879","loc":[-85.622763,41.95099]},"n288":{"id":"n288","loc":[-85.635237,41.941855]},"n2880":{"id":"n2880","loc":[-85.62814,41.946963]},"n2881":{"id":"n2881","loc":[-85.628245,41.947031]},"n2882":{"id":"n2882","loc":[-85.628331,41.947066]},"n2883":{"id":"n2883","loc":[-85.629722,41.944444],"tags":{"leisure":"park","name":"Scouter Park"}},"n2884":{"id":"n2884","loc":[-85.629977,41.943907]},"n2885":{"id":"n2885","loc":[-85.629947,41.943775]},"n2886":{"id":"n2886","loc":[-85.629899,41.943625]},"n2887":{"id":"n2887","loc":[-85.632286,41.944257]},"n2888":{"id":"n2888","loc":[-85.632523,41.944179]},"n2889":{"id":"n2889","loc":[-85.632141,41.944293]},"n289":{"id":"n289","loc":[-85.635568,41.940475]},"n2890":{"id":"n2890","loc":[-85.631571,41.9444]},"n2891":{"id":"n2891","loc":[-85.643236,41.941895]},"n2892":{"id":"n2892","loc":[-85.62865,41.945353]},"n2893":{"id":"n2893","loc":[-85.628594,41.945481]},"n2894":{"id":"n2894","loc":[-85.628581,41.947169]},"n2895":{"id":"n2895","loc":[-85.631843,41.943793]},"n2896":{"id":"n2896","loc":[-85.632299,41.943472]},"n2897":{"id":"n2897","loc":[-85.631519,41.944881]},"n2898":{"id":"n2898","loc":[-85.628429,41.947219]},"n2899":{"id":"n2899","loc":[-85.63145,41.945162]},"n29":{"id":"n29","loc":[-85.637963,41.944263]},"n290":{"id":"n290","loc":[-85.634584,41.940477]},"n2900":{"id":"n2900","loc":[-85.630939,41.945519]},"n2901":{"id":"n2901","loc":[-85.62903,41.945719]},"n2902":{"id":"n2902","loc":[-85.630521,41.945559]},"n2903":{"id":"n2903","loc":[-85.629294,41.945585]},"n2904":{"id":"n2904","loc":[-85.629845,41.945543]},"n2905":{"id":"n2905","loc":[-85.631497,41.944625]},"n2906":{"id":"n2906","loc":[-85.630281,41.945553]},"n2907":{"id":"n2907","loc":[-85.628553,41.946973]},"n2908":{"id":"n2908","loc":[-85.631383,41.945338]},"n2909":{"id":"n2909","loc":[-85.628843,41.946103]},"n291":{"id":"n291","loc":[-85.634583,41.940203]},"n2910":{"id":"n2910","loc":[-85.631193,41.945473]},"n2911":{"id":"n2911","loc":[-85.628897,41.945944]},"n2912":{"id":"n2912","loc":[-85.628789,41.946454]},"n2913":{"id":"n2913","loc":[-85.632548,41.944563]},"n2914":{"id":"n2914","loc":[-85.627527,41.944555]},"n2915":{"id":"n2915","loc":[-85.62752,41.943726]},"n2916":{"id":"n2916","loc":[-85.627894,41.943723]},"n2917":{"id":"n2917","loc":[-85.627897,41.943919]},"n2918":{"id":"n2918","loc":[-85.627991,41.943934]},"n2919":{"id":"n2919","loc":[-85.628082,41.943966]},"n292":{"id":"n292","loc":[-85.635567,41.940201]},"n2920":{"id":"n2920","loc":[-85.628177,41.944015]},"n2921":{"id":"n2921","loc":[-85.628193,41.944048]},"n2922":{"id":"n2922","loc":[-85.628167,41.944054]},"n2923":{"id":"n2923","loc":[-85.628193,41.944094]},"n2924":{"id":"n2924","loc":[-85.628213,41.944144]},"n2925":{"id":"n2925","loc":[-85.628214,41.944199]},"n2926":{"id":"n2926","loc":[-85.62833,41.944196]},"n2927":{"id":"n2927","loc":[-85.628328,41.944262]},"n2928":{"id":"n2928","loc":[-85.628173,41.944262]},"n2929":{"id":"n2929","loc":[-85.628171,41.944293]},"n293":{"id":"n293","loc":[-85.635816,41.942673],"tags":{"crossing":"zebra","highway":"crossing"}},"n2930":{"id":"n2930","loc":[-85.628039,41.944296]},"n2931":{"id":"n2931","loc":[-85.62804,41.944329]},"n2932":{"id":"n2932","loc":[-85.627829,41.944335]},"n2933":{"id":"n2933","loc":[-85.627835,41.94455]},"n2936":{"id":"n2936","loc":[-85.632823,41.945994]},"n294":{"id":"n294","loc":[-85.635696,41.942712]},"n2940":{"id":"n2940","loc":[-85.632192,41.945973]},"n2941":{"id":"n2941","loc":[-85.63226,41.94587]},"n2942":{"id":"n2942","loc":[-85.632721,41.946036]},"n2943":{"id":"n2943","loc":[-85.632641,41.946142]},"n2944":{"id":"n2944","loc":[-85.62937,41.947467]},"n2945":{"id":"n2945","loc":[-85.62959,41.942936]},"n2946":{"id":"n2946","loc":[-85.629551,41.94284]},"n2947":{"id":"n2947","loc":[-85.629501,41.942704]},"n2948":{"id":"n2948","loc":[-85.629472,41.942578]},"n2949":{"id":"n2949","loc":[-85.629361,41.941801]},"n295":{"id":"n295","loc":[-85.635679,41.941962]},"n2950":{"id":"n2950","loc":[-85.629339,41.941716]},"n2951":{"id":"n2951","loc":[-85.629315,41.94166]},"n2952":{"id":"n2952","loc":[-85.629279,41.941602]},"n2953":{"id":"n2953","loc":[-85.629227,41.941556]},"n2954":{"id":"n2954","loc":[-85.624261,41.95112]},"n2955":{"id":"n2955","loc":[-85.629153,41.941524]},"n2956":{"id":"n2956","loc":[-85.626904,41.941098]},"n2957":{"id":"n2957","loc":[-85.624588,41.951294]},"n2958":{"id":"n2958","loc":[-85.631844,41.942945]},"n2959":{"id":"n2959","loc":[-85.625854,41.949222]},"n296":{"id":"n296","loc":[-85.635672,41.941337]},"n2960":{"id":"n2960","loc":[-85.625146,41.955238]},"n2961":{"id":"n2961","loc":[-85.626745,41.948296]},"n2962":{"id":"n2962","loc":[-85.625721,41.95524]},"n2963":{"id":"n2963","loc":[-85.624706,41.952317]},"n2964":{"id":"n2964","loc":[-85.62609,41.956147]},"n2965":{"id":"n2965","loc":[-85.624401,41.954928]},"n2966":{"id":"n2966","loc":[-85.626558,41.955367]},"n2967":{"id":"n2967","loc":[-85.62468,41.955096]},"n2968":{"id":"n2968","loc":[-85.624159,41.953929]},"n2969":{"id":"n2969","loc":[-85.62506,41.951113]},"n297":{"id":"n297","loc":[-85.635658,41.941284]},"n2970":{"id":"n2970","loc":[-85.624942,41.951591]},"n2971":{"id":"n2971","loc":[-85.627399,41.947546]},"n2972":{"id":"n2972","loc":[-85.627695,41.947404]},"n2973":{"id":"n2973","loc":[-85.625925,41.94896]},"n2974":{"id":"n2974","loc":[-85.625725,41.950211]},"n2975":{"id":"n2975","loc":[-85.627008,41.947963]},"n2976":{"id":"n2976","loc":[-85.624373,41.953458]},"n2977":{"id":"n2977","loc":[-85.624137,41.954392]},"n2978":{"id":"n2978","loc":[-85.628257,41.947307]},"n2979":{"id":"n2979","loc":[-85.625281,41.95066]},"n298":{"id":"n298","loc":[-85.635602,41.941166]},"n2980":{"id":"n2980","loc":[-85.625865,41.949804]},"n2981":{"id":"n2981","loc":[-85.626508,41.955932]},"n2982":{"id":"n2982","loc":[-85.626333,41.955216]},"n2983":{"id":"n2983","loc":[-85.626637,41.955676]},"n2984":{"id":"n2984","loc":[-85.624223,41.954599]},"n2985":{"id":"n2985","loc":[-85.626219,41.948671]},"n2986":{"id":"n2986","loc":[-85.624556,41.953043]},"n2987":{"id":"n2987","loc":[-85.625598,41.956302]},"n2988":{"id":"n2988","loc":[-85.624571,41.952971]},"n2989":{"id":"n2989","loc":[-85.627141,41.940727]},"n299":{"id":"n299","loc":[-85.635598,41.941138]},"n2990":{"id":"n2990","loc":[-85.627102,41.939144]},"n2991":{"id":"n2991","loc":[-85.627127,41.940086]},"n2992":{"id":"n2992","loc":[-85.627116,41.940843]},"n2993":{"id":"n2993","loc":[-85.627132,41.9402]},"n2994":{"id":"n2994","loc":[-85.629734,41.940078]},"n2995":{"id":"n2995","loc":[-85.6276,41.937412]},"n2996":{"id":"n2996","loc":[-85.627451,41.937549]},"n2997":{"id":"n2997","loc":[-85.627375,41.937618]},"n2998":{"id":"n2998","loc":[-85.627278,41.937728]},"n2999":{"id":"n2999","loc":[-85.627199,41.937842]},"n3":{"id":"n3","loc":[-85.627345,41.953983]},"n30":{"id":"n30","loc":[-85.637882,41.944205]},"n300":{"id":"n300","loc":[-85.635614,41.941076]},"n3000":{"id":"n3000","loc":[-85.627141,41.937981]},"n3001":{"id":"n3001","loc":[-85.627109,41.938153]},"n3002":{"id":"n3002","loc":[-85.627101,41.938699]},"n3003":{"id":"n3003","loc":[-85.628311,41.942261]},"n3004":{"id":"n3004","loc":[-85.628439,41.940082]},"n3005":{"id":"n3005","loc":[-85.619538,41.942622],"tags":{"leisure":"slipway"}},"n3006":{"id":"n3006","loc":[-85.619872,41.942618]},"n3007":{"id":"n3007","loc":[-85.619755,41.942612]},"n3008":{"id":"n3008","loc":[-85.619647,41.942628]},"n3009":{"id":"n3009","loc":[-85.619415,41.942626]},"n301":{"id":"n301","loc":[-85.635659,41.940956]},"n3010":{"id":"n3010","loc":[-85.619212,41.942623]},"n3011":{"id":"n3011","loc":[-85.631485,41.942472]},"n3012":{"id":"n3012","loc":[-85.630986,41.941786]},"n3013":{"id":"n3013","loc":[-85.631797,41.942006]},"n3014":{"id":"n3014","loc":[-85.630972,41.941162]},"n3015":{"id":"n3015","loc":[-85.631396,41.941611],"tags":{"railway":"level_crossing"}},"n3016":{"id":"n3016","loc":[-85.631878,41.941545]},"n3017":{"id":"n3017","loc":[-85.630461,41.94055]},"n3018":{"id":"n3018","loc":[-85.629751,41.939539],"tags":{"railway":"level_crossing"}},"n3019":{"id":"n3019","loc":[-85.631663,41.941513]},"n302":{"id":"n302","loc":[-85.635666,41.940922]},"n3020":{"id":"n3020","loc":[-85.631328,41.941375]},"n3021":{"id":"n3021","loc":[-85.632554,41.941779]},"n3022":{"id":"n3022","loc":[-85.63245,41.941769]},"n3023":{"id":"n3023","loc":[-85.632475,41.941644]},"n3024":{"id":"n3024","loc":[-85.632581,41.941654]},"n3025":{"id":"n3025","loc":[-85.631957,41.941352]},"n3026":{"id":"n3026","loc":[-85.632293,41.941139]},"n3027":{"id":"n3027","loc":[-85.632315,41.941153]},"n3028":{"id":"n3028","loc":[-85.632302,41.941262]},"n3029":{"id":"n3029","loc":[-85.63237,41.941267]},"n303":{"id":"n303","loc":[-85.635667,41.940877]},"n3030":{"id":"n3030","loc":[-85.632356,41.941538]},"n3031":{"id":"n3031","loc":[-85.632134,41.941678]},"n3032":{"id":"n3032","loc":[-85.631942,41.941687]},"n3033":{"id":"n3033","loc":[-85.63203,41.941694]},"n3034":{"id":"n3034","loc":[-85.632166,41.941555]},"n3035":{"id":"n3035","loc":[-85.632412,41.941416]},"n3036":{"id":"n3036","loc":[-85.63248,41.941342]},"n3037":{"id":"n3037","loc":[-85.632502,41.941259]},"n3038":{"id":"n3038","loc":[-85.632453,41.941161]},"n3039":{"id":"n3039","loc":[-85.63235,41.941103]},"n304":{"id":"n304","loc":[-85.635668,41.940655]},"n3040":{"id":"n3040","loc":[-85.632236,41.941118]},"n3041":{"id":"n3041","loc":[-85.631894,41.941355]},"n3042":{"id":"n3042","loc":[-85.631859,41.941411]},"n3043":{"id":"n3043","loc":[-85.632011,41.941587]},"n3044":{"id":"n3044","loc":[-85.632446,41.941379]},"n3045":{"id":"n3045","loc":[-85.632511,41.941416]},"n3046":{"id":"n3046","loc":[-85.632545,41.941634]},"n3047":{"id":"n3047","loc":[-85.632612,41.94164]},"n3048":{"id":"n3048","loc":[-85.632595,41.942197]},"n3049":{"id":"n3049","loc":[-85.632565,41.942241]},"n305":{"id":"n305","loc":[-85.635628,41.940617]},"n3050":{"id":"n3050","loc":[-85.632515,41.942256]},"n3051":{"id":"n3051","loc":[-85.63245,41.94223]},"n3052":{"id":"n3052","loc":[-85.632401,41.942174]},"n3053":{"id":"n3053","loc":[-85.632391,41.942115]},"n3054":{"id":"n3054","loc":[-85.632029,41.941859]},"n3055":{"id":"n3055","loc":[-85.631828,41.941639]},"n3056":{"id":"n3056","loc":[-85.631829,41.941508]},"n3057":{"id":"n3057","loc":[-85.631281,41.94312]},"n3058":{"id":"n3058","loc":[-85.631421,41.943065]},"n3059":{"id":"n3059","loc":[-85.631339,41.942949]},"n306":{"id":"n306","loc":[-85.635623,41.940272]},"n3060":{"id":"n3060","loc":[-85.631199,41.943004]},"n3061":{"id":"n3061","loc":[-85.631102,41.942931]},"n3062":{"id":"n3062","loc":[-85.631009,41.942809]},"n3063":{"id":"n3063","loc":[-85.631383,41.94265]},"n3064":{"id":"n3064","loc":[-85.631477,41.942773]},"n3065":{"id":"n3065","loc":[-85.630638,41.942809]},"n3066":{"id":"n3066","loc":[-85.630738,41.942943]},"n3067":{"id":"n3067","loc":[-85.630841,41.9429]},"n3068":{"id":"n3068","loc":[-85.630741,41.942766]},"n3069":{"id":"n3069","loc":[-85.63054,41.942603]},"n307":{"id":"n307","loc":[-85.635651,41.940183]},"n3070":{"id":"n3070","loc":[-85.630498,41.942619]},"n3071":{"id":"n3071","loc":[-85.630567,41.942718]},"n3072":{"id":"n3072","loc":[-85.630616,41.942698]},"n3073":{"id":"n3073","loc":[-85.630642,41.94273]},"n3074":{"id":"n3074","loc":[-85.630686,41.942714]},"n3075":{"id":"n3075","loc":[-85.630715,41.942754]},"n3076":{"id":"n3076","loc":[-85.6309,41.942681]},"n3077":{"id":"n3077","loc":[-85.630843,41.942605]},"n3078":{"id":"n3078","loc":[-85.6309,41.942581]},"n3079":{"id":"n3079","loc":[-85.630832,41.942487]},"n308":{"id":"n308","loc":[-85.63577,41.940183],"tags":{"crossing":"zebra","highway":"crossing"}},"n3080":{"id":"n3080","loc":[-85.630773,41.942509]},"n3081":{"id":"n3081","loc":[-85.630718,41.942436]},"n3082":{"id":"n3082","loc":[-85.630485,41.942524]},"n3083":{"id":"n3083","loc":[-85.631468,41.941233]},"n3084":{"id":"n3084","loc":[-85.631334,41.94114]},"n3085":{"id":"n3085","loc":[-85.632052,41.940568]},"n3086":{"id":"n3086","loc":[-85.63219,41.940663]},"n3087":{"id":"n3087","loc":[-85.631323,41.940834]},"n3088":{"id":"n3088","loc":[-85.631122,41.941002]},"n3089":{"id":"n3089","loc":[-85.631321,41.941133]},"n309":{"id":"n309","loc":[-85.636939,41.942544]},"n3090":{"id":"n3090","loc":[-85.631521,41.940966]},"n3091":{"id":"n3091","loc":[-85.631103,41.940253]},"n3092":{"id":"n3092","loc":[-85.631226,41.940211]},"n3093":{"id":"n3093","loc":[-85.631597,41.940805]},"n3094":{"id":"n3094","loc":[-85.631474,41.940847]},"n3095":{"id":"n3095","loc":[-85.631811,41.940534]},"n3096":{"id":"n3096","loc":[-85.631588,41.94061]},"n3097":{"id":"n3097","loc":[-85.631438,41.940366]},"n3098":{"id":"n3098","loc":[-85.631661,41.94029]},"n3099":{"id":"n3099","loc":[-85.630621,41.940041]},"n31":{"id":"n31","loc":[-85.63827,41.944203]},"n310":{"id":"n310","loc":[-85.636323,41.942552]},"n3100":{"id":"n3100","loc":[-85.630436,41.939773]},"n3101":{"id":"n3101","loc":[-85.63059,41.939714]},"n3102":{"id":"n3102","loc":[-85.630775,41.939983]},"n3103":{"id":"n3103","loc":[-85.63047,41.940167]},"n3104":{"id":"n3104","loc":[-85.63013,41.939686]},"n3105":{"id":"n3105","loc":[-85.630302,41.939618]},"n3106":{"id":"n3106","loc":[-85.630641,41.9401]},"n3107":{"id":"n3107","loc":[-85.630966,41.940619]},"n3108":{"id":"n3108","loc":[-85.630874,41.940493]},"n3109":{"id":"n3109","loc":[-85.630933,41.940469]},"n311":{"id":"n311","loc":[-85.636257,41.942555]},"n3110":{"id":"n3110","loc":[-85.630763,41.940236]},"n3111":{"id":"n3111","loc":[-85.63088,41.940189]},"n3112":{"id":"n3112","loc":[-85.631142,41.940548]},"n3113":{"id":"n3113","loc":[-85.630958,41.940871]},"n3114":{"id":"n3114","loc":[-85.630874,41.940778]},"n3115":{"id":"n3115","loc":[-85.631062,41.940684]},"n3116":{"id":"n3116","loc":[-85.631146,41.940777]},"n3117":{"id":"n3117","loc":[-85.632031,41.940575]},"n3118":{"id":"n3118","loc":[-85.631777,41.940186]},"n3119":{"id":"n3119","loc":[-85.631346,41.940179]},"n312":{"id":"n312","loc":[-85.636208,41.942561]},"n3120":{"id":"n3120","loc":[-85.631342,41.94012]},"n3121":{"id":"n3121","loc":[-85.631831,41.940118]},"n3122":{"id":"n3122","loc":[-85.632115,41.940543]},"n3123":{"id":"n3123","loc":[-85.631031,41.941683]},"n3124":{"id":"n3124","loc":[-85.630981,41.941608]},"n3125":{"id":"n3125","loc":[-85.631209,41.941516]},"n3126":{"id":"n3126","loc":[-85.631264,41.941586]},"n3127":{"id":"n3127","loc":[-85.630938,41.94155]},"n3128":{"id":"n3128","loc":[-85.631156,41.941462]},"n3129":{"id":"n3129","loc":[-85.631197,41.94152]},"n313":{"id":"n313","loc":[-85.636159,41.942573]},"n3130":{"id":"n3130","loc":[-85.630895,41.941485]},"n3131":{"id":"n3131","loc":[-85.630824,41.941389]},"n3132":{"id":"n3132","loc":[-85.630986,41.941323]},"n3133":{"id":"n3133","loc":[-85.631057,41.941419]},"n3134":{"id":"n3134","loc":[-85.630777,41.941328]},"n3135":{"id":"n3135","loc":[-85.630907,41.941274]},"n3136":{"id":"n3136","loc":[-85.630953,41.941335]},"n3137":{"id":"n3137","loc":[-85.630797,41.941247]},"n3138":{"id":"n3138","loc":[-85.630701,41.94117]},"n3139":{"id":"n3139","loc":[-85.630829,41.941113]},"n314":{"id":"n314","loc":[-85.635743,41.942881]},"n3140":{"id":"n3140","loc":[-85.6309,41.941201]},"n3141":{"id":"n3141","loc":[-85.630765,41.941206]},"n3142":{"id":"n3142","loc":[-85.630739,41.941218]},"n3143":{"id":"n3143","loc":[-85.630582,41.941039]},"n3144":{"id":"n3144","loc":[-85.630412,41.940818]},"n3145":{"id":"n3145","loc":[-85.630509,41.940777]},"n3146":{"id":"n3146","loc":[-85.630678,41.941004]},"n3147":{"id":"n3147","loc":[-85.630773,41.942166]},"n3148":{"id":"n3148","loc":[-85.630708,41.942074]},"n3149":{"id":"n3149","loc":[-85.630863,41.942013]},"n315":{"id":"n315","loc":[-85.635452,41.942966]},"n3150":{"id":"n3150","loc":[-85.630928,41.942105]},"n3151":{"id":"n3151","loc":[-85.630701,41.942026]},"n3152":{"id":"n3152","loc":[-85.630665,41.941971]},"n3153":{"id":"n3153","loc":[-85.630793,41.941918]},"n3154":{"id":"n3154","loc":[-85.630837,41.94197]},"n3155":{"id":"n3155","loc":[-85.630757,41.941871]},"n3156":{"id":"n3156","loc":[-85.630629,41.941923]},"n3157":{"id":"n3157","loc":[-85.630694,41.941783]},"n3158":{"id":"n3158","loc":[-85.630534,41.941847]},"n3159":{"id":"n3159","loc":[-85.630598,41.941935]},"n316":{"id":"n316","loc":[-85.634911,41.943118]},"n3160":{"id":"n3160","loc":[-85.631548,41.93938]},"n3161":{"id":"n3161","loc":[-85.631525,41.939919]},"n3162":{"id":"n3162","loc":[-85.631648,41.940043]},"n3163":{"id":"n3163","loc":[-85.624586,41.951121]},"n3164":{"id":"n3164","loc":[-85.622139,41.952064]},"n3165":{"id":"n3165","loc":[-85.622141,41.952144]},"n3166":{"id":"n3166","loc":[-85.621977,41.952146]},"n3167":{"id":"n3167","loc":[-85.621978,41.952211]},"n3168":{"id":"n3168","loc":[-85.62191,41.952212]},"n3169":{"id":"n3169","loc":[-85.633628,41.935437]},"n317":{"id":"n317","loc":[-85.634743,41.943167]},"n3170":{"id":"n3170","loc":[-85.632849,41.935518]},"n3171":{"id":"n3171","loc":[-85.632376,41.93574]},"n3172":{"id":"n3172","loc":[-85.631517,41.935897]},"n3173":{"id":"n3173","loc":[-85.630433,41.936124]},"n3174":{"id":"n3174","loc":[-85.630207,41.936427]},"n3175":{"id":"n3175","loc":[-85.630346,41.936795]},"n3176":{"id":"n3176","loc":[-85.62996,41.936974]},"n3177":{"id":"n3177","loc":[-85.629916,41.937488]},"n3178":{"id":"n3178","loc":[-85.629946,41.937802]},"n3179":{"id":"n3179","loc":[-85.629977,41.937905]},"n318":{"id":"n318","loc":[-85.634401,41.94328]},"n3180":{"id":"n3180","loc":[-85.63016,41.937909]},"n3181":{"id":"n3181","loc":[-85.630804,41.937791]},"n3182":{"id":"n3182","loc":[-85.631688,41.937808]},"n3183":{"id":"n3183","loc":[-85.631685,41.938008]},"n3184":{"id":"n3184","loc":[-85.631845,41.938116]},"n3185":{"id":"n3185","loc":[-85.63207,41.938181]},"n3186":{"id":"n3186","loc":[-85.632143,41.938371]},"n3187":{"id":"n3187","loc":[-85.632056,41.938435]},"n3188":{"id":"n3188","loc":[-85.631787,41.938457]},"n3189":{"id":"n3189","loc":[-85.631657,41.938728]},"n319":{"id":"n319","loc":[-85.634345,41.943299]},"n3190":{"id":"n3190","loc":[-85.631595,41.93775]},"n3191":{"id":"n3191","loc":[-85.630264,41.937839]},"n3192":{"id":"n3192","loc":[-85.628591,41.948536]},"n3193":{"id":"n3193","loc":[-85.63205,41.951181]},"n3194":{"id":"n3194","loc":[-85.632034,41.949909]},"n3195":{"id":"n3195","loc":[-85.630841,41.951191]},"n3196":{"id":"n3196","loc":[-85.632083,41.9537]},"n3197":{"id":"n3197","loc":[-85.630929,41.959037]},"n3198":{"id":"n3198","loc":[-85.632151,41.959028]},"n3199":{"id":"n3199","loc":[-85.630911,41.957428]},"n32":{"id":"n32","loc":[-85.638273,41.944246]},"n320":{"id":"n320","loc":[-85.634287,41.943326]},"n3200":{"id":"n3200","loc":[-85.63213,41.957427]},"n3201":{"id":"n3201","loc":[-85.632072,41.952447]},"n3202":{"id":"n3202","loc":[-85.632095,41.954677]},"n3203":{"id":"n3203","loc":[-85.632111,41.955911]},"n3204":{"id":"n3204","loc":[-85.630855,41.952457]},"n3205":{"id":"n3205","loc":[-85.630869,41.953709]},"n3206":{"id":"n3206","loc":[-85.63088,41.954682]},"n3207":{"id":"n3207","loc":[-85.630894,41.955913]},"n3208":{"id":"n3208","loc":[-85.633214,41.948619]},"n3209":{"id":"n3209","loc":[-85.633253,41.951171]},"n321":{"id":"n321","loc":[-85.634233,41.943354]},"n3210":{"id":"n3210","loc":[-85.633234,41.949901]},"n3211":{"id":"n3211","loc":[-85.633922,41.948616]},"n3212":{"id":"n3212","loc":[-85.625188,41.947832]},"n3213":{"id":"n3213","loc":[-85.625208,41.947775]},"n3214":{"id":"n3214","loc":[-85.625229,41.94776]},"n3215":{"id":"n3215","loc":[-85.625201,41.947749]},"n3216":{"id":"n3216","loc":[-85.625168,41.947707]},"n3217":{"id":"n3217","loc":[-85.625171,41.947609]},"n3218":{"id":"n3218","loc":[-85.625213,41.947564]},"n3219":{"id":"n3219","loc":[-85.62529,41.94756]},"n322":{"id":"n322","loc":[-85.634099,41.943429]},"n3220":{"id":"n3220","loc":[-85.625303,41.947533]},"n3221":{"id":"n3221","loc":[-85.625344,41.947482]},"n3222":{"id":"n3222","loc":[-85.625442,41.947468]},"n3223":{"id":"n3223","loc":[-85.62565,41.947494]},"n3224":{"id":"n3224","loc":[-85.625726,41.947613]},"n3225":{"id":"n3225","loc":[-85.625703,41.947728]},"n3226":{"id":"n3226","loc":[-85.625534,41.94781]},"n3227":{"id":"n3227","loc":[-85.625391,41.947822]},"n3228":{"id":"n3228","loc":[-85.625304,41.947859]},"n3229":{"id":"n3229","loc":[-85.625203,41.947885]},"n323":{"id":"n323","loc":[-85.633958,41.943507],"tags":{"highway":"crossing"}},"n3230":{"id":"n3230","loc":[-85.624691,41.948659]},"n3231":{"id":"n3231","loc":[-85.624328,41.948661]},"n3232":{"id":"n3232","loc":[-85.624331,41.949046]},"n3233":{"id":"n3233","loc":[-85.624694,41.949045]},"n3234":{"id":"n3234","loc":[-85.623623,41.949606]},"n3235":{"id":"n3235","loc":[-85.623623,41.9497]},"n3236":{"id":"n3236","loc":[-85.623357,41.9497]},"n3237":{"id":"n3237","loc":[-85.623357,41.949614]},"n3238":{"id":"n3238","loc":[-85.623974,41.949429]},"n3239":{"id":"n3239","loc":[-85.623974,41.949605]},"n324":{"id":"n324","loc":[-85.633698,41.943651],"tags":{"railway":"crossing"}},"n3240":{"id":"n3240","loc":[-85.624501,41.951226]},"n3241":{"id":"n3241","loc":[-85.624501,41.951123]},"n3242":{"id":"n3242","loc":[-85.624319,41.951123]},"n3243":{"id":"n3243","loc":[-85.624319,41.951226]},"n3244":{"id":"n3244","loc":[-85.624121,41.950866]},"n3245":{"id":"n3245","loc":[-85.624115,41.950525]},"n3246":{"id":"n3246","loc":[-85.624315,41.950523]},"n3247":{"id":"n3247","loc":[-85.62432,41.950865]},"n3248":{"id":"n3248","loc":[-85.624393,41.950867]},"n3249":{"id":"n3249","loc":[-85.62439,41.950596]},"n325":{"id":"n325","loc":[-85.633508,41.943757]},"n3250":{"id":"n3250","loc":[-85.624673,41.950594]},"n3251":{"id":"n3251","loc":[-85.624675,41.95082]},"n3252":{"id":"n3252","loc":[-85.62451,41.950821]},"n3253":{"id":"n3253","loc":[-85.62451,41.950866]},"n3254":{"id":"n3254","loc":[-85.624101,41.949346]},"n3255":{"id":"n3255","loc":[-85.624244,41.949346]},"n3256":{"id":"n3256","loc":[-85.624244,41.949368]},"n3257":{"id":"n3257","loc":[-85.62434,41.949368]},"n3258":{"id":"n3258","loc":[-85.624342,41.949351]},"n3259":{"id":"n3259","loc":[-85.624725,41.949348]},"n326":{"id":"n326","loc":[-85.634839,41.942974]},"n3260":{"id":"n3260","loc":[-85.624755,41.950495]},"n3261":{"id":"n3261","loc":[-85.624121,41.950502]},"n3262":{"id":"n3262","loc":[-85.625453,41.950163]},"n3263":{"id":"n3263","loc":[-85.625454,41.949976]},"n3264":{"id":"n3264","loc":[-85.625549,41.949977]},"n3265":{"id":"n3265","loc":[-85.62555,41.949833]},"n3266":{"id":"n3266","loc":[-85.625577,41.949833]},"n3267":{"id":"n3267","loc":[-85.625578,41.949656]},"n3268":{"id":"n3268","loc":[-85.625195,41.949655]},"n3269":{"id":"n3269","loc":[-85.625192,41.950162]},"n327":{"id":"n327","loc":[-85.634657,41.943028]},"n3270":{"id":"n3270","loc":[-85.622992,41.949614]},"n3271":{"id":"n3271","loc":[-85.622991,41.949431]},"n3272":{"id":"n3272","loc":[-85.620103,41.951]},"n3273":{"id":"n3273","loc":[-85.605644,41.947468]},"n3274":{"id":"n3274","loc":[-85.617421,41.947457]},"n3275":{"id":"n3275","loc":[-85.620078,41.947444]},"n3276":{"id":"n3276","loc":[-85.620087,41.94924]},"n3277":{"id":"n3277","loc":[-85.62156,41.948333]},"n3278":{"id":"n3278","loc":[-85.620106,41.950132]},"n3279":{"id":"n3279","loc":[-85.637412,41.951136]},"n328":{"id":"n328","loc":[-85.634222,41.943152]},"n3280":{"id":"n3280","loc":[-85.635429,41.948608]},"n3281":{"id":"n3281","loc":[-85.635047,41.947788]},"n3282":{"id":"n3282","loc":[-85.635048,41.947796]},"n3283":{"id":"n3283","loc":[-85.635002,41.947797]},"n3284":{"id":"n3284","loc":[-85.635002,41.947788]},"n3285":{"id":"n3285","loc":[-85.634914,41.94779]},"n3286":{"id":"n3286","loc":[-85.634913,41.947753]},"n3287":{"id":"n3287","loc":[-85.63494,41.947753]},"n3288":{"id":"n3288","loc":[-85.634938,41.947708]},"n3289":{"id":"n3289","loc":[-85.635124,41.947705]},"n329":{"id":"n329","loc":[-85.634099,41.943202]},"n3290":{"id":"n3290","loc":[-85.635126,41.947787]},"n3291":{"id":"n3291","loc":[-85.634972,41.947599]},"n3292":{"id":"n3292","loc":[-85.634921,41.9476]},"n3293":{"id":"n3293","loc":[-85.63485,41.947546]},"n3294":{"id":"n3294","loc":[-85.63485,41.947508]},"n3295":{"id":"n3295","loc":[-85.634924,41.947457]},"n3296":{"id":"n3296","loc":[-85.634967,41.947456]},"n3297":{"id":"n3297","loc":[-85.635041,41.947512]},"n3298":{"id":"n3298","loc":[-85.635041,41.947542]},"n3299":{"id":"n3299","loc":[-85.634244,41.947839]},"n33":{"id":"n33","loc":[-85.638257,41.944188]},"n330":{"id":"n330","loc":[-85.634093,41.943138]},"n3300":{"id":"n3300","loc":[-85.634243,41.947793]},"n3301":{"id":"n3301","loc":[-85.634244,41.947686]},"n3302":{"id":"n3302","loc":[-85.634243,41.947657]},"n3303":{"id":"n3303","loc":[-85.634462,41.947653]},"n3304":{"id":"n3304","loc":[-85.634468,41.947835]},"n3305":{"id":"n3305","loc":[-85.634416,41.948006]},"n3306":{"id":"n3306","loc":[-85.634415,41.947898]},"n3307":{"id":"n3307","loc":[-85.634275,41.947899]},"n3308":{"id":"n3308","loc":[-85.634275,41.947927]},"n3309":{"id":"n3309","loc":[-85.63425,41.947927]},"n331":{"id":"n331","loc":[-85.633938,41.943291]},"n3310":{"id":"n3310","loc":[-85.63425,41.947976]},"n3311":{"id":"n3311","loc":[-85.634274,41.947976]},"n3312":{"id":"n3312","loc":[-85.634275,41.948007]},"n3313":{"id":"n3313","loc":[-85.634342,41.947635]},"n3314":{"id":"n3314","loc":[-85.634339,41.947497]},"n3315":{"id":"n3315","loc":[-85.634313,41.94748]},"n3316":{"id":"n3316","loc":[-85.634287,41.947474]},"n3317":{"id":"n3317","loc":[-85.63498,41.94815]},"n3318":{"id":"n3318","loc":[-85.634891,41.94815]},"n3319":{"id":"n3319","loc":[-85.634892,41.948169]},"n332":{"id":"n332","loc":[-85.633535,41.943511],"tags":{"railway":"crossing"}},"n3320":{"id":"n3320","loc":[-85.634852,41.948169]},"n3321":{"id":"n3321","loc":[-85.634853,41.948268]},"n3322":{"id":"n3322","loc":[-85.634832,41.948268]},"n3323":{"id":"n3323","loc":[-85.634832,41.948296]},"n3324":{"id":"n3324","loc":[-85.634965,41.948295]},"n3325":{"id":"n3325","loc":[-85.634966,41.948321]},"n3326":{"id":"n3326","loc":[-85.634999,41.948321]},"n3327":{"id":"n3327","loc":[-85.634999,41.948295]},"n3328":{"id":"n3328","loc":[-85.635175,41.948293]},"n3329":{"id":"n3329","loc":[-85.635175,41.948262]},"n333":{"id":"n333","loc":[-85.63339,41.943596]},"n3330":{"id":"n3330","loc":[-85.635159,41.948262]},"n3331":{"id":"n3331","loc":[-85.635158,41.948152]},"n3332":{"id":"n3332","loc":[-85.635067,41.948152]},"n3333":{"id":"n3333","loc":[-85.635065,41.947966]},"n3334":{"id":"n3334","loc":[-85.634979,41.947966]},"n3335":{"id":"n3335","loc":[-85.634307,41.948326]},"n3336":{"id":"n3336","loc":[-85.634305,41.948298]},"n3337":{"id":"n3337","loc":[-85.634331,41.948055]},"n3338":{"id":"n3338","loc":[-85.634331,41.948046]},"n3339":{"id":"n3339","loc":[-85.634435,41.948047]},"n334":{"id":"n334","loc":[-85.632842,41.943895]},"n3340":{"id":"n3340","loc":[-85.634434,41.948375]},"n3341":{"id":"n3341","loc":[-85.634463,41.948373]},"n3342":{"id":"n3342","loc":[-85.634464,41.948456]},"n3343":{"id":"n3343","loc":[-85.63443,41.948457]},"n3344":{"id":"n3344","loc":[-85.634432,41.948505]},"n3345":{"id":"n3345","loc":[-85.637386,41.94906]},"n3346":{"id":"n3346","loc":[-85.637113,41.9486]},"n3347":{"id":"n3347","loc":[-85.635448,41.949424]},"n335":{"id":"n335","loc":[-85.633856,41.943315]},"n3352":{"id":"n3352","loc":[-85.635457,41.949787]},"n3353":{"id":"n3353","loc":[-85.635459,41.949886]},"n336":{"id":"n336","loc":[-85.633697,41.943405]},"n337":{"id":"n337","loc":[-85.63347,41.943181]},"n3372":{"id":"n3372","loc":[-85.634423,41.950964]},"n3373":{"id":"n3373","loc":[-85.634424,41.95074]},"n3374":{"id":"n3374","loc":[-85.634394,41.950284]},"n3375":{"id":"n3375","loc":[-85.634398,41.950626]},"n3376":{"id":"n3376","loc":[-85.63452,41.951063]},"n3377":{"id":"n3377","loc":[-85.634511,41.949977]},"n3378":{"id":"n3378","loc":[-85.637409,41.949873]},"n3379":{"id":"n3379","loc":[-85.634824,41.94996]},"n338":{"id":"n338","loc":[-85.633597,41.943109]},"n3380":{"id":"n3380","loc":[-85.635437,41.949954]},"n3381":{"id":"n3381","loc":[-85.634844,41.951064]},"n3382":{"id":"n3382","loc":[-85.635458,41.951058]},"n3383":{"id":"n3383","loc":[-85.633921,41.947333]},"n3384":{"id":"n3384","loc":[-85.634208,41.947793]},"n3385":{"id":"n3385","loc":[-85.634204,41.947687]},"n3386":{"id":"n3386","loc":[-85.63424,41.947475]},"n3387":{"id":"n3387","loc":[-85.63424,41.947635]},"n3388":{"id":"n3388","loc":[-85.634089,41.948328]},"n3389":{"id":"n3389","loc":[-85.63424,41.948299]},"n339":{"id":"n339","loc":[-85.633673,41.943184]},"n3390":{"id":"n3390","loc":[-85.634239,41.948212]},"n3391":{"id":"n3391","loc":[-85.634086,41.948214]},"n3392":{"id":"n3392","loc":[-85.63408,41.948056]},"n3393":{"id":"n3393","loc":[-85.634093,41.948506]},"n3394":{"id":"n3394","loc":[-85.64344,41.941866]},"n3395":{"id":"n3395","loc":[-85.63378,41.95099]},"n3396":{"id":"n3396","loc":[-85.633779,41.950967]},"n3397":{"id":"n3397","loc":[-85.63375,41.950746]},"n3398":{"id":"n3398","loc":[-85.63375,41.950697]},"n3399":{"id":"n3399","loc":[-85.633903,41.950696]},"n34":{"id":"n34","loc":[-85.638176,41.944312]},"n340":{"id":"n340","loc":[-85.633714,41.94316]},"n3400":{"id":"n3400","loc":[-85.633901,41.950436]},"n3401":{"id":"n3401","loc":[-85.633492,41.950438]},"n3402":{"id":"n3402","loc":[-85.633494,41.950756]},"n3403":{"id":"n3403","loc":[-85.633454,41.950756]},"n3404":{"id":"n3404","loc":[-85.633456,41.950992]},"n3405":{"id":"n3405","loc":[-85.633994,41.950284]},"n3406":{"id":"n3406","loc":[-85.633998,41.950628]},"n3407":{"id":"n3407","loc":[-85.633364,41.951068]},"n3408":{"id":"n3408","loc":[-85.633356,41.949982]},"n3409":{"id":"n3409","loc":[-85.643327,41.941903]},"n341":{"id":"n341","loc":[-85.633811,41.943256]},"n3410":{"id":"n3410","loc":[-85.633292,41.953691]},"n3411":{"id":"n3411","loc":[-85.637432,41.952399]},"n3412":{"id":"n3412","loc":[-85.633349,41.957422]},"n3413":{"id":"n3413","loc":[-85.633326,41.955909]},"n3414":{"id":"n3414","loc":[-85.633307,41.954673]},"n3415":{"id":"n3415","loc":[-85.633273,41.952436]},"n3416":{"id":"n3416","loc":[-85.633361,41.95823],"tags":{"highway":"turning_circle"}},"n3417":{"id":"n3417","loc":[-85.619899,41.945527]},"n3418":{"id":"n3418","loc":[-85.643422,41.941946]},"n3419":{"id":"n3419","loc":[-85.643505,41.942033]},"n342":{"id":"n342","loc":[-85.633801,41.943261]},"n3420":{"id":"n3420","loc":[-85.620088,41.945571]},"n3421":{"id":"n3421","loc":[-85.620051,41.945505]},"n3422":{"id":"n3422","loc":[-85.62001,41.94541]},"n3423":{"id":"n3423","loc":[-85.620982,41.944742]},"n3424":{"id":"n3424","loc":[-85.621305,41.944782]},"n3425":{"id":"n3425","loc":[-85.621174,41.944819]},"n3426":{"id":"n3426","loc":[-85.621029,41.944871]},"n3427":{"id":"n3427","loc":[-85.620741,41.945011]},"n3428":{"id":"n3428","loc":[-85.620616,41.945085]},"n3429":{"id":"n3429","loc":[-85.620506,41.945172]},"n343":{"id":"n343","loc":[-85.63374,41.943514]},"n3430":{"id":"n3430","loc":[-85.620394,41.945273]},"n3431":{"id":"n3431","loc":[-85.620316,41.94536]},"n3432":{"id":"n3432","loc":[-85.620257,41.945452]},"n3433":{"id":"n3433","loc":[-85.620212,41.945535]},"n3434":{"id":"n3434","loc":[-85.620101,41.945811]},"n3435":{"id":"n3435","loc":[-85.620081,41.945937]},"n3436":{"id":"n3436","loc":[-85.619899,41.943718]},"n3437":{"id":"n3437","loc":[-85.619969,41.943211]},"n3438":{"id":"n3438","loc":[-85.619894,41.943292]},"n3439":{"id":"n3439","loc":[-85.620047,41.944738]},"n344":{"id":"n344","loc":[-85.633665,41.943441]},"n3440":{"id":"n3440","loc":[-85.620226,41.946088]},"n3441":{"id":"n3441","loc":[-85.620225,41.945864]},"n3442":{"id":"n3442","loc":[-85.620518,41.945863]},"n3443":{"id":"n3443","loc":[-85.620519,41.945944]},"n3444":{"id":"n3444","loc":[-85.620388,41.945944]},"n3445":{"id":"n3445","loc":[-85.620389,41.946088]},"n3446":{"id":"n3446","loc":[-85.618405,41.946566]},"n3447":{"id":"n3447","loc":[-85.619156,41.946562]},"n3448":{"id":"n3448","loc":[-85.619154,41.946319]},"n3449":{"id":"n3449","loc":[-85.618736,41.946322]},"n345":{"id":"n345","loc":[-85.633162,41.942947]},"n3450":{"id":"n3450","loc":[-85.618733,41.94612]},"n3451":{"id":"n3451","loc":[-85.619317,41.946116]},"n3452":{"id":"n3452","loc":[-85.619316,41.946023]},"n3453":{"id":"n3453","loc":[-85.619622,41.946021]},"n3454":{"id":"n3454","loc":[-85.619624,41.946171]},"n3455":{"id":"n3455","loc":[-85.61977,41.94617]},"n3456":{"id":"n3456","loc":[-85.619769,41.94602]},"n3457":{"id":"n3457","loc":[-85.619732,41.94602]},"n3458":{"id":"n3458","loc":[-85.619731,41.945856]},"n3459":{"id":"n3459","loc":[-85.619617,41.945857]},"n346":{"id":"n346","loc":[-85.633598,41.943083]},"n3460":{"id":"n3460","loc":[-85.619616,41.945776]},"n3461":{"id":"n3461","loc":[-85.619447,41.945777]},"n3462":{"id":"n3462","loc":[-85.619415,41.945778]},"n3463":{"id":"n3463","loc":[-85.618378,41.945788]},"n3464":{"id":"n3464","loc":[-85.618384,41.946132]},"n3465":{"id":"n3465","loc":[-85.618503,41.94613]},"n3466":{"id":"n3466","loc":[-85.618506,41.946319]},"n3467":{"id":"n3467","loc":[-85.6184,41.94632]},"n3468":{"id":"n3468","loc":[-85.618248,41.946416]},"n3469":{"id":"n3469","loc":[-85.618247,41.946319]},"n347":{"id":"n347","loc":[-85.63343,41.943179]},"n3470":{"id":"n3470","loc":[-85.618039,41.946321]},"n3471":{"id":"n3471","loc":[-85.61804,41.946418]},"n3472":{"id":"n3472","loc":[-85.620118,41.951895]},"n3473":{"id":"n3473","loc":[-85.617075,41.95469]},"n3474":{"id":"n3474","loc":[-85.620107,41.952113]},"n3475":{"id":"n3475","loc":[-85.620091,41.95232]},"n3476":{"id":"n3476","loc":[-85.620047,41.952505]},"n3477":{"id":"n3477","loc":[-85.61998,41.952715]},"n3478":{"id":"n3478","loc":[-85.619861,41.952986]},"n3479":{"id":"n3479","loc":[-85.619622,41.953365]},"n348":{"id":"n348","loc":[-85.633669,41.94341]},"n3480":{"id":"n3480","loc":[-85.619441,41.953567]},"n3481":{"id":"n3481","loc":[-85.619259,41.953741]},"n3482":{"id":"n3482","loc":[-85.618835,41.954056]},"n3483":{"id":"n3483","loc":[-85.618602,41.954194]},"n3484":{"id":"n3484","loc":[-85.618305,41.954347]},"n3485":{"id":"n3485","loc":[-85.618006,41.954466]},"n3486":{"id":"n3486","loc":[-85.617611,41.954587]},"n3487":{"id":"n3487","loc":[-85.615094,41.943412]},"n3488":{"id":"n3488","loc":[-85.619337,41.943025]},"n3489":{"id":"n3489","loc":[-85.610477,41.945527]},"n349":{"id":"n349","loc":[-85.633566,41.943466]},"n3490":{"id":"n3490","loc":[-85.610477,41.943718]},"n3491":{"id":"n3491","loc":[-85.619804,41.942976]},"n3492":{"id":"n3492","loc":[-85.61921,41.942672]},"n3493":{"id":"n3493","loc":[-85.619862,41.942836]},"n3494":{"id":"n3494","loc":[-85.616326,41.942769]},"n3495":{"id":"n3495","loc":[-85.617953,41.942917]},"n3496":{"id":"n3496","loc":[-85.61972,41.942728]},"n3497":{"id":"n3497","loc":[-85.61944,41.942784]},"n3498":{"id":"n3498","loc":[-85.615323,41.942841]},"n3499":{"id":"n3499","loc":[-85.612923,41.943718]},"n35":{"id":"n35","loc":[-85.637928,41.944249]},"n350":{"id":"n350","loc":[-85.633031,41.942986]},"n3500":{"id":"n3500","loc":[-85.61958,41.942756]},"n3501":{"id":"n3501","loc":[-85.619643,41.942647],"tags":{"leisure":"fishing"}},"n3502":{"id":"n3502","loc":[-85.619935,41.942962]},"n3503":{"id":"n3503","loc":[-85.629677,41.954687]},"n3504":{"id":"n3504","loc":[-85.629083,41.953722]},"n3505":{"id":"n3505","loc":[-85.621907,41.952067]},"n3506":{"id":"n3506","loc":[-85.621788,41.952058]},"n3507":{"id":"n3507","loc":[-85.629665,41.953718]},"n3508":{"id":"n3508","loc":[-85.624454,41.954707]},"n3509":{"id":"n3509","loc":[-85.634609,41.954585]},"n351":{"id":"n351","loc":[-85.633238,41.94283]},"n3510":{"id":"n3510","loc":[-85.634595,41.953772]},"n3511":{"id":"n3511","loc":[-85.633425,41.953783]},"n3512":{"id":"n3512","loc":[-85.633439,41.954596]},"n3517":{"id":"n3517","loc":[-85.621789,41.952179]},"n3518":{"id":"n3518","loc":[-85.624105,41.954704]},"n3519":{"id":"n3519","loc":[-85.623306,41.954542]},"n352":{"id":"n352","loc":[-85.633173,41.943556]},"n3520":{"id":"n3520","loc":[-85.623123,41.954502]},"n3521":{"id":"n3521","loc":[-85.622965,41.954473]},"n3522":{"id":"n3522","loc":[-85.622822,41.954455]},"n3523":{"id":"n3523","loc":[-85.62269,41.954448]},"n3524":{"id":"n3524","loc":[-85.622388,41.954467]},"n3525":{"id":"n3525","loc":[-85.62403,41.954895]},"n3526":{"id":"n3526","loc":[-85.623579,41.954855]},"n3527":{"id":"n3527","loc":[-85.623836,41.954951]},"n3528":{"id":"n3528","loc":[-85.622473,41.954592]},"n3529":{"id":"n3529","loc":[-85.622753,41.95458]},"n353":{"id":"n353","loc":[-85.633127,41.943552]},"n3530":{"id":"n3530","loc":[-85.62404,41.955078]},"n3531":{"id":"n3531","loc":[-85.624126,41.954999]},"n3532":{"id":"n3532","loc":[-85.623171,41.954687]},"n3533":{"id":"n3533","loc":[-85.624276,41.955206]},"n3534":{"id":"n3534","loc":[-85.62491,41.952801]},"n3535":{"id":"n3535","loc":[-85.625186,41.952756]},"n3536":{"id":"n3536","loc":[-85.625552,41.952792]},"n3537":{"id":"n3537","loc":[-85.626001,41.952948]},"n3538":{"id":"n3538","loc":[-85.626528,41.952984]},"n3539":{"id":"n3539","loc":[-85.626942,41.952886]},"n354":{"id":"n354","loc":[-85.632745,41.943222]},"n3540":{"id":"n3540","loc":[-85.627092,41.952685]},"n3541":{"id":"n3541","loc":[-85.627212,41.95244]},"n3542":{"id":"n3542","loc":[-85.627158,41.952226]},"n3543":{"id":"n3543","loc":[-85.627002,41.951972]},"n3544":{"id":"n3544","loc":[-85.626822,41.951838]},"n3545":{"id":"n3545","loc":[-85.626528,41.951807]},"n3546":{"id":"n3546","loc":[-85.625653,41.951852]},"n3547":{"id":"n3547","loc":[-85.625348,41.951834]},"n3548":{"id":"n3548","loc":[-85.625114,41.951767]},"n3549":{"id":"n3549","loc":[-85.620627,41.954682]},"n355":{"id":"n355","loc":[-85.632756,41.943199]},"n3550":{"id":"n3550","loc":[-85.622758,41.951884]},"n3551":{"id":"n3551","loc":[-85.618135,41.954734]},"n3552":{"id":"n3552","loc":[-85.620229,41.95472]},"n3553":{"id":"n3553","loc":[-85.624491,41.955573]},"n3554":{"id":"n3554","loc":[-85.621792,41.958314]},"n3555":{"id":"n3555","loc":[-85.623395,41.960001]},"n3556":{"id":"n3556","loc":[-85.620461,41.956212]},"n3557":{"id":"n3557","loc":[-85.62109,41.956766]},"n3558":{"id":"n3558","loc":[-85.620246,41.956224]},"n3559":{"id":"n3559","loc":[-85.625017,41.956068]},"n356":{"id":"n356","loc":[-85.632855,41.943147]},"n3560":{"id":"n3560","loc":[-85.622795,41.959702]},"n3561":{"id":"n3561","loc":[-85.621573,41.958457]},"n3562":{"id":"n3562","loc":[-85.619631,41.9573]},"n3563":{"id":"n3563","loc":[-85.62095,41.956311]},"n3564":{"id":"n3564","loc":[-85.619694,41.957408]},"n3565":{"id":"n3565","loc":[-85.621079,41.957751]},"n3566":{"id":"n3566","loc":[-85.622426,41.961142]},"n3567":{"id":"n3567","loc":[-85.623251,41.960484]},"n3568":{"id":"n3568","loc":[-85.619084,41.956291]},"n3569":{"id":"n3569","loc":[-85.622227,41.959303]},"n357":{"id":"n357","loc":[-85.632888,41.94315]},"n3570":{"id":"n3570","loc":[-85.620976,41.959104]},"n3571":{"id":"n3571","loc":[-85.621208,41.95653]},"n3572":{"id":"n3572","loc":[-85.623531,41.95951]},"n3573":{"id":"n3573","loc":[-85.623556,41.957935]},"n3574":{"id":"n3574","loc":[-85.623037,41.95746]},"n3575":{"id":"n3575","loc":[-85.621175,41.956427]},"n3576":{"id":"n3576","loc":[-85.622651,41.960109]},"n3577":{"id":"n3577","loc":[-85.621803,41.960747]},"n3578":{"id":"n3578","loc":[-85.620791,41.961874]},"n3579":{"id":"n3579","loc":[-85.625295,41.956786]},"n358":{"id":"n358","loc":[-85.633232,41.943547]},"n3580":{"id":"n3580","loc":[-85.619662,41.956894]},"n3581":{"id":"n3581","loc":[-85.622442,41.958708]},"n3582":{"id":"n3582","loc":[-85.621744,41.955864]},"n3583":{"id":"n3583","loc":[-85.621336,41.959212]},"n3584":{"id":"n3584","loc":[-85.622801,41.957304]},"n3585":{"id":"n3585","loc":[-85.619973,41.957433]},"n3586":{"id":"n3586","loc":[-85.619556,41.955717]},"n3587":{"id":"n3587","loc":[-85.622978,41.958601]},"n3588":{"id":"n3588","loc":[-85.625396,41.956264]},"n3589":{"id":"n3589","loc":[-85.623525,41.958034]},"n359":{"id":"n359","loc":[-85.633302,41.94351]},"n3590":{"id":"n3590","loc":[-85.623299,41.959631]},"n3591":{"id":"n3591","loc":[-85.622678,41.959873]},"n3592":{"id":"n3592","loc":[-85.625553,41.956179]},"n3593":{"id":"n3593","loc":[-85.623557,41.959231]},"n3594":{"id":"n3594","loc":[-85.622843,41.957373]},"n3595":{"id":"n3595","loc":[-85.619378,41.955677]},"n3596":{"id":"n3596","loc":[-85.620092,41.955425]},"n3597":{"id":"n3597","loc":[-85.622666,41.96044]},"n3598":{"id":"n3598","loc":[-85.621996,41.960256]},"n3599":{"id":"n3599","loc":[-85.623273,41.959997]},"n36":{"id":"n36","loc":[-85.637894,41.945551]},"n360":{"id":"n360","loc":[-85.633442,41.943794],"tags":{"highway":"crossing"}},"n3600":{"id":"n3600","loc":[-85.62477,41.95689]},"n3601":{"id":"n3601","loc":[-85.621641,41.955015]},"n3602":{"id":"n3602","loc":[-85.622495,41.960392]},"n3603":{"id":"n3603","loc":[-85.61918,41.955565]},"n3604":{"id":"n3604","loc":[-85.620017,41.955505]},"n3605":{"id":"n3605","loc":[-85.621739,41.956315]},"n3606":{"id":"n3606","loc":[-85.622957,41.959837]},"n3607":{"id":"n3607","loc":[-85.620912,41.960919]},"n3608":{"id":"n3608","loc":[-85.625231,41.956235]},"n3609":{"id":"n3609","loc":[-85.620976,41.961868]},"n361":{"id":"n361","loc":[-85.633381,41.94383]},"n3610":{"id":"n3610","loc":[-85.620956,41.958908]},"n3611":{"id":"n3611","loc":[-85.619035,41.956139]},"n3612":{"id":"n3612","loc":[-85.623643,41.958669]},"n3613":{"id":"n3613","loc":[-85.61949,41.956539]},"n3614":{"id":"n3614","loc":[-85.621927,41.958242]},"n3615":{"id":"n3615","loc":[-85.620826,41.955721]},"n3616":{"id":"n3616","loc":[-85.621202,41.961321]},"n3617":{"id":"n3617","loc":[-85.624877,41.95594]},"n3618":{"id":"n3618","loc":[-85.62065,41.958369]},"n3619":{"id":"n3619","loc":[-85.621524,41.956279]},"n362":{"id":"n362","loc":[-85.632977,41.944053]},"n3620":{"id":"n3620","loc":[-85.624662,41.955932]},"n3621":{"id":"n3621","loc":[-85.623048,41.958509]},"n3622":{"id":"n3622","loc":[-85.62111,41.95754]},"n3623":{"id":"n3623","loc":[-85.621508,41.954847]},"n3624":{"id":"n3624","loc":[-85.620655,41.958601]},"n3625":{"id":"n3625","loc":[-85.62154,41.954971]},"n3626":{"id":"n3626","loc":[-85.621691,41.955521]},"n3627":{"id":"n3627","loc":[-85.62154,41.954739]},"n3628":{"id":"n3628","loc":[-85.621996,41.959913]},"n3629":{"id":"n3629","loc":[-85.622286,41.960699]},"n363":{"id":"n363","loc":[-85.632915,41.943981],"tags":{"crossing":"zebra","highway":"crossing"}},"n3630":{"id":"n3630","loc":[-85.622844,41.9572]},"n3631":{"id":"n3631","loc":[-85.620252,41.955446]},"n3632":{"id":"n3632","loc":[-85.623434,41.957528]},"n3633":{"id":"n3633","loc":[-85.623429,41.956858]},"n3634":{"id":"n3634","loc":[-85.622957,41.957137]},"n3635":{"id":"n3635","loc":[-85.622554,41.959027]},"n3636":{"id":"n3636","loc":[-85.623289,41.958314]},"n3637":{"id":"n3637","loc":[-85.622977,41.960855]},"n3638":{"id":"n3638","loc":[-85.624008,41.956953]},"n3639":{"id":"n3639","loc":[-85.621278,41.960855]},"n364":{"id":"n364","loc":[-85.632724,41.943969],"tags":{"crossing":"zebra","highway":"crossing"}},"n3640":{"id":"n3640","loc":[-85.623128,41.956993]},"n3641":{"id":"n3641","loc":[-85.622452,41.959183]},"n3642":{"id":"n3642","loc":[-85.621095,41.961082]},"n3643":{"id":"n3643","loc":[-85.622011,41.960544]},"n3644":{"id":"n3644","loc":[-85.621637,41.955385]},"n3645":{"id":"n3645","loc":[-85.620999,41.959271]},"n3646":{"id":"n3646","loc":[-85.620044,41.956347]},"n3647":{"id":"n3647","loc":[-85.621936,41.959682]},"n3648":{"id":"n3648","loc":[-85.623761,41.95685]},"n3649":{"id":"n3649","loc":[-85.621239,41.959343]},"n365":{"id":"n365","loc":[-85.632621,41.944034]},"n3650":{"id":"n3650","loc":[-85.621073,41.956012]},"n3651":{"id":"n3651","loc":[-85.621271,41.956184]},"n3652":{"id":"n3652","loc":[-85.623444,41.95778]},"n3653":{"id":"n3653","loc":[-85.62125,41.96186]},"n3654":{"id":"n3654","loc":[-85.62169,41.961059]},"n3655":{"id":"n3655","loc":[-85.620012,41.955637]},"n3656":{"id":"n3656","loc":[-85.621058,41.9573]},"n3657":{"id":"n3657","loc":[-85.621138,41.957663]},"n3658":{"id":"n3658","loc":[-85.620773,41.957895]},"n3659":{"id":"n3659","loc":[-85.62007,41.957157]},"n366":{"id":"n366","loc":[-85.632684,41.944109],"tags":{"crossing":"zebra","highway":"crossing"}},"n3660":{"id":"n3660","loc":[-85.624534,41.955844]},"n3661":{"id":"n3661","loc":[-85.621932,41.960807]},"n3662":{"id":"n3662","loc":[-85.623358,41.958138]},"n3663":{"id":"n3663","loc":[-85.620456,41.955514]},"n3664":{"id":"n3664","loc":[-85.623504,41.957607]},"n3665":{"id":"n3665","loc":[-85.621444,41.960751]},"n3666":{"id":"n3666","loc":[-85.623492,41.960213]},"n3667":{"id":"n3667","loc":[-85.621669,41.954655]},"n3668":{"id":"n3668","loc":[-85.623106,41.958685]},"n3669":{"id":"n3669","loc":[-85.620922,41.957867]},"n367":{"id":"n367","loc":[-85.632738,41.944172]},"n3670":{"id":"n3670","loc":[-85.620092,41.957296]},"n3671":{"id":"n3671","loc":[-85.621669,41.955222]},"n3672":{"id":"n3672","loc":[-85.621614,41.960967]},"n3673":{"id":"n3673","loc":[-85.621691,41.955732]},"n3674":{"id":"n3674","loc":[-85.619207,41.956419]},"n3675":{"id":"n3675","loc":[-85.621116,41.956603]},"n3676":{"id":"n3676","loc":[-85.623311,41.956929]},"n3677":{"id":"n3677","loc":[-85.625671,41.956499]},"n3678":{"id":"n3678","loc":[-85.623525,41.956738]},"n3679":{"id":"n3679","loc":[-85.625381,41.956634]},"n368":{"id":"n368","loc":[-85.63287,41.944135],"tags":{"crossing":"zebra","highway":"crossing"}},"n3680":{"id":"n3680","loc":[-85.620096,41.95677]},"n3681":{"id":"n3681","loc":[-85.623803,41.958745]},"n3682":{"id":"n3682","loc":[-85.623498,41.958457]},"n3683":{"id":"n3683","loc":[-85.624223,41.957009]},"n3684":{"id":"n3684","loc":[-85.620026,41.956946]},"n3685":{"id":"n3685","loc":[-85.623005,41.960124]},"n3686":{"id":"n3686","loc":[-85.619073,41.955832]},"n3687":{"id":"n3687","loc":[-85.621744,41.95501]},"n3688":{"id":"n3688","loc":[-85.620804,41.958781]},"n3689":{"id":"n3689","loc":[-85.619844,41.957448]},"n369":{"id":"n369","loc":[-85.63298,41.944076]},"n3690":{"id":"n3690","loc":[-85.623713,41.958872]},"n3691":{"id":"n3691","loc":[-85.622329,41.960507]},"n3692":{"id":"n3692","loc":[-85.620804,41.956244]},"n3693":{"id":"n3693","loc":[-85.621818,41.955968]},"n3694":{"id":"n3694","loc":[-85.621405,41.958697]},"n3695":{"id":"n3695","loc":[-85.620998,41.960996]},"n3696":{"id":"n3696","loc":[-85.621621,41.960444]},"n3697":{"id":"n3697","loc":[-85.620941,41.961637]},"n3698":{"id":"n3698","loc":[-85.622195,41.958333]},"n3699":{"id":"n3699","loc":[-85.621668,41.961529]},"n37":{"id":"n37","loc":[-85.637611,41.945383]},"n370":{"id":"n370","loc":[-85.633191,41.944471]},"n3700":{"id":"n3700","loc":[-85.621015,41.957049]},"n3701":{"id":"n3701","loc":[-85.619368,41.955521]},"n3702":{"id":"n3702","loc":[-85.651578,41.942534]},"n3703":{"id":"n3703","loc":[-85.651541,41.943847]},"n3704":{"id":"n3704","loc":[-85.651365,41.944817]},"n3705":{"id":"n3705","loc":[-85.651076,41.945985]},"n3706":{"id":"n3706","loc":[-85.650626,41.947213]},"n3707":{"id":"n3707","loc":[-85.649669,41.949161]},"n3708":{"id":"n3708","loc":[-85.641802,41.961801]},"n3709":{"id":"n3709","loc":[-85.623333,41.961987]},"n371":{"id":"n371","loc":[-85.633132,41.94372]},"n3710":{"id":"n3710","loc":[-85.620621,41.965658]},"n3711":{"id":"n3711","loc":[-85.605673,41.965764]},"n3712":{"id":"n3712","loc":[-85.605664,41.962094]},"n3713":{"id":"n3713","loc":[-85.583774,41.962178]},"n3714":{"id":"n3714","loc":[-85.583774,41.961789]},"n3715":{"id":"n3715","loc":[-85.581303,41.961783]},"n3716":{"id":"n3716","loc":[-85.581245,41.958394]},"n3717":{"id":"n3717","loc":[-85.585299,41.955483]},"n3718":{"id":"n3718","loc":[-85.585588,41.955331]},"n3719":{"id":"n3719","loc":[-85.586053,41.955163]},"n372":{"id":"n372","loc":[-85.633011,41.943788]},"n3720":{"id":"n3720","loc":[-85.58632,41.955076]},"n3721":{"id":"n3721","loc":[-85.586478,41.955025]},"n3722":{"id":"n3722","loc":[-85.58692,41.954947]},"n3723":{"id":"n3723","loc":[-85.587345,41.954913]},"n3724":{"id":"n3724","loc":[-85.605592,41.954766]},"n3725":{"id":"n3725","loc":[-85.605303,41.936236]},"n3726":{"id":"n3726","loc":[-85.606941,41.936117]},"n3727":{"id":"n3727","loc":[-85.60876,41.935856]},"n3728":{"id":"n3728","loc":[-85.610092,41.935451]},"n3729":{"id":"n3729","loc":[-85.610681,41.935247]},"n373":{"id":"n373","loc":[-85.632854,41.943632]},"n3730":{"id":"n3730","loc":[-85.611446,41.934955]},"n3731":{"id":"n3731","loc":[-85.612057,41.934696]},"n3732":{"id":"n3732","loc":[-85.613256,41.934084]},"n3733":{"id":"n3733","loc":[-85.613948,41.933682]},"n3734":{"id":"n3734","loc":[-85.614638,41.933212]},"n3735":{"id":"n3735","loc":[-85.619801,41.929305]},"n3736":{"id":"n3736","loc":[-85.619768,41.925548]},"n3737":{"id":"n3737","loc":[-85.625761,41.925597]},"n3738":{"id":"n3738","loc":[-85.6263,41.927323]},"n3739":{"id":"n3739","loc":[-85.633708,41.927402]},"n374":{"id":"n374","loc":[-85.632974,41.943565]},"n3740":{"id":"n3740","loc":[-85.633927,41.929109]},"n3741":{"id":"n3741","loc":[-85.639213,41.929088]},"n3742":{"id":"n3742","loc":[-85.639204,41.925488]},"n3743":{"id":"n3743","loc":[-85.651425,41.925406]},"n3744":{"id":"n3744","loc":[-85.643386,41.941933]},"n3745":{"id":"n3745","loc":[-85.642776,41.941161]},"n3746":{"id":"n3746","loc":[-85.637277,41.948812]},"n3747":{"id":"n3747","loc":[-85.637366,41.94897]},"n3748":{"id":"n3748","loc":[-85.637329,41.94889]},"n3749":{"id":"n3749","loc":[-85.629649,41.952596]},"n375":{"id":"n375","loc":[-85.632741,41.943351]},"n3750":{"id":"n3750","loc":[-85.630291,41.954684]},"n3751":{"id":"n3751","loc":[-85.630284,41.953713]},"n3752":{"id":"n3752","loc":[-85.630269,41.952463]},"n3753":{"id":"n3753","loc":[-85.633933,41.949896]},"n3754":{"id":"n3754","loc":[-85.629339,41.941467]},"n3755":{"id":"n3755","loc":[-85.629857,41.94316]},"n3756":{"id":"n3756","loc":[-85.629987,41.944025]},"n3757":{"id":"n3757","loc":[-85.628538,41.948604]},"n3758":{"id":"n3758","loc":[-85.627415,41.957442]},"n3759":{"id":"n3759","loc":[-85.627019,41.957369]},"n376":{"id":"n376","loc":[-85.63251,41.943481]},"n3760":{"id":"n3760","loc":[-85.62167,41.952179]},"n3761":{"id":"n3761","loc":[-85.62167,41.952138]},"n3762":{"id":"n3762","loc":[-85.621562,41.952139]},"n3763":{"id":"n3763","loc":[-85.621562,41.952058]},"n3764":{"id":"n3764","loc":[-85.621476,41.952043]},"n3765":{"id":"n3765","loc":[-85.621477,41.952132]},"n3766":{"id":"n3766","loc":[-85.621386,41.952132]},"n3767":{"id":"n3767","loc":[-85.621387,41.95214]},"n3768":{"id":"n3768","loc":[-85.621262,41.95214]},"n3769":{"id":"n3769","loc":[-85.621261,41.952038]},"n377":{"id":"n377","loc":[-85.632706,41.943715]},"n3770":{"id":"n3770","loc":[-85.621389,41.952038]},"n3771":{"id":"n3771","loc":[-85.621389,41.952043]},"n3772":{"id":"n3772","loc":[-85.620898,41.952024]},"n3773":{"id":"n3773","loc":[-85.620898,41.952085]},"n3774":{"id":"n3774","loc":[-85.620774,41.952084]},"n3775":{"id":"n3775","loc":[-85.620774,41.952023]},"n3776":{"id":"n3776","loc":[-85.620749,41.952036]},"n3777":{"id":"n3777","loc":[-85.620723,41.952097]},"n3778":{"id":"n3778","loc":[-85.626158,41.958996]},"n3779":{"id":"n3779","loc":[-85.626319,41.958686]},"n378":{"id":"n378","loc":[-85.638683,41.943295]},"n3780":{"id":"n3780","loc":[-85.626119,41.958629]},"n3781":{"id":"n3781","loc":[-85.626064,41.958733]},"n3782":{"id":"n3782","loc":[-85.626155,41.958759]},"n3783":{"id":"n3783","loc":[-85.626048,41.958965]},"n3784":{"id":"n3784","loc":[-85.620648,41.952079]},"n3785":{"id":"n3785","loc":[-85.63826,41.961213]},"n3786":{"id":"n3786","loc":[-85.638003,41.961614]},"n3787":{"id":"n3787","loc":[-85.638817,41.961902]},"n3788":{"id":"n3788","loc":[-85.639073,41.961501]},"n3789":{"id":"n3789","loc":[-85.620674,41.952018]},"n379":{"id":"n379","loc":[-85.638684,41.94323]},"n3790":{"id":"n3790","loc":[-85.62082,41.952106]},"n3791":{"id":"n3791","loc":[-85.620819,41.952143]},"n3792":{"id":"n3792","loc":[-85.620778,41.952143]},"n3793":{"id":"n3793","loc":[-85.620778,41.952106]},"n3794":{"id":"n3794","loc":[-85.620563,41.952276]},"n3795":{"id":"n3795","loc":[-85.620543,41.95238]},"n3796":{"id":"n3796","loc":[-85.620422,41.952367]},"n3797":{"id":"n3797","loc":[-85.620441,41.952263]},"n3798":{"id":"n3798","loc":[-85.620561,41.952266]},"n3799":{"id":"n3799","loc":[-85.620444,41.952254]},"n38":{"id":"n38","loc":[-85.63879,41.943295]},"n380":{"id":"n380","loc":[-85.638627,41.94322]},"n3800":{"id":"n3800","loc":[-85.620773,41.955585]},"n3801":{"id":"n3801","loc":[-85.621265,41.955989]},"n3802":{"id":"n3802","loc":[-85.620692,41.954969]},"n3803":{"id":"n3803","loc":[-85.620691,41.955367]},"n3804":{"id":"n3804","loc":[-85.620458,41.952178]},"n3805":{"id":"n3805","loc":[-85.620575,41.95219]},"n3806":{"id":"n3806","loc":[-85.617609,41.952712]},"n3807":{"id":"n3807","loc":[-85.617533,41.952801],"tags":{"entrance":"yes"}},"n3808":{"id":"n3808","loc":[-85.616816,41.952911]},"n3809":{"id":"n3809","loc":[-85.616797,41.952901]},"n381":{"id":"n381","loc":[-85.638624,41.943294]},"n3810":{"id":"n3810","loc":[-85.616343,41.952694]},"n3811":{"id":"n3811","loc":[-85.616336,41.952729]},"n3812":{"id":"n3812","loc":[-85.616343,41.952772]},"n3813":{"id":"n3813","loc":[-85.628479,41.948649]},"n3814":{"id":"n3814","loc":[-85.628413,41.948679]},"n3815":{"id":"n3815","loc":[-85.628336,41.948694]},"n3816":{"id":"n3816","loc":[-85.62826,41.948694]},"n3817":{"id":"n3817","loc":[-85.628185,41.948679]},"n3818":{"id":"n3818","loc":[-85.628103,41.948649]},"n3819":{"id":"n3819","loc":[-85.627482,41.948395]},"n382":{"id":"n382","loc":[-85.638437,41.943291]},"n3820":{"id":"n3820","loc":[-85.619957,41.951168]},"n3821":{"id":"n3821","loc":[-85.619955,41.952077]},"n3822":{"id":"n3822","loc":[-85.619843,41.952666]},"n3823":{"id":"n3823","loc":[-85.619513,41.95324]},"n3824":{"id":"n3824","loc":[-85.619163,41.953668]},"n3825":{"id":"n3825","loc":[-85.618813,41.953947]},"n3826":{"id":"n3826","loc":[-85.618265,41.954252]},"n3827":{"id":"n3827","loc":[-85.617691,41.954458]},"n3828":{"id":"n3828","loc":[-85.616978,41.95459]},"n3829":{"id":"n3829","loc":[-85.615408,41.954628]},"n383":{"id":"n383","loc":[-85.63844,41.943209]},"n3830":{"id":"n3830","loc":[-85.615374,41.951076]},"n3831":{"id":"n3831","loc":[-85.61932,41.947564]},"n3832":{"id":"n3832","loc":[-85.610553,41.94755]},"n3833":{"id":"n3833","loc":[-85.610572,41.951065]},"n3834":{"id":"n3834","loc":[-85.617548,41.94757]},"n3835":{"id":"n3835","loc":[-85.619842,41.947939]},"n3836":{"id":"n3836","loc":[-85.619874,41.950905]},"n3837":{"id":"n3837","loc":[-85.619695,41.950911]},"n3838":{"id":"n3838","loc":[-85.617591,41.951078]},"n3839":{"id":"n3839","loc":[-85.619551,41.951065]},"n384":{"id":"n384","loc":[-85.632616,41.944021]},"n3840":{"id":"n3840","loc":[-85.626813,41.947337]},"n3841":{"id":"n3841","loc":[-85.616371,41.952814]},"n3842":{"id":"n3842","loc":[-85.617205,41.951308]},"n3843":{"id":"n3843","loc":[-85.616795,41.950953]},"n3844":{"id":"n3844","loc":[-85.617441,41.950889]},"n3845":{"id":"n3845","loc":[-85.619155,41.949377]},"n3846":{"id":"n3846","loc":[-85.618556,41.949377]},"n3847":{"id":"n3847","loc":[-85.618557,41.948372]},"n3848":{"id":"n3848","loc":[-85.619156,41.948372]},"n3849":{"id":"n3849","loc":[-85.61927,41.949796]},"n385":{"id":"n385","loc":[-85.632319,41.944172]},"n3850":{"id":"n3850","loc":[-85.61926,41.948344]},"n3851":{"id":"n3851","loc":[-85.619219,41.948264]},"n3852":{"id":"n3852","loc":[-85.619147,41.948196]},"n3853":{"id":"n3853","loc":[-85.619049,41.948144]},"n3854":{"id":"n3854","loc":[-85.618942,41.948116]},"n3855":{"id":"n3855","loc":[-85.618822,41.948109]},"n3856":{"id":"n3856","loc":[-85.618699,41.94813]},"n3857":{"id":"n3857","loc":[-85.618937,41.951943]},"n3858":{"id":"n3858","loc":[-85.616762,41.952222]},"n3859":{"id":"n3859","loc":[-85.616799,41.95472]},"n386":{"id":"n386","loc":[-85.63221,41.944066]},"n3860":{"id":"n3860","loc":[-85.616458,41.954735]},"n3861":{"id":"n3861","loc":[-85.61763,41.951515]},"n3862":{"id":"n3862","loc":[-85.617735,41.951572]},"n3863":{"id":"n3863","loc":[-85.61929,41.951573]},"n3864":{"id":"n3864","loc":[-85.617134,41.951348]},"n3865":{"id":"n3865","loc":[-85.616598,41.95192]},"n3866":{"id":"n3866","loc":[-85.616557,41.951997]},"n3867":{"id":"n3867","loc":[-85.61658,41.952093]},"n3868":{"id":"n3868","loc":[-85.616636,41.952145]},"n3869":{"id":"n3869","loc":[-85.616918,41.952276]},"n387":{"id":"n387","loc":[-85.632524,41.943912]},"n3870":{"id":"n3870","loc":[-85.617098,41.952235]},"n3871":{"id":"n3871","loc":[-85.61892,41.951467]},"n3872":{"id":"n3872","loc":[-85.618035,41.951473]},"n3873":{"id":"n3873","loc":[-85.618036,41.951572]},"n3874":{"id":"n3874","loc":[-85.61892,41.951573]},"n3875":{"id":"n3875","loc":[-85.618919,41.951957]},"n3876":{"id":"n3876","loc":[-85.619457,41.952237]},"n3877":{"id":"n3877","loc":[-85.618178,41.953618]},"n3878":{"id":"n3878","loc":[-85.617658,41.953366]},"n3879":{"id":"n3879","loc":[-85.617987,41.953024]},"n388":{"id":"n388","loc":[-85.632268,41.943621]},"n3880":{"id":"n3880","loc":[-85.618429,41.953248]},"n3881":{"id":"n3881","loc":[-85.618554,41.953119]},"n3882":{"id":"n3882","loc":[-85.618077,41.952868]},"n3883":{"id":"n3883","loc":[-85.618039,41.952886]},"n3884":{"id":"n3884","loc":[-85.619375,41.952169]},"n3885":{"id":"n3885","loc":[-85.618137,41.953538]},"n3886":{"id":"n3886","loc":[-85.61799,41.953555]},"n3887":{"id":"n3887","loc":[-85.617729,41.953423]},"n3888":{"id":"n3888","loc":[-85.618101,41.953029]},"n3889":{"id":"n3889","loc":[-85.618516,41.953119]},"n389":{"id":"n389","loc":[-85.631951,41.943773]},"n3890":{"id":"n3890","loc":[-85.619132,41.952042]},"n3891":{"id":"n3891","loc":[-85.618235,41.952981]},"n3892":{"id":"n3892","loc":[-85.618485,41.952425]},"n3893":{"id":"n3893","loc":[-85.618676,41.952519]},"n3894":{"id":"n3894","loc":[-85.618942,41.952648]},"n3895":{"id":"n3895","loc":[-85.618287,41.953122]},"n3896":{"id":"n3896","loc":[-85.617914,41.953516]},"n3897":{"id":"n3897","loc":[-85.617836,41.953573]},"n3898":{"id":"n3898","loc":[-85.616477,41.95289]},"n3899":{"id":"n3899","loc":[-85.618441,41.953201]},"n39":{"id":"n39","loc":[-85.619931,41.951013]},"n390":{"id":"n390","loc":[-85.631981,41.943654]},"n3900":{"id":"n3900","loc":[-85.617537,41.953335]},"n3901":{"id":"n3901","loc":[-85.617221,41.953166]},"n3902":{"id":"n3902","loc":[-85.617253,41.953135]},"n3903":{"id":"n3903","loc":[-85.617211,41.953114]},"n3904":{"id":"n3904","loc":[-85.617197,41.95313]},"n3905":{"id":"n3905","loc":[-85.616802,41.952925]},"n3906":{"id":"n3906","loc":[-85.616771,41.952928]},"n3907":{"id":"n3907","loc":[-85.616493,41.952785]},"n3908":{"id":"n3908","loc":[-85.616823,41.952426]},"n3909":{"id":"n3909","loc":[-85.617191,41.952616]},"n391":{"id":"n391","loc":[-85.631886,41.943699]},"n3910":{"id":"n3910","loc":[-85.61724,41.952559]},"n3911":{"id":"n3911","loc":[-85.61721,41.952542]},"n3912":{"id":"n3912","loc":[-85.617395,41.952351]},"n3913":{"id":"n3913","loc":[-85.617426,41.952368]},"n3914":{"id":"n3914","loc":[-85.617483,41.952309]},"n3915":{"id":"n3915","loc":[-85.617332,41.952229]},"n3916":{"id":"n3916","loc":[-85.617451,41.952102]},"n3917":{"id":"n3917","loc":[-85.617477,41.952115]},"n3918":{"id":"n3918","loc":[-85.617658,41.951923]},"n3919":{"id":"n3919","loc":[-85.617634,41.95191]},"n392":{"id":"n392","loc":[-85.631807,41.943606]},"n3920":{"id":"n3920","loc":[-85.617747,41.951786]},"n3921":{"id":"n3921","loc":[-85.618268,41.952056]},"n3922":{"id":"n3922","loc":[-85.618211,41.952122]},"n3923":{"id":"n3923","loc":[-85.618386,41.95222]},"n3924":{"id":"n3924","loc":[-85.618098,41.952527]},"n3925":{"id":"n3925","loc":[-85.617916,41.95243]},"n3926":{"id":"n3926","loc":[-85.617854,41.952498]},"n3927":{"id":"n3927","loc":[-85.617769,41.952453]},"n3928":{"id":"n3928","loc":[-85.617476,41.952773]},"n3929":{"id":"n3929","loc":[-85.617876,41.952973]},"n393":{"id":"n393","loc":[-85.631902,41.943561]},"n3930":{"id":"n3930","loc":[-85.617174,41.953638]},"n3931":{"id":"n3931","loc":[-85.618016,41.953578]},"n3932":{"id":"n3932","loc":[-85.618107,41.953628]},"n3933":{"id":"n3933","loc":[-85.618067,41.954268]},"n3934":{"id":"n3934","loc":[-85.617864,41.954263]},"n3935":{"id":"n3935","loc":[-85.61762,41.954205]},"n3936":{"id":"n3936","loc":[-85.617437,41.954103]},"n3937":{"id":"n3937","loc":[-85.617294,41.953978]},"n3938":{"id":"n3938","loc":[-85.617217,41.95384]},"n3939":{"id":"n3939","loc":[-85.616814,41.954327]},"n394":{"id":"n394","loc":[-85.63236,41.943543]},"n3940":{"id":"n3940","loc":[-85.616778,41.95381]},"n3941":{"id":"n3941","loc":[-85.616585,41.953707]},"n3942":{"id":"n3942","loc":[-85.616458,41.954318]},"n3943":{"id":"n3943","loc":[-85.616643,41.954345]},"n3944":{"id":"n3944","loc":[-85.618133,41.951412]},"n3945":{"id":"n3945","loc":[-85.618326,41.951411]},"n3946":{"id":"n3946","loc":[-85.618503,41.95141]},"n3947":{"id":"n3947","loc":[-85.618681,41.951409]},"n3948":{"id":"n3948","loc":[-85.618868,41.951408]},"n3949":{"id":"n3949","loc":[-85.617047,41.95136]},"n395":{"id":"n395","loc":[-85.633839,41.944082]},"n3950":{"id":"n3950","loc":[-85.616502,41.951946]},"n3951":{"id":"n3951","loc":[-85.616497,41.952072]},"n3952":{"id":"n3952","loc":[-85.616565,41.952165]},"n3953":{"id":"n3953","loc":[-85.616663,41.952218]},"n3954":{"id":"n3954","loc":[-85.616733,41.952255]},"n3955":{"id":"n3955","loc":[-85.617238,41.952512],"tags":{"entrance":"yes"}},"n3956":{"id":"n3956","loc":[-85.617043,41.952406]},"n3957":{"id":"n3957","loc":[-85.617691,41.951711]},"n3958":{"id":"n3958","loc":[-85.617773,41.951679]},"n3959":{"id":"n3959","loc":[-85.619085,41.951681]},"n396":{"id":"n396","loc":[-85.63376,41.944097]},"n3960":{"id":"n3960","loc":[-85.617943,41.952895]},"n3961":{"id":"n3961","loc":[-85.618039,41.952938]},"n3962":{"id":"n3962","loc":[-85.61763,41.95336]},"n3963":{"id":"n3963","loc":[-85.617554,41.95344]},"n3964":{"id":"n3964","loc":[-85.617381,41.952366],"tags":{"entrance":"yes"}},"n3965":{"id":"n3965","loc":[-85.617184,41.952254]},"n3966":{"id":"n3966","loc":[-85.617208,41.952496]},"n3967":{"id":"n3967","loc":[-85.617124,41.952581],"tags":{"entrance":"yes"}},"n3968":{"id":"n3968","loc":[-85.618094,41.952735]},"n3969":{"id":"n3969","loc":[-85.617702,41.952525],"tags":{"entrance":"yes"}},"n397":{"id":"n397","loc":[-85.63361,41.943957]},"n3970":{"id":"n3970","loc":[-85.617554,41.952686],"tags":{"entrance":"yes"}},"n3971":{"id":"n3971","loc":[-85.617959,41.952878]},"n3972":{"id":"n3972","loc":[-85.616367,41.952655]},"n3973":{"id":"n3973","loc":[-85.616416,41.952851]},"n3974":{"id":"n3974","loc":[-85.619777,41.951075]},"n3975":{"id":"n3975","loc":[-85.618611,41.94817]},"n3976":{"id":"n3976","loc":[-85.618538,41.948229]},"n3977":{"id":"n3977","loc":[-85.617421,41.947559]},"n3978":{"id":"n3978","loc":[-85.617395,41.951039]},"n3979":{"id":"n3979","loc":[-85.618488,41.94829]},"n398":{"id":"n398","loc":[-85.633309,41.943886]},"n3980":{"id":"n3980","loc":[-85.610238,41.954774]},"n3981":{"id":"n3981","loc":[-85.617449,41.950756]},"n3982":{"id":"n3982","loc":[-85.617288,41.951286]},"n3983":{"id":"n3983","loc":[-85.61745,41.950197]},"n3984":{"id":"n3984","loc":[-85.617436,41.948908]},"n3985":{"id":"n3985","loc":[-85.615915,41.953804]},"n3986":{"id":"n3986","loc":[-85.615953,41.953968]},"n3987":{"id":"n3987","loc":[-85.616031,41.954085]},"n3988":{"id":"n3988","loc":[-85.616135,41.954181]},"n3989":{"id":"n3989","loc":[-85.616273,41.954263]},"n399":{"id":"n399","loc":[-85.633226,41.943931]},"n3990":{"id":"n3990","loc":[-85.618327,41.951083]},"n3991":{"id":"n3991","loc":[-85.618135,41.951084]},"n3992":{"id":"n3992","loc":[-85.618503,41.951082]},"n3993":{"id":"n3993","loc":[-85.618682,41.951081]},"n3994":{"id":"n3994","loc":[-85.618864,41.951082]},"n3995":{"id":"n3995","loc":[-85.616761,41.950101]},"n3996":{"id":"n3996","loc":[-85.617317,41.947558]},"n3997":{"id":"n3997","loc":[-85.617336,41.948883]},"n3998":{"id":"n3998","loc":[-85.616779,41.949295]},"n3999":{"id":"n3999","loc":[-85.616754,41.949349]},"n4":{"id":"n4","loc":[-85.622764,41.950892],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n40":{"id":"n40","loc":[-85.619841,41.951037]},"n400":{"id":"n400","loc":[-85.63326,41.943966]},"n4000":{"id":"n4000","loc":[-85.616761,41.950865]},"n4001":{"id":"n4001","loc":[-85.616883,41.951041]},"n4002":{"id":"n4002","loc":[-85.617004,41.951142]},"n4003":{"id":"n4003","loc":[-85.617062,41.951248]},"n4004":{"id":"n4004","loc":[-85.616809,41.949273]},"n4005":{"id":"n4005","loc":[-85.616755,41.949489]},"n4006":{"id":"n4006","loc":[-85.616759,41.949971]},"n4007":{"id":"n4007","loc":[-85.616757,41.949702]},"n4008":{"id":"n4008","loc":[-85.618456,41.94836]},"n4009":{"id":"n4009","loc":[-85.618447,41.948428]},"n401":{"id":"n401","loc":[-85.63324,41.943976]},"n4010":{"id":"n4010","loc":[-85.618437,41.949322]},"n4011":{"id":"n4011","loc":[-85.618447,41.949418]},"n4012":{"id":"n4012","loc":[-85.618478,41.949491]},"n4013":{"id":"n4013","loc":[-85.618535,41.949559]},"n4014":{"id":"n4014","loc":[-85.618623,41.94962]},"n4015":{"id":"n4015","loc":[-85.618721,41.94966]},"n4016":{"id":"n4016","loc":[-85.618838,41.949674]},"n4017":{"id":"n4017","loc":[-85.618967,41.949667]},"n4018":{"id":"n4018","loc":[-85.619065,41.949632]},"n4019":{"id":"n4019","loc":[-85.61915,41.949578]},"n402":{"id":"n402","loc":[-85.63327,41.944006]},"n4020":{"id":"n4020","loc":[-85.619216,41.949507]},"n4021":{"id":"n4021","loc":[-85.61927,41.949399]},"n4022":{"id":"n4022","loc":[-85.619074,41.947639]},"n4023":{"id":"n4023","loc":[-85.619073,41.947793]},"n4024":{"id":"n4024","loc":[-85.618912,41.947793]},"n4025":{"id":"n4025","loc":[-85.618911,41.947947]},"n4026":{"id":"n4026","loc":[-85.618752,41.947947]},"n4027":{"id":"n4027","loc":[-85.618754,41.947637]},"n4028":{"id":"n4028","loc":[-85.617896,41.947599]},"n4029":{"id":"n4029","loc":[-85.617898,41.947811]},"n403":{"id":"n403","loc":[-85.633278,41.944002]},"n4030":{"id":"n4030","loc":[-85.617717,41.947812]},"n4031":{"id":"n4031","loc":[-85.617715,41.9476]},"n4032":{"id":"n4032","loc":[-85.619003,41.949828]},"n4033":{"id":"n4033","loc":[-85.619003,41.949882]},"n4034":{"id":"n4034","loc":[-85.618926,41.949882]},"n4035":{"id":"n4035","loc":[-85.618926,41.949828]},"n4036":{"id":"n4036","loc":[-85.618861,41.949809]},"n4037":{"id":"n4037","loc":[-85.618861,41.949898]},"n4038":{"id":"n4038","loc":[-85.618688,41.949898]},"n4039":{"id":"n4039","loc":[-85.618687,41.94981]},"n404":{"id":"n404","loc":[-85.63331,41.944036]},"n4040":{"id":"n4040","loc":[-85.618349,41.949473]},"n4041":{"id":"n4041","loc":[-85.618287,41.949473]},"n4042":{"id":"n4042","loc":[-85.618287,41.94942]},"n4043":{"id":"n4043","loc":[-85.618348,41.949419]},"n4044":{"id":"n4044","loc":[-85.62316,41.951604]},"n4045":{"id":"n4045","loc":[-85.623026,41.951605]},"n4046":{"id":"n4046","loc":[-85.623023,41.951466]},"n4047":{"id":"n4047","loc":[-85.623134,41.951465]},"n4048":{"id":"n4048","loc":[-85.623136,41.951539]},"n4049":{"id":"n4049","loc":[-85.623159,41.951539]},"n405":{"id":"n405","loc":[-85.633348,41.944015]},"n4050":{"id":"n4050","loc":[-85.623025,41.95155]},"n4051":{"id":"n4051","loc":[-85.622955,41.951551]},"n4052":{"id":"n4052","loc":[-85.622953,41.951507]},"n4053":{"id":"n4053","loc":[-85.623024,41.951506]},"n4054":{"id":"n4054","loc":[-85.623318,41.951242]},"n4055":{"id":"n4055","loc":[-85.623175,41.951241]},"n4056":{"id":"n4056","loc":[-85.623176,41.951153]},"n4057":{"id":"n4057","loc":[-85.623319,41.951154]},"n4058":{"id":"n4058","loc":[-85.623077,41.951191]},"n4059":{"id":"n4059","loc":[-85.622973,41.951191]},"n406":{"id":"n406","loc":[-85.63338,41.944048]},"n4060":{"id":"n4060","loc":[-85.622972,41.951349]},"n4061":{"id":"n4061","loc":[-85.623059,41.95135]},"n4062":{"id":"n4062","loc":[-85.62306,41.951301]},"n4063":{"id":"n4063","loc":[-85.623077,41.951301]},"n4064":{"id":"n4064","loc":[-85.623117,41.951405]},"n4065":{"id":"n4065","loc":[-85.62312,41.951087]},"n4066":{"id":"n4066","loc":[-85.623118,41.951274]},"n4067":{"id":"n4067","loc":[-85.62328,41.951275]},"n4068":{"id":"n4068","loc":[-85.62328,41.951242]},"n4069":{"id":"n4069","loc":[-85.623179,41.951392]},"n407":{"id":"n407","loc":[-85.633431,41.94402]},"n4070":{"id":"n4070","loc":[-85.623141,41.951392]},"n4071":{"id":"n4071","loc":[-85.623142,41.95136]},"n4072":{"id":"n4072","loc":[-85.623179,41.951361]},"n4073":{"id":"n4073","loc":[-85.622565,41.951639]},"n4074":{"id":"n4074","loc":[-85.622565,41.951741]},"n4075":{"id":"n4075","loc":[-85.622463,41.95174]},"n4076":{"id":"n4076","loc":[-85.622463,41.95173]},"n4077":{"id":"n4077","loc":[-85.622442,41.95173]},"n4078":{"id":"n4078","loc":[-85.622442,41.951742]},"n4079":{"id":"n4079","loc":[-85.622361,41.951742]},"n408":{"id":"n408","loc":[-85.633425,41.944014]},"n4080":{"id":"n4080","loc":[-85.622362,41.951667]},"n4081":{"id":"n4081","loc":[-85.622441,41.951667]},"n4082":{"id":"n4082","loc":[-85.622441,41.951688]},"n4083":{"id":"n4083","loc":[-85.622461,41.951688]},"n4084":{"id":"n4084","loc":[-85.622461,41.951638]},"n4085":{"id":"n4085","loc":[-85.62255,41.951587]},"n4086":{"id":"n4086","loc":[-85.622449,41.95159]},"n4087":{"id":"n4087","loc":[-85.622441,41.951448]},"n4088":{"id":"n4088","loc":[-85.62253,41.951445]},"n4089":{"id":"n4089","loc":[-85.622532,41.951486]},"n409":{"id":"n409","loc":[-85.633457,41.943997]},"n4090":{"id":"n4090","loc":[-85.622555,41.951485]},"n4091":{"id":"n4091","loc":[-85.622558,41.951531]},"n4092":{"id":"n4092","loc":[-85.622547,41.951531]},"n4093":{"id":"n4093","loc":[-85.622451,41.95159]},"n4094":{"id":"n4094","loc":[-85.622452,41.95161]},"n4095":{"id":"n4095","loc":[-85.622106,41.951617]},"n4096":{"id":"n4096","loc":[-85.622133,41.951443]},"n4097":{"id":"n4097","loc":[-85.622552,41.951379]},"n4098":{"id":"n4098","loc":[-85.622443,41.95138]},"n4099":{"id":"n4099","loc":[-85.622441,41.951281]},"n41":{"id":"n41","loc":[-85.636233,41.942764]},"n410":{"id":"n410","loc":[-85.633429,41.943969]},"n4100":{"id":"n4100","loc":[-85.62255,41.95128]},"n4101":{"id":"n4101","loc":[-85.622541,41.951437]},"n4102":{"id":"n4102","loc":[-85.622441,41.951438]},"n4103":{"id":"n4103","loc":[-85.621561,41.951444]},"n4104":{"id":"n4104","loc":[-85.622302,41.951479]},"n4105":{"id":"n4105","loc":[-85.6223,41.95152]},"n4106":{"id":"n4106","loc":[-85.622169,41.951517]},"n4107":{"id":"n4107","loc":[-85.622171,41.951476]},"n4108":{"id":"n4108","loc":[-85.622543,41.951228]},"n4109":{"id":"n4109","loc":[-85.622433,41.951228]},"n411":{"id":"n411","loc":[-85.633442,41.943962]},"n4110":{"id":"n4110","loc":[-85.622433,41.951133]},"n4111":{"id":"n4111","loc":[-85.622543,41.951133]},"n4112":{"id":"n4112","loc":[-85.622356,41.951256]},"n4113":{"id":"n4113","loc":[-85.622293,41.951256]},"n4114":{"id":"n4114","loc":[-85.622292,41.9512]},"n4115":{"id":"n4115","loc":[-85.622313,41.9512]},"n4116":{"id":"n4116","loc":[-85.622312,41.951173]},"n4117":{"id":"n4117","loc":[-85.622364,41.951173]},"n4118":{"id":"n4118","loc":[-85.622365,41.951231]},"n4119":{"id":"n4119","loc":[-85.622355,41.951231]},"n412":{"id":"n412","loc":[-85.633411,41.943932]},"n4120":{"id":"n4120","loc":[-85.62197,41.951155]},"n4121":{"id":"n4121","loc":[-85.62197,41.951213]},"n4122":{"id":"n4122","loc":[-85.621848,41.951213]},"n4123":{"id":"n4123","loc":[-85.621848,41.951155]},"n4124":{"id":"n4124","loc":[-85.622193,41.951268]},"n4125":{"id":"n4125","loc":[-85.622194,41.951305]},"n4126":{"id":"n4126","loc":[-85.622121,41.951306]},"n4127":{"id":"n4127","loc":[-85.622121,41.951322]},"n4128":{"id":"n4128","loc":[-85.621984,41.951324]},"n4129":{"id":"n4129","loc":[-85.621983,41.951271]},"n413":{"id":"n413","loc":[-85.633421,41.943926]},"n4130":{"id":"n4130","loc":[-85.622171,41.9514]},"n4131":{"id":"n4131","loc":[-85.622148,41.951382]},"n4132":{"id":"n4132","loc":[-85.6221,41.951414]},"n4133":{"id":"n4133","loc":[-85.622122,41.951433]},"n4134":{"id":"n4134","loc":[-85.621782,41.951148]},"n4135":{"id":"n4135","loc":[-85.621783,41.951219]},"n4136":{"id":"n4136","loc":[-85.62164,41.951221]},"n4137":{"id":"n4137","loc":[-85.62164,41.951236]},"n4138":{"id":"n4138","loc":[-85.621556,41.951237]},"n4139":{"id":"n4139","loc":[-85.621555,41.95117]},"n414":{"id":"n414","loc":[-85.633376,41.94388]},"n4140":{"id":"n4140","loc":[-85.621644,41.951169]},"n4141":{"id":"n4141","loc":[-85.621643,41.951139]},"n4142":{"id":"n4142","loc":[-85.621719,41.951138]},"n4143":{"id":"n4143","loc":[-85.621719,41.951148]},"n4144":{"id":"n4144","loc":[-85.621409,41.951322]},"n4145":{"id":"n4145","loc":[-85.621338,41.951322]},"n4146":{"id":"n4146","loc":[-85.621336,41.95115]},"n4147":{"id":"n4147","loc":[-85.621521,41.951149]},"n4148":{"id":"n4148","loc":[-85.621522,41.951228]},"n4149":{"id":"n4149","loc":[-85.621408,41.951228]},"n415":{"id":"n415","loc":[-85.633348,41.943895]},"n4150":{"id":"n4150","loc":[-85.621284,41.951219]},"n4151":{"id":"n4151","loc":[-85.621153,41.951219]},"n4152":{"id":"n4152","loc":[-85.621152,41.951152]},"n4153":{"id":"n4153","loc":[-85.621283,41.951152]},"n4154":{"id":"n4154","loc":[-85.621159,41.951241]},"n4155":{"id":"n4155","loc":[-85.62116,41.951301]},"n4156":{"id":"n4156","loc":[-85.621088,41.951302]},"n4157":{"id":"n4157","loc":[-85.621088,41.951241]},"n4158":{"id":"n4158","loc":[-85.621049,41.951158]},"n4159":{"id":"n4159","loc":[-85.62105,41.951229]},"n416":{"id":"n416","loc":[-85.633341,41.943888]},"n4160":{"id":"n4160","loc":[-85.620976,41.951229]},"n4161":{"id":"n4161","loc":[-85.620977,41.951295]},"n4162":{"id":"n4162","loc":[-85.620887,41.951296]},"n4163":{"id":"n4163","loc":[-85.620886,41.951229]},"n4164":{"id":"n4164","loc":[-85.620862,41.951229]},"n4165":{"id":"n4165","loc":[-85.620861,41.951159]},"n4166":{"id":"n4166","loc":[-85.620626,41.951133]},"n4167":{"id":"n4167","loc":[-85.620626,41.951205]},"n4168":{"id":"n4168","loc":[-85.620412,41.951206]},"n4169":{"id":"n4169","loc":[-85.620411,41.951134]},"n417":{"id":"n417","loc":[-85.633321,41.943898]},"n4170":{"id":"n4170","loc":[-85.621775,41.951443]},"n4171":{"id":"n4171","loc":[-85.621777,41.951264]},"n4172":{"id":"n4172","loc":[-85.621565,41.951654]},"n4173":{"id":"n4173","loc":[-85.621331,41.951439]},"n4174":{"id":"n4174","loc":[-85.621031,41.951443]},"n4175":{"id":"n4175","loc":[-85.621836,41.951724]},"n4176":{"id":"n4176","loc":[-85.621834,41.951621]},"n4177":{"id":"n4177","loc":[-85.62197,41.951619]},"n4178":{"id":"n4178","loc":[-85.621972,41.951722]},"n4179":{"id":"n4179","loc":[-85.621772,41.951638]},"n418":{"id":"n418","loc":[-85.633547,41.943896]},"n4180":{"id":"n4180","loc":[-85.621772,41.951715]},"n4181":{"id":"n4181","loc":[-85.621699,41.951716]},"n4182":{"id":"n4182","loc":[-85.6217,41.951722]},"n4183":{"id":"n4183","loc":[-85.621641,41.951722]},"n4184":{"id":"n4184","loc":[-85.62164,41.951639]},"n4185":{"id":"n4185","loc":[-85.621505,41.951655]},"n4186":{"id":"n4186","loc":[-85.621505,41.951729]},"n4187":{"id":"n4187","loc":[-85.621389,41.951729]},"n4188":{"id":"n4188","loc":[-85.62139,41.951654]},"n4189":{"id":"n4189","loc":[-85.621105,41.951635]},"n419":{"id":"n419","loc":[-85.633467,41.944075]},"n4190":{"id":"n4190","loc":[-85.621104,41.951576]},"n4191":{"id":"n4191","loc":[-85.621168,41.951576]},"n4192":{"id":"n4192","loc":[-85.621168,41.951595]},"n4193":{"id":"n4193","loc":[-85.621261,41.951595]},"n4194":{"id":"n4194","loc":[-85.621261,41.951646]},"n4195":{"id":"n4195","loc":[-85.621294,41.951646]},"n4196":{"id":"n4196","loc":[-85.621294,41.951732]},"n4197":{"id":"n4197","loc":[-85.621251,41.951732]},"n4198":{"id":"n4198","loc":[-85.621251,41.95174]},"n4199":{"id":"n4199","loc":[-85.621175,41.951741]},"n42":{"id":"n42","loc":[-85.635996,41.942727]},"n420":{"id":"n420","loc":[-85.633578,41.944055]},"n4200":{"id":"n4200","loc":[-85.621175,41.951651]},"n4201":{"id":"n4201","loc":[-85.621189,41.951651]},"n4202":{"id":"n4202","loc":[-85.621189,41.951635]},"n4203":{"id":"n4203","loc":[-85.620554,41.951641]},"n4204":{"id":"n4204","loc":[-85.620555,41.951742]},"n4205":{"id":"n4205","loc":[-85.620719,41.951742]},"n4206":{"id":"n4206","loc":[-85.620719,41.951731]},"n4207":{"id":"n4207","loc":[-85.620803,41.95173]},"n4208":{"id":"n4208","loc":[-85.620803,41.951603]},"n4209":{"id":"n4209","loc":[-85.62072,41.951603]},"n421":{"id":"n421","loc":[-85.633462,41.944125]},"n4210":{"id":"n4210","loc":[-85.620721,41.951641]},"n4211":{"id":"n4211","loc":[-85.620269,41.953053]},"n4212":{"id":"n4212","loc":[-85.620229,41.953051]},"n4213":{"id":"n4213","loc":[-85.620231,41.953013]},"n4214":{"id":"n4214","loc":[-85.620271,41.953015]},"n4215":{"id":"n4215","loc":[-85.620215,41.953133]},"n4216":{"id":"n4216","loc":[-85.62013,41.953134]},"n4217":{"id":"n4217","loc":[-85.620129,41.953083]},"n4218":{"id":"n4218","loc":[-85.620214,41.953082]},"n4219":{"id":"n4219","loc":[-85.62016,41.953272]},"n422":{"id":"n422","loc":[-85.633372,41.944061]},"n4220":{"id":"n4220","loc":[-85.620046,41.953273]},"n4221":{"id":"n4221","loc":[-85.620045,41.953171]},"n4222":{"id":"n4222","loc":[-85.620088,41.953171]},"n4223":{"id":"n4223","loc":[-85.620087,41.953162]},"n4224":{"id":"n4224","loc":[-85.620121,41.953162]},"n4225":{"id":"n4225","loc":[-85.620121,41.953173]},"n4226":{"id":"n4226","loc":[-85.620157,41.953173]},"n4227":{"id":"n4227","loc":[-85.620158,41.953196]},"n4228":{"id":"n4228","loc":[-85.620189,41.953196]},"n4229":{"id":"n4229","loc":[-85.620189,41.953246]},"n423":{"id":"n423","loc":[-85.633509,41.943981]},"n4230":{"id":"n4230","loc":[-85.62016,41.953246]},"n4231":{"id":"n4231","loc":[-85.6195,41.954012]},"n4232":{"id":"n4232","loc":[-85.619438,41.954057]},"n4233":{"id":"n4233","loc":[-85.619418,41.954043]},"n4234":{"id":"n4234","loc":[-85.619381,41.954069]},"n4235":{"id":"n4235","loc":[-85.619399,41.954083]},"n4236":{"id":"n4236","loc":[-85.619339,41.954126]},"n4237":{"id":"n4237","loc":[-85.619584,41.954313]},"n4238":{"id":"n4238","loc":[-85.619743,41.954198]},"n4239":{"id":"n4239","loc":[-85.619453,41.954727]},"n424":{"id":"n424","loc":[-85.635421,41.945367]},"n4240":{"id":"n4240","loc":[-85.619503,41.954581]},"n4241":{"id":"n4241","loc":[-85.619597,41.954472]},"n4242":{"id":"n4242","loc":[-85.619862,41.95419]},"n4243":{"id":"n4243","loc":[-85.619506,41.953907]},"n4244":{"id":"n4244","loc":[-85.619261,41.9541]},"n4245":{"id":"n4245","loc":[-85.619246,41.954139]},"n4246":{"id":"n4246","loc":[-85.619244,41.9542]},"n4247":{"id":"n4247","loc":[-85.619259,41.954243]},"n4248":{"id":"n4248","loc":[-85.619285,41.954274]},"n4249":{"id":"n4249","loc":[-85.619123,41.954381]},"n425":{"id":"n425","loc":[-85.634425,41.943552]},"n4250":{"id":"n4250","loc":[-85.619641,41.954607]},"n4251":{"id":"n4251","loc":[-85.619383,41.954615]},"n4252":{"id":"n4252","loc":[-85.61896,41.954391]},"n4253":{"id":"n4253","loc":[-85.619211,41.954178]},"n4254":{"id":"n4254","loc":[-85.619115,41.954102]},"n4255":{"id":"n4255","loc":[-85.619519,41.953821]},"n4256":{"id":"n4256","loc":[-85.619956,41.954156]},"n4257":{"id":"n4257","loc":[-85.619851,41.954266]},"n4258":{"id":"n4258","loc":[-85.619779,41.95436]},"n4259":{"id":"n4259","loc":[-85.620525,41.954364]},"n426":{"id":"n426","loc":[-85.634248,41.943654]},"n4260":{"id":"n4260","loc":[-85.620398,41.954365]},"n4261":{"id":"n4261","loc":[-85.620398,41.954324]},"n4262":{"id":"n4262","loc":[-85.620525,41.954323]},"n4263":{"id":"n4263","loc":[-85.620359,41.954588]},"n4264":{"id":"n4264","loc":[-85.620321,41.954588]},"n4265":{"id":"n4265","loc":[-85.620321,41.954599]},"n4266":{"id":"n4266","loc":[-85.620296,41.954599]},"n4267":{"id":"n4267","loc":[-85.620296,41.954587]},"n4268":{"id":"n4268","loc":[-85.620262,41.954588]},"n4269":{"id":"n4269","loc":[-85.620261,41.954516]},"n427":{"id":"n427","loc":[-85.634177,41.943585]},"n4270":{"id":"n4270","loc":[-85.620282,41.954516]},"n4271":{"id":"n4271","loc":[-85.620282,41.954373]},"n4272":{"id":"n4272","loc":[-85.620378,41.954373]},"n4273":{"id":"n4273","loc":[-85.620379,41.954486]},"n4274":{"id":"n4274","loc":[-85.620348,41.954486]},"n4275":{"id":"n4275","loc":[-85.620348,41.954537]},"n4276":{"id":"n4276","loc":[-85.620359,41.954537]},"n4277":{"id":"n4277","loc":[-85.620463,41.95521]},"n4278":{"id":"n4278","loc":[-85.620409,41.955273]},"n4279":{"id":"n4279","loc":[-85.620205,41.955177]},"n428":{"id":"n428","loc":[-85.634354,41.943484]},"n4280":{"id":"n4280","loc":[-85.620288,41.955079]},"n4281":{"id":"n4281","loc":[-85.620379,41.955121]},"n4282":{"id":"n4282","loc":[-85.620349,41.955157]},"n4283":{"id":"n4283","loc":[-85.620083,41.955101]},"n4284":{"id":"n4284","loc":[-85.620083,41.954986]},"n4285":{"id":"n4285","loc":[-85.620016,41.954986]},"n4286":{"id":"n4286","loc":[-85.620016,41.954999]},"n4287":{"id":"n4287","loc":[-85.619941,41.954999]},"n4288":{"id":"n4288","loc":[-85.619941,41.954988]},"n4289":{"id":"n4289","loc":[-85.619815,41.954988]},"n429":{"id":"n429","loc":[-85.638577,41.943212]},"n4290":{"id":"n4290","loc":[-85.619815,41.955075]},"n4291":{"id":"n4291","loc":[-85.619948,41.955075]},"n4292":{"id":"n4292","loc":[-85.619948,41.955082]},"n4293":{"id":"n4293","loc":[-85.620004,41.955082]},"n4294":{"id":"n4294","loc":[-85.620004,41.955101]},"n4295":{"id":"n4295","loc":[-85.619293,41.955127]},"n4296":{"id":"n4296","loc":[-85.619208,41.955124]},"n4297":{"id":"n4297","loc":[-85.619212,41.955061]},"n4298":{"id":"n4298","loc":[-85.619297,41.955064]},"n4299":{"id":"n4299","loc":[-85.619068,41.954936]},"n43":{"id":"n43","loc":[-85.637047,41.943054]},"n430":{"id":"n430","loc":[-85.638576,41.943219]},"n4300":{"id":"n4300","loc":[-85.619003,41.954936]},"n4301":{"id":"n4301","loc":[-85.619004,41.955003]},"n4302":{"id":"n4302","loc":[-85.618994,41.955003]},"n4303":{"id":"n4303","loc":[-85.618994,41.955016]},"n4304":{"id":"n4304","loc":[-85.618973,41.955016]},"n4305":{"id":"n4305","loc":[-85.618973,41.955071]},"n4306":{"id":"n4306","loc":[-85.619061,41.955071]},"n4307":{"id":"n4307","loc":[-85.61906,41.955024]},"n4308":{"id":"n4308","loc":[-85.619105,41.955024]},"n4309":{"id":"n4309","loc":[-85.619105,41.954956]},"n431":{"id":"n431","loc":[-85.638653,41.943078]},"n4310":{"id":"n4310","loc":[-85.619068,41.954956]},"n4311":{"id":"n4311","loc":[-85.618294,41.954596]},"n4312":{"id":"n4312","loc":[-85.618235,41.954602]},"n4313":{"id":"n4313","loc":[-85.618222,41.954535]},"n4314":{"id":"n4314","loc":[-85.618281,41.954529]},"n4315":{"id":"n4315","loc":[-85.618593,41.954556]},"n4316":{"id":"n4316","loc":[-85.618551,41.954565]},"n4317":{"id":"n4317","loc":[-85.618545,41.954552]},"n4318":{"id":"n4318","loc":[-85.618493,41.954563]},"n4319":{"id":"n4319","loc":[-85.618449,41.954455]},"n432":{"id":"n432","loc":[-85.638654,41.943148]},"n4320":{"id":"n4320","loc":[-85.618544,41.954434]},"n4321":{"id":"n4321","loc":[-85.622545,41.950775]},"n4322":{"id":"n4322","loc":[-85.622546,41.950843]},"n4323":{"id":"n4323","loc":[-85.622503,41.950844]},"n4324":{"id":"n4324","loc":[-85.622503,41.950853]},"n4325":{"id":"n4325","loc":[-85.622479,41.950853]},"n4326":{"id":"n4326","loc":[-85.622478,41.950843]},"n4327":{"id":"n4327","loc":[-85.622425,41.950843]},"n4328":{"id":"n4328","loc":[-85.622425,41.950808]},"n4329":{"id":"n4329","loc":[-85.622366,41.950809]},"n433":{"id":"n433","loc":[-85.638387,41.943151]},"n4330":{"id":"n4330","loc":[-85.622364,41.950673]},"n4331":{"id":"n4331","loc":[-85.622448,41.950673]},"n4332":{"id":"n4332","loc":[-85.622449,41.950732]},"n4333":{"id":"n4333","loc":[-85.622479,41.950731]},"n4334":{"id":"n4334","loc":[-85.622479,41.950775]},"n4335":{"id":"n4335","loc":[-85.621909,41.950641]},"n4336":{"id":"n4336","loc":[-85.621864,41.950641]},"n4337":{"id":"n4337","loc":[-85.621865,41.950567]},"n4338":{"id":"n4338","loc":[-85.62191,41.950567]},"n4339":{"id":"n4339","loc":[-85.621787,41.950829]},"n434":{"id":"n434","loc":[-85.638386,41.94308]},"n4340":{"id":"n4340","loc":[-85.621786,41.950775]},"n4341":{"id":"n4341","loc":[-85.621588,41.950776]},"n4342":{"id":"n4342","loc":[-85.621589,41.950848]},"n4343":{"id":"n4343","loc":[-85.621737,41.950847]},"n4344":{"id":"n4344","loc":[-85.621737,41.950829]},"n4345":{"id":"n4345","loc":[-85.621509,41.950846]},"n4346":{"id":"n4346","loc":[-85.621399,41.950846]},"n4347":{"id":"n4347","loc":[-85.621398,41.95073]},"n4348":{"id":"n4348","loc":[-85.621509,41.95073]},"n4349":{"id":"n4349","loc":[-85.621217,41.950841]},"n435":{"id":"n435","loc":[-85.634427,41.943533]},"n4350":{"id":"n4350","loc":[-85.6211,41.95084]},"n4351":{"id":"n4351","loc":[-85.6211,41.950777]},"n4352":{"id":"n4352","loc":[-85.621218,41.950778]},"n4353":{"id":"n4353","loc":[-85.621055,41.950764]},"n4354":{"id":"n4354","loc":[-85.621054,41.950826]},"n4355":{"id":"n4355","loc":[-85.620988,41.950826]},"n4356":{"id":"n4356","loc":[-85.620988,41.950843]},"n4357":{"id":"n4357","loc":[-85.620842,41.950843]},"n4358":{"id":"n4358","loc":[-85.620842,41.950764]},"n4359":{"id":"n4359","loc":[-85.620825,41.950922]},"n436":{"id":"n436","loc":[-85.63428,41.943229]},"n4360":{"id":"n4360","loc":[-85.620824,41.950553]},"n4361":{"id":"n4361","loc":[-85.620543,41.950771]},"n4362":{"id":"n4362","loc":[-85.620431,41.950772]},"n4363":{"id":"n4363","loc":[-85.62043,41.950585]},"n4364":{"id":"n4364","loc":[-85.620542,41.950585]},"n4365":{"id":"n4365","loc":[-85.62068,41.950505]},"n4366":{"id":"n4366","loc":[-85.620681,41.950552]},"n4367":{"id":"n4367","loc":[-85.620589,41.950553]},"n4368":{"id":"n4368","loc":[-85.620588,41.950506]},"n4369":{"id":"n4369","loc":[-85.620539,41.950407]},"n437":{"id":"n437","loc":[-85.634499,41.943461]},"n4370":{"id":"n4370","loc":[-85.62054,41.950504]},"n4371":{"id":"n4371","loc":[-85.620416,41.950504]},"n4372":{"id":"n4372","loc":[-85.620416,41.950408]},"n4373":{"id":"n4373","loc":[-85.620742,41.95038]},"n4374":{"id":"n4374","loc":[-85.620527,41.95038]},"n4375":{"id":"n4375","loc":[-85.620528,41.950408]},"n4376":{"id":"n4376","loc":[-85.622449,41.950373]},"n4377":{"id":"n4377","loc":[-85.622452,41.950397]},"n4378":{"id":"n4378","loc":[-85.622336,41.950404]},"n4379":{"id":"n4379","loc":[-85.622333,41.950379]},"n438":{"id":"n438","loc":[-85.634514,41.943486]},"n4380":{"id":"n4380","loc":[-85.622263,41.950324]},"n4381":{"id":"n4381","loc":[-85.622261,41.950256]},"n4382":{"id":"n4382","loc":[-85.62236,41.950254]},"n4383":{"id":"n4383","loc":[-85.62236,41.95027]},"n4384":{"id":"n4384","loc":[-85.622402,41.950281]},"n4385":{"id":"n4385","loc":[-85.622403,41.9503]},"n4386":{"id":"n4386","loc":[-85.622439,41.950299]},"n4387":{"id":"n4387","loc":[-85.62244,41.950334]},"n4388":{"id":"n4388","loc":[-85.622414,41.950335]},"n4389":{"id":"n4389","loc":[-85.622414,41.95036]},"n439":{"id":"n439","loc":[-85.63452,41.943511]},"n4390":{"id":"n4390","loc":[-85.62231,41.950362]},"n4391":{"id":"n4391","loc":[-85.622309,41.950323]},"n4392":{"id":"n4392","loc":[-85.622015,41.950539]},"n4393":{"id":"n4393","loc":[-85.621909,41.95054]},"n4394":{"id":"n4394","loc":[-85.621909,41.950472]},"n4395":{"id":"n4395","loc":[-85.622015,41.950471]},"n4396":{"id":"n4396","loc":[-85.62199,41.950439]},"n4397":{"id":"n4397","loc":[-85.621956,41.95044]},"n4398":{"id":"n4398","loc":[-85.621955,41.950405]},"n4399":{"id":"n4399","loc":[-85.621988,41.950404]},"n44":{"id":"n44","loc":[-85.636799,41.943055]},"n440":{"id":"n440","loc":[-85.63451,41.943534]},"n4400":{"id":"n4400","loc":[-85.621668,41.950418]},"n4401":{"id":"n4401","loc":[-85.621667,41.950343]},"n4402":{"id":"n4402","loc":[-85.621745,41.950342]},"n4403":{"id":"n4403","loc":[-85.621744,41.950306]},"n4404":{"id":"n4404","loc":[-85.621764,41.950306]},"n4405":{"id":"n4405","loc":[-85.621763,41.950254]},"n4406":{"id":"n4406","loc":[-85.621861,41.950253]},"n4407":{"id":"n4407","loc":[-85.621861,41.950274]},"n4408":{"id":"n4408","loc":[-85.621896,41.950273]},"n4409":{"id":"n4409","loc":[-85.621898,41.950389]},"n441":{"id":"n441","loc":[-85.634483,41.943556]},"n4410":{"id":"n4410","loc":[-85.621843,41.95039]},"n4411":{"id":"n4411","loc":[-85.621843,41.950425]},"n4412":{"id":"n4412","loc":[-85.621789,41.950425]},"n4413":{"id":"n4413","loc":[-85.621789,41.950386]},"n4414":{"id":"n4414","loc":[-85.621752,41.950387]},"n4415":{"id":"n4415","loc":[-85.621753,41.950417]},"n4416":{"id":"n4416","loc":[-85.621556,41.950562]},"n4417":{"id":"n4417","loc":[-85.621552,41.950217]},"n4418":{"id":"n4418","loc":[-85.621788,41.950562]},"n4419":{"id":"n4419","loc":[-85.621155,41.950562]},"n442":{"id":"n442","loc":[-85.63419,41.943713]},"n4420":{"id":"n4420","loc":[-85.622473,41.950551]},"n4421":{"id":"n4421","loc":[-85.622043,41.950551]},"n4422":{"id":"n4422","loc":[-85.62142,41.950454]},"n4423":{"id":"n4423","loc":[-85.621315,41.950455]},"n4424":{"id":"n4424","loc":[-85.621313,41.950311]},"n4425":{"id":"n4425","loc":[-85.621388,41.950311]},"n4426":{"id":"n4426","loc":[-85.621387,41.950261]},"n4427":{"id":"n4427","loc":[-85.621468,41.95026]},"n4428":{"id":"n4428","loc":[-85.621468,41.950271]},"n4429":{"id":"n4429","loc":[-85.621503,41.95027]},"n443":{"id":"n443","loc":[-85.634462,41.943294]},"n4430":{"id":"n4430","loc":[-85.621505,41.950353]},"n4431":{"id":"n4431","loc":[-85.621483,41.950354]},"n4432":{"id":"n4432","loc":[-85.621483,41.950392]},"n4433":{"id":"n4433","loc":[-85.621419,41.950393]},"n4434":{"id":"n4434","loc":[-85.621213,41.95039]},"n4435":{"id":"n4435","loc":[-85.621127,41.950391]},"n4436":{"id":"n4436","loc":[-85.621126,41.950357]},"n4437":{"id":"n4437","loc":[-85.621094,41.950357]},"n4438":{"id":"n4438","loc":[-85.621094,41.950391]},"n4439":{"id":"n4439","loc":[-85.620977,41.950392]},"n444":{"id":"n444","loc":[-85.634298,41.943389]},"n4440":{"id":"n4440","loc":[-85.620975,41.950278]},"n4441":{"id":"n4441","loc":[-85.621087,41.950277]},"n4442":{"id":"n4442","loc":[-85.621088,41.950331]},"n4443":{"id":"n4443","loc":[-85.621211,41.950312]},"n4444":{"id":"n4444","loc":[-85.621104,41.950313]},"n4445":{"id":"n4445","loc":[-85.621105,41.950331]},"n4446":{"id":"n4446","loc":[-85.620706,41.950328]},"n4447":{"id":"n4447","loc":[-85.620606,41.950327]},"n4448":{"id":"n4448","loc":[-85.620607,41.950261]},"n4449":{"id":"n4449","loc":[-85.620707,41.950262]},"n445":{"id":"n445","loc":[-85.634527,41.943623]},"n4450":{"id":"n4450","loc":[-85.620599,41.950336]},"n4451":{"id":"n4451","loc":[-85.620559,41.950336]},"n4452":{"id":"n4452","loc":[-85.620559,41.950299]},"n4453":{"id":"n4453","loc":[-85.620599,41.950299]},"n4454":{"id":"n4454","loc":[-85.620545,41.950357]},"n4455":{"id":"n4455","loc":[-85.620418,41.950357]},"n4456":{"id":"n4456","loc":[-85.620417,41.950257]},"n4457":{"id":"n4457","loc":[-85.620544,41.950256]},"n4458":{"id":"n4458","loc":[-85.620246,41.950131],"tags":{"highway":"crossing"}},"n4459":{"id":"n4459","loc":[-85.620252,41.950956]},"n446":{"id":"n446","loc":[-85.634608,41.943577]},"n4460":{"id":"n4460","loc":[-85.620245,41.950179]},"n4461":{"id":"n4461","loc":[-85.620246,41.950088]},"n4462":{"id":"n4462","loc":[-85.620251,41.950885]},"n4463":{"id":"n4463","loc":[-85.620103,41.950884],"tags":{"crossing":"zebra","highway":"crossing"}},"n4464":{"id":"n4464","loc":[-85.619992,41.950884]},"n4465":{"id":"n4465","loc":[-85.619704,41.951008]},"n4466":{"id":"n4466","loc":[-85.619599,41.951122]},"n4467":{"id":"n4467","loc":[-85.619264,41.951486]},"n4468":{"id":"n4468","loc":[-85.619179,41.951573],"tags":{"highway":"crossing"}},"n4469":{"id":"n4469","loc":[-85.620251,41.950999],"tags":{"highway":"crossing"}},"n447":{"id":"n447","loc":[-85.634555,41.943531]},"n4470":{"id":"n4470","loc":[-85.620249,41.951066]},"n4471":{"id":"n4471","loc":[-85.620256,41.951374]},"n4472":{"id":"n4472","loc":[-85.620249,41.951389]},"n4473":{"id":"n4473","loc":[-85.620249,41.951407]},"n4474":{"id":"n4474","loc":[-85.620255,41.951423]},"n4475":{"id":"n4475","loc":[-85.62026,41.951853]},"n4476":{"id":"n4476","loc":[-85.620262,41.951894],"tags":{"highway":"crossing"}},"n4477":{"id":"n4477","loc":[-85.620265,41.951957]},"n4478":{"id":"n4478","loc":[-85.620262,41.952135]},"n4479":{"id":"n4479","loc":[-85.620241,41.952424]},"n448":{"id":"n448","loc":[-85.634555,41.943482]},"n4480":{"id":"n4480","loc":[-85.620213,41.952583]},"n4481":{"id":"n4481","loc":[-85.620158,41.952754]},"n4482":{"id":"n4482","loc":[-85.620065,41.952942]},"n4483":{"id":"n4483","loc":[-85.619753,41.953439]},"n4484":{"id":"n4484","loc":[-85.619605,41.953626]},"n4485":{"id":"n4485","loc":[-85.619381,41.953834]},"n4486":{"id":"n4486","loc":[-85.619069,41.954066]},"n4487":{"id":"n4487","loc":[-85.618674,41.95429]},"n4488":{"id":"n4488","loc":[-85.621816,41.952389]},"n4489":{"id":"n4489","loc":[-85.6217,41.952386]},"n449":{"id":"n449","loc":[-85.634509,41.943427]},"n4490":{"id":"n4490","loc":[-85.621705,41.952306]},"n4491":{"id":"n4491","loc":[-85.621821,41.95231]},"n4492":{"id":"n4492","loc":[-85.621819,41.952272]},"n4493":{"id":"n4493","loc":[-85.621778,41.952272]},"n4494":{"id":"n4494","loc":[-85.621778,41.952199]},"n4495":{"id":"n4495","loc":[-85.621818,41.952199]},"n4496":{"id":"n4496","loc":[-85.621754,41.952281]},"n4497":{"id":"n4497","loc":[-85.621701,41.95228]},"n4498":{"id":"n4498","loc":[-85.621702,41.952197]},"n4499":{"id":"n4499","loc":[-85.621755,41.952197]},"n45":{"id":"n45","loc":[-85.636791,41.942792]},"n450":{"id":"n450","loc":[-85.63453,41.943365]},"n4500":{"id":"n4500","loc":[-85.628201,41.954694],"tags":{"highway":"stop","stop":"all","direction":"forward"}},"n4501":{"id":"n4501","loc":[-85.627921,41.954783],"tags":{"highway":"stop","stop":"all","direction":"backward"}},"n4502":{"id":"n4502","loc":[-85.62775,41.954696],"tags":{"highway":"stop","stop":"all","direction":"backward"}},"n4503":{"id":"n4503","loc":[-85.628046,41.954591],"tags":{"highway":"stop","stop":"all","direction":"forward"}},"n4504":{"id":"n4504","loc":[-85.631074,41.957428],"tags":{"highway":"stop","direction":"backward","stop":"minor"}},"n4505":{"id":"n4505","loc":[-85.630768,41.957429],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4506":{"id":"n4506","loc":[-85.629888,41.957432],"tags":{"highway":"stop","direction":"backward","stop":"minor"}},"n4507":{"id":"n4507","loc":[-85.629565,41.957433],"tags":{"highway":"stop","stop":"minor","direction":"forward"}},"n4508":{"id":"n4508","loc":[-85.629559,41.957343]},"n4509":{"id":"n4509","loc":[-85.628723,41.95735]},"n451":{"id":"n451","loc":[-85.634356,41.943468]},"n4510":{"id":"n4510","loc":[-85.62842,41.957515]},"n4511":{"id":"n4511","loc":[-85.627561,41.957525]},"n4512":{"id":"n4512","loc":[-85.630323,41.957508]},"n4513":{"id":"n4513","loc":[-85.630811,41.957506]},"n4514":{"id":"n4514","loc":[-85.630839,41.960874]},"n4515":{"id":"n4515","loc":[-85.631035,41.957506]},"n4516":{"id":"n4516","loc":[-85.632027,41.9575]},"n4517":{"id":"n4517","loc":[-85.631038,41.958066]},"n4518":{"id":"n4518","loc":[-85.630787,41.954769]},"n4519":{"id":"n4519","loc":[-85.630806,41.957342]},"n452":{"id":"n452","loc":[-85.634123,41.943596]},"n4520":{"id":"n4520","loc":[-85.630809,41.957428],"tags":{"highway":"crossing"}},"n4521":{"id":"n4521","loc":[-85.630912,41.957506],"tags":{"highway":"crossing"}},"n4522":{"id":"n4522","loc":[-85.631033,41.957428],"tags":{"highway":"crossing"}},"n4523":{"id":"n4523","loc":[-85.631032,41.957341]},"n4524":{"id":"n4524","loc":[-85.63091,41.957341],"tags":{"highway":"crossing"}},"n4525":{"id":"n4525","loc":[-85.631027,41.95597]},"n4526":{"id":"n4526","loc":[-85.631027,41.955913],"tags":{"highway":"crossing"}},"n4527":{"id":"n4527","loc":[-85.631025,41.955873]},"n4528":{"id":"n4528","loc":[-85.631073,41.955913],"tags":{"highway":"stop","stop":"minor","direction":"backward"}},"n4529":{"id":"n4529","loc":[-85.631007,41.954766]},"n453":{"id":"n453","loc":[-85.634709,41.943926]},"n4530":{"id":"n4530","loc":[-85.630881,41.954768],"tags":{"highway":"crossing"}},"n4531":{"id":"n4531","loc":[-85.628022,41.954776]},"n4532":{"id":"n4532","loc":[-85.627385,41.95584]},"n4533":{"id":"n4533","loc":[-85.627329,41.955937]},"n4534":{"id":"n4534","loc":[-85.626583,41.957153]},"n4535":{"id":"n4535","loc":[-85.629675,41.954564],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4536":{"id":"n4536","loc":[-85.630881,41.954806],"tags":{"highway":"stop","stop":"minor","direction":"backward"}},"n4537":{"id":"n4537","loc":[-85.630879,41.954564],"tags":{"highway":"stop","stop":"minor","direction":"forward"}},"n4538":{"id":"n4538","loc":[-85.630784,41.954682],"tags":{"highway":"crossing"}},"n4539":{"id":"n4539","loc":[-85.63078,41.954595]},"n454":{"id":"n454","loc":[-85.63525,41.943855]},"n4540":{"id":"n4540","loc":[-85.630879,41.954595],"tags":{"highway":"crossing"}},"n4541":{"id":"n4541","loc":[-85.631004,41.954594]},"n4542":{"id":"n4542","loc":[-85.631006,41.954681],"tags":{"highway":"crossing"}},"n4543":{"id":"n4543","loc":[-85.631045,41.959036],"tags":{"highway":"stop","stop":"minor","direction":"backward"}},"n4544":{"id":"n4544","loc":[-85.632071,41.959029],"tags":{"highway":"stop","stop":"minor","direction":"forward"}},"n4545":{"id":"n4545","loc":[-85.632257,41.959027],"tags":{"highway":"stop","stop":"minor","direction":"backward"}},"n4546":{"id":"n4546","loc":[-85.631966,41.957427],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4547":{"id":"n4547","loc":[-85.632297,41.957426],"tags":{"highway":"stop","direction":"backward","stop":"minor"}},"n4548":{"id":"n4548","loc":[-85.631976,41.955911],"tags":{"highway":"give_way","direction":"forward"}},"n4549":{"id":"n4549","loc":[-85.632272,41.955911],"tags":{"highway":"give_way","direction":"backward"}},"n455":{"id":"n455","loc":[-85.635224,41.943869]},"n4550":{"id":"n4550","loc":[-85.632097,41.954805],"tags":{"highway":"stop","stop":"minor","direction":"backward"}},"n4551":{"id":"n4551","loc":[-85.632094,41.954566],"tags":{"highway":"stop","stop":"minor","direction":"forward"}},"n4552":{"id":"n4552","loc":[-85.626519,41.957256]},"n4553":{"id":"n4553","loc":[-85.625334,41.959165]},"n4554":{"id":"n4554","loc":[-85.626483,41.95806]},"n4555":{"id":"n4555","loc":[-85.626481,41.958175]},"n4556":{"id":"n4556","loc":[-85.626412,41.958174]},"n4557":{"id":"n4557","loc":[-85.626412,41.958202]},"n4558":{"id":"n4558","loc":[-85.62628,41.958201]},"n4559":{"id":"n4559","loc":[-85.626283,41.958057]},"n456":{"id":"n456","loc":[-85.638854,41.943104]},"n4560":{"id":"n4560","loc":[-85.622763,41.95109],"tags":{"highway":"stop","direction":"backward","stop":"minor"}},"n4561":{"id":"n4561","loc":[-85.622858,41.950876],"tags":{"emergency":"fire_hydrant"}},"n4562":{"id":"n4562","loc":[-85.624073,41.950393]},"n4563":{"id":"n4563","loc":[-85.624077,41.950924]},"n4564":{"id":"n4564","loc":[-85.624599,41.950984],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4565":{"id":"n4565","loc":[-85.624831,41.95119],"tags":{"emergency":"fire_hydrant"}},"n4566":{"id":"n4566","loc":[-85.624437,41.952568],"tags":{"emergency":"fire_hydrant"}},"n4567":{"id":"n4567","loc":[-85.624077,41.954606],"tags":{"emergency":"fire_hydrant"}},"n4568":{"id":"n4568","loc":[-85.624263,41.954888]},"n4569":{"id":"n4569","loc":[-85.624206,41.954919]},"n457":{"id":"n457","loc":[-85.635186,41.943901]},"n4570":{"id":"n4570","loc":[-85.624154,41.954865]},"n4571":{"id":"n4571","loc":[-85.624212,41.954835]},"n4572":{"id":"n4572","loc":[-85.622442,41.954401],"tags":{"emergency":"fire_hydrant"}},"n4573":{"id":"n4573","loc":[-85.619751,41.954658],"tags":{"emergency":"fire_hydrant"}},"n4574":{"id":"n4574","loc":[-85.617785,41.954534]},"n4575":{"id":"n4575","loc":[-85.617416,41.954721]},"n4576":{"id":"n4576","loc":[-85.617662,41.95474]},"n4577":{"id":"n4577","loc":[-85.618014,41.954717]},"n4578":{"id":"n4578","loc":[-85.617886,41.954671]},"n4579":{"id":"n4579","loc":[-85.617831,41.954612]},"n458":{"id":"n458","loc":[-85.635162,41.943917]},"n4580":{"id":"n4580","loc":[-85.617968,41.954752]},"n4581":{"id":"n4581","loc":[-85.617815,41.954752]},"n4582":{"id":"n4582","loc":[-85.617938,41.954695]},"n4583":{"id":"n4583","loc":[-85.617856,41.954642],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4584":{"id":"n4584","loc":[-85.619116,41.954164],"tags":{"man_made":"flagpole"}},"n4585":{"id":"n4585","loc":[-85.619569,41.953255],"tags":{"emergency":"fire_hydrant"}},"n4586":{"id":"n4586","loc":[-85.620352,41.951894],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4587":{"id":"n4587","loc":[-85.620485,41.951948],"tags":{"emergency":"fire_hydrant"}},"n4588":{"id":"n4588","loc":[-85.620316,41.950999],"tags":{"highway":"stop","direction":"backward","stop":"minor"}},"n4589":{"id":"n4589","loc":[-85.620311,41.950131],"tags":{"highway":"stop","direction":"backward","stop":"minor"}},"n459":{"id":"n459","loc":[-85.634856,41.943905]},"n4590":{"id":"n4590","loc":[-85.620374,41.95018],"tags":{"emergency":"fire_hydrant"}},"n4591":{"id":"n4591","loc":[-85.620301,41.949239],"tags":{"highway":"stop","direction":"backward","stop":"minor"}},"n4592":{"id":"n4592","loc":[-85.620278,41.947443],"tags":{"highway":"stop","direction":"backward","stop":"minor"}},"n4593":{"id":"n4593","loc":[-85.619844,41.947444],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4594":{"id":"n4594","loc":[-85.620191,41.947352],"tags":{"emergency":"fire_hydrant"}},"n4595":{"id":"n4595","loc":[-85.622819,41.947493],"tags":{"emergency":"fire_hydrant"}},"n4596":{"id":"n4596","loc":[-85.622744,41.947541],"tags":{"highway":"stop","stop":"minor","direction":"backward"}},"n4597":{"id":"n4597","loc":[-85.622739,41.947316],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4598":{"id":"n4598","loc":[-85.622909,41.948333],"tags":{"highway":"give_way"}},"n4599":{"id":"n4599","loc":[-85.622593,41.948333],"tags":{"highway":"give_way"}},"n46":{"id":"n46","loc":[-85.637131,41.94307]},"n460":{"id":"n460","loc":[-85.634811,41.944007]},"n4600":{"id":"n4600","loc":[-85.622835,41.948387],"tags":{"emergency":"fire_hydrant"}},"n4601":{"id":"n4601","loc":[-85.622768,41.949125],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4602":{"id":"n4602","loc":[-85.622769,41.949325],"tags":{"highway":"stop","stop":"minor","direction":"backward"}},"n4603":{"id":"n4603","loc":[-85.622837,41.949329],"tags":{"emergency":"fire_hydrant"}},"n4604":{"id":"n4604","loc":[-85.622614,41.950113],"tags":{"highway":"give_way","direction":"forward"}},"n4605":{"id":"n4605","loc":[-85.624777,41.949219],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4606":{"id":"n4606","loc":[-85.624849,41.949106],"tags":{"emergency":"fire_hydrant"}},"n4607":{"id":"n4607","loc":[-85.624858,41.950119],"tags":{"emergency":"fire_hydrant"}},"n4608":{"id":"n4608","loc":[-85.624752,41.948334],"tags":{"highway":"give_way"}},"n4609":{"id":"n4609","loc":[-85.624845,41.948422],"tags":{"emergency":"fire_hydrant"}},"n461":{"id":"n461","loc":[-85.634987,41.943112]},"n4610":{"id":"n4610","loc":[-85.62484,41.947539],"tags":{"emergency":"fire_hydrant"}},"n4611":{"id":"n4611","loc":[-85.62476,41.947428],"tags":{"highway":"stop","stop":"minor","direction":"forward"}},"n4612":{"id":"n4612","loc":[-85.620286,41.950926]},"n4613":{"id":"n4613","loc":[-85.618237,41.950963]},"n4614":{"id":"n4614","loc":[-85.618107,41.950876]},"n4615":{"id":"n4615","loc":[-85.618131,41.950393]},"n4616":{"id":"n4616","loc":[-85.618232,41.949913]},"n4617":{"id":"n4617","loc":[-85.619138,41.950212]},"n4618":{"id":"n4618","loc":[-85.619299,41.950388]},"n4619":{"id":"n4619","loc":[-85.619306,41.950897]},"n462":{"id":"n462","loc":[-85.634698,41.943194]},"n4620":{"id":"n4620","loc":[-85.619155,41.950958]},"n4621":{"id":"n4621","loc":[-85.620079,41.947715]},"n4622":{"id":"n4622","loc":[-85.619674,41.947728]},"n4623":{"id":"n4623","loc":[-85.619634,41.947735]},"n4624":{"id":"n4624","loc":[-85.619587,41.947756],"tags":{"barrier":"gate"}},"n4625":{"id":"n4625","loc":[-85.61953,41.947796]},"n4626":{"id":"n4626","loc":[-85.619475,41.947847]},"n4627":{"id":"n4627","loc":[-85.619433,41.947903]},"n4628":{"id":"n4628","loc":[-85.619402,41.947982]},"n4629":{"id":"n4629","loc":[-85.619394,41.948043]},"n463":{"id":"n463","loc":[-85.634632,41.943219]},"n4630":{"id":"n4630","loc":[-85.619395,41.948476]},"n4631":{"id":"n4631","loc":[-85.618367,41.947452]},"n4632":{"id":"n4632","loc":[-85.618371,41.947567],"tags":{"barrier":"gate"}},"n4633":{"id":"n4633","loc":[-85.618341,41.947622]},"n4634":{"id":"n4634","loc":[-85.618138,41.94773]},"n4635":{"id":"n4635","loc":[-85.618078,41.947814]},"n4636":{"id":"n4636","loc":[-85.618072,41.948009]},"n4637":{"id":"n4637","loc":[-85.618269,41.947666]},"n4638":{"id":"n4638","loc":[-85.618099,41.947765]},"n4639":{"id":"n4639","loc":[-85.618378,41.954453]},"n464":{"id":"n464","loc":[-85.63459,41.943239]},"n4640":{"id":"n4640","loc":[-85.618198,41.95453]},"n4641":{"id":"n4641","loc":[-85.618212,41.954623]},"n4642":{"id":"n4642","loc":[-85.635211,41.943103],"tags":{"leisure":"picnic_table"}},"n4643":{"id":"n4643","loc":[-85.635345,41.943448],"tags":{"leisure":"picnic_table"}},"n4644":{"id":"n4644","loc":[-85.635901,41.943353],"tags":{"amenity":"bench"}},"n4645":{"id":"n4645","loc":[-85.635815,41.942638],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4646":{"id":"n4646","loc":[-85.635355,41.942044],"tags":{"leisure":"picnic_table"}},"n4647":{"id":"n4647","loc":[-85.635206,41.942045],"tags":{"leisure":"picnic_table"}},"n4648":{"id":"n4648","loc":[-85.63504,41.941992],"tags":{"leisure":"picnic_table"}},"n4649":{"id":"n4649","loc":[-85.635185,41.942001]},"n465":{"id":"n465","loc":[-85.634555,41.943263]},"n4650":{"id":"n4650","loc":[-85.635176,41.942021]},"n4651":{"id":"n4651","loc":[-85.635127,41.942008]},"n4652":{"id":"n4652","loc":[-85.635136,41.941988]},"n4653":{"id":"n4653","loc":[-85.635,41.941709],"tags":{"emergency":"fire_hydrant"}},"n4654":{"id":"n4654","loc":[-85.634893,41.941801]},"n4655":{"id":"n4655","loc":[-85.634937,41.941843]},"n4656":{"id":"n4656","loc":[-85.634963,41.941859]},"n4657":{"id":"n4657","loc":[-85.635027,41.941904]},"n4658":{"id":"n4658","loc":[-85.63494,41.94187]},"n4659":{"id":"n4659","loc":[-85.634951,41.941871]},"n466":{"id":"n466","loc":[-85.634526,41.943289]},"n4660":{"id":"n4660","loc":[-85.634753,41.941701],"tags":{"amenity":"drinking_water"}},"n4661":{"id":"n4661","loc":[-85.634717,41.941804],"tags":{"amenity":"bench"}},"n4662":{"id":"n4662","loc":[-85.634554,41.941883],"tags":{"amenity":"bench"}},"n4663":{"id":"n4663","loc":[-85.635002,41.941579],"tags":{"amenity":"fountain"}},"n4664":{"id":"n4664","loc":[-85.635258,41.94188],"tags":{"amenity":"waste_basket"}},"n4665":{"id":"n4665","loc":[-85.635262,41.941581],"tags":{"amenity":"bench"}},"n4666":{"id":"n4666","loc":[-85.635319,41.941744],"tags":{"amenity":"bench"}},"n4667":{"id":"n4667","loc":[-85.634702,41.941473],"tags":{"amenity":"waste_basket"}},"n4668":{"id":"n4668","loc":[-85.633981,41.941966],"tags":{"amenity":"bench"}},"n4669":{"id":"n4669","loc":[-85.63388,41.941743]},"n467":{"id":"n467","loc":[-85.635163,41.944985]},"n4670":{"id":"n4670","loc":[-85.633746,41.941741]},"n4671":{"id":"n4671","loc":[-85.633749,41.941664]},"n4672":{"id":"n4672","loc":[-85.633883,41.941667]},"n4673":{"id":"n4673","loc":[-85.634283,41.941183],"tags":{"leisure":"picnic_table"}},"n4674":{"id":"n4674","loc":[-85.634046,41.941102],"tags":{"amenity":"bbq"}},"n4675":{"id":"n4675","loc":[-85.63401,41.941093],"tags":{"amenity":"bbq"}},"n4676":{"id":"n4676","loc":[-85.633408,41.940862],"tags":{"amenity":"bench"}},"n4677":{"id":"n4677","loc":[-85.633359,41.940651],"tags":{"amenity":"bench"}},"n4678":{"id":"n4678","loc":[-85.634109,41.940831]},"n4679":{"id":"n4679","loc":[-85.63396,41.940867]},"n468":{"id":"n468","loc":[-85.635095,41.945035]},"n4680":{"id":"n4680","loc":[-85.633816,41.940913]},"n4681":{"id":"n4681","loc":[-85.633237,41.940455]},"n4682":{"id":"n4682","loc":[-85.634453,41.940025],"tags":{"emergency":"fire_hydrant"}},"n4683":{"id":"n4683","loc":[-85.635692,41.940218],"tags":{"emergency":"fire_hydrant"}},"n4684":{"id":"n4684","loc":[-85.635566,41.940102],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4685":{"id":"n4685","loc":[-85.635961,41.940125],"tags":{"highway":"stop","stop":"minor","direction":"backward"}},"n4686":{"id":"n4686","loc":[-85.635883,41.94012],"tags":{"crossing":"zebra","highway":"crossing"}},"n4687":{"id":"n4687","loc":[-85.635883,41.94006]},"n4688":{"id":"n4688","loc":[-85.635768,41.940051],"tags":{"crossing":"zebra","highway":"crossing"}},"n4689":{"id":"n4689","loc":[-85.635669,41.940043]},"n469":{"id":"n469","loc":[-85.634269,41.944431]},"n4690":{"id":"n4690","loc":[-85.635661,41.940107],"tags":{"crossing":"zebra","highway":"crossing"}},"n4691":{"id":"n4691","loc":[-85.635424,41.941005],"tags":{"amenity":"fountain"}},"n4692":{"id":"n4692","loc":[-85.635542,41.941371],"tags":{"amenity":"bench"}},"n4693":{"id":"n4693","loc":[-85.635709,41.941341],"tags":{"emergency":"fire_hydrant"}},"n4694":{"id":"n4694","loc":[-85.637038,41.942513],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4695":{"id":"n4695","loc":[-85.637174,41.941354],"tags":{"highway":"stop","direction":"backward","stop":"minor"}},"n4696":{"id":"n4696","loc":[-85.637091,41.941273],"tags":{"emergency":"fire_hydrant"}},"n4697":{"id":"n4697","loc":[-85.638058,41.941346],"tags":{"highway":"give_way","direction":"forward"}},"n4698":{"id":"n4698","loc":[-85.638359,41.941344],"tags":{"highway":"give_way","direction":"backward"}},"n4699":{"id":"n4699","loc":[-85.638288,41.941236],"tags":{"emergency":"fire_hydrant"}},"n47":{"id":"n47","loc":[-85.636693,41.943073]},"n470":{"id":"n470","loc":[-85.634352,41.944376]},"n4700":{"id":"n4700","loc":[-85.63935,41.94128],"tags":{"emergency":"fire_hydrant"}},"n4701":{"id":"n4701","loc":[-85.639277,41.941337],"tags":{"highway":"give_way","direction":"forward"}},"n4702":{"id":"n4702","loc":[-85.639548,41.941334],"tags":{"highway":"give_way","direction":"backward"}},"n4703":{"id":"n4703","loc":[-85.642191,41.940039]},"n4704":{"id":"n4704","loc":[-85.640585,41.941263],"tags":{"emergency":"fire_hydrant"}},"n4705":{"id":"n4705","loc":[-85.64049,41.941327],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4706":{"id":"n4706","loc":[-85.640803,41.941324],"tags":{"highway":"stop","direction":"backward","stop":"minor"}},"n4707":{"id":"n4707","loc":[-85.641717,41.941317],"tags":{"highway":"stop","direction":"forward","stop":"all"}},"n4708":{"id":"n4708","loc":[-85.641846,41.941415],"tags":{"highway":"stop","direction":"backward","stop":"all"}},"n4709":{"id":"n4709","loc":[-85.641756,41.941392],"tags":{"emergency":"fire_hydrant"}},"n471":{"id":"n471","loc":[-85.634747,41.944561],"tags":{"railway":"crossing"}},"n4710":{"id":"n4710","loc":[-85.642014,41.941313],"tags":{"highway":"stop","direction":"forward","stop":"all"}},"n4711":{"id":"n4711","loc":[-85.641854,41.942455],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4712":{"id":"n4712","loc":[-85.641859,41.942739],"tags":{"highway":"stop","direction":"backward","stop":"minor"}},"n4713":{"id":"n4713","loc":[-85.640754,41.942707],"tags":{"emergency":"fire_hydrant"}},"n4714":{"id":"n4714","loc":[-85.640669,41.942716],"tags":{"highway":"stop","direction":"backward","stop":"minor"}},"n4715":{"id":"n4715","loc":[-85.640664,41.942478],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4716":{"id":"n4716","loc":[-85.63964,41.94274],"tags":{"man_made":"flagpole"}},"n4717":{"id":"n4717","loc":[-85.639455,41.942731],"tags":{"highway":"stop","direction":"backward","stop":"minor"}},"n4718":{"id":"n4718","loc":[-85.63945,41.942492],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4719":{"id":"n4719","loc":[-85.639527,41.942505],"tags":{"emergency":"fire_hydrant"}},"n472":{"id":"n472","loc":[-85.634667,41.944613]},"n4720":{"id":"n4720","loc":[-85.638238,41.942745],"tags":{"highway":"stop","direction":"backward","stop":"minor"}},"n4721":{"id":"n4721","loc":[-85.638233,41.942511],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4722":{"id":"n4722","loc":[-85.638018,41.94299],"tags":{"amenity":"waste_disposal"}},"n4723":{"id":"n4723","loc":[-85.637918,41.944152],"tags":{"amenity":"waste_basket"}},"n4724":{"id":"n4724","loc":[-85.635902,41.943291],"tags":{"leisure":"picnic_table"}},"n4725":{"id":"n4725","loc":[-85.63704,41.942741],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4726":{"id":"n4726","loc":[-85.633467,41.943818],"tags":{"highway":"stop","stop":"minor","direction":"backward"}},"n4727":{"id":"n4727","loc":[-85.633987,41.943531],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4728":{"id":"n4728","loc":[-85.632154,41.943539],"tags":{"emergency":"fire_hydrant"}},"n4729":{"id":"n4729","loc":[-85.633567,41.944641],"tags":{"amenity":"bench"}},"n473":{"id":"n473","loc":[-85.634161,41.944371]},"n4730":{"id":"n4730","loc":[-85.633127,41.944574],"tags":{"amenity":"bench"}},"n4731":{"id":"n4731","loc":[-85.633439,41.944871],"tags":{"amenity":"bench"}},"n4732":{"id":"n4732","loc":[-85.633676,41.944799],"tags":{"amenity":"waste_basket"}},"n4733":{"id":"n4733","loc":[-85.633466,41.944862],"tags":{"amenity":"waste_basket"}},"n4734":{"id":"n4734","loc":[-85.633451,41.944847],"tags":{"emergency":"fire_hydrant"}},"n4735":{"id":"n4735","loc":[-85.634202,41.945543],"tags":{"amenity":"waste_basket"}},"n4736":{"id":"n4736","loc":[-85.634652,41.945472],"tags":{"leisure":"picnic_table"}},"n4737":{"id":"n4737","loc":[-85.6347,41.945445],"tags":{"leisure":"picnic_table"}},"n4738":{"id":"n4738","loc":[-85.634646,41.945662],"tags":{"emergency":"fire_hydrant"}},"n4739":{"id":"n4739","loc":[-85.634673,41.945687],"tags":{"amenity":"waste_basket"}},"n474":{"id":"n474","loc":[-85.633861,41.944117]},"n4740":{"id":"n4740","loc":[-85.63449,41.945827],"tags":{"amenity":"clock","display":"analog"}},"n4741":{"id":"n4741","loc":[-85.63481,41.946056],"tags":{"highway":"stop","stop":"minor","direction":"backward"}},"n4742":{"id":"n4742","loc":[-85.634814,41.946176],"tags":{"amenity":"post_box"}},"n4743":{"id":"n4743","loc":[-85.638744,41.945328]},"n4744":{"id":"n4744","loc":[-85.63867,41.945228],"tags":{"amenity":"bench"}},"n4745":{"id":"n4745","loc":[-85.639487,41.945042],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4746":{"id":"n4746","loc":[-85.639635,41.94387],"tags":{"highway":"stop","stop":"minor","direction":"backward"}},"n4747":{"id":"n4747","loc":[-85.639549,41.943756],"tags":{"emergency":"fire_hydrant"}},"n4748":{"id":"n4748","loc":[-85.64055,41.943862],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4749":{"id":"n4749","loc":[-85.640864,41.943859],"tags":{"highway":"stop","stop":"minor","direction":"backward"}},"n475":{"id":"n475","loc":[-85.633906,41.943535]},"n4750":{"id":"n4750","loc":[-85.640718,41.945022],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4751":{"id":"n4751","loc":[-85.640664,41.945076],"tags":{"emergency":"fire_hydrant"}},"n4752":{"id":"n4752","loc":[-85.641913,41.94502],"tags":{"highway":"stop","direction":"forward","stop":"minor"}},"n4753":{"id":"n4753","loc":[-85.641838,41.945076],"tags":{"emergency":"fire_hydrant"}},"n4754":{"id":"n4754","loc":[-85.642045,41.94385],"tags":{"highway":"give_way","direction":"backward"}},"n4755":{"id":"n4755","loc":[-85.641738,41.943852],"tags":{"highway":"give_way","direction":"forward"}},"n4756":{"id":"n4756","loc":[-85.642928,41.943843],"tags":{"highway":"stop","stop":"minor","direction":"forward"}},"n4757":{"id":"n4757","loc":[-85.64305,41.943902],"tags":{"emergency":"fire_hydrant"}},"n4758":{"id":"n4758","loc":[-85.642986,41.945105],"tags":{"highway":"stop","direction":"backward","stop":"all"}},"n4759":{"id":"n4759","loc":[-85.643136,41.94502],"tags":{"highway":"stop","stop":"all","direction":"forward"}},"n476":{"id":"n476","loc":[-85.63423,41.943692]},"n4760":{"id":"n4760","loc":[-85.63169,41.947812]},"n4761":{"id":"n4761","loc":[-85.631307,41.947655]},"n4762":{"id":"n4762","loc":[-85.631407,41.947413]},"n4763":{"id":"n4763","loc":[-85.631173,41.947306]},"n4764":{"id":"n4764","loc":[-85.631316,41.947145]},"n4765":{"id":"n4765","loc":[-85.631476,41.947087]},"n4766":{"id":"n4766","loc":[-85.631793,41.946871]},"n4767":{"id":"n4767","loc":[-85.631884,41.946723]},"n4768":{"id":"n4768","loc":[-85.631814,41.946397]},"n4769":{"id":"n4769","loc":[-85.631382,41.947685]},"n477":{"id":"n477","loc":[-85.635096,41.942814]},"n4770":{"id":"n4770","loc":[-85.63109,41.947819]},"n4771":{"id":"n4771","loc":[-85.630921,41.947961]},"n4772":{"id":"n4772","loc":[-85.630249,41.947709]},"n4773":{"id":"n4773","loc":[-85.630149,41.947451]},"n4774":{"id":"n4774","loc":[-85.629733,41.947339]},"n4775":{"id":"n4775","loc":[-85.629755,41.946948]},"n4776":{"id":"n4776","loc":[-85.630457,41.947103]},"n4777":{"id":"n4777","loc":[-85.630934,41.946939]},"n4778":{"id":"n4778","loc":[-85.631277,41.946852]},"n4779":{"id":"n4779","loc":[-85.63142,41.946781]},"n478":{"id":"n478","loc":[-85.635058,41.942795]},"n4780":{"id":"n4780","loc":[-85.631116,41.946474]},"n4781":{"id":"n4781","loc":[-85.63073,41.945965]},"n4782":{"id":"n4782","loc":[-85.631337,41.94571]},"n4783":{"id":"n4783","loc":[-85.631589,41.945487]},"n4784":{"id":"n4784","loc":[-85.632278,41.945784]},"n4785":{"id":"n4785","loc":[-85.632105,41.946034]},"n4786":{"id":"n4786","loc":[-85.632532,41.946198]},"n4787":{"id":"n4787","loc":[-85.632566,41.946151]},"n4788":{"id":"n4788","loc":[-85.632684,41.946196]},"n4789":{"id":"n4789","loc":[-85.628676,41.947106]},"n479":{"id":"n479","loc":[-85.635002,41.94279]},"n4790":{"id":"n4790","loc":[-85.628973,41.946476]},"n4791":{"id":"n4791","loc":[-85.629094,41.946079]},"n4792":{"id":"n4792","loc":[-85.629226,41.94578]},"n4793":{"id":"n4793","loc":[-85.629479,41.945682]},"n4794":{"id":"n4794","loc":[-85.630606,41.94569]},"n4795":{"id":"n4795","loc":[-85.631255,41.945588]},"n4796":{"id":"n4796","loc":[-85.631546,41.945281]},"n4797":{"id":"n4797","loc":[-85.631629,41.944823]},"n4798":{"id":"n4798","loc":[-85.631766,41.944958]},"n4799":{"id":"n4799","loc":[-85.631689,41.945318]},"n48":{"id":"n48","loc":[-85.636689,41.94276]},"n480":{"id":"n480","loc":[-85.634908,41.94279]},"n4800":{"id":"n4800","loc":[-85.615069,41.945527]},"n4801":{"id":"n4801","loc":[-85.615058,41.946677]},"n4802":{"id":"n4802","loc":[-85.613692,41.946689]},"n4803":{"id":"n4803","loc":[-85.613475,41.946531]},"n4804":{"id":"n4804","loc":[-85.611717,41.946252]},"n4805":{"id":"n4805","loc":[-85.611353,41.946385]},"n4806":{"id":"n4806","loc":[-85.611304,41.947397]},"n4807":{"id":"n4807","loc":[-85.610564,41.947401]},"n4808":{"id":"n4808","loc":[-85.610553,41.947122]},"n4809":{"id":"n4809","loc":[-85.610194,41.946992]},"n481":{"id":"n481","loc":[-85.634478,41.942342]},"n4810":{"id":"n4810","loc":[-85.609976,41.946628]},"n4811":{"id":"n4811","loc":[-85.609769,41.946523]},"n4812":{"id":"n4812","loc":[-85.609307,41.946523]},"n4813":{"id":"n4813","loc":[-85.609035,41.946462]},"n4814":{"id":"n4814","loc":[-85.609018,41.943277]},"n4815":{"id":"n4815","loc":[-85.609617,41.943423]},"n4816":{"id":"n4816","loc":[-85.610471,41.943447]},"n4817":{"id":"n4817","loc":[-85.621491,41.949168]},"n4818":{"id":"n4818","loc":[-85.620266,41.94917]},"n4819":{"id":"n4819","loc":[-85.620262,41.947557]},"n482":{"id":"n482","loc":[-85.634521,41.942254]},"n4820":{"id":"n4820","loc":[-85.620825,41.947556]},"n4821":{"id":"n4821","loc":[-85.620827,41.948371]},"n4822":{"id":"n4822","loc":[-85.621489,41.94837]},"n4823":{"id":"n4823","loc":[-85.622865,41.950928]},"n4824":{"id":"n4824","loc":[-85.622858,41.949744]},"n4825":{"id":"n4825","loc":[-85.623696,41.949714]},"n4826":{"id":"n4826","loc":[-85.623696,41.949647]},"n4827":{"id":"n4827","loc":[-85.624019,41.949647]},"n4828":{"id":"n4828","loc":[-85.624024,41.950093]},"n4829":{"id":"n4829","loc":[-85.622885,41.949711]},"n483":{"id":"n483","loc":[-85.63425,41.941819]},"n4830":{"id":"n4830","loc":[-85.624584,41.951049]},"n4831":{"id":"n4831","loc":[-85.624669,41.9511]},"n4832":{"id":"n4832","loc":[-85.624316,41.952218]},"n4833":{"id":"n4833","loc":[-85.623819,41.952094]},"n4834":{"id":"n4834","loc":[-85.623385,41.952101]},"n4835":{"id":"n4835","loc":[-85.623456,41.951238]},"n4836":{"id":"n4836","loc":[-85.623535,41.951051]},"n4837":{"id":"n4837","loc":[-85.624693,41.950921]},"n4838":{"id":"n4838","loc":[-85.624727,41.950897]},"n4839":{"id":"n4839","loc":[-85.624869,41.950341]},"n484":{"id":"n484","loc":[-85.634324,41.942131]},"n4840":{"id":"n4840","loc":[-85.624859,41.949284]},"n4841":{"id":"n4841","loc":[-85.624788,41.949262]},"n4842":{"id":"n4842","loc":[-85.62402,41.949265]},"n4843":{"id":"n4843","loc":[-85.610382,41.954663]},"n4844":{"id":"n4844","loc":[-85.605675,41.954667]},"n4845":{"id":"n4845","loc":[-85.605669,41.949407]},"n4846":{"id":"n4846","loc":[-85.610376,41.949404]},"n4847":{"id":"n4847","loc":[-85.605552,41.958536]},"n4848":{"id":"n4848","loc":[-85.595755,41.958588]},"n4849":{"id":"n4849","loc":[-85.595732,41.956419]},"n485":{"id":"n485","loc":[-85.634211,41.941374]},"n4850":{"id":"n4850","loc":[-85.596908,41.955605]},"n4851":{"id":"n4851","loc":[-85.597723,41.955596]},"n4852":{"id":"n4852","loc":[-85.597715,41.954967]},"n4853":{"id":"n4853","loc":[-85.5874,41.955018]},"n4854":{"id":"n4854","loc":[-85.586615,41.955124]},"n4855":{"id":"n4855","loc":[-85.58613,41.955293]},"n4856":{"id":"n4856","loc":[-85.586166,41.962122]},"n4857":{"id":"n4857","loc":[-85.587008,41.955052]},"n4858":{"id":"n4858","loc":[-85.591685,41.95499]},"n4859":{"id":"n4859","loc":[-85.591718,41.956649]},"n486":{"id":"n486","loc":[-85.634085,41.940704]},"n4860":{"id":"n4860","loc":[-85.591133,41.956649]},"n4861":{"id":"n4861","loc":[-85.591061,41.95582]},"n4862":{"id":"n4862","loc":[-85.590677,41.95613]},"n4863":{"id":"n4863","loc":[-85.590826,41.956369]},"n4864":{"id":"n4864","loc":[-85.591016,41.954991]},"n4865":{"id":"n4865","loc":[-85.587656,41.954855]},"n4866":{"id":"n4866","loc":[-85.5964,41.955274]},"n4867":{"id":"n4867","loc":[-85.58776,41.96178]},"n4868":{"id":"n4868","loc":[-85.601172,41.960448]},"n4869":{"id":"n4869","loc":[-85.589489,41.960478]},"n487":{"id":"n487","loc":[-85.635567,41.940944]},"n4870":{"id":"n4870","loc":[-85.586664,41.960493]},"n4871":{"id":"n4871","loc":[-85.591227,41.95676]},"n4872":{"id":"n4872","loc":[-85.589424,41.958093]},"n4873":{"id":"n4873","loc":[-85.588779,41.957611]},"n4874":{"id":"n4874","loc":[-85.590583,41.956278]},"n4875":{"id":"n4875","loc":[-85.590759,41.957106]},"n4876":{"id":"n4876","loc":[-85.592213,41.958218]},"n4877":{"id":"n4877","loc":[-85.592262,41.958279]},"n4878":{"id":"n4878","loc":[-85.592304,41.958358]},"n4879":{"id":"n4879","loc":[-85.592351,41.95849]},"n488":{"id":"n488","loc":[-85.635542,41.940919]},"n4880":{"id":"n4880","loc":[-85.592363,41.958605]},"n4881":{"id":"n4881","loc":[-85.592383,41.96047]},"n4882":{"id":"n4882","loc":[-85.592376,41.959808]},"n4883":{"id":"n4883","loc":[-85.600825,41.959779]},"n4884":{"id":"n4884","loc":[-85.601084,41.959844]},"n4885":{"id":"n4885","loc":[-85.601144,41.959908]},"n4886":{"id":"n4886","loc":[-85.601164,41.960008]},"n4887":{"id":"n4887","loc":[-85.601162,41.960125]},"n4888":{"id":"n4888","loc":[-85.601134,41.960221]},"n4889":{"id":"n4889","loc":[-85.600993,41.960353]},"n489":{"id":"n489","loc":[-85.635514,41.940906]},"n4890":{"id":"n4890","loc":[-85.600794,41.960449]},"n4891":{"id":"n4891","loc":[-85.60098,41.959792]},"n4892":{"id":"n4892","loc":[-85.601067,41.960294]},"n4893":{"id":"n4893","loc":[-85.596829,41.959793]},"n4894":{"id":"n4894","loc":[-85.596839,41.960459]},"n4895":{"id":"n4895","loc":[-85.589364,41.958048]},"n4896":{"id":"n4896","loc":[-85.587374,41.959511]},"n4897":{"id":"n4897","loc":[-85.587286,41.959564]},"n4898":{"id":"n4898","loc":[-85.587163,41.959632]},"n4899":{"id":"n4899","loc":[-85.586694,41.959865]},"n49":{"id":"n49","loc":[-85.637127,41.942757]},"n490":{"id":"n490","loc":[-85.635469,41.940896]},"n4900":{"id":"n4900","loc":[-85.586634,41.959921]},"n4901":{"id":"n4901","loc":[-85.586607,41.960001]},"n4902":{"id":"n4902","loc":[-85.586599,41.960099]},"n4903":{"id":"n4903","loc":[-85.586602,41.96034]},"n4904":{"id":"n4904","loc":[-85.586669,41.960439]},"n4905":{"id":"n4905","loc":[-85.586758,41.960493]},"n4906":{"id":"n4906","loc":[-85.586618,41.960391]},"n4907":{"id":"n4907","loc":[-85.591201,41.956352]},"n4908":{"id":"n4908","loc":[-85.59112,41.954843]},"n4909":{"id":"n4909","loc":[-85.591536,41.956349]},"n491":{"id":"n491","loc":[-85.635667,41.940826]},"n4910":{"id":"n4910","loc":[-85.590953,41.956354]},"n4911":{"id":"n4911","loc":[-85.591468,41.956406]},"n4912":{"id":"n4912","loc":[-85.591469,41.956478]},"n4913":{"id":"n4913","loc":[-85.591123,41.956481]},"n4914":{"id":"n4914","loc":[-85.591121,41.956409]},"n4915":{"id":"n4915","loc":[-85.590826,41.955954]},"n4916":{"id":"n4916","loc":[-85.590612,41.956115]},"n4917":{"id":"n4917","loc":[-85.590402,41.955962]},"n4918":{"id":"n4918","loc":[-85.590622,41.955804]},"n4919":{"id":"n4919","loc":[-85.59011,41.956502]},"n492":{"id":"n492","loc":[-85.636197,41.940599]},"n4920":{"id":"n4920","loc":[-85.589877,41.956668]},"n4921":{"id":"n4921","loc":[-85.589777,41.95659]},"n4922":{"id":"n4922","loc":[-85.59001,41.956424]},"n4923":{"id":"n4923","loc":[-85.589595,41.956427]},"n4924":{"id":"n4924","loc":[-85.589434,41.956549]},"n4925":{"id":"n4925","loc":[-85.589262,41.956424]},"n4926":{"id":"n4926","loc":[-85.589422,41.956302]},"n4927":{"id":"n4927","loc":[-85.589358,41.956286]},"n4928":{"id":"n4928","loc":[-85.5892,41.956408]},"n4929":{"id":"n4929","loc":[-85.589032,41.956288]},"n493":{"id":"n493","loc":[-85.6362,41.940686]},"n4930":{"id":"n4930","loc":[-85.58919,41.956166]},"n4931":{"id":"n4931","loc":[-85.589165,41.956132]},"n4932":{"id":"n4932","loc":[-85.589002,41.956253]},"n4933":{"id":"n4933","loc":[-85.588826,41.956122]},"n4934":{"id":"n4934","loc":[-85.588989,41.956001]},"n4935":{"id":"n4935","loc":[-85.588673,41.955757]},"n4936":{"id":"n4936","loc":[-85.588502,41.955882]},"n4937":{"id":"n4937","loc":[-85.588339,41.955759]},"n4938":{"id":"n4938","loc":[-85.58851,41.955633]},"n4939":{"id":"n4939","loc":[-85.590382,41.955892]},"n494":{"id":"n494","loc":[-85.635969,41.94069]},"n4940":{"id":"n4940","loc":[-85.589923,41.956231]},"n4941":{"id":"n4941","loc":[-85.58984,41.956168]},"n4942":{"id":"n4942","loc":[-85.5903,41.95583]},"n4943":{"id":"n4943","loc":[-85.589636,41.956038]},"n4944":{"id":"n4944","loc":[-85.589546,41.956105]},"n4945":{"id":"n4945","loc":[-85.589045,41.955729]},"n4946":{"id":"n4946","loc":[-85.589135,41.955662]},"n4947":{"id":"n4947","loc":[-85.590718,41.955293]},"n4948":{"id":"n4948","loc":[-85.590718,41.955374]},"n4949":{"id":"n4949","loc":[-85.589211,41.955369]},"n495":{"id":"n495","loc":[-85.635965,41.940561]},"n4950":{"id":"n4950","loc":[-85.589212,41.955287]},"n4951":{"id":"n4951","loc":[-85.589675,41.956817]},"n4952":{"id":"n4952","loc":[-85.58947,41.95697]},"n4953":{"id":"n4953","loc":[-85.589219,41.956784]},"n4954":{"id":"n4954","loc":[-85.589425,41.95663]},"n4955":{"id":"n4955","loc":[-85.589373,41.95702]},"n4956":{"id":"n4956","loc":[-85.589171,41.957172]},"n4957":{"id":"n4957","loc":[-85.588962,41.957019]},"n4958":{"id":"n4958","loc":[-85.589164,41.956867]},"n4959":{"id":"n4959","loc":[-85.588881,41.955006]},"n496":{"id":"n496","loc":[-85.636031,41.94056]},"n4960":{"id":"n4960","loc":[-85.588804,41.955006]},"n4961":{"id":"n4961","loc":[-85.604773,41.954521]},"n4962":{"id":"n4962","loc":[-85.601603,41.954527]},"n4963":{"id":"n4963","loc":[-85.600823,41.954169]},"n4964":{"id":"n4964","loc":[-85.600828,41.950191]},"n4965":{"id":"n4965","loc":[-85.601673,41.949457]},"n4966":{"id":"n4966","loc":[-85.604464,41.949488]},"n4967":{"id":"n4967","loc":[-85.60538,41.950212]},"n4968":{"id":"n4968","loc":[-85.605395,41.954108]},"n4969":{"id":"n4969","loc":[-85.604771,41.954109]},"n497":{"id":"n497","loc":[-85.636032,41.940602]},"n4970":{"id":"n4970","loc":[-85.600613,41.953916]},"n4971":{"id":"n4971","loc":[-85.599758,41.954649]},"n4972":{"id":"n4972","loc":[-85.591194,41.954663]},"n4973":{"id":"n4973","loc":[-85.591182,41.950465]},"n4974":{"id":"n4974","loc":[-85.591871,41.950464]},"n4975":{"id":"n4975","loc":[-85.591868,41.949209]},"n4976":{"id":"n4976","loc":[-85.592155,41.949209]},"n4977":{"id":"n4977","loc":[-85.592155,41.94848]},"n4978":{"id":"n4978","loc":[-85.600615,41.948482]},"n4979":{"id":"n4979","loc":[-85.605421,41.949378]},"n498":{"id":"n498","loc":[-85.635776,41.940583]},"n4980":{"id":"n4980","loc":[-85.600614,41.949373]},"n4981":{"id":"n4981","loc":[-85.601316,41.94849]},"n4982":{"id":"n4982","loc":[-85.601592,41.947641]},"n4983":{"id":"n4983","loc":[-85.60395,41.947618]},"n4984":{"id":"n4984","loc":[-85.603973,41.948114]},"n4985":{"id":"n4985","loc":[-85.605398,41.948103]},"n4986":{"id":"n4986","loc":[-85.614017,41.965566]},"n4987":{"id":"n4987","loc":[-85.605787,41.965619]},"n4988":{"id":"n4988","loc":[-85.60577,41.963821]},"n4989":{"id":"n4989","loc":[-85.612886,41.963808]},"n499":{"id":"n499","loc":[-85.63589,41.940578]},"n4990":{"id":"n4990","loc":[-85.613207,41.963705]},"n4991":{"id":"n4991","loc":[-85.613511,41.963525]},"n4992":{"id":"n4992","loc":[-85.613667,41.963305]},"n4993":{"id":"n4993","loc":[-85.613779,41.962983]},"n4994":{"id":"n4994","loc":[-85.613797,41.959709]},"n4995":{"id":"n4995","loc":[-85.613663,41.95936]},"n4996":{"id":"n4996","loc":[-85.61339,41.959064]},"n4997":{"id":"n4997","loc":[-85.610503,41.956898]},"n4998":{"id":"n4998","loc":[-85.610485,41.956595]},"n4999":{"id":"n4999","loc":[-85.613892,41.956621]},"n5":{"id":"n5","loc":[-85.622744,41.95268]},"n50":{"id":"n50","loc":[-85.636673,41.943143]},"n500":{"id":"n500","loc":[-85.636198,41.940578]},"n5000":{"id":"n5000","loc":[-85.613866,41.958574]},"n5001":{"id":"n5001","loc":[-85.615262,41.958561]},"n5002":{"id":"n5002","loc":[-85.615279,41.959541]},"n5003":{"id":"n5003","loc":[-85.615314,41.95597]},"n5004":{"id":"n5004","loc":[-85.613887,41.955988]},"n5005":{"id":"n5005","loc":[-85.613074,41.962244]},"n5006":{"id":"n5006","loc":[-85.611678,41.963354]},"n5007":{"id":"n5007","loc":[-85.611678,41.963487]},"n5008":{"id":"n5008","loc":[-85.606906,41.963502]},"n5009":{"id":"n5009","loc":[-85.605777,41.962657]},"n501":{"id":"n501","loc":[-85.636251,41.940584]},"n5010":{"id":"n5010","loc":[-85.605711,41.9599]},"n5011":{"id":"n5011","loc":[-85.608139,41.9585]},"n5012":{"id":"n5012","loc":[-85.60814,41.956306]},"n5013":{"id":"n5013","loc":[-85.608854,41.95581]},"n5014":{"id":"n5014","loc":[-85.610039,41.955883]},"n5015":{"id":"n5015","loc":[-85.610068,41.956754]},"n5016":{"id":"n5016","loc":[-85.613058,41.959411]},"n5017":{"id":"n5017","loc":[-85.610234,41.957068]},"n5018":{"id":"n5018","loc":[-85.609826,41.95581]},"n5019":{"id":"n5019","loc":[-85.606987,41.958505]},"n502":{"id":"n502","loc":[-85.636279,41.940605]},"n5020":{"id":"n5020","loc":[-85.606498,41.958846]},"n5021":{"id":"n5021","loc":[-85.606013,41.959342]},"n5022":{"id":"n5022","loc":[-85.614553,41.961581]},"n5023":{"id":"n5023","loc":[-85.61465,41.96214]},"n5024":{"id":"n5024","loc":[-85.615277,41.962442]},"n5025":{"id":"n5025","loc":[-85.615451,41.962972]},"n5026":{"id":"n5026","loc":[-85.614355,41.964826]},"n5027":{"id":"n5027","loc":[-85.615133,41.964589]},"n5028":{"id":"n5028","loc":[-85.615342,41.963818]},"n5029":{"id":"n5029","loc":[-85.615971,41.963792]},"n503":{"id":"n503","loc":[-85.636285,41.940633]},"n5030":{"id":"n5030","loc":[-85.615751,41.963122]},"n5031":{"id":"n5031","loc":[-85.616575,41.963123]},"n5032":{"id":"n5032","loc":[-85.612527,41.963846]},"n5033":{"id":"n5033","loc":[-85.630653,41.940709]},"n5034":{"id":"n5034","loc":[-85.629858,41.939568]},"n5035":{"id":"n5035","loc":[-85.629847,41.937926]},"n504":{"id":"n504","loc":[-85.636281,41.940662]},"n505":{"id":"n505","loc":[-85.636266,41.940688]},"n506":{"id":"n506","loc":[-85.636236,41.940701]},"n507":{"id":"n507","loc":[-85.63619,41.940706]},"n508":{"id":"n508","loc":[-85.635892,41.940707]},"n509":{"id":"n509","loc":[-85.635777,41.9407]},"n51":{"id":"n51","loc":[-85.636673,41.942864]},"n510":{"id":"n510","loc":[-85.636044,41.940578]},"n511":{"id":"n511","loc":[-85.635946,41.940578]},"n512":{"id":"n512","loc":[-85.636475,41.940732]},"n513":{"id":"n513","loc":[-85.636475,41.940777]},"n514":{"id":"n514","loc":[-85.636405,41.940777]},"n515":{"id":"n515","loc":[-85.636405,41.940732]},"n516":{"id":"n516","loc":[-85.636471,41.940916]},"n517":{"id":"n517","loc":[-85.636471,41.940961]},"n518":{"id":"n518","loc":[-85.636404,41.940961]},"n519":{"id":"n519","loc":[-85.636404,41.940916]},"n52":{"id":"n52","loc":[-85.636227,41.942864]},"n520":{"id":"n520","loc":[-85.636286,41.941127]},"n521":{"id":"n521","loc":[-85.636203,41.941126]},"n522":{"id":"n522","loc":[-85.636204,41.941083]},"n523":{"id":"n523","loc":[-85.636287,41.941083]},"n524":{"id":"n524","loc":[-85.636124,41.941064]},"n525":{"id":"n525","loc":[-85.636,41.941065]},"n526":{"id":"n526","loc":[-85.636,41.940964]},"n527":{"id":"n527","loc":[-85.636045,41.940964]},"n528":{"id":"n528","loc":[-85.636045,41.940928]},"n529":{"id":"n529","loc":[-85.636111,41.940928]},"n53":{"id":"n53","loc":[-85.636227,41.943143]},"n530":{"id":"n530","loc":[-85.636111,41.940961]},"n531":{"id":"n531","loc":[-85.636123,41.940961]},"n532":{"id":"n532","loc":[-85.636124,41.940997]},"n533":{"id":"n533","loc":[-85.636164,41.940997]},"n534":{"id":"n534","loc":[-85.636164,41.941044]},"n535":{"id":"n535","loc":[-85.636124,41.941044]},"n536":{"id":"n536","loc":[-85.636534,41.941256]},"n537":{"id":"n537","loc":[-85.63645,41.941246]},"n538":{"id":"n538","loc":[-85.636462,41.941189]},"n539":{"id":"n539","loc":[-85.636546,41.941199]},"n54":{"id":"n54","loc":[-85.636198,41.943119]},"n540":{"id":"n540","loc":[-85.636802,41.941226]},"n541":{"id":"n541","loc":[-85.636701,41.941215]},"n542":{"id":"n542","loc":[-85.636709,41.941174]},"n543":{"id":"n543","loc":[-85.636656,41.941168]},"n544":{"id":"n544","loc":[-85.636666,41.941122]},"n545":{"id":"n545","loc":[-85.636781,41.941136]},"n546":{"id":"n546","loc":[-85.636774,41.94117]},"n547":{"id":"n547","loc":[-85.636812,41.941175]},"n548":{"id":"n548","loc":[-85.636803,41.941047]},"n549":{"id":"n549","loc":[-85.636785,41.941047]},"n55":{"id":"n55","loc":[-85.635945,41.94312]},"n550":{"id":"n550","loc":[-85.636785,41.941058]},"n551":{"id":"n551","loc":[-85.636644,41.941059]},"n552":{"id":"n552","loc":[-85.636644,41.941038]},"n553":{"id":"n553","loc":[-85.636581,41.941039]},"n554":{"id":"n554","loc":[-85.636581,41.940995]},"n555":{"id":"n555","loc":[-85.636746,41.940995]},"n556":{"id":"n556","loc":[-85.636746,41.940978]},"n557":{"id":"n557","loc":[-85.636803,41.940978]},"n558":{"id":"n558","loc":[-85.636781,41.940768]},"n559":{"id":"n559","loc":[-85.636783,41.940828]},"n56":{"id":"n56","loc":[-85.635943,41.942909]},"n560":{"id":"n560","loc":[-85.636761,41.940828]},"n561":{"id":"n561","loc":[-85.636762,41.940857]},"n562":{"id":"n562","loc":[-85.636641,41.940859]},"n563":{"id":"n563","loc":[-85.63664,41.940805]},"n564":{"id":"n564","loc":[-85.636676,41.940804]},"n565":{"id":"n565","loc":[-85.636675,41.940769]},"n566":{"id":"n566","loc":[-85.636733,41.94033]},"n567":{"id":"n567","loc":[-85.636471,41.940334]},"n568":{"id":"n568","loc":[-85.636469,41.940262]},"n569":{"id":"n569","loc":[-85.636731,41.940257]},"n57":{"id":"n57","loc":[-85.636227,41.942909]},"n570":{"id":"n570","loc":[-85.636798,41.940419]},"n571":{"id":"n571","loc":[-85.6368,41.940524]},"n572":{"id":"n572","loc":[-85.63664,41.940526]},"n573":{"id":"n573","loc":[-85.636638,41.940421]},"n574":{"id":"n574","loc":[-85.636372,41.940551]},"n575":{"id":"n575","loc":[-85.636338,41.94055]},"n576":{"id":"n576","loc":[-85.636339,41.940524]},"n577":{"id":"n577","loc":[-85.636373,41.940525]},"n578":{"id":"n578","loc":[-85.636388,41.940435]},"n579":{"id":"n579","loc":[-85.636222,41.940436]},"n58":{"id":"n58","loc":[-85.63627,41.943175]},"n580":{"id":"n580","loc":[-85.636222,41.940366]},"n581":{"id":"n581","loc":[-85.636387,41.940365]},"n582":{"id":"n582","loc":[-85.636158,41.940482]},"n583":{"id":"n583","loc":[-85.635963,41.940484]},"n584":{"id":"n584","loc":[-85.635961,41.940399]},"n585":{"id":"n585","loc":[-85.636156,41.940397]},"n586":{"id":"n586","loc":[-85.635987,41.940314]},"n587":{"id":"n587","loc":[-85.635987,41.940268]},"n588":{"id":"n588","loc":[-85.635968,41.940268]},"n589":{"id":"n589","loc":[-85.635967,41.940212]},"n59":{"id":"n59","loc":[-85.635531,41.943176]},"n590":{"id":"n590","loc":[-85.636082,41.940211]},"n591":{"id":"n591","loc":[-85.636083,41.94027]},"n592":{"id":"n592","loc":[-85.636064,41.94027]},"n593":{"id":"n593","loc":[-85.636064,41.940313]},"n594":{"id":"n594","loc":[-85.638071,41.941562]},"n595":{"id":"n595","loc":[-85.637953,41.941562]},"n596":{"id":"n596","loc":[-85.637952,41.941522]},"n597":{"id":"n597","loc":[-85.637876,41.941523]},"n598":{"id":"n598","loc":[-85.637876,41.941471]},"n599":{"id":"n599","loc":[-85.638035,41.94147]},"n6":{"id":"n6","loc":[-85.624925,41.950604]},"n60":{"id":"n60","loc":[-85.63542,41.942883]},"n600":{"id":"n600","loc":[-85.638035,41.941513]},"n601":{"id":"n601","loc":[-85.638071,41.941512]},"n602":{"id":"n602","loc":[-85.637038,41.942543],"tags":{"crossing":"zebra","highway":"crossing"}},"n603":{"id":"n603","loc":[-85.637134,41.942542]},"n604":{"id":"n604","loc":[-85.638122,41.942532]},"n605":{"id":"n605","loc":[-85.638121,41.942478]},"n606":{"id":"n606","loc":[-85.638104,41.941424]},"n607":{"id":"n607","loc":[-85.637115,41.941438]},"n608":{"id":"n608","loc":[-85.637133,41.942453]},"n609":{"id":"n609","loc":[-85.637429,41.942004]},"n61":{"id":"n61","loc":[-85.635701,41.942802]},"n610":{"id":"n610","loc":[-85.637125,41.942004]},"n611":{"id":"n611","loc":[-85.637022,41.942004]},"n612":{"id":"n612","loc":[-85.635952,41.943579]},"n613":{"id":"n613","loc":[-85.635872,41.943594]},"n614":{"id":"n614","loc":[-85.635857,41.943551]},"n615":{"id":"n615","loc":[-85.635937,41.943535]},"n616":{"id":"n616","loc":[-85.63671,41.94344]},"n617":{"id":"n617","loc":[-85.636427,41.94334]},"n618":{"id":"n618","loc":[-85.635353,41.943279]},"n619":{"id":"n619","loc":[-85.635319,41.943257]},"n62":{"id":"n62","loc":[-85.6358,41.942997]},"n620":{"id":"n620","loc":[-85.638786,41.943105]},"n621":{"id":"n621","loc":[-85.634957,41.943146]},"n622":{"id":"n622","loc":[-85.635012,41.943119]},"n623":{"id":"n623","loc":[-85.632409,41.944222]},"n624":{"id":"n624","loc":[-85.631863,41.944749]},"n625":{"id":"n625","loc":[-85.631915,41.944722]},"n626":{"id":"n626","loc":[-85.631884,41.94464]},"n627":{"id":"n627","loc":[-85.631792,41.944359]},"n628":{"id":"n628","loc":[-85.631817,41.944703]},"n629":{"id":"n629","loc":[-85.633464,41.945787]},"n63":{"id":"n63","loc":[-85.635808,41.943176]},"n630":{"id":"n630","loc":[-85.633583,41.945919]},"n631":{"id":"n631","loc":[-85.63382,41.945698]},"n632":{"id":"n632","loc":[-85.633681,41.945571]},"n633":{"id":"n633","loc":[-85.634217,41.946824]},"n634":{"id":"n634","loc":[-85.634271,41.946836]},"n635":{"id":"n635","loc":[-85.634319,41.94573]},"n636":{"id":"n636","loc":[-85.634377,41.945672]},"n637":{"id":"n637","loc":[-85.634909,41.945354]},"n638":{"id":"n638","loc":[-85.634726,41.945493],"tags":{"artwork_type":"mural","tourism":"artwork"}},"n639":{"id":"n639","loc":[-85.63546,41.945612]},"n64":{"id":"n64","loc":[-85.63631,41.943253]},"n640":{"id":"n640","loc":[-85.635561,41.945493]},"n641":{"id":"n641","loc":[-85.635417,41.945565]},"n642":{"id":"n642","loc":[-85.635315,41.945583]},"n643":{"id":"n643","loc":[-85.63506,41.945383]},"n644":{"id":"n644","loc":[-85.635198,41.945199]},"n645":{"id":"n645","loc":[-85.635361,41.94558]},"n646":{"id":"n646","loc":[-85.635017,41.945066]},"n647":{"id":"n647","loc":[-85.634779,41.945206]},"n648":{"id":"n648","loc":[-85.63425,41.945655]},"n649":{"id":"n649","loc":[-85.634247,41.945631]},"n65":{"id":"n65","loc":[-85.635398,41.943259]},"n650":{"id":"n650","loc":[-85.634889,41.945921]},"n651":{"id":"n651","loc":[-85.634889,41.945939]},"n652":{"id":"n652","loc":[-85.634889,41.945761]},"n653":{"id":"n653","loc":[-85.634889,41.945778]},"n654":{"id":"n654","loc":[-85.635112,41.945715]},"n655":{"id":"n655","loc":[-85.635025,41.945714]},"n656":{"id":"n656","loc":[-85.635027,41.945761]},"n657":{"id":"n657","loc":[-85.635438,41.945665]},"n658":{"id":"n658","loc":[-85.635416,41.945676]},"n659":{"id":"n659","loc":[-85.635401,41.945709]},"n66":{"id":"n66","loc":[-85.635336,41.943036]},"n660":{"id":"n660","loc":[-85.635271,41.945566]},"n661":{"id":"n661","loc":[-85.636106,41.946268]},"n662":{"id":"n662","loc":[-85.635867,41.946747]},"n663":{"id":"n663","loc":[-85.636476,41.946797]},"n664":{"id":"n664","loc":[-85.63651,41.946796]},"n665":{"id":"n665","loc":[-85.635367,41.946389]},"n666":{"id":"n666","loc":[-85.635367,41.946437]},"n667":{"id":"n667","loc":[-85.634787,41.946441]},"n668":{"id":"n668","loc":[-85.6358,41.946243]},"n669":{"id":"n669","loc":[-85.635784,41.94622]},"n67":{"id":"n67","loc":[-85.635911,41.942899]},"n670":{"id":"n670","loc":[-85.635727,41.946195]},"n671":{"id":"n671","loc":[-85.635708,41.946588]},"n672":{"id":"n672","loc":[-85.635648,41.946561]},"n673":{"id":"n673","loc":[-85.635624,41.946555]},"n674":{"id":"n674","loc":[-85.635417,41.946559]},"n675":{"id":"n675","loc":[-85.634866,41.946561]},"n676":{"id":"n676","loc":[-85.634866,41.946543]},"n677":{"id":"n677","loc":[-85.635085,41.946546]},"n678":{"id":"n678","loc":[-85.635085,41.946554]},"n679":{"id":"n679","loc":[-85.634584,41.94488]},"n68":{"id":"n68","loc":[-85.635915,41.943156]},"n680":{"id":"n680","loc":[-85.634557,41.944882]},"n681":{"id":"n681","loc":[-85.634455,41.944943]},"n682":{"id":"n682","loc":[-85.634305,41.944968]},"n683":{"id":"n683","loc":[-85.634261,41.944927]},"n684":{"id":"n684","loc":[-85.634132,41.944741]},"n685":{"id":"n685","loc":[-85.633705,41.944759]},"n686":{"id":"n686","loc":[-85.633918,41.944616]},"n687":{"id":"n687","loc":[-85.633974,41.944663]},"n688":{"id":"n688","loc":[-85.6336,41.944665]},"n689":{"id":"n689","loc":[-85.633817,41.944528]},"n69":{"id":"n69","loc":[-85.63631,41.943157]},"n690":{"id":"n690","loc":[-85.633889,41.944485]},"n691":{"id":"n691","loc":[-85.633931,41.944525]},"n692":{"id":"n692","loc":[-85.633864,41.944563]},"n693":{"id":"n693","loc":[-85.633456,41.944524]},"n694":{"id":"n694","loc":[-85.633676,41.944399]},"n695":{"id":"n695","loc":[-85.633352,41.944415]},"n696":{"id":"n696","loc":[-85.633655,41.944234]},"n697":{"id":"n697","loc":[-85.633761,41.94435]},"n698":{"id":"n698","loc":[-85.633254,41.944318]},"n699":{"id":"n699","loc":[-85.633472,41.944188]},"n7":{"id":"n7","loc":[-85.638791,41.943231]},"n70":{"id":"n70","loc":[-85.63579,41.942967]},"n700":{"id":"n700","loc":[-85.633524,41.944237]},"n701":{"id":"n701","loc":[-85.633583,41.944202]},"n702":{"id":"n702","loc":[-85.633632,41.944247]},"n703":{"id":"n703","loc":[-85.633165,41.944228]},"n704":{"id":"n704","loc":[-85.633388,41.944105]},"n705":{"id":"n705","loc":[-85.633117,41.944175]},"n706":{"id":"n706","loc":[-85.633302,41.944077]},"n707":{"id":"n707","loc":[-85.633352,41.944126]},"n708":{"id":"n708","loc":[-85.633052,41.944107]},"n709":{"id":"n709","loc":[-85.633237,41.944009]},"n71":{"id":"n71","loc":[-85.637506,41.942824]},"n710":{"id":"n710","loc":[-85.633187,41.943955]},"n711":{"id":"n711","loc":[-85.633,41.944054]},"n712":{"id":"n712","loc":[-85.633155,41.944265]},"n713":{"id":"n713","loc":[-85.633669,41.944765]},"n714":{"id":"n714","loc":[-85.634468,41.945503]},"n715":{"id":"n715","loc":[-85.63455,41.945566]},"n716":{"id":"n716","loc":[-85.634737,41.945729]},"n717":{"id":"n717","loc":[-85.634753,41.945752]},"n718":{"id":"n718","loc":[-85.634756,41.945781]},"n719":{"id":"n719","loc":[-85.634758,41.945978]},"n72":{"id":"n72","loc":[-85.637511,41.943056]},"n720":{"id":"n720","loc":[-85.634363,41.945548],"tags":{"crossing":"zebra","highway":"crossing"}},"n721":{"id":"n721","loc":[-85.634245,41.945599]},"n722":{"id":"n722","loc":[-85.633474,41.944889]},"n723":{"id":"n723","loc":[-85.632997,41.944418]},"n724":{"id":"n724","loc":[-85.63278,41.944183]},"n725":{"id":"n725","loc":[-85.63331,41.944429]},"n726":{"id":"n726","loc":[-85.633568,41.944829],"tags":{"crossing":"zebra","highway":"crossing"}},"n727":{"id":"n727","loc":[-85.634669,41.94567]},"n728":{"id":"n728","loc":[-85.634462,41.945787]},"n729":{"id":"n729","loc":[-85.634272,41.945625]},"n73":{"id":"n73","loc":[-85.637361,41.943058]},"n730":{"id":"n730","loc":[-85.634344,41.945699],"tags":{"crossing":"zebra","highway":"crossing"}},"n731":{"id":"n731","loc":[-85.634426,41.945783]},"n732":{"id":"n732","loc":[-85.632425,41.944137]},"n733":{"id":"n733","loc":[-85.632302,41.944192]},"n734":{"id":"n734","loc":[-85.632762,41.944174]},"n735":{"id":"n735","loc":[-85.632713,41.944179]},"n736":{"id":"n736","loc":[-85.632411,41.944327]},"n737":{"id":"n737","loc":[-85.632362,41.944341]},"n738":{"id":"n738","loc":[-85.632236,41.944204]},"n739":{"id":"n739","loc":[-85.634939,41.942165]},"n74":{"id":"n74","loc":[-85.637356,41.942825]},"n740":{"id":"n740","loc":[-85.635079,41.941535]},"n741":{"id":"n741","loc":[-85.635112,41.941595]},"n742":{"id":"n742","loc":[-85.635113,41.941633]},"n743":{"id":"n743","loc":[-85.635067,41.941652]},"n744":{"id":"n744","loc":[-85.634989,41.941651]},"n745":{"id":"n745","loc":[-85.634921,41.941609]},"n746":{"id":"n746","loc":[-85.634881,41.941544]},"n747":{"id":"n747","loc":[-85.635537,41.940939]},"n748":{"id":"n748","loc":[-85.635573,41.941048]},"n749":{"id":"n749","loc":[-85.635453,41.94091]},"n75":{"id":"n75","loc":[-85.638097,41.942833]},"n750":{"id":"n750","loc":[-85.635319,41.940943]},"n751":{"id":"n751","loc":[-85.637057,41.943224]},"n752":{"id":"n752","loc":[-85.636989,41.943296]},"n753":{"id":"n753","loc":[-85.636851,41.943299]},"n754":{"id":"n754","loc":[-85.636848,41.94322]},"n755":{"id":"n755","loc":[-85.636986,41.943217]},"n756":{"id":"n756","loc":[-85.637569,41.943454]},"n757":{"id":"n757","loc":[-85.637437,41.943458]},"n758":{"id":"n758","loc":[-85.637432,41.943384]},"n759":{"id":"n759","loc":[-85.637564,41.94338]},"n76":{"id":"n76","loc":[-85.638098,41.942912]},"n760":{"id":"n760","loc":[-85.637213,41.943378]},"n761":{"id":"n761","loc":[-85.637217,41.943435]},"n762":{"id":"n762","loc":[-85.637235,41.943434]},"n763":{"id":"n763","loc":[-85.637237,41.943465]},"n764":{"id":"n764","loc":[-85.637424,41.943459]},"n765":{"id":"n765","loc":[-85.637418,41.943371]},"n766":{"id":"n766","loc":[-85.638094,41.943149]},"n767":{"id":"n767","loc":[-85.638096,41.943201]},"n768":{"id":"n768","loc":[-85.638041,41.943202]},"n769":{"id":"n769","loc":[-85.638042,41.943216]},"n77":{"id":"n77","loc":[-85.637705,41.942913]},"n770":{"id":"n770","loc":[-85.637927,41.943218]},"n771":{"id":"n771","loc":[-85.637926,41.943201]},"n772":{"id":"n772","loc":[-85.637897,41.943201]},"n773":{"id":"n773","loc":[-85.637896,41.943155]},"n774":{"id":"n774","loc":[-85.637962,41.943153]},"n775":{"id":"n775","loc":[-85.637962,41.943134]},"n776":{"id":"n776","loc":[-85.638017,41.943132]},"n777":{"id":"n777","loc":[-85.638018,41.943151]},"n778":{"id":"n778","loc":[-85.638045,41.943289]},"n779":{"id":"n779","loc":[-85.638048,41.943363]},"n78":{"id":"n78","loc":[-85.637705,41.942834]},"n780":{"id":"n780","loc":[-85.637842,41.943367]},"n781":{"id":"n781","loc":[-85.637839,41.943296]},"n782":{"id":"n782","loc":[-85.637896,41.943295]},"n783":{"id":"n783","loc":[-85.637897,41.943314]},"n784":{"id":"n784","loc":[-85.637957,41.943312]},"n785":{"id":"n785","loc":[-85.637957,41.943291]},"n786":{"id":"n786","loc":[-85.637816,41.943375]},"n787":{"id":"n787","loc":[-85.637815,41.943416]},"n788":{"id":"n788","loc":[-85.637715,41.943415]},"n789":{"id":"n789","loc":[-85.637716,41.943374]},"n79":{"id":"n79","loc":[-85.638071,41.942298]},"n790":{"id":"n790","loc":[-85.637912,41.943545]},"n791":{"id":"n791","loc":[-85.637909,41.943479]},"n792":{"id":"n792","loc":[-85.637967,41.943477]},"n793":{"id":"n793","loc":[-85.637967,41.94346]},"n794":{"id":"n794","loc":[-85.638077,41.943457]},"n795":{"id":"n795","loc":[-85.638078,41.943473]},"n796":{"id":"n796","loc":[-85.638124,41.943471]},"n797":{"id":"n797","loc":[-85.638126,41.943514]},"n798":{"id":"n798","loc":[-85.638079,41.943515]},"n799":{"id":"n799","loc":[-85.638079,41.943532]},"n8":{"id":"n8","loc":[-85.635241,41.941948]},"n80":{"id":"n80","loc":[-85.638074,41.942431]},"n800":{"id":"n800","loc":[-85.638028,41.943534]},"n801":{"id":"n801","loc":[-85.638028,41.943542]},"n802":{"id":"n802","loc":[-85.638845,41.942983]},"n803":{"id":"n803","loc":[-85.638846,41.94305]},"n804":{"id":"n804","loc":[-85.638661,41.943052]},"n805":{"id":"n805","loc":[-85.63866,41.942984]},"n806":{"id":"n806","loc":[-85.638579,41.942753]},"n807":{"id":"n807","loc":[-85.638445,41.942755]},"n808":{"id":"n808","loc":[-85.638452,41.942978]},"n809":{"id":"n809","loc":[-85.638545,41.942976]},"n81":{"id":"n81","loc":[-85.637836,41.942433]},"n810":{"id":"n810","loc":[-85.638543,41.942935]},"n811":{"id":"n811","loc":[-85.638571,41.942934]},"n812":{"id":"n812","loc":[-85.63857,41.942901]},"n813":{"id":"n813","loc":[-85.638611,41.9429]},"n814":{"id":"n814","loc":[-85.638607,41.942769]},"n815":{"id":"n815","loc":[-85.63858,41.94277]},"n816":{"id":"n816","loc":[-85.638597,41.942614]},"n817":{"id":"n817","loc":[-85.638601,41.94273]},"n818":{"id":"n818","loc":[-85.638686,41.942731]},"n819":{"id":"n819","loc":[-85.638689,41.942917]},"n82":{"id":"n82","loc":[-85.637835,41.94242]},"n820":{"id":"n820","loc":[-85.638558,41.943018]},"n821":{"id":"n821","loc":[-85.638243,41.943019]},"n822":{"id":"n822","loc":[-85.637536,41.943887]},"n823":{"id":"n823","loc":[-85.63749,41.943926]},"n824":{"id":"n824","loc":[-85.63743,41.943886]},"n825":{"id":"n825","loc":[-85.637476,41.943847]},"n826":{"id":"n826","loc":[-85.637527,41.943846]},"n827":{"id":"n827","loc":[-85.637141,41.943728]},"n828":{"id":"n828","loc":[-85.637201,41.943755]},"n829":{"id":"n829","loc":[-85.636987,41.943608]},"n83":{"id":"n83","loc":[-85.63776,41.942421]},"n830":{"id":"n830","loc":[-85.637441,41.943807]},"n831":{"id":"n831","loc":[-85.637673,41.94399]},"n832":{"id":"n832","loc":[-85.637783,41.944137]},"n833":{"id":"n833","loc":[-85.63845,41.944333]},"n834":{"id":"n834","loc":[-85.638159,41.944248]},"n835":{"id":"n835","loc":[-85.637859,41.94416]},"n836":{"id":"n836","loc":[-85.638685,41.944542]},"n837":{"id":"n837","loc":[-85.638714,41.944611]},"n838":{"id":"n838","loc":[-85.638711,41.944757]},"n839":{"id":"n839","loc":[-85.638774,41.945069]},"n84":{"id":"n84","loc":[-85.637758,41.942339]},"n840":{"id":"n840","loc":[-85.638742,41.945205]},"n841":{"id":"n841","loc":[-85.640267,41.942403]},"n842":{"id":"n842","loc":[-85.640154,41.942404]},"n843":{"id":"n843","loc":[-85.640152,41.942249]},"n844":{"id":"n844","loc":[-85.640266,41.942248]},"n845":{"id":"n845","loc":[-85.640366,41.942599]},"n846":{"id":"n846","loc":[-85.640362,41.942192]},"n847":{"id":"n847","loc":[-85.640146,41.942191]},"n848":{"id":"n848","loc":[-85.640122,41.942196]},"n849":{"id":"n849","loc":[-85.640108,41.942211]},"n85":{"id":"n85","loc":[-85.637836,41.942339]},"n850":{"id":"n850","loc":[-85.640101,41.942236]},"n851":{"id":"n851","loc":[-85.640103,41.94241]},"n852":{"id":"n852","loc":[-85.64011,41.942435]},"n853":{"id":"n853","loc":[-85.640126,41.942445]},"n854":{"id":"n854","loc":[-85.640153,41.942451]},"n855":{"id":"n855","loc":[-85.640183,41.942452]},"n856":{"id":"n856","loc":[-85.640364,41.942452]},"n857":{"id":"n857","loc":[-85.640007,41.942452]},"n858":{"id":"n858","loc":[-85.639449,41.942461]},"n859":{"id":"n859","loc":[-85.640049,41.942391]},"n86":{"id":"n86","loc":[-85.637835,41.942301]},"n860":{"id":"n860","loc":[-85.640052,41.942503]},"n861":{"id":"n861","loc":[-85.639575,41.94251]},"n862":{"id":"n862","loc":[-85.639572,41.942398]},"n863":{"id":"n863","loc":[-85.638782,41.942227]},"n864":{"id":"n864","loc":[-85.63843,41.942226]},"n865":{"id":"n865","loc":[-85.63823,41.942183]},"n866":{"id":"n866","loc":[-85.638363,41.942216],"tags":{"barrier":"gate"}},"n867":{"id":"n867","loc":[-85.6384,41.942223]},"n868":{"id":"n868","loc":[-85.636042,41.942797]},"n869":{"id":"n869","loc":[-85.636308,41.942752]},"n87":{"id":"n87","loc":[-85.637566,41.942367]},"n870":{"id":"n870","loc":[-85.636516,41.942729]},"n871":{"id":"n871","loc":[-85.636782,41.942712]},"n872":{"id":"n872","loc":[-85.636944,41.942706]},"n873":{"id":"n873","loc":[-85.63704,41.942706]},"n874":{"id":"n874","loc":[-85.637237,41.942703]},"n875":{"id":"n875","loc":[-85.637553,41.9427]},"n876":{"id":"n876","loc":[-85.638236,41.942697]},"n877":{"id":"n877","loc":[-85.636284,41.942781]},"n878":{"id":"n878","loc":[-85.636551,41.942641]},"n879":{"id":"n879","loc":[-85.633914,41.943693]},"n88":{"id":"n88","loc":[-85.637566,41.94241]},"n880":{"id":"n880","loc":[-85.63389,41.943708]},"n881":{"id":"n881","loc":[-85.633866,41.943686]},"n882":{"id":"n882","loc":[-85.63389,41.943671]},"n883":{"id":"n883","loc":[-85.633857,41.943609]},"n884":{"id":"n884","loc":[-85.634858,41.944474]},"n885":{"id":"n885","loc":[-85.633988,41.943234]},"n886":{"id":"n886","loc":[-85.633999,41.943485]},"n887":{"id":"n887","loc":[-85.634109,41.943449],"tags":{"emergency":"fire_hydrant"}},"n888":{"id":"n888","loc":[-85.635728,41.942655],"tags":{"emergency":"fire_hydrant"}},"n889":{"id":"n889","loc":[-85.636499,41.942845],"tags":{"man_made":"flagpole"}},"n89":{"id":"n89","loc":[-85.637455,41.94241]},"n890":{"id":"n890","loc":[-85.636197,41.943073]},"n891":{"id":"n891","loc":[-85.636227,41.943073]},"n892":{"id":"n892","loc":[-85.637433,41.942933],"tags":{"addr:city":"Three Rivers","addr:housenumber":"401","addr:postcode":"49093","addr:state":"MI","addr:street":"Michigan Avenue","amenity":"restaurant","cuisine":"pizza","name":"Pizza Hut"}},"n893":{"id":"n893","loc":[-85.637907,41.942879],"tags":{"amenity":"car_wash"}},"n894":{"id":"n894","loc":[-85.637661,41.943018]},"n895":{"id":"n895","loc":[-85.636933,41.942733],"tags":{"emergency":"fire_hydrant"}},"n896":{"id":"n896","loc":[-85.637661,41.94304]},"n897":{"id":"n897","loc":[-85.637562,41.943041]},"n898":{"id":"n898","loc":[-85.637556,41.942725]},"n899":{"id":"n899","loc":[-85.637656,41.942724]},"n9":{"id":"n9","loc":[-85.635159,41.941926]},"n90":{"id":"n90","loc":[-85.637454,41.942367]},"n900":{"id":"n900","loc":[-85.637657,41.942779]},"n901":{"id":"n901","loc":[-85.637983,41.942777]},"n902":{"id":"n902","loc":[-85.637982,41.942616]},"n903":{"id":"n903","loc":[-85.637777,41.942778]},"n904":{"id":"n904","loc":[-85.637775,41.942699]},"n905":{"id":"n905","loc":[-85.637772,41.942618]},"n906":{"id":"n906","loc":[-85.637982,41.942698]},"n907":{"id":"n907","loc":[-85.637941,41.942378],"tags":{"addr:city":"Three Rivers","addr:housenumber":"416","addr:postcode":"49093","addr:state":"MI","addr:street":"Michigan Avenue","name":"Gem Pawnbroker","shop":"pawnbroker"}},"n908":{"id":"n908","loc":[-85.637515,41.942394],"tags":{"second_hand":"only","shop":"car"}},"n909":{"id":"n909","loc":[-85.638743,41.942374],"tags":{"addr:city":"Three Rivers","addr:housenumber":"500","addr:postcode":"49093","addr:state":"MI","addr:street":"Michigan Avenue","name":"William Towing","service:vehicle:towing":"yes","service:vehicle:tyres":"yes","shop":"car_repair"}},"n91":{"id":"n91","loc":[-85.637565,41.942341]},"n910":{"id":"n910","loc":[-85.638594,41.942357]},"n911":{"id":"n911","loc":[-85.634312,41.943562],"tags":{"addr:city":"Three Rivers","addr:housenumber":"145","addr:postcode":"49093","addr:state":"MI","addr:street":"Michigan Avenue","amenity":"cafe","cuisine":"coffee_shop","name":"L.A.'s Coffee Cafe","outdoor_seating":"yes"}},"n912":{"id":"n912","loc":[-85.634404,41.943512]},"n913":{"id":"n913","loc":[-85.634391,41.943519],"tags":{"entrance":"yes"}},"n914":{"id":"n914","loc":[-85.634259,41.943538],"tags":{"entrance":"yes"}},"n915":{"id":"n915","loc":[-85.634247,41.943528]},"n916":{"id":"n916","loc":[-85.633747,41.943322],"tags":{"addr:city":"Three Rivers","addr:housenumber":"132","addr:postcode":"49093","addr:state":"MI","addr:street":"Michigan Avenue","name":"Preferred Insurance Services","office":"insurance"}},"n917":{"id":"n917","loc":[-85.63299,41.943686],"tags":{"addr:city":"Three Rivers","addr:housenumber":"101","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","name":"Lynn's Garage","service:vehicle:tyres":"yes","shop":"car_repair"}},"n918":{"id":"n918","loc":[-85.633438,41.944883]},"n919":{"id":"n919","loc":[-85.633265,41.944983]},"n92":{"id":"n92","loc":[-85.637481,41.942341]},"n920":{"id":"n920","loc":[-85.633315,41.945027]},"n921":{"id":"n921","loc":[-85.633376,41.944827]},"n922":{"id":"n922","loc":[-85.633199,41.944922]},"n923":{"id":"n923","loc":[-85.633316,41.944772]},"n924":{"id":"n924","loc":[-85.633147,41.944867]},"n925":{"id":"n925","loc":[-85.633261,41.944719]},"n926":{"id":"n926","loc":[-85.633096,41.944812]},"n927":{"id":"n927","loc":[-85.633191,41.944645]},"n928":{"id":"n928","loc":[-85.632981,41.94476]},"n929":{"id":"n929","loc":[-85.633062,41.94483]},"n93":{"id":"n93","loc":[-85.637481,41.94226]},"n930":{"id":"n930","loc":[-85.633146,41.944602]},"n931":{"id":"n931","loc":[-85.632969,41.944703]},"n932":{"id":"n932","loc":[-85.633008,41.944745]},"n933":{"id":"n933","loc":[-85.633088,41.944545]},"n934":{"id":"n934","loc":[-85.632868,41.944655]},"n935":{"id":"n935","loc":[-85.632941,41.944718]},"n936":{"id":"n936","loc":[-85.633028,41.944483]},"n937":{"id":"n937","loc":[-85.632817,41.944605]},"n938":{"id":"n938","loc":[-85.632923,41.944373]},"n939":{"id":"n939","loc":[-85.632692,41.944485]},"n94":{"id":"n94","loc":[-85.637565,41.94226]},"n940":{"id":"n940","loc":[-85.632871,41.944316]},"n941":{"id":"n941","loc":[-85.632655,41.944421]},"n942":{"id":"n942","loc":[-85.632711,41.944478]},"n943":{"id":"n943","loc":[-85.632825,41.94426]},"n944":{"id":"n944","loc":[-85.632606,41.944363]},"n945":{"id":"n945","loc":[-85.63275,41.94418]},"n946":{"id":"n946","loc":[-85.632588,41.944256]},"n947":{"id":"n947","loc":[-85.632611,41.944279]},"n948":{"id":"n948","loc":[-85.632548,41.944306]},"n949":{"id":"n949","loc":[-85.632512,41.944406]},"n95":{"id":"n95","loc":[-85.637188,41.942217]},"n950":{"id":"n950","loc":[-85.632565,41.944463]},"n951":{"id":"n951","loc":[-85.632579,41.944456]},"n952":{"id":"n952","loc":[-85.632634,41.944518]},"n953":{"id":"n953","loc":[-85.632686,41.944569]},"n954":{"id":"n954","loc":[-85.632745,41.944537]},"n955":{"id":"n955","loc":[-85.632659,41.944587]},"n956":{"id":"n956","loc":[-85.632778,41.944705]},"n957":{"id":"n957","loc":[-85.632815,41.944301],"tags":{"addr:city":"Three Rivers","addr:housenumber":"5","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","name":"Access Point Employment","office":"employment_agency"}},"n958":{"id":"n958","loc":[-85.6332,41.944174],"tags":{"addr:city":"Three Rivers","addr:housenumber":"6","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","name":"Paisley Emporium","shop":"second_hand"}},"n959":{"id":"n959","loc":[-85.633578,41.944568],"tags":{"addr:city":"Three Rivers","addr:housenumber":"22","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","name":"Lowry's Books","shop":"books"}},"n96":{"id":"n96","loc":[-85.637189,41.942303]},"n960":{"id":"n960","loc":[-85.63344,41.944443],"tags":{"addr:city":"Three Rivers","addr:housenumber":"16","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","amenity":"restaurant","cuisine":"pizza","name":"Paisano's Bar and Grill"}},"n961":{"id":"n961","loc":[-85.633009,41.944542],"tags":{"addr:city":"Three Rivers","addr:housenumber":"13","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","amenity":"cafe","cuisine":"american","internet_access":"yes","name":"Main Street Cafe"}},"n962":{"id":"n962","loc":[-85.633674,41.944682],"tags":{"addr:city":"Three Rivers","addr:housenumber":"28","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","leisure":"fitness_centre","name":"Main Street Fitness"}},"n963":{"id":"n963","loc":[-85.633376,41.944868],"tags":{"addr:city":"Three Rivers","addr:housenumber":"27","addr:postcode":"49093","addr:state":"MI","addr:street":"Main Street","leisure":"fitness_centre","name":"Main Street Barbell"}},"n964":{"id":"n964","loc":[-85.633366,41.944783]},"n965":{"id":"n965","loc":[-85.633296,41.94482]},"n966":{"id":"n966","loc":[-85.633214,41.94487]},"n967":{"id":"n967","loc":[-85.633005,41.944988]},"n968":{"id":"n968","loc":[-85.633269,41.944816]},"n969":{"id":"n969","loc":[-85.633215,41.944842]},"n97":{"id":"n97","loc":[-85.637299,41.942302]},"n970":{"id":"n970","loc":[-85.633245,41.944871]},"n971":{"id":"n971","loc":[-85.633296,41.944845]},"n972":{"id":"n972","loc":[-85.633254,41.944845],"tags":{"natural":"tree"}},"n973":{"id":"n973","loc":[-85.633557,41.945515]},"n974":{"id":"n974","loc":[-85.633279,41.945246]},"n975":{"id":"n975","loc":[-85.63324,41.945226]},"n976":{"id":"n976","loc":[-85.6332,41.945213]},"n977":{"id":"n977","loc":[-85.633133,41.945164]},"n978":{"id":"n978","loc":[-85.63312,41.945132]},"n979":{"id":"n979","loc":[-85.633095,41.945081]},"n98":{"id":"n98","loc":[-85.637299,41.942314]},"n980":{"id":"n980","loc":[-85.633064,41.945047]},"n981":{"id":"n981","loc":[-85.632739,41.944742]},"n982":{"id":"n982","loc":[-85.633281,41.945026]},"n983":{"id":"n983","loc":[-85.633155,41.944903]},"n984":{"id":"n984","loc":[-85.633079,41.944829]},"n985":{"id":"n985","loc":[-85.63304,41.944853]},"n986":{"id":"n986","loc":[-85.632949,41.944776]},"n987":{"id":"n987","loc":[-85.632921,41.944725]},"n988":{"id":"n988","loc":[-85.632859,41.944673]},"n989":{"id":"n989","loc":[-85.632895,41.94505]},"n99":{"id":"n99","loc":[-85.637396,41.942313]},"n990":{"id":"n990","loc":[-85.633336,41.945138]},"n991":{"id":"n991","loc":[-85.633466,41.945265]},"n992":{"id":"n992","loc":[-85.633367,41.945327]},"n993":{"id":"n993","loc":[-85.633163,41.945189]},"n994":{"id":"n994","loc":[-85.633678,41.945309]},"n995":{"id":"n995","loc":[-85.633619,41.945261]},"n996":{"id":"n996","loc":[-85.63355,41.945301]},"n997":{"id":"n997","loc":[-85.633607,41.945352]},"n998":{"id":"n998","loc":[-85.633579,41.945327],"tags":{"entrance":"yes"}},"n999":{"id":"n999","loc":[-85.633445,41.945404]},"r2":{"id":"r2","members":[{"id":"w225","role":"outer","type":"way"}],"tags":{"type":"multipolygon","waterway":"riverbank"}},"r5":{"id":"r5","members":[{"id":"w642","role":"outer","type":"way"}],"tags":{"admin_level":"8","border_type":"city","boundary":"administrative","name":"Three Rivers","place":"city","type":"boundary"}},"w1":{"id":"w1","nodes":["n5","n1797"],"tags":{"highway":"residential","name":"12th Avenue"}},"w10":{"id":"w10","nodes":["n54","n55","n56","n57","n891","n890","n54"],"tags":{"building":"yes"}},"w100":{"id":"w100","nodes":["n451","n915","n452"],"tags":{"highway":"footway"}},"w101":{"id":"w101","nodes":["n461","n462","n463","n464","n465","n466"],"tags":{"barrier":"fence"}},"w102":{"id":"w102","nodes":["n467","n468","n469","n470","n472","n467"],"tags":{"amenity":"parking"}},"w103":{"id":"w103","nodes":["n2597","n2444","n471","n472"],"tags":{"highway":"footway"}},"w104":{"id":"w104","nodes":["n473","n474","n325"],"tags":{"footway":"sidewalk","highway":"footway"}},"w105":{"id":"w105","nodes":["n475","n324","n325"],"tags":{"footway":"sidewalk","highway":"footway"}},"w106":{"id":"w106","nodes":["n886","n452","n476"],"tags":{"footway":"sidewalk","highway":"footway"}},"w107":{"id":"w107","nodes":["n485","n4678","n486","n18"],"tags":{"highway":"service"}},"w108":{"id":"w108","nodes":["n300","n487","n488","n489","n490"],"tags":{"highway":"footway"}},"w109":{"id":"w109","nodes":["n490","n491"],"tags":{"highway":"footway"}},"w11":{"id":"w11","nodes":["n58","n63","n59","n315","n60"],"tags":{"highway":"service"}},"w110":{"id":"w110","nodes":["n492","n493","n494","n495","n496","n497","n492"],"tags":{"building":"yes"}},"w111":{"id":"w111","nodes":["n498","n499","n511"],"tags":{"highway":"service"}},"w112":{"id":"w112","nodes":["n510","n500","n501","n502","n503","n504","n505","n506","n507","n508","n509"],"tags":{"highway":"service"}},"w113":{"id":"w113","nodes":["n511","n510"],"tags":{"covered":"yes","highway":"service"}},"w114":{"id":"w114","nodes":["n512","n513","n514","n515","n512"],"tags":{"building":"yes"}},"w115":{"id":"w115","nodes":["n516","n517","n518","n519","n516"],"tags":{"building":"yes"}},"w116":{"id":"w116","nodes":["n520","n521","n522","n523","n520"],"tags":{"building":"yes"}},"w117":{"id":"w117","nodes":["n524","n525","n526","n527","n528","n529","n530","n531","n532","n533","n534","n535","n524"],"tags":{"building":"yes"}},"w118":{"id":"w118","nodes":["n536","n537","n538","n539","n536"],"tags":{"building":"yes"}},"w119":{"id":"w119","nodes":["n540","n541","n542","n543","n544","n545","n546","n547","n540"],"tags":{"building":"yes"}},"w12":{"id":"w12","nodes":["n61","n314","n70","n62","n63"],"tags":{"highway":"service"}},"w120":{"id":"w120","nodes":["n548","n549","n550","n551","n552","n553","n554","n555","n556","n557","n548"],"tags":{"building":"yes"}},"w121":{"id":"w121","nodes":["n558","n559","n560","n561","n562","n563","n564","n565","n558"],"tags":{"building":"yes"}},"w122":{"id":"w122","nodes":["n566","n567","n568","n569","n566"],"tags":{"building":"yes"}},"w123":{"id":"w123","nodes":["n570","n571","n572","n573","n570"],"tags":{"building":"yes"}},"w124":{"id":"w124","nodes":["n574","n575","n576","n577","n574"],"tags":{"building":"yes"}},"w125":{"id":"w125","nodes":["n578","n579","n580","n581","n578"],"tags":{"building":"yes"}},"w126":{"id":"w126","nodes":["n582","n583","n584","n585","n582"],"tags":{"building":"yes"}},"w127":{"id":"w127","nodes":["n586","n587","n588","n589","n590","n591","n592","n593","n586"],"tags":{"building":"yes"}},"w128":{"id":"w128","nodes":["n594","n595","n596","n597","n598","n599","n600","n601","n594"],"tags":{"building":"yes"}},"w129":{"id":"w129","nodes":["n309","n602","n603"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w13":{"id":"w13","nodes":["n64","n65","n66","n67","n68","n69","n64"],"tags":{"amenity":"parking"}},"w130":{"id":"w130","nodes":["n603","n604"],"tags":{"footway":"sidewalk","highway":"footway"}},"w131":{"id":"w131","nodes":["n604","n605","n606"],"tags":{"footway":"sidewalk","highway":"footway"}},"w132":{"id":"w132","nodes":["n606","n607"],"tags":{"footway":"sidewalk","highway":"footway"}},"w133":{"id":"w133","nodes":["n607","n610","n608","n603"],"tags":{"footway":"sidewalk","highway":"footway"}},"w134":{"id":"w134","nodes":["n609","n610","n611"],"tags":{"highway":"service","service":"driveway","surface":"unpaved"}},"w135":{"id":"w135","nodes":["n244","n245","n246"],"tags":{"highway":"service"}},"w136":{"id":"w136","nodes":["n612","n613","n614","n615","n612"],"tags":{"amenity":"shelter"}},"w137":{"id":"w137","nodes":["n2779","n2788","n2776","n2778","n2775","n2787","n2440","n2437","n629","n2438","n630","n2439","n2407","n2408","n2409"],"tags":{"highway":"residential","name":"Foster Street"}},"w138":{"id":"w138","nodes":["n2779","n625","n626","n627"],"tags":{"highway":"residential","name":"Foster Street","oneway":"yes"}},"w139":{"id":"w139","nodes":["n630","n631","n632","n2437"],"tags":{"highway":"service"}},"w14":{"id":"w14","nodes":["n71","n72","n73","n74","n71"],"tags":{"building":"yes"}},"w140":{"id":"w140","nodes":["n643","n637","n715","n2410"],"tags":{"highway":"footway","name":"Mural Mall"}},"w141":{"id":"w141","nodes":["n639","n2516"],"tags":{"barrier":"wall"}},"w142":{"id":"w142","nodes":["n640","n641","n645","n642","n660","n643","n644"],"tags":{"highway":"service"}},"w143":{"id":"w143","nodes":["n646","n647"],"tags":{"highway":"service"}},"w144":{"id":"w144","nodes":["n654","n655","n656"],"tags":{"barrier":"wall"}},"w145":{"id":"w145","nodes":["n665","n666","n667"],"tags":{"barrier":"wall"}},"w146":{"id":"w146","nodes":["n2727","n662","n2719"],"tags":{"highway":"service","oneway":"yes","service":"parking_aisle"}},"w147":{"id":"w147","nodes":["n2725","n674"],"tags":{"highway":"service","oneway":"yes"}},"w148":{"id":"w148","nodes":["n2464","n2460","n2454","n684","n2455","n2464"],"tags":{"building":"yes"}},"w149":{"id":"w149","nodes":["n2456","n685","n686","n687","n2456"],"tags":{"building":"yes"}},"w15":{"id":"w15","nodes":["n75","n76","n77","n78","n75"],"tags":{"building":"yes"}},"w150":{"id":"w150","nodes":["n685","n688","n689","n690","n691","n692","n686","n685"],"tags":{"building":"yes"}},"w151":{"id":"w151","nodes":["n688","n693","n694","n689","n688"],"tags":{"building":"yes"}},"w152":{"id":"w152","nodes":["n693","n695","n702","n696","n697","n694","n693"],"tags":{"building":"yes"}},"w153":{"id":"w153","nodes":["n695","n698","n699","n700","n701","n702","n695"],"tags":{"building":"yes"}},"w154":{"id":"w154","nodes":["n698","n703","n707","n704","n699","n698"],"tags":{"building":"yes"}},"w155":{"id":"w155","nodes":["n703","n705","n706","n707","n703"],"tags":{"building":"yes"}},"w156":{"id":"w156","nodes":["n705","n708","n709","n706","n705"],"tags":{"building":"yes"}},"w157":{"id":"w157","nodes":["n709","n710","n711","n708","n709"],"tags":{"building":"yes"}},"w158":{"id":"w158","nodes":["n369","n712","n725","n713","n714","n715","n727","n716","n717","n718","n719"],"tags":{"footway":"sidewalk","highway":"footway"}},"w159":{"id":"w159","nodes":["n714","n720","n721"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w16":{"id":"w16","nodes":["n79","n80","n81","n82","n83","n84","n85","n86","n79"],"tags":{"building":"yes"}},"w160":{"id":"w160","nodes":["n729","n721","n722","n964","n723","n724"],"tags":{"footway":"sidewalk","highway":"footway"}},"w161":{"id":"w161","nodes":["n713","n726","n722"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w162":{"id":"w162","nodes":["n727","n2411","n728"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w163":{"id":"w163","nodes":["n729","n730","n731"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w164":{"id":"w164","nodes":["n365","n732","n733","n738"],"tags":{"footway":"sidewalk","highway":"footway"}},"w165":{"id":"w165","nodes":["n724","n734","n367","n735","n736","n737"],"tags":{"footway":"sidewalk","highway":"footway"}},"w166":{"id":"w166","nodes":["n739","n2037","n2038","n2039","n2040","n1623","n2032"],"tags":{"highway":"footway"}},"w167":{"id":"w167","nodes":["n150","n751"],"tags":{"highway":"service"}},"w168":{"id":"w168","nodes":["n752","n753","n754","n755","n752"],"tags":{"building":"yes"}},"w169":{"id":"w169","nodes":["n756","n757","n758","n759","n756"],"tags":{"building":"yes"}},"w17":{"id":"w17","nodes":["n87","n88","n89","n90","n87"],"tags":{"building":"yes"}},"w170":{"id":"w170","nodes":["n760","n761","n762","n763","n764","n765","n760"],"tags":{"building":"yes"}},"w171":{"id":"w171","nodes":["n766","n767","n768","n769","n770","n771","n772","n773","n774","n775","n776","n777","n766"],"tags":{"building":"yes"}},"w172":{"id":"w172","nodes":["n778","n779","n780","n781","n782","n783","n784","n785","n778"],"tags":{"building":"yes"}},"w173":{"id":"w173","nodes":["n786","n787","n788","n789","n786"],"tags":{"building":"yes"}},"w174":{"id":"w174","nodes":["n790","n791","n792","n793","n794","n795","n796","n797","n798","n799","n800","n801","n790"],"tags":{"building":"yes"}},"w175":{"id":"w175","nodes":["n802","n803","n804","n805","n802"],"tags":{"building":"yes"}},"w176":{"id":"w176","nodes":["n806","n807","n808","n809","n810","n811","n812","n813","n814","n815","n806"],"tags":{"building":"yes"}},"w177":{"id":"w177","nodes":["n816","n1140","n817","n818","n819","n820","n821"],"tags":{"highway":"service"}},"w178":{"id":"w178","nodes":["n822","n823","n824","n825","n822"],"tags":{"building":"yes"}},"w179":{"id":"w179","nodes":["n841","n842","n843","n844","n841"],"tags":{"building":"yes"}},"w18":{"id":"w18","nodes":["n91","n92","n93","n94","n91"],"tags":{"building":"yes"}},"w180":{"id":"w180","nodes":["n845","n856","n846"],"tags":{"highway":"service"}},"w181":{"id":"w181","nodes":["n846","n847","n848","n849","n850","n851","n852","n853","n854","n855","n856"],"tags":{"highway":"service","oneway":"yes","service":"drive-through"}},"w182":{"id":"w182","nodes":["n857","n858"],"tags":{"highway":"service"}},"w183":{"id":"w183","nodes":["n859","n860","n861","n862","n859"],"tags":{"amenity":"parking"}},"w184":{"id":"w184","nodes":["n863","n864","n867","n866","n865"],"tags":{"highway":"service"}},"w185":{"id":"w185","nodes":["n883","n884"],"tags":{"barrier":"fence"}},"w186":{"id":"w186","nodes":["n1954","n622","n1955"],"tags":{"highway":"path","name":"Riverwalk Trail"}},"w187":{"id":"w187","nodes":["n621","n1954"],"tags":{"highway":"steps","incline":"up","name":"Riverwalk Trail","surface":"wood"}},"w188":{"id":"w188","nodes":["n2274","n2275","n2276","n2277","n2278","n2279","n1953","n621"],"tags":{"highway":"path","name":"Riverwalk Trail","surface":"wood"}},"w189":{"id":"w189","nodes":["n2273","n2274"],"tags":{"highway":"steps","incline":"down","name":"Riverwalk Trail","surface":"wood"}},"w19":{"id":"w19","nodes":["n95","n96","n97","n98","n99","n100","n101","n102","n95"],"tags":{"building":"yes"}},"w190":{"id":"w190","nodes":["n821","n894","n900","n903","n901"],"tags":{"highway":"service"}},"w191":{"id":"w191","nodes":["n896","n897","n898","n899","n900","n894","n896"],"tags":{"amenity":"parking"}},"w192":{"id":"w192","nodes":["n903","n904","n905"],"tags":{"highway":"service"}},"w193":{"id":"w193","nodes":["n901","n906","n902"],"tags":{"highway":"service"}},"w194":{"id":"w194","nodes":["n912","n913"],"tags":{"highway":"footway"}},"w195":{"id":"w195","nodes":["n914","n915"],"tags":{"highway":"footway"}},"w196":{"id":"w196","nodes":["n2466","n918","n919","n920","n2466"],"tags":{"building":"yes"}},"w197":{"id":"w197","nodes":["n918","n921","n922","n919","n918"],"tags":{"building":"yes"}},"w198":{"id":"w198","nodes":["n923","n925","n926","n924","n923"],"tags":{"building":"yes"}},"w199":{"id":"w199","nodes":["n925","n927","n932","n928","n929","n926","n925"],"tags":{"building":"yes"}},"w2":{"id":"w2","nodes":["n3523","n2182","n2160"],"tags":{"highway":"service"}},"w20":{"id":"w20","nodes":["n103","n104","n105","n106","n107","n108","n109","n110","n111","n112","n113","n114","n103"],"tags":{"building":"yes"}},"w200":{"id":"w200","nodes":["n927","n930","n931","n932","n927"],"tags":{"building":"yes"}},"w201":{"id":"w201","nodes":["n930","n933","n934","n935","n931","n930"],"tags":{"building":"yes"}},"w202":{"id":"w202","nodes":["n933","n936","n937","n934","n933"],"tags":{"building":"yes"}},"w203":{"id":"w203","nodes":["n936","n938","n942","n939","n954","n937","n936"],"tags":{"building":"yes"}},"w204":{"id":"w204","nodes":["n938","n940","n941","n942","n938"],"tags":{"building":"yes"}},"w205":{"id":"w205","nodes":["n940","n943","n944","n941","n940"],"tags":{"building":"yes"}},"w206":{"id":"w206","nodes":["n943","n945","n946","n947","n948","n944","n943"],"tags":{"building":"yes"}},"w207":{"id":"w207","nodes":["n944","n949","n950","n951","n941","n944"],"tags":{"building":"yes"}},"w208":{"id":"w208","nodes":["n941","n951","n952","n939","n942","n941"],"tags":{"building":"yes"}},"w209":{"id":"w209","nodes":["n952","n953","n954","n939","n952"],"tags":{"building":"yes"}},"w21":{"id":"w21","nodes":["n115","n116","n117","n118","n115"],"tags":{"building":"yes"}},"w210":{"id":"w210","nodes":["n953","n955","n956","n934","n937","n954","n953"],"tags":{"building":"yes"}},"w211":{"id":"w211","nodes":["n964","n965"],"tags":{"highway":"footway"}},"w212":{"id":"w212","nodes":["n966","n983","n967","n989"],"tags":{"highway":"footway"}},"w213":{"id":"w213","nodes":["n965","n968","n969","n966","n970","n971","n965"],"tags":{"highway":"footway"}},"w214":{"id":"w214","nodes":["n973","n999","n992","n974","n975","n976","n993","n977","n978","n979","n980","n967","n981","n1000","n1001","n1002","n1003","n1004","n1005","n1006","n1007","n1008","n1009"],"tags":{"footway":"sidewalk","highway":"footway"}},"w215":{"id":"w215","nodes":["n978","n982","n983","n984","n985","n986","n987","n988","n981"],"tags":{"highway":"footway"}},"w216":{"id":"w216","nodes":["n976","n990","n991","n992"],"tags":{"highway":"footway"}},"w217":{"id":"w217","nodes":["n998","n999"],"tags":{"highway":"footway"}},"w218":{"id":"w218","nodes":["n1019","n1020","n1021","n1022","n731","n728","n1023","n1025","n1024","n1019"],"tags":{"footway":"sidewalk","highway":"footway"}},"w219":{"id":"w219","nodes":["n719","n1026","n1027"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w22":{"id":"w22","nodes":["n119","n120","n121","n122","n119"],"tags":{"building":"yes"}},"w220":{"id":"w220","nodes":["n1027","n1028","n1019"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w221":{"id":"w221","nodes":["n2080","n1828","n1863","n1829"],"tags":{"highway":"tertiary","name":"Constantine Street"}},"w222":{"id":"w222","nodes":["n1029","n1030","n1031"],"tags":{"highway":"service"}},"w223":{"id":"w223","nodes":["n2213","n2171","n2183","n2180","n2205","n2177","n2179","n2218","n2200","n2188","n2169","n2196","n2162","n2170","n2211","n2216","n2204","n2220","n2164","n2210","n2217","n2189","n460","n453","n2282"],"tags":{"name":"Rocky River","waterway":"river"}},"w224":{"id":"w224","nodes":["n3750","n3751","n3752"],"tags":{"highway":"service","service":"alley","surface":"unpaved"}},"w225":{"id":"w225","nodes":["n2134","n2127","n2313","n2109","n2112","n2129","n2156","n2146","n2126","n2153","n2288","n2283","n2284","n2131","n2286","n2287","n2285","n2132","n2140","n2289","n2122","n2114","n2149","n2119","n2106","n2111","n2145","n2113","n2117","n2159","n2143","n2123","n2142","n2116","n2154","n2139","n2150","n2157","n2120","n2138","n2130","n2136","n2155","n2107","n2141","n2124","n3754","n2121","n2105","n2108","n3755","n2128","n2110","n2152","n2125","n2135","n2186","n2115","n2144","n2137","n2133","n2148","n2118","n1871","n1875","n1872","n2041","n1873","n2042","n1874","n1884","n1870","n2151","n2147","n2158","n2104","n2134"]},"w226":{"id":"w226","nodes":["n2243","n2280","n2244","n2245","n2246","n2247","n1931","n1932","n1933","n1934","n1935","n1936","n1937","n1938","n4681","n1939","n1940","n1941","n1942","n1943","n1944","n1945","n1946","n1947"],"tags":{"highway":"path","name":"Riverwalk Trail","surface":"asphalt","width":"3"}},"w227":{"id":"w227","nodes":["n2994","n3012","n3011","n2958"],"tags":{"highway":"secondary","name":"Main Street"}},"w228":{"id":"w228","nodes":["n2747","n2762","n2757","n2746","n2761","n2758","n2760","n2755","n2749","n2691","n1028","n2432","n2414","n2413","n2412","n2411","n2410","n720","n726","n370","n368","n2748"],"tags":{"highway":"primary","name":"Main Street"}},"w229":{"id":"w229","nodes":["n2083","n2103","n2102","n2084","n2085","n2086","n2087","n2242","n471","n324","n2101","n332","n1868"],"tags":{"name":"Conrail Railroad","railway":"rail"}},"w23":{"id":"w23","nodes":["n123","n124","n125","n126","n123"],"tags":{"building":"yes"}},"w230":{"id":"w230","nodes":["n2232","n2236","n2231","n2230","n2226","n2241","n2237","n2227","n1182","n2233","n2228","n2229","n1183","n2234","n19","n1891","n20","n2223","n2224","n2238","n2235","n2240","n2225","n2239"],"tags":{"name":"Saint Joseph River","waterway":"river"}},"w231":{"id":"w231","nodes":["n456","n1036","n1037","n1038"],"tags":{"barrier":"wall"}},"w232":{"id":"w232","nodes":["n1034","n1039","n1040"],"tags":{"barrier":"wall"}},"w233":{"id":"w233","nodes":["n1041","n1042","n1043","n1044","n1045","n1046","n1041"],"tags":{"access":"private","leisure":"swimming_pool"}},"w234":{"id":"w234","nodes":["n1047","n1048"],"tags":{"barrier":"hedge"}},"w235":{"id":"w235","nodes":["n1049","n1050","n1051","n1052","n1049"],"tags":{"building":"yes"}},"w236":{"id":"w236","nodes":["n1053","n1054","n1055","n1056","n1057","n1058","n1059","n1060","n1053"],"tags":{"building":"yes"}},"w237":{"id":"w237","nodes":["n1061","n1062","n1063","n1064","n1065","n1061"],"tags":{"building":"yes"}},"w238":{"id":"w238","nodes":["n1066","n1067","n1068","n1069","n1070","n1071","n1066"],"tags":{"building":"yes"}},"w239":{"id":"w239","nodes":["n1072","n1073","n1074","n1075","n1072"],"tags":{"building":"yes"}},"w24":{"id":"w24","nodes":["n127","n128","n129","n130","n127"],"tags":{"building":"yes"}},"w240":{"id":"w240","nodes":["n1076","n1077","n1078","n1079","n1080","n1081","n1076"],"tags":{"building":"yes"}},"w241":{"id":"w241","nodes":["n1082","n1083","n1084","n1085","n1082"],"tags":{"building":"yes"}},"w242":{"id":"w242","nodes":["n1086","n1087","n1088","n1089","n1086"],"tags":{"building":"yes"}},"w243":{"id":"w243","nodes":["n1090","n1091","n1092","n1093","n1094","n1095","n1096","n1097","n1090"],"tags":{"building":"yes"}},"w244":{"id":"w244","nodes":["n1098","n1099","n1100","n1101"],"tags":{"barrier":"fence"}},"w245":{"id":"w245","nodes":["n1102","n835","n30","n2590","n35","n29","n2591","n34","n28","n2592","n2312","n32","n2593","n31","n33","n2594","n2595","n1102"],"tags":{"highway":"service"}},"w246":{"id":"w246","nodes":["n1103","n1139","n1104"],"tags":{"barrier":"fence"}},"w247":{"id":"w247","nodes":["n1105","n1106","n1107","n1108","n1109","n1110","n1111","n1112","n1113","n1114","n1105"],"tags":{"building":"yes"}},"w248":{"id":"w248","nodes":["n1115","n1116","n1117","n1118","n1119","n1120","n1115"],"tags":{"building":"yes"}},"w249":{"id":"w249","nodes":["n1121","n1122","n1123","n1124","n1121"],"tags":{"building":"yes"}},"w25":{"id":"w25","nodes":["n131","n132","n133","n134","n135","n136","n137","n138","n139","n140","n141","n142","n131"],"tags":{"building":"yes"}},"w250":{"id":"w250","nodes":["n1125","n1126","n1127","n1128","n1129","n1130","n1131","n1132","n1133","n1134","n1135","n1136","n1125"],"tags":{"building":"yes"}},"w251":{"id":"w251","nodes":["n1137","n1138","n1139"],"tags":{"barrier":"fence"}},"w252":{"id":"w252","nodes":["n876","n1140","n1141"],"tags":{"footway":"sidewalk","highway":"footway"}},"w253":{"id":"w253","nodes":["n1141","n1142","n1143","n1144","n1145","n1146"],"tags":{"footway":"sidewalk","highway":"footway"}},"w254":{"id":"w254","nodes":["n1146","n4743","n1147","n1148"],"tags":{"footway":"sidewalk","highway":"footway"}},"w255":{"id":"w255","nodes":["n1148","n1149","n1150","n1151"],"tags":{"bridge":"yes","footway":"sidewalk","highway":"footway","layer":"1"}},"w256":{"id":"w256","nodes":["n1151","n1153","n1154","n1155"],"tags":{"footway":"sidewalk","highway":"footway"}},"w257":{"id":"w257","nodes":["n1155","n1156"],"tags":{"bridge":"yes","footway":"sidewalk","highway":"footway","layer":"1"}},"w258":{"id":"w258","nodes":["n1157","n1158"],"tags":{"barrier":"retaining_wall"}},"w259":{"id":"w259","nodes":["n1156","n1161","n1159","n1160","n719"],"tags":{"footway":"sidewalk","highway":"footway"}},"w26":{"id":"w26","nodes":["n143","n608","n144"],"tags":{"highway":"service"}},"w260":{"id":"w260","nodes":["n1162","n1163","n1164","n1165","n1166","n1167","n1168","n1169","n1170","n2528"],"tags":{"highway":"footway"}},"w261":{"id":"w261","nodes":["n1171","n1172","n1173"],"tags":{"barrier":"wall"}},"w262":{"id":"w262","nodes":["n1175","n1176","n1177","n1178","n1179","n1180","n1181","n1175"],"tags":{"natural":"wood"}},"w263":{"id":"w263","nodes":["n1947","n1184","n1948","n1185","n1949","n1957","n1950","n480","n1951","n479","n478","n477","n1952","n1851","n1956","n2248","n619","n618","n2249","n2250","n2251","n617","n2252","n616","n2253","n829","n2254","n827","n828","n2255","n830","n2256","n826","n2257","n831","n2258","n832","n835","n834","n2312","n2267","n2259","n833","n2268","n2260","n836","n2261","n837","n2262","n838","n2263","n2264","n839","n2265","n840","n2266"],"tags":{"highway":"path","name":"Riverwalk Trail","surface":"asphalt","width":"3"}},"w264":{"id":"w264","nodes":["n1186","n1187","n1188","n1189","n1186"],"tags":{"building":"yes"}},"w265":{"id":"w265","nodes":["n1190","n1191","n1192","n1193","n1190"],"tags":{"building":"yes"}},"w266":{"id":"w266","nodes":["n1194","n1195","n1196","n1197","n1198","n1199","n1200","n1201","n1194"],"tags":{"building":"yes"}},"w267":{"id":"w267","nodes":["n1205","n1206","n1207","n1208","n1209","n1210","n1205"],"tags":{"building":"house"}},"w268":{"id":"w268","nodes":["n1211","n1212","n1213","n1214","n1215","n1216","n1217","n1218","n1219","n1220","n1211"],"tags":{"building":"house"}},"w269":{"id":"w269","nodes":["n1221","n1225","n1222","n1223","n1224","n1221"],"tags":{"building":"house"}},"w27":{"id":"w27","nodes":["n145","n147","n146"],"tags":{"highway":"footway"}},"w270":{"id":"w270","nodes":["n1225","n1226","n1227","n1229","n1228"],"tags":{"barrier":"fence"}},"w271":{"id":"w271","nodes":["n1229","n1230"],"tags":{"barrier":"fence"}},"w272":{"id":"w272","nodes":["n1231","n1232","n1233","n1234","n1235","n1236","n1237","n1238","n1231"],"tags":{"building":"house"}},"w273":{"id":"w273","nodes":["n1239","n1240","n1241","n1242","n1243","n1244","n1245","n1246","n1239"],"tags":{"building":"house"}},"w274":{"id":"w274","nodes":["n1247","n1248","n1249","n1250","n1247"],"tags":{"building":"house"}},"w275":{"id":"w275","nodes":["n1251","n1252","n1253","n1254","n1255","n1256","n1251"],"tags":{"building":"house"}},"w276":{"id":"w276","nodes":["n1257","n1258","n1259","n1260","n1257"],"tags":{"building":"shed"}},"w277":{"id":"w277","nodes":["n1261","n1262","n1263","n1264","n1265","n1266","n1267","n1268","n1261"],"tags":{"building":"house"}},"w278":{"id":"w278","nodes":["n1269","n1270","n1271","n1272","n1273","n1274","n1284","n1269"],"tags":{"building":"house"}},"w279":{"id":"w279","nodes":["n1275","n1276","n1277","n1278","n1279","n1280","n1275"],"tags":{"building":"house"}},"w28":{"id":"w28","nodes":["n147","n148"],"tags":{"highway":"footway"}},"w280":{"id":"w280","nodes":["n1281","n1282","n1283","n1284"],"tags":{"barrier":"fence"}},"w281":{"id":"w281","nodes":["n1285","n1286","n1287","n1288","n1285"],"tags":{"building":"house"}},"w282":{"id":"w282","nodes":["n1289","n1290","n1291","n1292","n1293","n1294","n1295","n1296","n1289"],"tags":{"building":"house"}},"w283":{"id":"w283","nodes":["n1297","n1298","n1299","n1300","n1301","n1302","n1297"],"tags":{"access":"private","leisure":"swimming_pool"}},"w284":{"id":"w284","nodes":["n1303","n1304","n1305","n1306","n1307","n1308","n1309","n1310","n1311","n1312","n1303"],"tags":{"building":"house"}},"w285":{"id":"w285","nodes":["n1313","n1314","n1315","n1316","n1313"],"tags":{"building":"house"}},"w286":{"id":"w286","nodes":["n1317","n1318","n1319","n1320","n1321","n1322","n1323","n1324","n1325","n1326","n1327","n1328","n1329","n1330","n1317"],"tags":{"building":"house"}},"w287":{"id":"w287","nodes":["n1331","n1332","n1333","n1334","n1465","n1335","n1336","n1331"],"tags":{"building":"yes"}},"w288":{"id":"w288","nodes":["n1349","n1350","n1351","n1352","n1353","n1354","n1355","n1337","n1338","n1341","n1342","n1343","n1344","n1345","n1346","n1347","n1348","n1339","n1340","n1349"],"tags":{"access":"private","leisure":"swimming_pool"}},"w289":{"id":"w289","nodes":["n1356","n1331"],"tags":{"barrier":"fence"}},"w29":{"id":"w29","nodes":["n149","n874","n150","n151","n897","n898","n875","n152"],"tags":{"highway":"service","oneway":"yes"}},"w290":{"id":"w290","nodes":["n1357","n1358","n1359","n1360","n1357"],"tags":{"building":"shed"}},"w291":{"id":"w291","nodes":["n1358","n1361","n1362"],"tags":{"barrier":"fence"}},"w292":{"id":"w292","nodes":["n1363","n1364","n1365","n1366","n1367","n1368","n1363"],"tags":{"building":"house"}},"w293":{"id":"w293","nodes":["n1369","n1370","n1371","n1372","n1373","n1374","n1369"],"tags":{"leisure":"swimming_pool"}},"w294":{"id":"w294","nodes":["n1367","n1375","n1376","n1377"],"tags":{"barrier":"fence"}},"w295":{"id":"w295","nodes":["n1378","n1379","n1380","n1381","n1378"],"tags":{"building":"house"}},"w296":{"id":"w296","nodes":["n1382","n1383","n1384","n1385","n1386","n1387","n1382"],"tags":{"building":"house"}},"w297":{"id":"w297","nodes":["n1388","n1389","n1390","n1391","n1392","n1393","n1388"],"tags":{"building":"house"}},"w298":{"id":"w298","nodes":["n1394","n1395","n1396","n1397","n1394"],"tags":{"building":"house"}},"w299":{"id":"w299","nodes":["n1398","n1399","n1400","n1401","n1398"],"tags":{"access":"private3","leisure":"swimming_pool"}},"w3":{"id":"w3","nodes":["n1","n2"],"tags":{"highway":"track","name":"Water Street"}},"w30":{"id":"w30","nodes":["n153","n154","n155","n156","n153"],"tags":{"amenity":"parking"}},"w300":{"id":"w300","nodes":["n1402","n1403","n1404","n1405","n1406","n1407","n1408","n1409","n1410","n1411","n1412","n1413","n1402"],"tags":{"building":"house"}},"w301":{"id":"w301","nodes":["n1414","n1415","n1416","n1417","n1414"],"tags":{"building":"garage"}},"w302":{"id":"w302","nodes":["n1406","n1418","n1419","n1403"],"tags":{"barrier":"fence"}},"w303":{"id":"w303","nodes":["n1423","n1424","n1425","n1426","n1427","n1428","n1429","n1430","n1431","n1432","n1423"],"tags":{"building":"house"}},"w304":{"id":"w304","nodes":["n1433","n1434","n1435","n1446","n1436","n1437","n1438","n1439","n1444","n1440","n1441","n1445","n1442","n1443","n1433"],"tags":{"access":"private","leisure":"swimming_pool"}},"w305":{"id":"w305","nodes":["n1447","n1448","n1452","n1453","n1454","n1451","n1449","n1450","n1447"],"tags":{"building":"house"}},"w306":{"id":"w306","nodes":["n1455","n1456","n1457","n1458","n1455"],"tags":{"building":"shed"}},"w307":{"id":"w307","nodes":["n1459","n1460","n1461","n1462","n1459"],"tags":{"building":"shed"}},"w308":{"id":"w308","nodes":["n1463","n1464"],"tags":{"barrier":"fence"}},"w309":{"id":"w309","nodes":["n1465","n1466","n1467","n1468"],"tags":{"barrier":"fence"}},"w31":{"id":"w31","nodes":["n157","n605","n158"],"tags":{"highway":"service"}},"w310":{"id":"w310","nodes":["n1469","n1481","n1463"],"tags":{"barrier":"hedge"}},"w311":{"id":"w311","nodes":["n1470","n1471","n1472","n1473","n1474","n1475","n1480","n1476","n1477","n1478","n1479","n1470"],"tags":{"building":"house"}},"w312":{"id":"w312","nodes":["n1480","n1481"],"tags":{"barrier":"wall"}},"w313":{"id":"w313","nodes":["n1482","n1483","n1484","n1485","n1486","n1487","n1488","n1489","n1490","n1491","n1482"],"tags":{"access":"private","leisure":"swimming_pool"}},"w314":{"id":"w314","nodes":["n1492","n1493","n1494","n1495","n1496","n1497","n1498","n1499","n1500","n1501","n1502","n1503","n1504","n1505","n1492"],"tags":{"building":"house"}},"w315":{"id":"w315","nodes":["n1506","n1507","n1508","n1509","n1510","n1511","n1512","n1513","n1514","n1515","n1506"],"tags":{"building":"house"}},"w316":{"id":"w316","nodes":["n1516","n1517","n1518","n1519","n1520","n1521","n1522","n1523","n1516"],"tags":{"building":"house"}},"w317":{"id":"w317","nodes":["n1524","n1525","n1526","n1527","n1528","n1529","n1530","n1531","n1524"],"tags":{"building":"house"}},"w318":{"id":"w318","nodes":["n1532","n1533"],"tags":{"barrier":"fence"}},"w319":{"id":"w319","nodes":["n1534","n1532","n1535"],"tags":{"barrier":"fence"}},"w32":{"id":"w32","nodes":["n159","n160","n161","n162","n159"],"tags":{"amenity":"parking"}},"w320":{"id":"w320","nodes":["n1536","n1537","n1538","n1539","n1536"],"tags":{"building":"shed"}},"w321":{"id":"w321","nodes":["n1540","n1541","n1542","n1543","n1540"],"tags":{"building":"shed"}},"w322":{"id":"w322","nodes":["n1544","n1545","n1546","n1547","n1544"],"tags":{"building":"shed"}},"w323":{"id":"w323","nodes":["n1548","n1549","n1550","n1551","n1548"],"tags":{"building":"house"}},"w324":{"id":"w324","nodes":["n1552","n1553","n1554","n1555","n1556","n1557","n1558","n1559","n1552"],"tags":{"building":"house"}},"w325":{"id":"w325","nodes":["n1560","n1561","n1562","n1563","n1564","n1565","n1566","n1567","n1560"],"tags":{"building":"house"}},"w326":{"id":"w326","nodes":["n1561","n1568","n1569","n1570"],"tags":{"barrier":"wall"}},"w327":{"id":"w327","nodes":["n1571","n1572"],"tags":{"barrier":"fence"}},"w328":{"id":"w328","nodes":["n1573","n1574","n1575","n1576","n1573"],"tags":{"building":"house"}},"w329":{"id":"w329","nodes":["n1577","n1578","n1579","n1580","n1581","n1582","n1583","n1584","n1585","n1586","n1577"],"tags":{"building":"house"}},"w33":{"id":"w33","nodes":["n157","n163"],"tags":{"highway":"service"}},"w330":{"id":"w330","nodes":["n1587","n1588","n1589","n1590","n1591","n1592","n1593","n1594","n1587"],"tags":{"building":"house"}},"w331":{"id":"w331","nodes":["n1595","n1596","n1597","n1598","n1599","n1600","n1601","n1595"],"tags":{"access":"private","leisure":"swimming_pool"}},"w332":{"id":"w332","nodes":["n1602","n1603","n1604","n1605","n1606","n1607","n1608","n1609","n1611","n1610","n1612","n1613","n1602"],"tags":{"building":"house"}},"w333":{"id":"w333","nodes":["n2018","n1626","n1627","n2017","n2018"],"tags":{"amenity":"shelter","shelter_type":"picnic_shelter"}},"w334":{"id":"w334","nodes":["n2","n3","n2764"],"tags":{"highway":"service","name":"Water Street"}},"w335":{"id":"w335","nodes":["n3","n1628","n1614"],"tags":{"highway":"service"}},"w336":{"id":"w336","nodes":["n3198","n4545","n2747"],"tags":{"highway":"residential","name":"Morris Avenue"}},"w337":{"id":"w337","nodes":["n1629","n3504"],"tags":{"highway":"service","service":"alley","surface":"unpaved"}},"w338":{"id":"w338","nodes":["n1813","n1635","n1814","n1634","n1815","n1632","n1816","n1817"],"tags":{"highway":"service","service":"parking_aisle"}},"w339":{"id":"w339","nodes":["n1827","n4684","n4690","n1842","n4686","n4685","n1826","n1828","n1846","n1645","n1637","n4703","n1641"],"tags":{"highway":"residential","name":"Millard Street"}},"w34":{"id":"w34","nodes":["n164","n165","n166","n171","n866","n172","n167","n168","n169","n910","n170","n164"],"tags":{"amenity":"parking"}},"w340":{"id":"w340","nodes":["n1824","n1825"],"tags":{"highway":"service","service":"parking_aisle"}},"w341":{"id":"w341","nodes":["n1701","n1702","n1703","n1704","n1705","n1706","n1701"],"tags":{"building":"yes"}},"w342":{"id":"w342","nodes":["n1855","n1860","n1856","n1775","n1804","n1776","n1855"],"tags":{"amenity":"parking","fee":"no"}},"w343":{"id":"w343","nodes":["n1757","n1758","n1759","n1760","n1757"],"tags":{"building":"yes"}},"w344":{"id":"w344","nodes":["n1659","n1660","n1661","n1662","n1663","n1664","n1665","n1666","n1659"],"tags":{"building":"school"}},"w345":{"id":"w345","nodes":["n1751","n1752","n1753","n1754","n1755","n1756","n1751"],"tags":{"building":"yes"}},"w346":{"id":"w346","nodes":["n1641","n1676","n1673","n1639","n1810","n1642","n1849","n4759","n1845"],"tags":{"highway":"residential","name":"Douglas Avenue"}},"w347":{"id":"w347","nodes":["n1642","n1643","n1031","n1630","n845","n1631","n816","n1831","n902","n905","n152","n149","n1832","n1850","n878","n1833","n1852","n42","n1834","n61","n60","n1851","n1835"],"tags":{"highway":"primary","name":"Michigan Avenue"}},"w348":{"id":"w348","nodes":["n1650","n1651","n1652","n1653","n1654","n1655","n1656","n1657","n1658","n1650"],"tags":{"leisure":"playground"}},"w349":{"id":"w349","nodes":["n1861","n1818","n1819","n1820","n1821","n1825","n1823","n1639"],"tags":{"highway":"service"}},"w35":{"id":"w35","nodes":["n168","n167","n172"],"tags":{"barrier":"fence","fence_type":"chain_link"}},"w350":{"id":"w350","nodes":["n1783","n1819","n1784","n1857","n1861","n1858","n1783"],"tags":{"amenity":"parking"}},"w351":{"id":"w351","nodes":["n1717","n1718","n1719","n1720","n1717"],"tags":{"building":"yes"}},"w352":{"id":"w352","nodes":["n1743","n1744","n1745","n1746","n1747","n1748","n1749","n1750","n1743"],"tags":{"building":"yes"}},"w353":{"id":"w353","nodes":["n1637","n1636","n1029","n4715","n1630"],"tags":{"highway":"residential","name":"Lincoln Avenue"}},"w354":{"id":"w354","nodes":["n1713","n1714","n1715","n1716","n1713"],"tags":{"building":"yes"}},"w355":{"id":"w355","nodes":["n1689","n1690","n1691","n1692","n1693","n1694","n1695","n1696","n1689"],"tags":{"building":"yes"}},"w356":{"id":"w356","nodes":["n1631","n4717","n1840","n4745","n1841"],"tags":{"highway":"residential","name":"Hook Avenue"}},"w357":{"id":"w357","nodes":["n1737","n1738","n1739","n1740","n1741","n1742","n1737"],"tags":{"building":"yes"}},"w358":{"id":"w358","nodes":["n1707","n1708","n1709","n1710","n1711","n1712","n1707"],"tags":{"building":"yes"}},"w359":{"id":"w359","nodes":["n1829","n4695","n4697","n1843","n4698","n4701","n1638","n4702","n4705","n1636","n4706","n4707","n1633"],"tags":{"highway":"residential","name":"South Street"}},"w36":{"id":"w36","nodes":["n910","n171","n866","n172"],"tags":{"barrier":"fence","fence_type":"chain_link"}},"w360":{"id":"w360","nodes":["n1767","n1768","n1769","n1770","n1771","n1772","n1773","n1774","n1767"],"tags":{"building":"yes"}},"w361":{"id":"w361","nodes":["n1859","n1860","n1804","n1640","n1805","n1817","n1806","n1644","n1811","n1807","n1808","n3419","n1812","n1790","n3418","n3744","n1809","n1813","n1810"],"tags":{"highway":"service"}},"w362":{"id":"w362","nodes":["n1639","n1683","n4710","n1633"],"tags":{"highway":"residential","name":"South Street","oneway":"yes"}},"w363":{"id":"w363","nodes":["n1646","n1647","n1648","n1649","n1646"],"tags":{"leisure":"pitch","pitch":"basketball"}},"w364":{"id":"w364","nodes":["n3820","n3821","n3822","n3823","n3824","n3825","n3826","n3827","n3828","n3829","n3830","n3838","n3839","n3820"],"tags":{"amenity":"school","name":"Three Rivers Middle School"}},"w365":{"id":"w365","nodes":["n1721","n1722","n1723","n1724","n1725","n1726","n1727","n1728","n1729","n1730","n1731","n1732","n1733","n1734","n1735","n1736","n1721"],"tags":{"building":"yes"}},"w366":{"id":"w366","nodes":["n1791","n1792","n1793","n1794","n1795","n1796","n1798","n1799","n1800","n1801","n1802","n1803","n1791"],"tags":{"amenity":"parking"}},"w367":{"id":"w367","nodes":["n1633","n4708","n4711","n1643","n4712","n1838","n4752","n1839"],"tags":{"highway":"residential","name":"Grant Avenue"}},"w368":{"id":"w368","nodes":["n1853","n1687","n1688","n1854","n1853"],"tags":{"amenity":"library","building":"yes","name":"Three Rivers Public Library"}},"w369":{"id":"w369","nodes":["n1777","n1778","n1779","n1780","n1781","n1782","n1777"],"tags":{"amenity":"parking"}},"w37":{"id":"w37","nodes":["n173","n174","n175","n176","n177","n178","n179","n180","n173"],"tags":{"building":"yes"}},"w370":{"id":"w370","nodes":["n1645","n1638","n858","n4718","n1631"],"tags":{"highway":"residential","name":"Hook Avenue"}},"w371":{"id":"w371","nodes":["n3836","n3835","n4624","n3831","n4632","n3834","n3832","n3833","n3830","n3838","n3839","n3837","n3836"],"tags":{"amenity":"school","name":"Three Rivers High School"}},"w372":{"id":"w372","nodes":["n1697","n1698","n1699","n1700","n1697"],"tags":{"building":"yes"}},"w373":{"id":"w373","nodes":["n2891","n1785","n1786","n3394","n1787","n1788","n1789","n1830","n1836","n1837","n1848","n3409","n2891"],"tags":{"amenity":"parking"}},"w374":{"id":"w374","nodes":["n1761","n1762","n1763","n1764","n1765","n1766","n1761"],"tags":{"building":"yes"}},"w375":{"id":"w375","nodes":["n1822","n1823"],"tags":{"highway":"service","service":"parking_aisle"}},"w376":{"id":"w376","nodes":["n1677","n1678","n1679","n1680","n1681","n1682","n1677"],"tags":{"amenity":"parking"}},"w377":{"id":"w377","nodes":["n1676","n1675","n1674","n1673"],"tags":{"highway":"service","oneway":"yes"}},"w378":{"id":"w378","nodes":["n1667","n1668","n1669","n1670","n1671","n1672","n1667"],"tags":{"amenity":"school","name":"Andrews Elementary School"}},"w379":{"id":"w379","nodes":["n1630","n4714","n1847","n4750","n1844"],"tags":{"highway":"residential","name":"Lincoln Avenue"}},"w38":{"id":"w38","nodes":["n181","n182","n183","n185","n184","n181"],"tags":{"building":"yes"}},"w380":{"id":"w380","nodes":["n1683","n3745","n1686","n1633"],"tags":{"highway":"service","oneway":"yes","service":"parking_aisle"}},"w381":{"id":"w381","nodes":["n2022","n2037"],"tags":{"highway":"footway"}},"w382":{"id":"w382","nodes":["n1826","n1863"],"tags":{"highway":"residential"}},"w383":{"id":"w383","nodes":["n2011","n2012","n739","n2013","n2014","n2029","n2011"],"tags":{"amenity":"shelter","building":"yes","shelter_type":"picnic_shelter"}},"w384":{"id":"w384","nodes":["n2064","n2065","n2066","n2067","n2068","n2069","n2070","n2071","n2072","n2073","n2074","n2075","n2076","n2077","n2078","n2079","n2064"],"tags":{"building":"yes"}},"w385":{"id":"w385","nodes":["n1923","n1924","n1925","n1926","n1927","n1928","n1930","n1929","n1923"],"tags":{"natural":"water"}},"w386":{"id":"w386","nodes":["n1827","n14","n1886","n15","n1887","n16","n1888","n18","n17","n1889","n12","n13","n1890","n485","n1864","n11","n10","n2058","n2036","n1865","n2020","n9","n8","n1866","n295","n1867"],"tags":{"highway":"service"}},"w387":{"id":"w387","nodes":["n1846","n1843","n865","n157","n4721","n1831"],"tags":{"highway":"residential","name":"Andrews Street"}},"w388":{"id":"w388","nodes":["n2019","n2020","n2021","n2022","n2023","n2024","n2025","n2026","n2027","n2028","n2029"],"tags":{"highway":"footway"}},"w389":{"id":"w389","nodes":["n2217","n2222","n2221","n2219","n1877","n1879","n1882","n1883","n484","n1885","n483","n1880","n1881","n1878","n1884","n2223"],"tags":{"name":"Rocky River","waterway":"river"}},"w39":{"id":"w39","nodes":["n185","n186","n187"],"tags":{"barrier":"fence"}},"w390":{"id":"w390","nodes":["n2050","n2051","n2052","n2053","n2050"],"tags":{"amenity":"shelter","shelter_type":"picnic_shelter"}},"w391":{"id":"w391","nodes":["n2089","n2090","n2091","n2092","n2093","n2094","n2311","n2095","n2096","n2097","n2098","n1174","n2099","n751","n43","n2062","n4725","n873","n1832"],"tags":{"highway":"residential","name":"Constantine Street"}},"w392":{"id":"w392","nodes":["n1869","n212","n436","n2281","n2081"],"tags":{"highway":"primary","name":"Michigan Avenue"}},"w393":{"id":"w393","nodes":["n1829","n611","n144","n4694","n602","n1832"],"tags":{"highway":"tertiary","name":"Constantine Street"}},"w394":{"id":"w394","nodes":["n1997","n1998","n2000","n1999"],"tags":{"highway":"service","service":"parking_aisle"}},"w395":{"id":"w395","nodes":["n1835","n1869"],"tags":{"bridge":"yes","highway":"primary","name":"Michigan Avenue"}},"w396":{"id":"w396","nodes":["n2000","n2001"],"tags":{"highway":"service","service":"parking_aisle"}},"w397":{"id":"w397","nodes":["n2082","n4688","n1842","n308","n498","n509","n246","n241","n1867","n4645","n293","n1834"],"tags":{"highway":"residential","name":"Spring Street"}},"w398":{"id":"w398","nodes":["n2015","n2016","n2017","n2018","n2015"],"tags":{"building":"yes"}},"w399":{"id":"w399","nodes":["n2062","n45","n2063","n877","n41","n1852"],"tags":{"highway":"service"}},"w4":{"id":"w4","nodes":["n7","n38","n378","n379","n7"],"tags":{"building":"yes"}},"w40":{"id":"w40","nodes":["n188","n189","n190","n191","n192","n193","n188"],"tags":{"building":"house"}},"w400":{"id":"w400","nodes":["n1968","n1969","n1970","n1971","n2007","n1972","n1973","n1978","n1974","n1977","n1976","n1975","n1968"],"tags":{"amenity":"parking"}},"w401":{"id":"w401","nodes":["n1963","n1964"],"tags":{"bridge":"yes","highway":"footway"}},"w402":{"id":"w402","nodes":["n1892","n1893","n1894","n1895","n1896","n1897","n1898","n1899","n1900","n1901","n1902","n1903","n1892"],"tags":{"addr:city":"Three Rivers","addr:housenumber":"112","addr:postcode":"49093","addr:state":"MI","addr:street":"Spring Street","barrier":"fence","name":"Scidmore Park Petting Zoo","tourism":"zoo","zoo":"petting_zoo"}},"w403":{"id":"w403","nodes":["n1957","n1958","n1959","n481","n1960","n482","n1949"],"tags":{"highway":"path"}},"w404":{"id":"w404","nodes":["n2281","n27","n330","n1987","n1988"],"tags":{"highway":"service"}},"w405":{"id":"w405","nodes":["n2249","n2269","n2270","n2271","n2272","n454","n455","n2273"],"tags":{"highway":"path","name":"Riverwalk Trail"}},"w406":{"id":"w406","nodes":["n1947","n1624","n1625","n2030","n2033","n4658","n4659","n2031","n2032","n2021"],"tags":{"highway":"footway"}},"w407":{"id":"w407","nodes":["n2034","n2036","n2009"],"tags":{"highway":"footway"}},"w408":{"id":"w408","nodes":["n1964","n1965","n2002","n1966","n21","n1967","n1969"],"tags":{"highway":"footway"}},"w409":{"id":"w409","nodes":["n1904","n1905","n1906","n1907","n1908","n1909","n748","n1910","n747","n1911","n749","n1912","n750","n1913","n1922","n1914","n1921","n1915","n746","n1916","n745","n1917","n744","n1918","n743","n742","n1919","n741","n1920","n740","n1904"],"tags":{"natural":"water"}},"w41":{"id":"w41","nodes":["n194","n195","n196","n197","n198","n199","n200","n201","n202","n203","n204","n205","n194"],"tags":{"building":"house"}},"w410":{"id":"w410","nodes":["n1868","n2088"],"tags":{"bridge":"yes","name":"Conrail Railroad","railway":"rail"}},"w411":{"id":"w411","nodes":["n2010","n2019","n2009","n2008","n2058","n2035","n1961","n1962","n1947","n1963"],"tags":{"highway":"footway"}},"w412":{"id":"w412","nodes":["n2290","n2043","n2044","n2045","n1872","n2041","n1873","n2042","n1874","n2046","n2047","n2048","n2049","n2290"],"tags":{"addr:city":"Three Rivers","addr:housenumber":"112","addr:postcode":"49093","addr:state":"MI","addr:street":"Spring Street","leisure":"park","name":"Scidmore Park"}},"w413":{"id":"w413","nodes":["n1831","n876","n4720","n821","n2089"],"tags":{"highway":"residential","name":"Andrews Street"}},"w414":{"id":"w414","nodes":["n2002","n2003","n2004","n2005","n2006","n2007"],"tags":{"highway":"footway"}},"w415":{"id":"w415","nodes":["n1979","n1980","n1981","n1982","n1979"],"tags":{"amenity":"parking"}},"w416":{"id":"w416","nodes":["n2054","n2055","n2056","n2057","n2054"],"tags":{"amenity":"shelter","shelter_type":"picnic_shelter"}},"w417":{"id":"w417","nodes":["n2291","n2292","n2293","n2294","n2295","n2296","n2297","n2298","n2299","n1098","n2300","n2301","n2302","n2303","n2304","n2059","n2060","n2305","n2307","n2306","n2310","n2308","n2309","n2291"],"tags":{"leisure":"park","name":"Memory Isle Park"}},"w418":{"id":"w418","nodes":["n2033","n2034","n2035"],"tags":{"highway":"footway"}},"w419":{"id":"w419","nodes":["n1983","n1984","n1985","n1986","n1983"],"tags":{"amenity":"parking"}},"w42":{"id":"w42","nodes":["n206","n207","n208","n209","n210","n211","n206"],"tags":{"building":"house"}},"w420":{"id":"w420","nodes":["n1840","n4746","n4748","n1847","n4749","n4755","n1838","n4754","n4756","n1849"],"tags":{"highway":"residential","name":"French Street"}},"w421":{"id":"w421","nodes":["n2337","n2268"],"tags":{"highway":"path"}},"w422":{"id":"w422","nodes":["n2338","n2339","n2320","n2317","n2319","n2318","n2340","n2341","n2342","n2343","n2344","n2345","n2346","n2347","n2348","n2338"],"tags":{"natural":"water"}},"w423":{"id":"w423","nodes":["n2180","n2349","n2350","n2351","n2352","n2404","n2353","n2354","n2355","n2356","n2357","n2358","n2359","n2360","n2361","n2362","n2363","n2364","n2365","n2366","n2370","n2371","n2372","n2373","n2374","n2375","n2377","n2378","n2380","n2381","n2382","n2383","n2386","n2389","n2390","n2391","n2392","n2393","n2396","n2397","n2401","n2402","n2321","n2322","n2323","n2403","n2180"],"tags":{"natural":"wetland"}},"w424":{"id":"w424","nodes":["n2324","n2316","n1841","n2315","n2314","n1844","n1839","n4758","n1845"],"tags":{"highway":"residential","name":"Pealer Street"}},"w425":{"id":"w425","nodes":["n2267","n2337","n2336","n2335","n2334","n2333","n2332","n2331","n2330","n37","n2329","n2328","n2327","n36","n2326","n2325","n2266"],"tags":{"highway":"path","name":"Riverwalk Trail"}},"w426":{"id":"w426","nodes":["n2478","n681","n680","n679","n2459","n2467","n2487","n2478"],"tags":{"building":"yes"}},"w427":{"id":"w427","nodes":["n2671","n2672","n2673","n2674","n2671"],"tags":{"building":"yes"}},"w428":{"id":"w428","nodes":["n2483","n2482","n2486","n2489","n2492","n2502","n2495","n2480","n2483"],"tags":{"building":"yes"}},"w429":{"id":"w429","nodes":["n2707","n2708","n2716","n2712","n2714","n2713","n2715","n2711","n2710","n2723","n2709","n2707"],"tags":{"amenity":"parking"}},"w43":{"id":"w43","nodes":["n1955","n1956"],"tags":{"footway":"sidewalk","highway":"footway","name":"Riverwalk Trail"}},"w430":{"id":"w430","nodes":["n2471","n2474","n2484","n2479","n2471"],"tags":{"building":"yes"}},"w431":{"id":"w431","nodes":["n2218","n2434","n2436","n2433","n2435","n2210"],"tags":{"name":"Rocky River","waterway":"river"}},"w432":{"id":"w432","nodes":["n2782","n2532","n2783","n2784","n2782"],"tags":{"amenity":"parking"}},"w433":{"id":"w433","nodes":["n2513","n649","n2520","n2514","n2507","n2513"],"tags":{"building":"yes"}},"w434":{"id":"w434","nodes":["n2470","n2468","n2461","n2465","n2470"],"tags":{"building":"yes"}},"w435":{"id":"w435","nodes":["n2598","n2599","n648","n649","n2520","n2598"],"tags":{"building":"yes"}},"w436":{"id":"w436","nodes":["n2639","n2640","n2641","n2642","n2643","n2644","n2645","n2646","n2647","n2648","n2639"],"tags":{"building":"yes"}},"w437":{"id":"w437","nodes":["n2503","n2512","n2508","n2499","n2503"],"tags":{"building":"yes"}},"w438":{"id":"w438","nodes":["n2440","n2800","n2774","n1"],"tags":{"highway":"residential","name":"Water Street"}},"w439":{"id":"w439","nodes":["n2675","n2676","n2677","n2678","n2675"],"tags":{"building":"yes"}},"w44":{"id":"w44","nodes":["n213","n214","n215","n216","n213"],"tags":{"building":"yes"}},"w440":{"id":"w440","nodes":["n2512","n2503","n2507","n2514","n2512"],"tags":{"building":"yes"}},"w441":{"id":"w441","nodes":["n2554","n2717","n674","n2720","n2798"],"tags":{"highway":"service","oneway":"yes"}},"w442":{"id":"w442","nodes":["n2583","n2596","n2584","n2585","n2595","n2586","n2587","n2588","n2589","n2583"],"tags":{"amenity":"parking"}},"w443":{"id":"w443","nodes":["n2629","n2627","n2628","n2616","n2630","n2629"],"tags":{"building":"yes"}},"w444":{"id":"w444","nodes":["n2717","n2724","n670","n2718","n669","n668","n2722","n2727"],"tags":{"highway":"service","oneway":"yes","service":"parking_aisle"}},"w445":{"id":"w445","nodes":["n2572","n2573"],"tags":{"bridge":"yes","highway":"path","name":"Riverwalk Trail"}},"w446":{"id":"w446","nodes":["n2603","n2604","n2601","n2605","n2606","n2607","n2603"],"tags":{"building":"yes"}},"w447":{"id":"w447","nodes":["n2780","n2777","n628","n624","n2779"],"tags":{"highway":"residential","name":"Foster Street","oneway":"yes"}},"w448":{"id":"w448","nodes":["n2733","n2734","n2735","n2736","n2737","n2738","n663","n664","n2739","n2733"],"tags":{"building":"yes"}},"w449":{"id":"w449","nodes":["n2564","n2565","n2566","n2567","n2568","n2794","n2795","n2564"],"tags":{"amenity":"parking"}},"w45":{"id":"w45","nodes":["n217","n218","n219","n220","n217"],"tags":{"amenity":"shelter","shelter_type":"picnic_shelter"}},"w450":{"id":"w450","nodes":["n2799","n2728","n2729","n2730","n2731","n2732","n2799"],"tags":{"building":"yes"}},"w451":{"id":"w451","nodes":["n2441","n1170","n2442","n2575","n2443","n2445","n2444","n2448","n2441"],"tags":{"amenity":"parking"}},"w452":{"id":"w452","nodes":["n2273","n457","n2569","n458","n2570"],"tags":{"highway":"path","name":"Riverwalk Trail"}},"w453":{"id":"w453","nodes":["n2447","n2242","n2448","n2527","n2530"],"tags":{"highway":"service"}},"w454":{"id":"w454","nodes":["n2560","n333","n2561"],"tags":{"highway":"service","service":"parking_aisle"}},"w455":{"id":"w455","nodes":["n2679","n2680","n2681","n2682","n2683","n2684","n2685","n2686","n2687","n2688","n2689","n2690","n2679"],"tags":{"building":"yes"}},"w456":{"id":"w456","nodes":["n2425","n2429","n2424"],"tags":{"bridge":"yes","highway":"residential","name":"Moore Street"}},"w457":{"id":"w457","nodes":["n2487","n2467","n2472","n2480","n2495","n2487"],"tags":{"building":"yes"}},"w458":{"id":"w458","nodes":["n2659","n2660","n2661","n2662","n678","n677","n2663","n2664","n2665","n2666","n675","n676","n2659"],"tags":{"building":"yes"}},"w459":{"id":"w459","nodes":["n2600","n2598","n2599","n2601","n2605","n2602","n2600"],"tags":{"building":"yes"}},"w46":{"id":"w46","nodes":["n221","n222","n223","n224","n221"],"tags":{"amenity":"shelter","shelter_type":"picnic_shelter"}},"w460":{"id":"w460","nodes":["n2468","n2464","n2455","n2457","n2461","n2468"],"tags":{"building":"yes"}},"w461":{"id":"w461","nodes":["n2478","n2473","n683","n682","n2463","n681","n2478"],"tags":{"building":"yes"}},"w462":{"id":"w462","nodes":["n2547","n473","n2548","n2549"],"tags":{"highway":"service","service":"parking_aisle"}},"w463":{"id":"w463","nodes":["n2573","n2574"],"tags":{"highway":"path","name":"Riverwalk Trail"}},"w464":{"id":"w464","nodes":["n2445","n2597","n2527","n2528","n2529","n2530","n2531","n2597"],"tags":{"highway":"service","service":"parking_aisle"}},"w465":{"id":"w465","nodes":["n2571","n459","n2572"],"tags":{"highway":"path","name":"Riverwalk Trail"}},"w466":{"id":"w466","nodes":["n2445","n2574","n2552","n442","n2551","n4727","n323","n2446"],"tags":{"highway":"service"}},"w467":{"id":"w467","nodes":["n2484","n2474","n2477","n2485","n2488","n2484"],"tags":{"building":"yes"}},"w468":{"id":"w468","nodes":["n2695","n2696","n2697","n2698","n2699","n2700","n2701","n2702","n2695"],"tags":{"building":"yes"}},"w469":{"id":"w469","nodes":["n2469","n2476","n2481","n2475","n920","n2466","n2469"],"tags":{"building":"yes"}},"w47":{"id":"w47","nodes":["n1988","n1997","n1989","n25","n24","n1990","n26","n1991","n21","n1992","n2006","n1993","n22","n1994","n23","n1995","n1999","n1996","n2001","n1988"],"tags":{"highway":"service"}},"w470":{"id":"w470","nodes":["n2473","n2470","n2465","n2458","n2462","n683","n2473"],"tags":{"building":"yes"}},"w471":{"id":"w471","nodes":["n2490","n2496","n994","n997","n998","n996","n995","n2485","n2477","n2490"],"tags":{"building":"yes"}},"w472":{"id":"w472","nodes":["n2424","n2426","n2427","n2428"],"tags":{"highway":"residential","name":"Moore Street"}},"w473":{"id":"w473","nodes":["n2432","n1026","n4741","n2554","n2425"],"tags":{"highway":"residential","name":"Moore Street"}},"w474":{"id":"w474","nodes":["n2577","n2576"],"tags":{"bridge":"yes","highway":"footway"}},"w475":{"id":"w475","nodes":["n2497","n2505","n2500","n2493","n2497"],"tags":{"building":"yes"}},"w476":{"id":"w476","nodes":["n2493","n2500","n2501","n2496","n2490","n2493"],"tags":{"building":"yes"}},"w477":{"id":"w477","nodes":["n2431","n360","n4726","n418","n397","n396","n2547","n646","n2447","n644","n2418","n424","n640","n2419","n2420","n2423"],"tags":{"highway":"residential","name":"Railroad Drive"}},"w478":{"id":"w478","nodes":["n2515","n2511","n2498","n2504","n2509","n2515"],"tags":{"building":"yes"}},"w479":{"id":"w479","nodes":["n2525","n651","n650","n2526","n2524","n653","n652","n656","n2523","n654","n2518","n2517","n2521","n2522","n2525"],"tags":{"building":"yes"}},"w48":{"id":"w48","nodes":["n225","n237","n226","n227","n228","n229","n230","n231","n232","n233","n234","n235","n236","n225"],"tags":{"building":"yes"}},"w480":{"id":"w480","nodes":["n2703","n2704","n2710","n2711","n2705","n2706","n2703"],"tags":{"amenity":"parking"}},"w481":{"id":"w481","nodes":["n2796","n2657","n2658","n2797","n2796"],"tags":{"building":"yes"}},"w482":{"id":"w482","nodes":["n2550","n2551","n442","n2552","n2553","n2550"],"tags":{"amenity":"parking"}},"w483":{"id":"w483","nodes":["n2790","n2542"],"tags":{"highway":"service","service":"parking_aisle"}},"w484":{"id":"w484","nodes":["n2311","n1102"],"tags":{"highway":"service"}},"w485":{"id":"w485","nodes":["n2515","n2509","n2516","n2519","n2515"],"tags":{"building":"yes"}},"w486":{"id":"w486","nodes":["n2506","n2502","n2492","n2491","n2494","n2506"],"tags":{"building":"yes"}},"w487":{"id":"w487","nodes":["n2667","n2668","n2669","n2670","n2667"],"tags":{"building":"yes"}},"w488":{"id":"w488","nodes":["n2616","n2608","n2617","n2618","n2619","n2620","n2621","n2622","n2623","n2624","n2625","n2626","n2627","n2628","n2616"],"tags":{"building":"yes"}},"w489":{"id":"w489","nodes":["n2081","n2430"],"tags":{"bridge":"yes","highway":"primary","name":"Michigan Avenue"}},"w49":{"id":"w49","nodes":["n237","n238"],"tags":{"highway":"footway"}},"w490":{"id":"w490","nodes":["n2410","n636","n730","n635","n2409","n2694","n2751","n2765","n2753","n2768","n2754","n2769","n2745","n2766","n4503","n2763","n4501","n2752","n2781"],"tags":{"highway":"residential","name":"Portage Avenue"}},"w491":{"id":"w491","nodes":["n2578","n2579","n2580","n2581","n2578"],"tags":{"amenity":"shelter","building":"yes","shelter_type":"picnic_shelter"}},"w492":{"id":"w492","nodes":["n2556","n2557","n2558","n2559","n2556"],"tags":{"amenity":"parking"}},"w493":{"id":"w493","nodes":["n2460","n2456","n687","n2453","n2454","n2460"],"tags":{"building":"yes"}},"w494":{"id":"w494","nodes":["n2471","n2479","n2476","n2469","n2471"],"tags":{"building":"yes"}},"w495":{"id":"w495","nodes":["n2724","n2725","n673","n672","n671","n2726","n2727"],"tags":{"highway":"service","oneway":"yes","service":"parking_aisle"}},"w496":{"id":"w496","nodes":["n2649","n2650","n2651","n2652","n2653","n2654","n2655","n2656","n2649"],"tags":{"building":"yes"}},"w497":{"id":"w497","nodes":["n2430","n2446","n343","n2101","n2560","n2431","n363","n2748"],"tags":{"highway":"primary","name":"Michigan Avenue"}},"w498":{"id":"w498","nodes":["n2691","n2692","n634","n633","n2693","n2694"],"tags":{"highway":"service"}},"w499":{"id":"w499","nodes":["n2423","n2415","n661","n2416","n2417","n2719","n2721","n2772","n2756","n2773","n2759","n2767"],"tags":{"highway":"residential","name":"West Street"}},"w5":{"id":"w5","nodes":["n380","n381","n382","n383","n429","n430","n380"],"tags":{"building":"yes"}},"w50":{"id":"w50","nodes":["n239","n499","n508","n245","n238","n242","n240"],"tags":{"footway":"sidewalk","highway":"footway"}},"w500":{"id":"w500","nodes":["n2428","n1152","n2421","n2324"],"tags":{"bridge":"yes","highway":"residential","name":"Moore Street"}},"w501":{"id":"w501","nodes":["n2608","n2609","n2610","n2611","n2612","n2613","n2614","n2615","n2617","n2608"],"tags":{"building":"yes"}},"w502":{"id":"w502","nodes":["n2570","n2571"],"tags":{"bridge":"yes","highway":"path","name":"Riverwalk Trail"}},"w503":{"id":"w503","nodes":["n2540","n2542","n2787"],"tags":{"highway":"service"}},"w504":{"id":"w504","nodes":["n2269","n2582","n2250"],"tags":{"highway":"path"}},"w505":{"id":"w505","nodes":["n2631","n2632","n2633","n2634","n2635","n2636","n2637","n2638","n2631"],"tags":{"building":"yes"}},"w506":{"id":"w506","nodes":["n2543","n2544","n2545","n395","n2546","n2543"],"tags":{"amenity":"parking"}},"w507":{"id":"w507","nodes":["n2449","n2450","n2451","n2452","n1162","n2449"],"tags":{"leisure":"pitch","sport":"tennis"}},"w508":{"id":"w508","nodes":["n2554","n1160","n2559","n2558","n659","n2555","n658","n657","n2419"],"tags":{"highway":"service"}},"w509":{"id":"w509","nodes":["n2499","n2508","n2510","n2505","n2497","n2499"],"tags":{"building":"yes"}},"w51":{"id":"w51","nodes":["n241","n242","n243","n244"],"tags":{"highway":"service","surface":"unpaved"}},"w510":{"id":"w510","nodes":["n2575","n2577"],"tags":{"highway":"footway"}},"w511":{"id":"w511","nodes":["n2533","n2534","n2535","n2536","n2537","n2538","n2539","n2785","n2786","n2533"],"tags":{"amenity":"parking"}},"w512":{"id":"w512","nodes":["n2801","n2740","n2741","n2742","n2743","n2744","n2801"],"tags":{"building":"yes"}},"w513":{"id":"w513","nodes":["n2720","n2721"],"tags":{"highway":"service","service":"parking_aisle"}},"w514":{"id":"w514","nodes":["n2788","n2790","n2789","n989","n2540","n2541"],"tags":{"highway":"service","service":"parking_aisle"}},"w515":{"id":"w515","nodes":["n2848","n2849","n2850","n2851","n2803","n2804","n2812"],"tags":{"highway":"residential","name":"Middle Street"}},"w516":{"id":"w516","nodes":["n2852","n2805"],"tags":{"access":"private","highway":"service","name":"Battle Street"}},"w517":{"id":"w517","nodes":["n2863","n2815","n2814","n2812","n2864","n2855","n2865","n2867","n2868"],"tags":{"highway":"secondary","name":"Michigan Avenue","name_1":"State Highway 60","ref":"M 60"}},"w518":{"id":"w518","nodes":["n2859","n2808"],"tags":{"highway":"residential","name":"2nd Avenue"}},"w519":{"id":"w519","nodes":["n2823","n2824","n2825","n2826","n2827","n2828","n2823"],"tags":{"building":"yes"}},"w52":{"id":"w52","nodes":["n247","n248","n249","n250","n247"],"tags":{"amenity":"parking"}},"w520":{"id":"w520","nodes":["n2806","n2807","n2803"],"tags":{"highway":"residential","name":"2nd Avenue"}},"w521":{"id":"w521","nodes":["n2829","n2830","n2831","n2832","n2833","n2834","n2835","n2836","n2837","n2838","n2829"],"tags":{"building":"yes"}},"w522":{"id":"w522","nodes":["n2815","n2813","n2811","n4597","n2846","n4596","n2857","n4601","n2853","n4602","n2861","n4","n2879","n4560","n3550","n5","n1685"],"tags":{"highway":"residential","name":"Washington Street"}},"w523":{"id":"w523","nodes":["n2878","n2811","n2810","n2860","n2880","n2881","n2882"],"tags":{"highway":"residential","name":"5th Avenue"}},"w524":{"id":"w524","nodes":["n2816","n2817","n2818","n2819","n2820","n2821","n2822","n2816"],"tags":{"building":"yes"}},"w525":{"id":"w525","nodes":["n2869","n2856","n2806","n2808","n2814","n2809","n2810","n2847","n2858","n2854","n2870","n2871","n6","n2872","n2839","n2862"],"tags":{"highway":"residential","name":"Wood Street"}},"w526":{"id":"w526","nodes":["n2877","n2809","n2813","n2844","n2843"],"tags":{"highway":"residential","name":"4th Avenue"}},"w527":{"id":"w527","nodes":["n4785","n4784","n2936","n4788","n4787","n4786","n4785"],"tags":{"amenity":"parking"}},"w528":{"id":"w528","nodes":["n2864","n2892","n2893","n2877","n2860","n3840"],"tags":{"highway":"residential","name":"Garden Street"}},"w529":{"id":"w529","nodes":["n2868","n2890"],"tags":{"bridge":"yes","highway":"secondary","name":"Michigan Avenue","name_1":"State Highway 60","ref":"M 60"}},"w53":{"id":"w53","nodes":["n251","n252","n253","n254","n255","n256","n257","n258","n259","n260","n261","n262","n251"],"tags":{"building":"yes"}},"w530":{"id":"w530","nodes":["n2914","n2915","n2916","n2917","n2918","n2919","n2920","n2921","n2922","n2923","n2924","n2925","n2926","n2927","n2928","n2929","n2930","n2931","n2932","n2933","n2914"],"tags":{"building":"yes"}},"w531":{"id":"w531","nodes":["n2958","n2896"],"tags":{"bridge":"yes","highway":"secondary","name":"Main Street"}},"w532":{"id":"w532","nodes":["n2896","n394","n364","n2748"],"tags":{"highway":"secondary","name":"Main Street"}},"w533":{"id":"w533","nodes":["n2800","n2943","n2940","n2941","n2942","n2943"],"tags":{"highway":"service","service":"parking_aisle"}},"w534":{"id":"w534","nodes":["n3836","n3837","n3839","n3838","n3834","n4632","n3831","n4624","n3835","n3836"],"tags":{"barrier":"fence"}},"w535":{"id":"w535","nodes":["n2894","n2944","n2774","n2765"],"tags":{"highway":"residential","name":"5th Avenue"}},"w536":{"id":"w536","nodes":["n2890","n2780","n627","n2889","n2887","n623","n2888","n366","n2748"],"tags":{"highway":"secondary","name":"Michigan Avenue","name_1":"State Highway 60","ref":"M 60"}},"w537":{"id":"w537","nodes":["n2895","n738","n2887","n737","n2913"],"tags":{"highway":"residential","name":"Water Street"}},"w538":{"id":"w538","nodes":["n2855","n3756","n2884","n2885","n2886","n2945","n2946","n2947","n2948","n2949","n2950","n2951","n2952","n2953","n2955","n2848","n2956","n2856"],"tags":{"highway":"residential","name":"River Drive"}},"w539":{"id":"w539","nodes":["n2882","n2894"],"tags":{"bridge":"yes","highway":"residential","name":"5th Avenue"}},"w54":{"id":"w54","nodes":["n263","n264","n265","n266","n267","n268","n269","n270","n271","n272","n273","n274","n275","n276","n263"],"tags":{"building":"yes"}},"w540":{"id":"w540","nodes":["n2987","n2964","n2981","n2983","n2966","n2982","n2962","n2960","n2967","n2965","n2984","n2977","n2968","n2976","n2986","n2988","n2963","n2970","n2969","n2979","n2974","n2980","n2959","n2973","n2985","n2961","n2975","n2971","n2972","n2978","n2898","n2907","n2912","n2909","n2911","n2901","n2903","n2904","n2906","n2902","n2900","n2910","n2908","n2899","n2897","n2905","n2186","n2233"],"tags":{"name":"Portage River","waterway":"river"}},"w541":{"id":"w541","nodes":["n2852","n2851","n3003"],"tags":{"highway":"residential","name":"1st Avenue"}},"w542":{"id":"w542","nodes":["n2991","n3004","n2994"],"tags":{"highway":"residential","name":"River Street"}},"w543":{"id":"w543","nodes":["n2993","n2989"],"tags":{"bridge":"yes","highway":"residential","name":"6th Street"}},"w544":{"id":"w544","nodes":["n2995","n2996","n2997","n2998","n2999","n3000","n3001","n3002","n2990","n2991","n2993"],"tags":{"highway":"residential","name":"6th Street"}},"w545":{"id":"w545","nodes":["n2989","n2992","n2848"],"tags":{"highway":"residential","name":"6th Street"}},"w546":{"id":"w546","nodes":["n2313","n3169","n3170","n3171","n3172","n3173","n3174","n3175","n3176","n3177","n3178","n3179","n3180","n3191","n3181","n3190","n3182","n3183","n3184","n3185","n3186","n3187","n3188","n3189","n3160","n3161","n3162","n2126","n2146","n2156","n2129","n2112","n2109","n2313"],"tags":{"natural":"wetland"}},"w547":{"id":"w547","nodes":["n2088","n3013","n3015","n3014","n3017","n3018"],"tags":{"name":"Conrail Railroad","railway":"rail"}},"w548":{"id":"w548","nodes":["n3083","n3084","n3085","n3086","n3083"],"tags":{"building":"yes"}},"w549":{"id":"w549","nodes":["n3020","n2288","n2283","n2284","n2131","n2286","n2287","n2285","n2132","n2140","n2289","n3020"],"tags":{"leisure":"park","name":"Conservation Park"}},"w55":{"id":"w55","nodes":["n277","n278","n279","n280","n281","n282","n283","n284","n277"],"tags":{"building":"yes"}},"w550":{"id":"w550","nodes":["n3056","n3042","n3041","n3040","n3039","n3038","n3037","n3036","n3044","n3035","n3034","n3043","n3016","n3056","n3019","n3015","n3012"],"tags":{"highway":"service"}},"w551":{"id":"w551","nodes":["n3044","n3045","n3046","n3047","n3048","n3049","n3050","n3051","n3052","n3053","n3054","n3055","n3016"],"tags":{"highway":"footway"}},"w552":{"id":"w552","nodes":["n3117","n3118","n3119","n3120","n3121","n3122","n3117"],"tags":{"building":"yes"}},"w553":{"id":"w553","nodes":["n3123","n3124","n3129","n3125","n3126","n3123"],"tags":{"building":"yes"}},"w554":{"id":"w554","nodes":["n3069","n3070","n3071","n3072","n3073","n3074","n3075","n3076","n3077","n3078","n3079","n3080","n3081","n3082","n3069"],"tags":{"building":"yes"}},"w555":{"id":"w555","nodes":["n3087","n3088","n3089","n3090","n3087"],"tags":{"building":"yes"}},"w556":{"id":"w556","nodes":["n3113","n3114","n3115","n3116","n3113"],"tags":{"building":"yes"}},"w557":{"id":"w557","nodes":["n3103","n3104","n3105","n3106","n3103"],"tags":{"building":"yes"}},"w558":{"id":"w558","nodes":["n3127","n3128","n3129","n3124","n3127"],"tags":{"building":"yes"}},"w559":{"id":"w559","nodes":["n3137","n3141","n3142","n3138","n3139","n3140","n3137"],"tags":{"building":"yes"}},"w56":{"id":"w56","nodes":["n285","n286","n287","n288","n285"],"tags":{"amenity":"parking"}},"w560":{"id":"w560","nodes":["n3091","n3092","n3093","n3094","n3091"],"tags":{"building":"yes"}},"w561":{"id":"w561","nodes":["n3155","n3157","n3158","n3159","n3156","n3155"],"tags":{"building":"yes"}},"w562":{"id":"w562","nodes":["n3057","n3058","n3059","n3060","n3057"],"tags":{"building":"yes"}},"w563":{"id":"w563","nodes":["n3107","n3108","n3109","n3110","n3111","n3112","n3107"],"tags":{"building":"yes"}},"w564":{"id":"w564","nodes":["n3134","n3135","n3136","n3131","n3134"],"tags":{"building":"yes"}},"w565":{"id":"w565","nodes":["n3143","n3144","n3145","n3146","n3143"],"tags":{"building":"yes"}},"w566":{"id":"w566","nodes":["n3095","n3096","n3097","n3098","n3095"],"tags":{"building":"yes"}},"w567":{"id":"w567","nodes":["n3130","n3131","n3136","n3132","n3133","n3130"],"tags":{"building":"yes"}},"w568":{"id":"w568","nodes":["n3025","n3026","n3027","n3028","n3029","n3030","n3031","n3033","n3032","n3025"],"tags":{"amenity":"parking"}},"w569":{"id":"w569","nodes":["n3061","n3062","n3063","n3064","n3061"],"tags":{"building":"yes"}},"w57":{"id":"w57","nodes":["n289","n290","n291","n292","n289"],"tags":{"amenity":"parking"}},"w570":{"id":"w570","nodes":["n3155","n3156","n3152","n3153","n3155"],"tags":{"building":"yes"}},"w571":{"id":"w571","nodes":["n3099","n3100","n3101","n3102","n3099"],"tags":{"building":"yes"}},"w572":{"id":"w572","nodes":["n3147","n3148","n3149","n3150","n3147"],"tags":{"building":"yes"}},"w573":{"id":"w573","nodes":["n3039","n2284"],"tags":{"highway":"service"}},"w574":{"id":"w574","nodes":["n3151","n3152","n3153","n3154","n3151"],"tags":{"building":"yes"}},"w575":{"id":"w575","nodes":["n3021","n3022","n3023","n3024","n3021"],"tags":{"amenity":"shelter","shelter_type":"picnic_shelter"}},"w576":{"id":"w576","nodes":["n3065","n3066","n3067","n3068","n3065"],"tags":{"building":"yes"}},"w577":{"id":"w577","nodes":["n2944","n3192","n3757","n3813","n3814","n3815","n3816","n3817","n3818","n3819"],"tags":{"highway":"service","name":"Willow Drive","service":"driveway","surface":"unpaved"}},"w578":{"id":"w578","nodes":["n2163","n2165","n2166","n2167","n2168","n2172","n2173","n2174","n2175","n2176","n2178","n2181","n2163"],"tags":{"building":"yes"}},"w579":{"id":"w579","nodes":["n2754","n3195","n3204","n3205","n4537","n4540","n3206","n4530","n4536","n3207","n4524","n3199","n4521","n3197","n1032"],"tags":{"highway":"residential","name":"Elm Street"}},"w58":{"id":"w58","nodes":["n240","n293","n294"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w580":{"id":"w580","nodes":["n2184","n2185","n2187","n2190","n2191","n2192","n2184"],"tags":{"building":"yes"}},"w581":{"id":"w581","nodes":["n2765","n3208","n3211","n2755","n3280","n2756","n3346"],"tags":{"highway":"residential","name":"Kelsey Street"}},"w582":{"id":"w582","nodes":["n2753","n3194","n3193","n3201","n3196","n4551","n3202","n4550","n3203","n3200","n3198","n1033"],"tags":{"highway":"residential","name":"Walnut Street"}},"w583":{"id":"w583","nodes":["n3272","n4469","n4588","n2879","n4564","n2872"],"tags":{"highway":"residential","name":"10th Avenue"}},"w584":{"id":"w584","nodes":["n3243","n3242","n3241","n3240","n3243"],"tags":{"building":"industrial"}},"w585":{"id":"w585","nodes":["n3273","n3274","n4631","n4593","n3275","n4592","n2846","n4611","n2847"],"tags":{"highway":"residential","name":"6th Avenue"}},"w586":{"id":"w586","nodes":["n3276","n4591","n2853","n4605","n2854"],"tags":{"highway":"residential","name":"8th Avenue"}},"w587":{"id":"w587","nodes":["n3269","n3268","n3267","n3266","n3265","n3264","n3263","n3262","n3269"],"tags":{"building":"industrial"}},"w588":{"id":"w588","nodes":["n3277","n4599","n2857","n4598","n4608","n2858"],"tags":{"highway":"residential","name":"7th Avenue"}},"w589":{"id":"w589","nodes":["n3239","n3238","n3271","n3270","n3237","n3236","n3235","n3234","n3239"],"tags":{"building":"yes"}},"w59":{"id":"w59","nodes":["n294","n295","n296","n297","n298","n299","n300","n301","n302","n303","n491","n304","n305","n306","n307"],"tags":{"footway":"sidewalk","highway":"footway"}},"w590":{"id":"w590","nodes":["n3278","n4458","n4589","n4604","n2861"],"tags":{"highway":"residential","name":"9th Avenue"}},"w591":{"id":"w591","nodes":["n3253","n3252","n3251","n3250","n3249","n3248","n3253"],"tags":{"building":"industrial"}},"w592":{"id":"w592","nodes":["n3229","n3228","n3227","n3226","n3225","n3224","n3223","n3222","n3221","n3220","n3219","n3218","n3217","n3216","n3215","n3214","n3213","n3212","n3229"],"tags":{"natural":"water","water":"pond"}},"w593":{"id":"w593","nodes":["n3261","n3260","n3259","n3258","n3257","n3256","n3255","n3254","n3261"],"tags":{"building":"industrial"}},"w594":{"id":"w594","nodes":["n3233","n3232","n3231","n3230","n3233"],"tags":{"building":"yes"}},"w595":{"id":"w595","nodes":["n3247","n3246","n3245","n3244","n3247"],"tags":{"building":"industrial"}},"w596":{"id":"w596","nodes":["n2769","n3195","n3193","n3209","n2758","n2759","n3279"],"tags":{"highway":"residential","name":"Armitage Street"}},"w597":{"id":"w597","nodes":["n2193","n2194","n2195","n2197","n2193"],"tags":{"building":"yes"}},"w598":{"id":"w598","nodes":["n3404","n3403","n3402","n3401","n3400","n3399","n3398","n3397","n3373","n3372","n3396","n3395","n3404"],"tags":{"building":"school"}},"w6":{"id":"w6","nodes":["n879","n880","n881","n882","n879"],"tags":{"building":"shed"}},"w60":{"id":"w60","nodes":["n239","n308","n307"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w600":{"id":"w600","nodes":["n3387","n3386","n3316","n3315","n3314","n3313","n3387"],"tags":{"building":"yes"}},"w601":{"id":"w601","nodes":["n3304","n3303","n3302","n3301","n3385","n3384","n3300","n3299","n3304"],"tags":{"building":"yes"}},"w602":{"id":"w602","nodes":["n3334","n3333","n3332","n3331","n3330","n3329","n3328","n3327","n3326","n3325","n3324","n3323","n3322","n3321","n3320","n3319","n3318","n3317","n3334"],"tags":{"building":"yes"}},"w603":{"id":"w603","nodes":["n3353","n3352","n3347","n3280","n2798"],"tags":{"highway":"service","service":"alley","surface":"unpaved"}},"w604":{"id":"w604","nodes":["n3753","n3211","n3383"],"tags":{"highway":"service","service":"alley"}},"w605":{"id":"w605","nodes":["n3290","n3289","n3288","n3287","n3286","n3285","n3284","n3283","n3282","n3281","n3290"],"tags":{"building":"yes"}},"w606":{"id":"w606","nodes":["n2198","n2199","n2201","n2202","n2203","n2206","n2198"],"tags":{"building":"yes"}},"w607":{"id":"w607","nodes":["n2198","n2207"],"tags":{"barrier":"wall"}},"w608":{"id":"w608","nodes":["n2751","n3208","n3210","n3209","n3415","n3410","n3414","n3413","n3412","n3416"],"tags":{"highway":"residential","name":"East Street"}},"w609":{"id":"w609","nodes":["n2772","n3346","n3746","n3748","n3747","n3345","n3378","n3279","n3411"],"tags":{"highway":"residential","name":"Maple Street"}},"w61":{"id":"w61","nodes":["n309","n310","n311","n312","n313","n240"],"tags":{"footway":"sidewalk","highway":"footway"}},"w610":{"id":"w610","nodes":["n3379","n3380","n3382","n3381","n3379"],"tags":{"leisure":"park","name":"LaFayette Park"}},"w611":{"id":"w611","nodes":["n2768","n3194","n3210","n3753","n2760","n3353","n2773","n3378"],"tags":{"highway":"residential","name":"Bennett Street"}},"w612":{"id":"w612","nodes":["n2751","n3383","n2749","n2798","n2772"],"tags":{"highway":"residential","name":"Market Street"}},"w613":{"id":"w613","nodes":["n3298","n3297","n3296","n3295","n3294","n3293","n3292","n3291","n3298"],"tags":{"building":"yes"}},"w614":{"id":"w614","nodes":["n3375","n3406","n3405","n3374","n3375"],"tags":{"leisure":"playground"}},"w615":{"id":"w615","nodes":["n3393","n3344","n3343","n3342","n3341","n3340","n3339","n3338","n3337","n3392","n3391","n3390","n3389","n3336","n3335","n3388","n3393"],"tags":{"building":"yes"}},"w616":{"id":"w616","nodes":["n3376","n3407","n3408","n3377","n3376"],"tags":{"amenity":"school","name":"Three Rivers Elementary School"}},"w617":{"id":"w617","nodes":["n3312","n3311","n3310","n3309","n3308","n3307","n3306","n3305","n3312"],"tags":{"building":"yes"}},"w619":{"id":"w619","nodes":["n2863","n3424","n3425","n3426","n3427","n3428","n3429","n3430","n3431","n3432","n3433","n2844"],"tags":{"highway":"secondary","name":"Michigan Avenue","ref":"M 60"}},"w62":{"id":"w62","nodes":["n876","n906","n904","n875","n874","n873","n872","n871","n870","n869","n41","n868","n146","n314","n315","n1956"],"tags":{"footway":"sidewalk","highway":"footway"}},"w620":{"id":"w620","nodes":["n2844","n3420","n3421","n3422","n3439","n2859","n3437","n3493","n3496","n3500","n3497"],"tags":{"highway":"residential"}},"w621":{"id":"w621","nodes":["n3468","n3469","n3470","n3471","n3468"],"tags":{"building":"yes"}},"w622":{"id":"w622","nodes":["n3417","n3436","n3438","n3491","n3488","n3492","n3495","n3494","n3498","n3487","n3499","n3490","n3489","n4800","n3417"],"tags":{"landuse":"cemetery","name":"Riverside Cemetery"}},"w623":{"id":"w623","nodes":["n3440","n3441","n3442","n3443","n3444","n3445","n3440"],"tags":{"building":"yes"}},"w624":{"id":"w624","nodes":["n3446","n3447","n3448","n3449","n3450","n3451","n3452","n3453","n3454","n3455","n3456","n3457","n3458","n3459","n3460","n3461","n3462","n3463","n3464","n3465","n3466","n3467","n3446"],"tags":{"building":"yes"}},"w625":{"id":"w625","nodes":["n2844","n3434","n3435","n2878","n3275","n4621","n3276","n3278","n4463","n3272","n3472","n3474","n3475","n3476","n3477","n3478","n1202","n3479","n3480","n3481","n1203","n3482","n3483","n3484","n3485","n4574","n3486","n3473"],"tags":{"highway":"secondary","name":"Jefferson Street","name_1":"State Highway 60","ref":"M 60"}},"w626":{"id":"w626","nodes":["n3439","n3423","n2863"],"tags":{"highway":"unclassified","name":"Michigan Avenue","name_1":"State Highway 60"}},"w627":{"id":"w627","nodes":["n3500","n3005"],"tags":{"highway":"service"}},"w628":{"id":"w628","nodes":["n3491","n3488","n3492","n3010","n3009","n3005","n3008","n3007","n3006","n3502","n3491"],"tags":{"leisure":"park","name":"Marina Park"}},"w629":{"id":"w629","nodes":["n2208","n2209","n2212","n2214","n2208"],"tags":{"building":"yes"}},"w63":{"id":"w63","nodes":["n1955","n316"],"tags":{"footway":"sidewalk","highway":"footway"}},"w630":{"id":"w630","nodes":["n2757","n3414","n3202","n4542","n3206","n4538","n3750","n3503","n1629","n4500","n2763","n4502","n2764","n3508"],"tags":{"highway":"residential","name":"Hoffman Street"}},"w631":{"id":"w631","nodes":["n2215","n2750","n2770","n2771","n2215"],"tags":{"building":"yes"}},"w632":{"id":"w632","nodes":["n2766","n3504","n3507","n3751","n3205","n3196","n3410","n2746"],"tags":{"highway":"residential","name":"Cushman Street"}},"w633":{"id":"w633","nodes":["n2745","n3749","n3507","n4535","n3503"],"tags":{"highway":"residential","name":"Pine Street"}},"w634":{"id":"w634","nodes":["n3510","n3511","n3512","n3509","n3510"],"tags":{"leisure":"park","name":"Bowman Park"}},"w636":{"id":"w636","nodes":["n2745","n3752","n3204","n3201","n3415","n2761","n2767","n3411"],"tags":{"highway":"residential","name":"Wheeler Street"}},"w637":{"id":"w637","nodes":["n3550","n4586","n4476","n3472"],"tags":{"highway":"residential","name":"11th Avenue"}},"w638":{"id":"w638","nodes":["n3508","n3518"],"tags":{"bridge":"yes","highway":"residential","name":"Hoffman Street"}},"w639":{"id":"w639","nodes":["n3518","n1204","n2862","n3519","n3520","n3521","n3522","n3523","n2161","n3524","n3549","n3552","n4239","n3551","n4577","n4582","n4578","n4583","n4579","n4574"],"tags":{"highway":"residential","name":"Hoffman Street"}},"w64":{"id":"w64","nodes":["n316","n317"],"tags":{"bridge":"yes","footway":"sidewalk","highway":"footway","layer":"1"}},"w640":{"id":"w640","nodes":["n3634","n3640","n3676","n3633","n3678","n3648","n3638","n3683","n3600","n3579","n3679","n3677","n2987","n3592","n3588","n3608","n3559","n3617","n3620","n3660","n3553","n3533","n3530","n3531","n3525","n3527","n3526","n3532","n3529","n3528","n3667","n3627","n3623","n3625","n3601","n3687","n3671","n3644","n3626","n3673","n3582","n3693","n3605","n3619","n3651","n3650","n3615","n3663","n3631","n3596","n3604","n3655","n3586","n3595","n3701","n3603","n3686","n3611","n3568","n3674","n3613","n3580","n3562","n3564","n3689","n3585","n3670","n3659","n3684","n3680","n3646","n3558","n3556","n3692","n3563","n3575","n3571","n3675","n3557","n3700","n3656","n3622","n3657","n3565","n3669","n3658","n3618","n3624","n3688","n3610","n3570","n3645","n3649","n3583","n3694","n3561","n3554","n3614","n3698","n3581","n3635","n3641","n3569","n3647","n3628","n3598","n3696","n3665","n3639","n3607","n3695","n3642","n3672","n3577","n3643","n3691","n3602","n3576","n3591","n3560","n3606","n3685","n3597","n3629","n3661","n3654","n3616","n3697","n3578","n3609","n3653","n3699","n3566","n3637","n3567","n3666","n3555","n3599","n3590","n3572","n3593","n3690","n3681","n3612","n3682","n3668","n3587","n3621","n3636","n3662","n3589","n3573","n3652","n3664","n3632","n3574","n3594","n3584","n3630","n3634"],"tags":{"landuse":"reservoir","name":"Hoffman Pond","natural":"water"}},"w641":{"id":"w641","nodes":["n2988","n3534","n3535","n3536","n3537","n3538","n3539","n3540","n3541","n3542","n3543","n3544","n3545","n3546","n3547","n3548","n2970"],"tags":{"waterway":"river"}},"w642":{"id":"w642","nodes":["n3702","n3703","n3704","n3705","n3706","n3707","n3708","n3709","n3710","n3711","n3712","n3713","n3714","n3715","n3716","n3717","n3718","n3719","n3720","n3721","n3722","n3723","n3724","n3725","n3726","n3727","n3728","n3729","n3730","n3731","n3732","n3733","n3734","n3735","n3736","n3737","n3738","n3739","n3740","n3741","n3742","n3743","n3702"],"tags":{"admin_level":"8","boundary":"administrative"}},"w643":{"id":"w643","nodes":["n2839","n2873"],"tags":{"highway":"service","service":"driveway"}},"w644":{"id":"w644","nodes":["n2873","n2840"],"tags":{"bridge":"yes","highway":"service","layer":"1","service":"driveway"}},"w645":{"id":"w645","nodes":["n2840","n2841","n2842","n2845","n2866"],"tags":{"highway":"service","service":"driveway","surface":"unpaved"}},"w646":{"id":"w646","nodes":["n2752","n3759","n1420","n1421","n1422","n3758","n4507","n4506","n4505","n4520","n3199","n4522","n4504","n4546","n3200","n4547","n3412"],"tags":{"highway":"residential","name":"Flower Street"}},"w647":{"id":"w647","nodes":["n2874","n2875","n2876","n2954","n2874"],"tags":{"building":"industrial"}},"w648":{"id":"w648","nodes":["n3778","n3779","n3780","n3781","n3782","n3783","n3778"],"tags":{"building":"yes"}},"w649":{"id":"w649","nodes":["n3197","n4543","n4544","n3198"],"tags":{"highway":"residential","name":"Morris Avenue","surface":"unpaved"}},"w65":{"id":"w65","nodes":["n317","n318","n319","n320","n321"],"tags":{"footway":"sidewalk","highway":"footway"}},"w650":{"id":"w650","nodes":["n3207","n4526","n4528","n4548","n3203","n4549","n3413","n2762"],"tags":{"highway":"residential","name":"Adams Street"}},"w651":{"id":"w651","nodes":["n3788","n3785","n3786","n3787","n3788"],"tags":{"power":"station"}},"w652":{"id":"w652","nodes":["n2957","n3163","n3241"],"tags":{"barrier":"wall"}},"w653":{"id":"w653","nodes":["n3549","n3802","n3803","n3800","n3801"],"tags":{"highway":"service","surface":"unpaved"}},"w654":{"id":"w654","nodes":["n3164","n3165","n3166","n3167","n3168","n3505","n3164"],"tags":{"building":"yes"}},"w655":{"id":"w655","nodes":["n3506","n3517","n3760","n3761","n3762","n3763","n3506"],"tags":{"building":"yes"}},"w656":{"id":"w656","nodes":["n3764","n3765","n3766","n3767","n3768","n3769","n3770","n3771","n3764"],"tags":{"building":"yes"}},"w657":{"id":"w657","nodes":["n3772","n3773","n3774","n3775","n3772"],"tags":{"building":"yes"}},"w658":{"id":"w658","nodes":["n3776","n3777","n3784","n3789","n3776"],"tags":{"building":"yes"}},"w659":{"id":"w659","nodes":["n3930","n3931","n3932","n3933","n3934","n3935","n3936","n3937","n3938","n3930"],"tags":{"leisure":"pitch","sport":"baseball"}},"w66":{"id":"w66","nodes":["n321","n322"],"tags":{"bridge":"yes","footway":"sidewalk","highway":"footway","layer":"1"}},"w660":{"id":"w660","nodes":["n3982","n3842","n3864","n3865","n2938","n3866","n2939","n3867","n3868","n3858","n2937","n3869","n2935","n2934","n3870","n3348","n3862"],"tags":{"highway":"service"}},"w661":{"id":"w661","nodes":["n3968","n3969"],"tags":{"highway":"footway"}},"w662":{"id":"w662","nodes":["n3875","n3876","n3877","n3878","n3879","n3880","n3881","n3882","n3875"],"tags":{"amenity":"parking"}},"w663":{"id":"w663","nodes":["n3964","n3965"],"tags":{"highway":"footway"}},"w664":{"id":"w664","nodes":["n3966","n3967"],"tags":{"highway":"footway"}},"w665":{"id":"w665","nodes":["n3857","n3890","n3884","n3894","n3889","n3899","n3885","n3886","n3896","n3887"],"tags":{"highway":"service","service":"parking_aisle"}},"w666":{"id":"w666","nodes":["n3895","n3896"],"tags":{"highway":"service","service":"parking_aisle"}},"w667":{"id":"w667","nodes":["n3274","n3977","n3984","n3983","n3981","n3844","n3978","n3982","n3861","n3862","n3873","n3874","n4468","n3863"],"tags":{"access":"private","highway":"service","name":"Collins Drive"}},"w668":{"id":"w668","nodes":["n3900","n3901","n3902","n3903","n3904","n3905","n3808","n3809","n3906","n3907","n3908","n3967","n3909","n3910","n3911","n3955","n3964","n3912","n3913","n3914","n3915","n3916","n3917","n3918","n3919","n3920","n3921","n3922","n3923","n3924","n3925","n3926","n3927","n3969","n3970","n3928","n3807","n3929","n3900"],"tags":{"building":"school"}},"w669":{"id":"w669","nodes":["n3272","n39","n40","n3974","n3863","n3857","n3892","n3883","n3891","n3889"],"tags":{"highway":"service"}},"w67":{"id":"w67","nodes":["n322","n886","n323","n475"],"tags":{"footway":"crossing","highway":"footway"}},"w670":{"id":"w670","nodes":["n3473","n3859","n3860","n3980","n4908","n4865"],"tags":{"highway":"secondary","name":"Hoffman Street","ref":"M 60"}},"w671":{"id":"w671","nodes":["n3970","n3806","n3971"],"tags":{"highway":"footway"}},"w672":{"id":"w672","nodes":["n3892","n3893","n3894"],"tags":{"highway":"service","service":"parking_aisle"}},"w673":{"id":"w673","nodes":["n3945","n3946","n3992","n3990","n3945"],"tags":{"leisure":"pitch","sport":"tennis"}},"w674":{"id":"w674","nodes":["n3890","n3893","n3891"],"tags":{"highway":"service","service":"parking_aisle"}},"w675":{"id":"w675","nodes":["n3947","n3948","n3994","n3993","n3947"],"tags":{"leisure":"pitch","sport":"tennis"}},"w676":{"id":"w676","nodes":["n3858","n3954","n3972","n3810","n3811","n3812","n3841","n3973","n3898","n3963","n3897","n3896"],"tags":{"highway":"service"}},"w677":{"id":"w677","nodes":["n3977","n3996","n3997","n4004","n3998","n3999","n4005","n4007","n4006","n3995","n4000","n3843","n4001","n4002","n4003","n3949","n3351","n3950","n3354","n3350","n3951","n3349","n3952","n3953","n3954","n3956","n3966","n3955"],"tags":{"highway":"footway"}},"w678":{"id":"w678","nodes":["n3887","n3888","n3895","n3899"],"tags":{"highway":"service","service":"parking_aisle"}},"w679":{"id":"w679","nodes":["n3946","n3947","n3993","n3992","n3946"],"tags":{"leisure":"pitch","sport":"tennis"}},"w68":{"id":"w68","nodes":["n294","n1952","n326"],"tags":{"footway":"sidewalk","highway":"footway"}},"w680":{"id":"w680","nodes":["n3939","n3940","n3941","n3985","n3986","n3987","n3988","n3989","n3942","n3943","n3939"],"tags":{"leisure":"pitch","sport":"baseball"}},"w681":{"id":"w681","nodes":["n3990","n3991","n3944","n3945","n3990"],"tags":{"leisure":"pitch","sport":"tennis"}},"w682":{"id":"w682","nodes":["n3871","n3872","n3873","n3874","n3871"],"tags":{"amenity":"parking"}},"w683":{"id":"w683","nodes":["n3956","n3965","n3957","n3958","n3959"],"tags":{"footway":"sidewalk","highway":"footway"}},"w684":{"id":"w684","nodes":["n3790","n3791","n3792","n3793","n3790"],"tags":{"building":"shed"}},"w685":{"id":"w685","nodes":["n3794","n3795","n3796","n3797","n3794"],"tags":{"building":"yes"}},"w686":{"id":"w686","nodes":["n3798","n3799","n3804","n3805","n3798"],"tags":{"building":"yes"}},"w687":{"id":"w687","nodes":["n3806","n3807"],"tags":{"highway":"footway"}},"w688":{"id":"w688","nodes":["n3845","n3846","n3847","n3848","n3845"],"tags":{"leisure":"pitch","sport":"american_football"}},"w689":{"id":"w689","nodes":["n3849","n4021","n3850","n3851","n3852","n3853","n3854","n3855","n3856","n3975","n3976","n3979","n4008","n4009","n4010","n4011","n4012","n4013","n4014","n4015","n4016","n4017","n4018","n4019","n4020","n4021"],"tags":{"leisure":"track","sport":"running"}},"w69":{"id":"w69","nodes":["n326","n327"],"tags":{"bridge":"yes","footway":"sidewalk","highway":"footway","layer":"1"}},"w690":{"id":"w690","nodes":["n4022","n4023","n4024","n4025","n4026","n4027","n4022"],"tags":{"building":"yes"}},"w691":{"id":"w691","nodes":["n4028","n4029","n4030","n4031","n4028"],"tags":{"building":"yes"}},"w692":{"id":"w692","nodes":["n4032","n4033","n4034","n4035","n4032"],"tags":{"building":"yes"}},"w693":{"id":"w693","nodes":["n4036","n4037","n4038","n4039","n4036"],"tags":{"building":"yes"}},"w694":{"id":"w694","nodes":["n4040","n4041","n4042","n4043","n4040"],"tags":{"building":"yes"}},"w695":{"id":"w695","nodes":["n4044","n4045","n4050","n4053","n4046","n4047","n4048","n4049","n4044"],"tags":{"building":"yes"}},"w696":{"id":"w696","nodes":["n4050","n4051","n4052","n4053","n4050"],"tags":{"building":"roof"}},"w697":{"id":"w697","nodes":["n4054","n4068","n4055","n4056","n4057","n4054"],"tags":{"building":"yes"}},"w698":{"id":"w698","nodes":["n4058","n4059","n4060","n4061","n4062","n4063","n4058"],"tags":{"building":"yes"}},"w699":{"id":"w699","nodes":["n4064","n4066","n4065"],"tags":{"barrier":"fence"}},"w7":{"id":"w7","nodes":["n43","n44","n45"],"tags":{"highway":"service"}},"w70":{"id":"w70","nodes":["n327","n328","n27","n329"],"tags":{"footway":"sidewalk","highway":"footway"}},"w700":{"id":"w700","nodes":["n4066","n4067","n4068"],"tags":{"barrier":"fence"}},"w701":{"id":"w701","nodes":["n4069","n4070","n4071","n4072","n4069"],"tags":{"building":"shed"}},"w702":{"id":"w702","nodes":["n4073","n4074","n4075","n4076","n4077","n4078","n4079","n4080","n4081","n4082","n4083","n4084","n4073"],"tags":{"building":"yes"}},"w703":{"id":"w703","nodes":["n4085","n4093","n4086","n4087","n4088","n4089","n4090","n4091","n4092","n4085"],"tags":{"building":"yes"}},"w704":{"id":"w704","nodes":["n4093","n4094","n4095","n4096"],"tags":{"barrier":"fence"}},"w705":{"id":"w705","nodes":["n4097","n4098","n4099","n4100","n4097"],"tags":{"building":"yes"}},"w706":{"id":"w706","nodes":["n4098","n4102","n4087"],"tags":{"barrier":"fence"}},"w707":{"id":"w707","nodes":["n4101","n4102","n4096","n4170","n4103"],"tags":{"barrier":"fence"}},"w708":{"id":"w708","nodes":["n4104","n4105","n4106","n4107","n4104"],"tags":{"access":"private","leisure":"swimming_pool"}},"w709":{"id":"w709","nodes":["n4108","n4109","n4110","n4111","n4108"],"tags":{"building":"yes"}},"w71":{"id":"w71","nodes":["n329","n331"],"tags":{"bridge":"yes","footway":"sidewalk","highway":"footway","layer":"1"}},"w710":{"id":"w710","nodes":["n4112","n4113","n4114","n4115","n4116","n4117","n4118","n4119","n4112"],"tags":{"building":"yes"}},"w711":{"id":"w711","nodes":["n4120","n4121","n4122","n4123","n4120"],"tags":{"building":"yes"}},"w712":{"id":"w712","nodes":["n4124","n4125","n4126","n4127","n4128","n4129","n4124"],"tags":{"building":"yes"}},"w713":{"id":"w713","nodes":["n4130","n4131","n4132","n4133","n4130"],"tags":{"building":"shed"}},"w714":{"id":"w714","nodes":["n4134","n4135","n4136","n4137","n4138","n4139","n4140","n4141","n4142","n4143","n4134"],"tags":{"building":"yes"}},"w715":{"id":"w715","nodes":["n4144","n4145","n4146","n4147","n4148","n4149","n4144"],"tags":{"building":"yes"}},"w716":{"id":"w716","nodes":["n4150","n4151","n4152","n4153","n4150"],"tags":{"building":"yes"}},"w717":{"id":"w717","nodes":["n4154","n4155","n4156","n4157","n4154"],"tags":{"building":"yes"}},"w718":{"id":"w718","nodes":["n4158","n4159","n4160","n4161","n4162","n4163","n4164","n4165","n4158"],"tags":{"building":"yes"}},"w719":{"id":"w719","nodes":["n4166","n4167","n4168","n4169","n4166"],"tags":{"building":"yes"}},"w72":{"id":"w72","nodes":["n331","n344","n332","n333","n334"],"tags":{"footway":"sidewalk","highway":"footway"}},"w720":{"id":"w720","nodes":["n4170","n4171"],"tags":{"barrier":"fence"}},"w721":{"id":"w721","nodes":["n4138","n4103"],"tags":{"barrier":"fence"}},"w722":{"id":"w722","nodes":["n4103","n4172"],"tags":{"barrier":"fence"}},"w723":{"id":"w723","nodes":["n4173","n4174"],"tags":{"barrier":"fence"}},"w724":{"id":"w724","nodes":["n4175","n4176","n4177","n4178","n4175"],"tags":{"building":"yes"}},"w725":{"id":"w725","nodes":["n4179","n4180","n4181","n4182","n4183","n4184","n4179"],"tags":{"building":"yes"}},"w726":{"id":"w726","nodes":["n4185","n4186","n4187","n4188","n4185"],"tags":{"building":"yes"}},"w727":{"id":"w727","nodes":["n4189","n4190","n4191","n4192","n4193","n4194","n4195","n4196","n4197","n4198","n4199","n4200","n4201","n4202","n4189"],"tags":{"building":"yes"}},"w728":{"id":"w728","nodes":["n4203","n4204","n4205","n4206","n4207","n4208","n4209","n4210","n4203"],"tags":{"building":"yes"}},"w729":{"id":"w729","nodes":["n4211","n4212","n4213","n4214","n4211"],"tags":{"building":"shed"}},"w73":{"id":"w73","nodes":["n335","n336","n337","n338","n339","n340","n341","n342","n335"],"tags":{"building":"yes"}},"w730":{"id":"w730","nodes":["n4215","n4216","n4217","n4218","n4215"],"tags":{"building":"yes"}},"w731":{"id":"w731","nodes":["n4219","n4220","n4221","n4222","n4223","n4224","n4225","n4226","n4227","n4228","n4229","n4230","n4219"],"tags":{"building":"yes"}},"w732":{"id":"w732","nodes":["n4231","n4232","n4233","n4234","n4235","n4236","n4237","n4238","n4231"],"tags":{"building":"yes"}},"w733":{"id":"w733","nodes":["n4239","n4240","n4241","n4242","n4243","n4244","n4245","n4246","n4247","n4248","n4241"],"tags":{"highway":"service"}},"w734":{"id":"w734","nodes":["n4240","n4249","n4248"],"tags":{"highway":"service","service":"parking_aisle"}},"w735":{"id":"w735","nodes":["n4250","n4251","n4252","n4253","n4254","n4255","n4256","n4257","n4258","n4250"],"tags":{"amenity":"parking"}},"w736":{"id":"w736","nodes":["n4259","n4260","n4261","n4262","n4259"],"tags":{"building":"yes"}},"w737":{"id":"w737","nodes":["n4263","n4264","n4265","n4266","n4267","n4268","n4269","n4270","n4271","n4272","n4273","n4274","n4275","n4276","n4263"],"tags":{"building":"yes"}},"w738":{"id":"w738","nodes":["n4277","n4278","n4279","n4280","n4281","n4282","n4277"],"tags":{"building":"yes"}},"w739":{"id":"w739","nodes":["n4283","n4284","n4285","n4286","n4287","n4288","n4289","n4290","n4291","n4292","n4293","n4294","n4283"],"tags":{"building":"yes"}},"w74":{"id":"w74","nodes":["n343","n344","n345"],"tags":{"highway":"service"}},"w740":{"id":"w740","nodes":["n4295","n4296","n4297","n4298","n4295"],"tags":{"building":"yes"}},"w741":{"id":"w741","nodes":["n4299","n4300","n4301","n4302","n4303","n4304","n4305","n4306","n4307","n4308","n4309","n4310","n4299"],"tags":{"building":"yes"}},"w742":{"id":"w742","nodes":["n4311","n4312","n4313","n4314","n4311"],"tags":{"building":"shed"}},"w743":{"id":"w743","nodes":["n4315","n4316","n4317","n4318","n4319","n4320","n4315"],"tags":{"building":"yes"}},"w744":{"id":"w744","nodes":["n4321","n4322","n4323","n4324","n4325","n4326","n4327","n4328","n4329","n4330","n4331","n4332","n4333","n4334","n4321"],"tags":{"building":"yes"}},"w745":{"id":"w745","nodes":["n4335","n4336","n4337","n4338","n4335"],"tags":{"building":"shed"}},"w746":{"id":"w746","nodes":["n4339","n4340","n4341","n4342","n4343","n4344","n4339"],"tags":{"building":"yes"}},"w747":{"id":"w747","nodes":["n4345","n4346","n4347","n4348","n4345"],"tags":{"building":"yes"}},"w748":{"id":"w748","nodes":["n4349","n4350","n4351","n4352","n4349"],"tags":{"building":"yes"}},"w749":{"id":"w749","nodes":["n4353","n4354","n4355","n4356","n4357","n4358","n4353"],"tags":{"building":"yes"}},"w75":{"id":"w75","nodes":["n346","n347","n348","n349","n350","n351","n346"],"tags":{"amenity":"parking"}},"w750":{"id":"w750","nodes":["n4612","n4359","n4360"],"tags":{"barrier":"fence"}},"w751":{"id":"w751","nodes":["n4361","n4362","n4363","n4364","n4361"],"tags":{"building":"yes"}},"w752":{"id":"w752","nodes":["n4365","n4366","n4367","n4368","n4365"],"tags":{"building":"yes"}},"w753":{"id":"w753","nodes":["n4369","n4370","n4371","n4372","n4375","n4369"],"tags":{"building":"yes"}},"w754":{"id":"w754","nodes":["n4373","n4374","n4375"],"tags":{"barrier":"fence"}},"w755":{"id":"w755","nodes":["n4376","n4377","n4378","n4379","n4376"],"tags":{"building":"shed"}},"w756":{"id":"w756","nodes":["n4380","n4381","n4382","n4383","n4384","n4385","n4386","n4387","n4388","n4389","n4390","n4391","n4380"],"tags":{"building":"yes"}},"w757":{"id":"w757","nodes":["n4392","n4393","n4394","n4395","n4392"],"tags":{"building":"yes"}},"w758":{"id":"w758","nodes":["n4396","n4397","n4398","n4399","n4396"],"tags":{"building":"shed"}},"w759":{"id":"w759","nodes":["n4400","n4401","n4402","n4403","n4404","n4405","n4406","n4407","n4408","n4409","n4410","n4411","n4412","n4413","n4414","n4415","n4400"],"tags":{"building":"yes"}},"w76":{"id":"w76","nodes":["n2561","n359","n2563","n2793","n357","n356","n2792","n355","n354","n2791","n2562","n353","n352","n358","n2561"],"tags":{"highway":"service","oneway":"yes","service":"parking_aisle"}},"w760":{"id":"w760","nodes":["n4416","n4417"],"tags":{"barrier":"fence"}},"w761":{"id":"w761","nodes":["n4418","n4416","n4419"],"tags":{"barrier":"fence"}},"w762":{"id":"w762","nodes":["n4420","n4421"],"tags":{"barrier":"fence"}},"w763":{"id":"w763","nodes":["n4422","n4423","n4424","n4425","n4426","n4427","n4428","n4429","n4430","n4431","n4432","n4433","n4422"],"tags":{"building":"yes"}},"w764":{"id":"w764","nodes":["n4434","n4435","n4436","n4437","n4438","n4439","n4440","n4441","n4442","n4445","n4444","n4443","n4434"],"tags":{"building":"yes"}},"w765":{"id":"w765","nodes":["n4446","n4447","n4448","n4449","n4446"],"tags":{"building":"yes"}},"w766":{"id":"w766","nodes":["n4450","n4451","n4452","n4453","n4450"],"tags":{"building":"yes"}},"w767":{"id":"w767","nodes":["n4454","n4455","n4456","n4457","n4454"],"tags":{"building":"yes"}},"w768":{"id":"w768","nodes":["n4461","n4458","n4460"],"tags":{"footway":"crossing","highway":"footway"}},"w769":{"id":"w769","nodes":["n4460","n4462","n4459"],"tags":{"footway":"sidewalk","highway":"footway"}},"w77":{"id":"w77","nodes":["n325","n360","n361"],"tags":{"footway":"crossing","highway":"footway"}},"w770":{"id":"w770","nodes":["n4462","n4463","n4464"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w771":{"id":"w771","nodes":["n4464","n4465","n4466","n4467"],"tags":{"footway":"sidewalk","highway":"footway"}},"w772":{"id":"w772","nodes":["n3959","n3968","n3971","n3960","n3961","n3962","n3963"],"tags":{"footway":"sidewalk","highway":"footway"}},"w773":{"id":"w773","nodes":["n4467","n4468","n3959"],"tags":{"footway":"crossing","highway":"footway"}},"w774":{"id":"w774","nodes":["n4459","n4469","n4470"],"tags":{"footway":"crossing","highway":"footway"}},"w775":{"id":"w775","nodes":["n4470","n4471","n4472","n4473","n4474","n4475"],"tags":{"footway":"sidewalk","highway":"footway"}},"w776":{"id":"w776","nodes":["n4475","n4476","n4477"],"tags":{"footway":"crossing","highway":"footway"}},"w777":{"id":"w777","nodes":["n4477","n4478","n4479","n4480","n4481","n4482","n4483","n4484","n4485","n4486","n4487"],"tags":{"footway":"sidewalk","highway":"footway"}},"w778":{"id":"w778","nodes":["n4488","n4489","n4490","n4491","n4488"],"tags":{"building":"yes"}},"w779":{"id":"w779","nodes":["n4492","n4493","n4494","n4495","n4492"],"tags":{"building":"yes"}},"w78":{"id":"w78","nodes":["n361","n362","n369"],"tags":{"footway":"sidewalk","highway":"footway"}},"w780":{"id":"w780","nodes":["n4496","n4497","n4498","n4499","n4496"],"tags":{"access":"private","leisure":"swimming_pool"}},"w781":{"id":"w781","nodes":["n4508","n4509"],"tags":{"footway":"sidewalk","highway":"footway"}},"w782":{"id":"w782","nodes":["n4510","n4511"],"tags":{"footway":"sidewalk","highway":"footway"}},"w783":{"id":"w783","nodes":["n4512","n4513"],"tags":{"footway":"sidewalk","highway":"footway"}},"w784":{"id":"w784","nodes":["n4513","n4514"],"tags":{"footway":"sidewalk","highway":"footway"}},"w785":{"id":"w785","nodes":["n4515","n4516"],"tags":{"footway":"sidewalk","highway":"footway"}},"w786":{"id":"w786","nodes":["n4517","n4515"],"tags":{"footway":"sidewalk","highway":"footway"}},"w787":{"id":"w787","nodes":["n4518","n4519"],"tags":{"footway":"sidewalk","highway":"footway"}},"w788":{"id":"w788","nodes":["n4519","n4520","n4513"],"tags":{"footway":"crossing","highway":"footway"}},"w789":{"id":"w789","nodes":["n4515","n4521","n4513"],"tags":{"footway":"crossing","highway":"footway"}},"w79":{"id":"w79","nodes":["n362","n363","n334"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w790":{"id":"w790","nodes":["n4515","n4522","n4523"],"tags":{"footway":"crossing","highway":"footway"}},"w791":{"id":"w791","nodes":["n4523","n4524","n4519"],"tags":{"footway":"crossing","highway":"footway"}},"w792":{"id":"w792","nodes":["n4523","n4525"],"tags":{"footway":"sidewalk","highway":"footway"}},"w793":{"id":"w793","nodes":["n4525","n4526","n4527"],"tags":{"footway":"crossing","highway":"footway"}},"w794":{"id":"w794","nodes":["n4527","n4529"],"tags":{"footway":"sidewalk","highway":"footway"}},"w795":{"id":"w795","nodes":["n4529","n4530","n4518"],"tags":{"footway":"crossing","highway":"footway"}},"w796":{"id":"w796","nodes":["n4518","n4531"],"tags":{"footway":"sidewalk","highway":"footway"}},"w797":{"id":"w797","nodes":["n4531","n4532"],"tags":{"footway":"sidewalk","highway":"footway"}},"w798":{"id":"w798","nodes":["n4533","n4534"],"tags":{"footway":"sidewalk","highway":"footway"}},"w799":{"id":"w799","nodes":["n4518","n4538","n4539"],"tags":{"footway":"crossing","highway":"footway"}},"w8":{"id":"w8","nodes":["n46","n47","n145","n48","n49","n46"],"tags":{"amenity":"parking"}},"w80":{"id":"w80","nodes":["n334","n364","n365"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w800":{"id":"w800","nodes":["n4539","n4540","n4541"],"tags":{"footway":"crossing","highway":"footway"}},"w801":{"id":"w801","nodes":["n4541","n4542","n4529"],"tags":{"footway":"crossing","highway":"footway"}},"w802":{"id":"w802","nodes":["n4552","n4553"],"tags":{"footway":"sidewalk","highway":"footway"}},"w803":{"id":"w803","nodes":["n4554","n4555","n4556","n4557","n4558","n4559","n4554"],"tags":{"building":"yes"}},"w804":{"id":"w804","nodes":["n4562","n4563"],"tags":{"barrier":"retaining_wall"}},"w805":{"id":"w805","nodes":["n4568","n4569","n4570","n4571","n4568"],"tags":{"building":"yes"}},"w806":{"id":"w806","nodes":["n3473","n4575","n4576","n4581","n4580","n3551"],"tags":{"highway":"residential","oneway":"yes"}},"w807":{"id":"w807","nodes":["n4613","n4614","n4615","n4616","n4617","n4618","n4619","n4620","n4613"],"tags":{"leisure":"pitch","sport":"baseball"}},"w808":{"id":"w808","nodes":["n4621","n4622","n4623","n4624","n4625","n4626","n4627","n4628","n4629","n4630"],"tags":{"highway":"service"}},"w809":{"id":"w809","nodes":["n4631","n4632","n4633","n4637","n4634","n4638","n4635","n4636"],"tags":{"highway":"service"}},"w81":{"id":"w81","nodes":["n365","n366","n367"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w810":{"id":"w810","nodes":["n4639","n4640","n4641"],"tags":{"barrier":"fence"}},"w811":{"id":"w811","nodes":["n4649","n4650","n4651","n4652","n4649"],"tags":{"building":"yes"}},"w812":{"id":"w812","nodes":["n4654","n4655"],"tags":{"barrier":"fence"}},"w813":{"id":"w813","nodes":["n4656","n4657"],"tags":{"barrier":"fence"}},"w814":{"id":"w814","nodes":["n4669","n4670","n4671","n4672","n4669"],"tags":{"amenity":"shelter","shelter_type":"picnic_shelters"}},"w815":{"id":"w815","nodes":["n4678","n4679","n4680","n1889"],"tags":{"highway":"service"}},"w816":{"id":"w816","nodes":["n239","n4686","n4687"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w817":{"id":"w817","nodes":["n4687","n4688","n4689"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w818":{"id":"w818","nodes":["n4689","n4690","n307"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w819":{"id":"w819","nodes":["n2266","n4743"],"tags":{"highway":"path"}},"w82":{"id":"w82","nodes":["n724","n368","n369"],"tags":{"crossing":"zebra","footway":"crossing","highway":"footway"}},"w820":{"id":"w820","nodes":["n4785","n4786","n4787","n4788","n1684","n4760","n4769","n4761","n4762","n4763","n4764","n4765","n4766","n4767","n4768","n4785"],"tags":{"natural":"wood"}},"w821":{"id":"w821","nodes":["n4769","n4770","n4771","n4772","n4773","n4774","n4775","n4776","n4777","n4778","n4779","n4780","n4781","n4782","n4783","n4784","n4785","n4768","n4767","n4766","n4765","n4764","n4763","n4762","n4761","n4769"],"tags":{"natural":"scrub"}},"w822":{"id":"w822","nodes":["n4772","n4789","n4790","n4791","n4792","n4793","n4794","n4795","n4796","n4797","n4798","n4799","n4783","n4782","n4781","n4780","n4779","n4778","n4777","n4776","n4775","n4774","n4773","n4772"],"tags":{"natural":"wood"}},"w823":{"id":"w823","nodes":["n4800","n4801","n4802","n4803","n4804","n4805","n4806","n4807","n4808","n4809","n4810","n4811","n4812","n4813","n4814","n4815","n4816","n3490","n3489","n4800"],"tags":{"natural":"wood"}},"w824":{"id":"w824","nodes":["n4817","n4818","n4819","n4820","n4821","n4822","n4817"],"tags":{"landuse":"recreation_ground"}},"w825":{"id":"w825","nodes":["n4563","n4823","n4824","n4829","n4825","n4826","n4827","n4828","n4562","n4563"],"tags":{"landuse":"recreation_ground"}},"w826":{"id":"w826","nodes":["n4830","n4831","n4832","n4833","n4834","n4835","n4836","n4830"],"tags":{"landuse":"industrial"}},"w827":{"id":"w827","nodes":["n4563","n4837","n4838","n4839","n4840","n4841","n4842","n4827","n4828","n4562","n4563"],"tags":{"landuse":"industrial"}},"w828":{"id":"w828","nodes":["n4843","n4844","n4845","n4846","n4843"],"tags":{"landuse":"farmland"}},"w829":{"id":"w829","nodes":["n3712","n4847","n4848","n4849","n4850","n4851","n4852","n4858","n4864","n4959","n4960","n4853","n4857","n4854","n4855","n4856","n3712"],"tags":{"aeroway":"aerodrome","name":"Three Rivers Municipal Airport"}},"w83":{"id":"w83","nodes":["n371","n372","n373","n374","n371"],"tags":{"building":"yes"}},"w830":{"id":"w830","nodes":["n4855","n4854","n4857","n4853","n4960"],"tags":{"barrier":"fence"}},"w831":{"id":"w831","nodes":["n4860","n4859","n4858","n4852","n4851"],"tags":{"barrier":"fence"}},"w832":{"id":"w832","nodes":["n4866","n4878","n4869","n4867"],"tags":{"aeroway":"runway","ref":"5/23"}},"w833":{"id":"w833","nodes":["n4868","n4890","n4894","n4881","n4869","n4905","n4870"],"tags":{"aeroway":"runway","ref":"9/27"}},"w834":{"id":"w834","nodes":["n4871","n4875","n4872","n4895","n4873","n4874","n4871"],"tags":{"aeroway":"apron"}},"w835":{"id":"w835","nodes":["n4875","n4876","n4877","n4878","n4879","n4880","n4882","n4881"],"tags":{"aeroway":"taxiway"}},"w836":{"id":"w836","nodes":["n4882","n4893","n4883","n4891","n4884","n4885","n4886","n4887","n4888","n4892","n4889","n4890"],"tags":{"aeroway":"taxiway"}},"w837":{"id":"w837","nodes":["n4893","n4894"],"tags":{"aeroway":"taxiway"}},"w838":{"id":"w838","nodes":["n4895","n4896","n4897","n4898","n4899","n4900","n4901","n4902","n4903","n4906","n4904","n4905"],"tags":{"aeroway":"taxiway"}},"w839":{"id":"w839","nodes":["n4907","n4908"],"tags":{"highway":"service"}},"w84":{"id":"w84","nodes":["n374","n375","n376","n377","n373","n374"],"tags":{"building":"yes"}},"w840":{"id":"w840","nodes":["n4909","n4907","n4910"],"tags":{"highway":"service"}},"w841":{"id":"w841","nodes":["n4911","n4912","n4913","n4914","n4911"],"tags":{"building":"yes"}},"w842":{"id":"w842","nodes":["n4915","n4916","n4917","n4918","n4915"],"tags":{"aeroway":"hangar","building":"yes"}},"w843":{"id":"w843","nodes":["n4919","n4920","n4921","n4922","n4919"],"tags":{"building":"yes"}},"w844":{"id":"w844","nodes":["n4923","n4924","n4925","n4926","n4923"],"tags":{"aeroway":"hangar","building":"yes"}},"w845":{"id":"w845","nodes":["n4927","n4928","n4929","n4930","n4927"],"tags":{"aeroway":"hangar","building":"yes"}},"w846":{"id":"w846","nodes":["n4931","n4932","n4933","n4934","n4931"],"tags":{"aeroway":"hangar","building":"yes"}},"w847":{"id":"w847","nodes":["n4935","n4936","n4937","n4938","n4935"],"tags":{"aeroway":"hangar","building":"yes"}},"w848":{"id":"w848","nodes":["n4939","n4940","n4941","n4942","n4939"],"tags":{"aeroway":"hangar","building":"yes"}},"w849":{"id":"w849","nodes":["n4943","n4944","n4945","n4946","n4943"],"tags":{"aeroway":"hangar","building":"yes"}},"w85":{"id":"w85","nodes":["n431","n432","n1038","n433","n434","n1040","n431"],"tags":{"building":"yes"}},"w850":{"id":"w850","nodes":["n4947","n4948","n4949","n4950","n4947"],"tags":{"aeroway":"hangar","building":"yes"}},"w851":{"id":"w851","nodes":["n4951","n4952","n4953","n4954","n4951"],"tags":{"aeroway":"hangar","building":"yes"}},"w852":{"id":"w852","nodes":["n4955","n4956","n4957","n4958","n4955"],"tags":{"aeroway":"hangar","building":"yes"}},"w853":{"id":"w853","nodes":["n4959","n4864","n4861","n4862","n4863"],"tags":{"barrier":"fence"}},"w854":{"id":"w854","nodes":["n4961","n4962","n4963","n4964","n4965","n4966","n4967","n4968","n4969","n4961"],"tags":{"landuse":"farmland"}},"w855":{"id":"w855","nodes":["n4970","n4971","n4972","n4973","n4974","n4975","n4976","n4977","n4978","n4980","n4970"],"tags":{"landuse":"farmland"}},"w856":{"id":"w856","nodes":["n4979","n4980","n4978","n4981","n4982","n4983","n4984","n4985","n4979"],"tags":{"natural":"scrub"}},"w857":{"id":"w857","nodes":["n4986","n4987","n4988","n5032","n4989","n4990","n4991","n4992","n4993","n4994","n4995","n4996","n4997","n4998","n4999","n5000","n5001","n5002","n5022","n5023","n5024","n5025","n5030","n5031","n5029","n5028","n5027","n5026","n4986"],"tags":{"landuse":"farmland"}},"w858":{"id":"w858","nodes":["n5001","n5003","n5004","n4999","n5000","n5001"],"tags":{"natural":"scrub"}},"w859":{"id":"w859","nodes":["n5005","n5006","n5007","n5008","n5009","n5010","n5021","n5020","n5019","n5011","n5012","n5013","n5018","n5014","n5015","n5017","n5016","n5005"],"tags":{"landuse":"farmland"}},"w86":{"id":"w86","nodes":["n384","n385","n386","n387","n384"],"tags":{"building":"yes"}},"w860":{"id":"w860","nodes":["n3020","n5033","n5034","n5035","n3179","n3180","n3191","n3181","n3190","n3182","n3183","n3184","n3185","n3186","n3187","n3188","n3189","n3160","n3161","n3162","n2126","n2153","n2288","n3020"],"tags":{"landuse":"industrial"}},"w87":{"id":"w87","nodes":["n387","n388","n389","n386","n387"],"tags":{"building":"yes"}},"w88":{"id":"w88","nodes":["n390","n391","n392","n393","n390"],"tags":{"building":"yes"}},"w89":{"id":"w89","nodes":["n394","n2895"],"tags":{"highway":"service"}},"w9":{"id":"w9","nodes":["n50","n51","n148","n52","n57","n891","n53","n50"],"tags":{"building":"yes"}},"w90":{"id":"w90","nodes":["n398","n399","n400","n401","n402","n403","n404","n405","n406","n407","n408","n409","n410","n411","n412","n413","n414","n415","n416","n417","n398"],"tags":{"building":"yes"}},"w91":{"id":"w91","nodes":["n418","n423","n419"],"tags":{"highway":"service"}},"w92":{"id":"w92","nodes":["n420","n421","n422","n423","n420"],"tags":{"amenity":"parking"}},"w93":{"id":"w93","nodes":["n2282","n1876"],"tags":{"name":"Rocky River","tunnel":"building_passage","waterway":"river"}},"w94":{"id":"w94","nodes":["n1876","n885","n1875","n2234"],"tags":{"name":"Rocky River","waterway":"river"}},"w95":{"id":"w95","nodes":["n425","n426","n427","n914","n428","n913","n425"],"tags":{"building":"yes"}},"w96":{"id":"w96","nodes":["n456","n620","n1034","n1035","n456"],"tags":{"building":"yes"}},"w97":{"id":"w97","nodes":["n435","n912","n451","n321"],"tags":{"highway":"footway"}},"w98":{"id":"w98","nodes":["n436","n319","n437","n438","n439","n440","n441","n476","n442"],"tags":{"highway":"service"}},"w99":{"id":"w99","nodes":["n443","n444","n445","n446","n447","n448","n449","n450","n443"],"tags":{"amenity":"parking"}},"n2934":{"id":"n2934","loc":[-85.617051,41.952263]},"n2935":{"id":"n2935","loc":[-85.61699,41.952276]},"n2937":{"id":"n2937","loc":[-85.616847,41.952262]},"n2938":{"id":"n2938","loc":[-85.616577,41.951956]},"n2939":{"id":"n2939","loc":[-85.61656,41.952044]},"n3348":{"id":"n3348","loc":[-85.61714,41.9522]},"n3349":{"id":"n3349","loc":[-85.616517,41.95212]},"n3350":{"id":"n3350","loc":[-85.616489,41.952033]},"n3351":{"id":"n3351","loc":[-85.616529,41.951907]},"n3354":{"id":"n3354","loc":[-85.616488,41.951994]}};
49237
49238 // Tooltips and svg mask used to highlight certain features
49239 function uiCurtain() {
49240
49241     var surface = d3_select(null),
49242         tooltip = d3_select(null),
49243         darkness = d3_select(null);
49244
49245     function curtain(selection) {
49246         surface = selection
49247             .append('svg')
49248             .attr('id', 'curtain')
49249             .style('z-index', 1000)
49250             .style('pointer-events', 'none')
49251             .style('position', 'absolute')
49252             .style('top', 0)
49253             .style('left', 0);
49254
49255         darkness = surface.append('path')
49256             .attr('x', 0)
49257             .attr('y', 0)
49258             .attr('class', 'curtain-darkness');
49259
49260         d3_select(window).on('resize.curtain', resize);
49261
49262         tooltip = selection.append('div')
49263             .attr('class', 'tooltip')
49264             .style('z-index', 1002);
49265
49266         tooltip
49267             .append('div')
49268             .attr('class', 'tooltip-arrow');
49269
49270         tooltip
49271             .append('div')
49272             .attr('class', 'tooltip-inner');
49273
49274         resize();
49275
49276
49277         function resize() {
49278             surface
49279                 .attr('width', window.innerWidth)
49280                 .attr('height', window.innerHeight);
49281             curtain.cut(darkness.datum());
49282         }
49283     }
49284
49285
49286     /**
49287      * Reveal cuts the curtain to highlight the given box,
49288      * and shows a tooltip with instructions next to the box.
49289      *
49290      * @param  {String|ClientRect} [box]   box used to cut the curtain
49291      * @param  {String}    [text]          text for a tooltip
49292      * @param  {Object}    [options]
49293      * @param  {string}    [options.tooltipClass]    optional class to add to the tooltip
49294      * @param  {integer}   [options.duration]        transition time in milliseconds
49295      * @param  {string}    [options.buttonText]      if set, create a button with this text label
49296      * @param  {function}  [options.buttonCallback]  if set, the callback for the button
49297      * @param  {String|ClientRect} [options.tooltipBox]  box for tooltip position, if different from box for the curtain
49298      */
49299     curtain.reveal = function(box, text, options) {
49300         if (typeof box === 'string') {
49301             box = d3_select(box).node();
49302         }
49303         if (box && box.getBoundingClientRect) {
49304             box = copyBox(box.getBoundingClientRect());
49305         }
49306
49307         options = options || {};
49308
49309         var tooltipBox;
49310         if (options.tooltipBox) {
49311             tooltipBox = options.tooltipBox;
49312             if (typeof tooltipBox === 'string') {
49313                 tooltipBox = d3_select(tooltipBox).node();
49314             }
49315             if (tooltipBox && tooltipBox.getBoundingClientRect) {
49316                 tooltipBox = copyBox(tooltipBox.getBoundingClientRect());
49317             }
49318         } else {
49319             tooltipBox = box;
49320         }
49321
49322         if (tooltipBox && text) {
49323             // pseudo markdown bold text for the instruction section..
49324             var parts = text.split('**');
49325             var html = parts[0] ? '<span>' + parts[0] + '</span>' : '';
49326             if (parts[1]) {
49327                 html += '<span class="instruction">' + parts[1] + '</span>';
49328             }
49329
49330             html = html.replace(/\*(.*?)\*/g, '<em>$1</em>');   // emphasis
49331             html = html.replace(/\{br\}/g, '<br/><br/>');       // linebreak
49332
49333             if (options.buttonText && options.buttonCallback) {
49334                 html += '<div class="button-section">' +
49335                     '<button href="#" class="button action col8">' + options.buttonText + '</button></div>';
49336             }
49337
49338             var classes = 'curtain-tooltip tooltip in ' + (options.tooltipClass || '');
49339             tooltip
49340                 .classed(classes, true)
49341                 .selectAll('.tooltip-inner')
49342                 .html(html);
49343
49344             if (options.buttonText && options.buttonCallback) {
49345                 var button = tooltip.selectAll('.button-section .button.action');
49346                 button
49347                     .on('click', function() {
49348                         event.preventDefault();
49349                         options.buttonCallback();
49350                     });
49351             }
49352
49353             var tip = copyBox(tooltip.node().getBoundingClientRect()),
49354                 w = window.innerWidth,
49355                 h = window.innerHeight,
49356                 tooltipWidth = 200,
49357                 tooltipArrow = 5,
49358                 side, pos;
49359
49360
49361             // hack: this will have bottom placement,
49362             // so need to reserve extra space for the tooltip illustration.
49363             if (options.tooltipClass === 'intro-mouse') {
49364                 tip.height += 80;
49365             }
49366
49367             // trim box dimensions to just the portion that fits in the window..
49368             if (tooltipBox.top + tooltipBox.height > h) {
49369                 tooltipBox.height -= (tooltipBox.top + tooltipBox.height - h);
49370             }
49371             if (tooltipBox.left + tooltipBox.width > w) {
49372                 tooltipBox.width -= (tooltipBox.left + tooltipBox.width - w);
49373             }
49374
49375             // determine tooltip placement..
49376
49377             if (tooltipBox.top + tooltipBox.height < 100) {
49378                 // tooltip below box..
49379                 side = 'bottom';
49380                 pos = [
49381                     tooltipBox.left + tooltipBox.width / 2 - tip.width / 2,
49382                     tooltipBox.top + tooltipBox.height
49383                 ];
49384
49385             } else if (tooltipBox.top > h - 140) {
49386                 // tooltip above box..
49387                 side = 'top';
49388                 pos = [
49389                     tooltipBox.left + tooltipBox.width / 2 - tip.width / 2,
49390                     tooltipBox.top - tip.height
49391                 ];
49392
49393             } else {
49394                 // tooltip to the side of the tooltipBox..
49395                 var tipY = tooltipBox.top + tooltipBox.height / 2 - tip.height / 2;
49396
49397                 if (textDirection === 'rtl') {
49398                     if (tooltipBox.left - tooltipWidth - tooltipArrow < 70) {
49399                         side = 'right';
49400                         pos = [tooltipBox.left + tooltipBox.width + tooltipArrow, tipY];
49401
49402                     } else {
49403                         side = 'left';
49404                         pos = [tooltipBox.left - tooltipWidth - tooltipArrow, tipY];
49405                     }
49406
49407                 } else {
49408                     if (tooltipBox.left + tooltipBox.width + tooltipArrow + tooltipWidth > w - 70) {
49409                         side = 'left';
49410                         pos = [tooltipBox.left - tooltipWidth - tooltipArrow, tipY];
49411                     }
49412                     else {
49413                         side = 'right';
49414                         pos = [tooltipBox.left + tooltipBox.width + tooltipArrow, tipY];
49415                     }
49416                 }
49417             }
49418
49419             if (options.duration !== 0 || !tooltip.classed(side)) {
49420                 tooltip.call(uiToggle(true));
49421             }
49422
49423             tooltip
49424                 .style('top', pos[1] + 'px')
49425                 .style('left', pos[0] + 'px')
49426                 .attr('class', classes + ' ' + side);
49427
49428
49429             // shift tooltip-inner if it is very close to the top or bottom edge
49430             // (doesn't affect the placement of the tooltip-arrow)
49431             var shiftY = 0;
49432             if (side === 'left' || side === 'right') {
49433                 if (pos[1] < 60) {
49434                     shiftY = 60 - pos[1];
49435                 }
49436                 else if (pos[1] + tip.height > h - 100) {
49437                     shiftY = h - pos[1] - tip.height - 100;
49438                 }
49439             }
49440             tooltip.selectAll('.tooltip-inner')
49441                 .style('top', shiftY + 'px');
49442
49443         } else {
49444             tooltip
49445                 .classed('in', false)
49446                 .call(uiToggle(false));
49447         }
49448
49449         curtain.cut(box, options.duration);
49450
49451         return tooltip;
49452     };
49453
49454
49455     curtain.cut = function(datum, duration) {
49456         darkness.datum(datum)
49457             .interrupt();
49458
49459         var selection;
49460         if (duration === 0) {
49461             selection = darkness;
49462         } else {
49463             selection = darkness
49464                 .transition()
49465                 .duration(duration || 600)
49466                 .ease(linear$1);
49467         }
49468
49469         selection
49470             .attr('d', function(d) {
49471                 var string = 'M 0,0 L 0,' + window.innerHeight + ' L ' +
49472                     window.innerWidth + ',' + window.innerHeight + 'L' +
49473                     window.innerWidth + ',0 Z';
49474
49475                 if (!d) return string;
49476                 return string + 'M' +
49477                     d.left + ',' + d.top + 'L' +
49478                     d.left + ',' + (d.top + d.height) + 'L' +
49479                     (d.left + d.width) + ',' + (d.top + d.height) + 'L' +
49480                     (d.left + d.width) + ',' + (d.top) + 'Z';
49481
49482             });
49483     };
49484
49485
49486     curtain.remove = function() {
49487         surface.remove();
49488         tooltip.remove();
49489         d3_select(window).on('resize.curtain', null);
49490     };
49491
49492
49493     // ClientRects are immutable, so copy them to an object,
49494     // in case we need to trim the height/width.
49495     function copyBox(src) {
49496         return {
49497             top: src.top,
49498             right: src.right,
49499             bottom: src.bottom,
49500             left: src.left,
49501             width: src.width,
49502             height: src.height
49503         };
49504     }
49505
49506
49507     return curtain;
49508 }
49509
49510 function uiIntroWelcome(context, reveal) {
49511     var dispatch$$1 = dispatch('done'),
49512         listener = clickListener();
49513
49514     var chapter = {
49515         title: 'intro.welcome.title'
49516     };
49517
49518
49519     function welcome() {
49520         context.map().centerZoom([-85.63591, 41.94285], 19);
49521         reveal('.intro-nav-wrap .chapter-welcome',
49522             t('intro.welcome.welcome'),
49523             { buttonText: t('intro.ok'), buttonCallback: practice }
49524         );
49525     }
49526
49527     function practice() {
49528         reveal('.intro-nav-wrap .chapter-welcome',
49529             t('intro.welcome.practice'),
49530             { buttonText: t('intro.ok'), buttonCallback: words }
49531         );
49532     }
49533
49534     function words() {
49535         reveal('.intro-nav-wrap .chapter-welcome',
49536             t('intro.welcome.words'),
49537             { buttonText: t('intro.ok'), buttonCallback: mouse }
49538         );
49539     }
49540
49541
49542     function mouse() {
49543         reveal('.intro-nav-wrap .chapter-welcome',
49544             t('intro.welcome.mouse'),
49545             { buttonText: t('intro.ok'), buttonCallback: leftClick }
49546         );
49547     }
49548
49549
49550     function leftClick() {
49551         var counter = 0,
49552             times = 5;
49553
49554         var tooltip = reveal('.intro-nav-wrap .chapter-welcome',
49555             t('intro.welcome.leftclick', { num: times }),
49556             { tooltipClass: 'intro-mouse' }
49557         );
49558
49559         tooltip.selectAll('.tooltip-inner')
49560             .insert('svg', 'span')
49561             .attr('class', 'tooltip-illustration')
49562             .append('use')
49563             .attr('xlink:href', '#walkthrough-mouse');
49564
49565         tooltip
49566             .append('div')
49567             .attr('class', 'counter');
49568
49569         tooltip.call(listener);
49570
49571         listener.on('click', function(which) {
49572             if (which === 'left') {
49573                 d3_select('.curtain-tooltip.intro-mouse .counter')
49574                     .text(String(++counter));
49575
49576                 if (counter === times) {
49577                     window.setTimeout(function() { continueTo(rightClick); }, 1000);
49578                 }
49579             }
49580         });
49581
49582         function continueTo(nextStep) {
49583             listener.on('click', null);
49584             tooltip.call(listener.off);
49585             tooltip.select('.counter').remove();
49586             nextStep();
49587         }
49588     }
49589
49590
49591     function rightClick() {
49592         var counter = 0,
49593             times = 5;
49594
49595         var tooltip = reveal('.intro-nav-wrap .chapter-welcome',
49596             t('intro.welcome.rightclick', { num: times }),
49597             { tooltipClass: 'intro-mouse' }
49598         );
49599
49600         tooltip.selectAll('.tooltip-inner')
49601             .insert('svg', 'span')
49602             .attr('class', 'tooltip-illustration')
49603             .append('use')
49604             .attr('xlink:href', '#walkthrough-mouse');
49605
49606         tooltip
49607             .append('div')
49608             .attr('class', 'counter');
49609
49610         tooltip.call(listener);
49611
49612         listener.on('click', function(which) {
49613             if (which === 'right') {
49614                 d3_select('.curtain-tooltip.intro-mouse .counter')
49615                     .text(String(++counter));
49616
49617                 if (counter === times) {
49618                     window.setTimeout(function() { continueTo(chapters); }, 1000);
49619                 }
49620             }
49621         });
49622
49623         function continueTo(nextStep) {
49624             listener.on('click', null);
49625             tooltip.call(listener.off);
49626             tooltip.select('.counter').remove();
49627             nextStep();
49628         }
49629     }
49630
49631
49632     function chapters() {
49633         dispatch$$1.call('done');
49634         reveal('.intro-nav-wrap .chapter-navigation',
49635             t('intro.welcome.chapters', { next: t('intro.navigation.title') })
49636         );
49637     }
49638
49639
49640     chapter.enter = function() {
49641         welcome();
49642     };
49643
49644
49645     chapter.exit = function() {
49646         listener.off();
49647         d3_select('.curtain-tooltip.intro-mouse')
49648             .selectAll('.counter')
49649             .remove();
49650     };
49651
49652
49653     chapter.restart = function() {
49654         chapter.exit();
49655         chapter.enter();
49656     };
49657
49658
49659     return utilRebind(chapter, dispatch$$1, 'on');
49660 }
49661
49662
49663
49664 function clickListener() {
49665     var dispatch$$1 = dispatch('click'),
49666         minTime = 120,
49667         tooltip = d3_select(null),
49668         down = {};
49669
49670     // `down` keeps track of which buttons/keys are down.
49671     // Setting a property in `down` happens immediately.
49672     // Unsetting a property in `down` is delayed because
49673     //   on Windows a contextmenu event happens after keyup/mouseup
49674
49675     function keydown() {
49676         if (event.keyCode === 93)  {   // context menu
49677             event.preventDefault();
49678             event.stopPropagation();
49679             down.menu = event.timeStamp;
49680             tooltip.classed('rightclick', true);
49681         }
49682     }
49683
49684
49685     function keyup() {
49686         if (event.keyCode === 93)  {   // context menu
49687             event.preventDefault();
49688             event.stopPropagation();
49689             var endTime = event.timeStamp,
49690                 startTime = down.menu || endTime,
49691                 delay = (endTime - startTime < minTime) ? minTime : 0;
49692
49693             window.setTimeout(function() {
49694                 tooltip.classed('rightclick', false);
49695                 down.menu = undefined;  // delayed, for Windows
49696             }, delay);
49697
49698             dispatch$$1.call('click', this, 'right');
49699         }
49700     }
49701
49702
49703     function mousedown() {
49704         var button = event.button;
49705         if (button === 0 && !event.ctrlKey) {
49706             tooltip.classed('leftclick', true);
49707         } else if (button === 2) {
49708             tooltip.classed('rightclick', true);
49709         }
49710         down[button] = event.timeStamp;
49711     }
49712
49713
49714     function mouseup() {
49715         var button = event.button,
49716             endTime = event.timeStamp,
49717             startTime = down[button] || endTime,
49718             delay = (endTime - startTime < minTime) ? minTime : 0;
49719
49720         if (button === 0 && !event.ctrlKey) {
49721             window.setTimeout(function() {
49722                 tooltip.classed('leftclick', false);
49723                 down[button] = undefined;  // delayed, for Windows
49724             }, delay);
49725
49726             dispatch$$1.call('click', this, 'left');
49727
49728         } else if (button === 2) {
49729             window.setTimeout(function() {
49730                 tooltip.classed('rightclick', false);
49731                 down[button] = undefined;  // delayed, for Windows
49732             }, delay);
49733
49734             dispatch$$1.call('click', this, 'right');
49735
49736         } else {
49737             window.setTimeout(function() {
49738                 down[button] = undefined;  // delayed, for Windows
49739             }, delay);
49740         }
49741     }
49742
49743
49744     function contextmenu() {
49745         event.preventDefault();
49746         event.stopPropagation();
49747         if (!down[2] && !down.menu) {
49748             tooltip.classed('rightclick', true);
49749             window.setTimeout(function() {
49750                 tooltip.classed('rightclick', false);
49751             }, minTime);
49752             dispatch$$1.call('click', this, 'right');
49753         }
49754     }
49755
49756
49757     var behavior = function(selection) {
49758         tooltip = selection;
49759         down = {};
49760
49761         d3_select(window)
49762             .on('keydown.intro', keydown)
49763             .on('keyup.intro', keyup)
49764             .on('mousedown.intro', mousedown)
49765             .on('mouseup.intro', mouseup)
49766             .on('contextmenu.intro', contextmenu);
49767     };
49768
49769
49770     behavior.off = function() {
49771         d3_select(window)
49772             .on('keydown.intro', null)
49773             .on('keyup.intro', null)
49774             .on('mousedown.intro', null)
49775             .on('mouseup.intro', null)
49776             .on('contextmenu.intro', null);
49777
49778         tooltip
49779             .classed('leftclick', false)
49780             .classed('rightclick', false);
49781     };
49782
49783     return utilRebind(behavior, dispatch$$1, 'on');
49784 }
49785
49786 function uiIntroNavigation(context, reveal) {
49787     var dispatch$$1 = dispatch('done'),
49788         timeouts = [],
49789         hallId = 'n2061',
49790         townHall = [-85.63591, 41.94285],
49791         springStreetId = 'w397',
49792         springStreetEndId = 'n1834',
49793         springStreet = [-85.63582, 41.94255],
49794         onewayField = context.presets().field('oneway'),
49795         maxspeedField = context.presets().field('maxspeed');
49796
49797
49798     var chapter = {
49799         title: 'intro.navigation.title'
49800     };
49801
49802
49803     function timeout(f, t$$1) {
49804         timeouts.push(window.setTimeout(f, t$$1));
49805     }
49806
49807
49808     function eventCancel() {
49809         event.stopPropagation();
49810         event.preventDefault();
49811     }
49812
49813
49814     function isTownHallSelected() {
49815         var ids = context.selectedIDs();
49816         return ids.length === 1 && ids[0] === hallId;
49817     }
49818
49819
49820     function dragMap() {
49821         context.enter(modeBrowse(context));
49822         context.history().reset('initial');
49823
49824         var msec = transitionTime(townHall, context.map().center());
49825         if (msec) { reveal(null, null, { duration: 0 }); }
49826         context.map().zoom(19).centerEase(townHall, msec);
49827
49828         timeout(function() {
49829             var centerStart = context.map().center();
49830
49831             reveal('#surface', t('intro.navigation.drag'));
49832             context.map().on('drawn.intro', function() {
49833                 reveal('#surface', t('intro.navigation.drag'), { duration: 0 });
49834             });
49835
49836             context.map().on('move.intro', function() {
49837                 var centerNow = context.map().center();
49838                 if (centerStart[0] !== centerNow[0] || centerStart[1] !== centerNow[1]) {
49839                     context.map().on('move.intro', null);
49840                     timeout(function() { continueTo(zoomMap); }, 3000);
49841                 }
49842             });
49843
49844         }, msec + 100);
49845
49846         function continueTo(nextStep) {
49847             context.map().on('move.intro drawn.intro', null);
49848             nextStep();
49849         }
49850     }
49851
49852
49853     function zoomMap() {
49854         var zoomStart = context.map().zoom();
49855
49856         reveal('#surface',
49857             t('intro.navigation.zoom', {
49858                 plus: icon('#icon-plus', 'pre-text'),
49859                 minus: icon('#icon-minus', 'pre-text')
49860             })
49861         );
49862
49863         context.map().on('drawn.intro', function() {
49864             reveal('#surface',
49865                 t('intro.navigation.zoom', {
49866                     plus: icon('#icon-plus', 'pre-text'),
49867                     minus: icon('#icon-minus', 'pre-text')
49868                 }), { duration: 0 }
49869             );
49870         });
49871
49872         context.map().on('move.intro', function() {
49873             if (context.map().zoom() !== zoomStart) {
49874                 context.map().on('move.intro', null);
49875                 timeout(function() { continueTo(features); }, 3000);
49876             }
49877         });
49878
49879         function continueTo(nextStep) {
49880             context.map().on('move.intro drawn.intro', null);
49881             nextStep();
49882         }
49883     }
49884
49885
49886     function features() {
49887         var onClick = function() { continueTo(pointsLinesAreas); };
49888
49889         reveal('#surface', t('intro.navigation.features'),
49890             { buttonText: t('intro.ok'), buttonCallback: onClick }
49891         );
49892
49893         context.map().on('drawn.intro', function() {
49894             reveal('#surface', t('intro.navigation.features'),
49895                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
49896             );
49897         });
49898
49899         function continueTo(nextStep) {
49900             context.map().on('drawn.intro', null);
49901             nextStep();
49902         }
49903     }
49904
49905     function pointsLinesAreas() {
49906         var onClick = function() { continueTo(nodesWays); };
49907
49908         reveal('#surface', t('intro.navigation.points_lines_areas'),
49909             { buttonText: t('intro.ok'), buttonCallback: onClick }
49910         );
49911
49912         context.map().on('drawn.intro', function() {
49913             reveal('#surface', t('intro.navigation.points_lines_areas'),
49914                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
49915             );
49916         });
49917
49918         function continueTo(nextStep) {
49919             context.map().on('drawn.intro', null);
49920             nextStep();
49921         }
49922     }
49923
49924     function nodesWays() {
49925         var onClick = function() { continueTo(clickTownHall); };
49926
49927         reveal('#surface', t('intro.navigation.nodes_ways'),
49928             { buttonText: t('intro.ok'), buttonCallback: onClick }
49929         );
49930
49931         context.map().on('drawn.intro', function() {
49932             reveal('#surface', t('intro.navigation.nodes_ways'),
49933                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
49934             );
49935         });
49936
49937         function continueTo(nextStep) {
49938             context.map().on('drawn.intro', null);
49939             nextStep();
49940         }
49941     }
49942
49943     function clickTownHall() {
49944         context.enter(modeBrowse(context));
49945         context.history().reset('initial');
49946
49947         reveal(null, null, { duration: 0 });
49948         context.map().zoomEase(19, 500);
49949
49950         timeout(function() {
49951             var entity = context.hasEntity(hallId);
49952             if (!entity) return;
49953             context.map().centerEase(entity.loc, 500);
49954
49955             timeout(function() {
49956                 var entity = context.hasEntity(hallId);
49957                 if (!entity) return;
49958                 var box = pointBox(entity.loc, context);
49959                 reveal(box, t('intro.navigation.click_townhall'));
49960
49961                 context.map().on('move.intro drawn.intro', function() {
49962                     var entity = context.hasEntity(hallId);
49963                     if (!entity) return;
49964                     var box = pointBox(entity.loc, context);
49965                     reveal(box, t('intro.navigation.click_townhall'), { duration: 0 });
49966                 });
49967
49968                 context.on('enter.intro', function() {
49969                     if (isTownHallSelected()) continueTo(selectedTownHall);
49970                 });
49971
49972             }, 550);  // after centerEase
49973
49974         }, 550); // after zoomEase
49975
49976         context.history().on('change.intro', function() {
49977             if (!context.hasEntity(hallId)) {
49978                 continueTo(clickTownHall);
49979             }
49980         });
49981
49982         function continueTo(nextStep) {
49983             context.on('enter.intro', null);
49984             context.map().on('move.intro drawn.intro', null);
49985             context.history().on('change.intro', null);
49986             nextStep();
49987         }
49988     }
49989
49990
49991     function selectedTownHall() {
49992         if (!isTownHallSelected()) return clickTownHall();
49993
49994         var entity = context.hasEntity(hallId);
49995         if (!entity) return clickTownHall();
49996
49997         var box = pointBox(entity.loc, context);
49998         var onClick = function() { continueTo(editorTownHall); };
49999
50000         reveal(box, t('intro.navigation.selected_townhall'),
50001             { buttonText: t('intro.ok'), buttonCallback: onClick }
50002         );
50003
50004         context.map().on('move.intro drawn.intro', function() {
50005             var entity = context.hasEntity(hallId);
50006             if (!entity) return;
50007             var box = pointBox(entity.loc, context);
50008             reveal(box, t('intro.navigation.selected_townhall'),
50009                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
50010             );
50011         });
50012
50013         context.history().on('change.intro', function() {
50014             if (!context.hasEntity(hallId)) {
50015                 continueTo(clickTownHall);
50016             }
50017         });
50018
50019         function continueTo(nextStep) {
50020             context.map().on('move.intro drawn.intro', null);
50021             context.history().on('change.intro', null);
50022             nextStep();
50023         }
50024     }
50025
50026
50027     function editorTownHall() {
50028         if (!isTownHallSelected()) return clickTownHall();
50029
50030         // disallow scrolling
50031         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
50032
50033         var onClick = function() { continueTo(presetTownHall); };
50034
50035         reveal('.entity-editor-pane',
50036             t('intro.navigation.editor_townhall'),
50037             { buttonText: t('intro.ok'), buttonCallback: onClick }
50038         );
50039
50040         context.on('exit.intro', function() {
50041             continueTo(clickTownHall);
50042         });
50043
50044         context.history().on('change.intro', function() {
50045             if (!context.hasEntity(hallId)) {
50046                 continueTo(clickTownHall);
50047             }
50048         });
50049
50050         function continueTo(nextStep) {
50051             context.on('exit.intro', null);
50052             context.history().on('change.intro', null);
50053             d3_select('.inspector-wrap').on('wheel.intro', null);
50054             nextStep();
50055         }
50056     }
50057
50058
50059     function presetTownHall() {
50060         if (!isTownHallSelected()) return clickTownHall();
50061
50062         // reset pane, in case user happened to change it..
50063         d3_select('.inspector-wrap .panewrap').style('right', '0%');
50064         // disallow scrolling
50065         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
50066
50067         // preset match, in case the user happened to change it.
50068         var entity = context.entity(context.selectedIDs()[0]);
50069         var preset = context.presets().match(entity, context.graph());
50070
50071         var onClick = function() { continueTo(fieldsTownHall); };
50072
50073         context.on('exit.intro', function() {
50074             continueTo(clickTownHall);
50075         });
50076
50077         context.history().on('change.intro', function() {
50078             if (!context.hasEntity(hallId)) {
50079                 continueTo(clickTownHall);
50080             }
50081         });
50082
50083         reveal('.inspector-body .preset-list-item.inspector-inner',
50084             t('intro.navigation.preset_townhall', { preset: preset.name() }),
50085             { buttonText: t('intro.ok'), buttonCallback: onClick }
50086         );
50087
50088         function continueTo(nextStep) {
50089             context.on('exit.intro', null);
50090             context.history().on('change.intro', null);
50091             d3_select('.inspector-wrap').on('wheel.intro', null);
50092             nextStep();
50093         }
50094     }
50095
50096
50097     function fieldsTownHall() {
50098         if (!isTownHallSelected()) return clickTownHall();
50099
50100         // reset pane, in case user happened to change it..
50101         d3_select('.inspector-wrap .panewrap').style('right', '0%');
50102         // disallow scrolling
50103         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
50104
50105         var onClick = function() { continueTo(closeTownHall); };
50106
50107         reveal('.inspector-body .preset-editor',
50108             t('intro.navigation.fields_townhall'),
50109             { buttonText: t('intro.ok'), buttonCallback: onClick }
50110         );
50111
50112         context.on('exit.intro', function() {
50113             continueTo(clickTownHall);
50114         });
50115
50116         context.history().on('change.intro', function() {
50117             if (!context.hasEntity(hallId)) {
50118                 continueTo(clickTownHall);
50119             }
50120         });
50121
50122         function continueTo(nextStep) {
50123             context.on('exit.intro', null);
50124             context.history().on('change.intro', null);
50125             d3_select('.inspector-wrap').on('wheel.intro', null);
50126             nextStep();
50127         }
50128     }
50129
50130
50131     function closeTownHall() {
50132         if (!isTownHallSelected()) return clickTownHall();
50133
50134         var selector = '.entity-editor-pane button.preset-close svg use';
50135         var href = d3_select(selector).attr('href') || '#icon-close';
50136
50137         reveal('.entity-editor-pane',
50138             t('intro.navigation.close_townhall', { button: icon(href, 'pre-text') })
50139         );
50140
50141         context.on('exit.intro', function() {
50142             continueTo(searchStreet);
50143         });
50144
50145         context.history().on('change.intro', function() {
50146             // update the close icon in the tooltip if the user edits something.
50147             var selector = '.entity-editor-pane button.preset-close svg use';
50148             var href = d3_select(selector).attr('href') || '#icon-close';
50149
50150             reveal('.entity-editor-pane',
50151                 t('intro.navigation.close_townhall', { button: icon(href, 'pre-text') }),
50152                 { duration: 0 }
50153             );
50154         });
50155
50156         function continueTo(nextStep) {
50157             context.on('exit.intro', null);
50158             context.history().on('change.intro', null);
50159             nextStep();
50160         }
50161     }
50162
50163
50164     function searchStreet() {
50165         context.enter(modeBrowse(context));
50166         context.history().reset('initial');  // ensure spring street exists
50167
50168         var msec = transitionTime(springStreet, context.map().center());
50169         if (msec) { reveal(null, null, { duration: 0 }); }
50170         context.map().zoom(19).centerEase(springStreet, msec);  // ..and user can see it
50171
50172         timeout(function() {
50173             reveal('.search-header input',
50174                 t('intro.navigation.search_street', { name: t('intro.graph.name.spring-street') })
50175             );
50176
50177             d3_select('.search-header input')
50178                 .on('keyup.intro', checkSearchResult);
50179         }, msec + 100);
50180     }
50181
50182
50183     function checkSearchResult() {
50184         var first = d3_select('.feature-list-item:nth-child(0n+2)'),  // skip "No Results" item
50185             firstName = first.select('.entity-name'),
50186             name = t('intro.graph.name.spring-street');
50187
50188         if (!firstName.empty() && firstName.text() === name) {
50189             reveal(first.node(),
50190                 t('intro.navigation.choose_street', { name: name }),
50191                 { duration: 300 }
50192             );
50193
50194             context.on('exit.intro', function() {
50195                 continueTo(selectedStreet);
50196             });
50197
50198             d3_select('.search-header input')
50199                 .on('keydown.intro', eventCancel, true)
50200                 .on('keyup.intro', null);
50201         }
50202
50203         function continueTo(nextStep) {
50204             context.on('exit.intro', null);
50205             d3_select('.search-header input')
50206                 .on('keydown.intro', null)
50207                 .on('keyup.intro', null);
50208             nextStep();
50209         }
50210     }
50211
50212
50213     function selectedStreet() {
50214         if (!context.hasEntity(springStreetEndId) || !context.hasEntity(springStreetId)) {
50215             return searchStreet();
50216         }
50217
50218         var onClick = function() { continueTo(editorStreet); };
50219         var entity = context.entity(springStreetEndId);
50220         var box = pointBox(entity.loc, context);
50221         box.height = 500;
50222
50223         reveal(box,
50224             t('intro.navigation.selected_street', { name: t('intro.graph.name.spring-street') }),
50225             { duration: 600, buttonText: t('intro.ok'), buttonCallback: onClick }
50226         );
50227
50228         timeout(function() {
50229             context.map().on('move.intro drawn.intro', function() {
50230                 var entity = context.hasEntity(springStreetEndId);
50231                 if (!entity) return;
50232                 var box = pointBox(entity.loc, context);
50233                 box.height = 500;
50234                 reveal(box,
50235                     t('intro.navigation.selected_street', { name: t('intro.graph.name.spring-street') }),
50236                     { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
50237                 );
50238             });
50239         }, 600);  // after reveal.
50240
50241         context.on('enter.intro', function(mode) {
50242             if (!context.hasEntity(springStreetId)) {
50243                 return continueTo(searchStreet);
50244             }
50245             var ids = context.selectedIDs();
50246             if (mode.id !== 'select' || !ids.length || ids[0] !== springStreetId) {
50247                 // keep Spring Street selected..
50248                 context.enter(modeSelect(context, [springStreetId]));
50249             }
50250         });
50251
50252         context.history().on('change.intro', function() {
50253             if (!context.hasEntity(springStreetEndId) || !context.hasEntity(springStreetId)) {
50254                 timeout(function() {
50255                     continueTo(searchStreet);
50256                 }, 300);  // after any transition (e.g. if user deleted intersection)
50257             }
50258         });
50259
50260         function continueTo(nextStep) {
50261             context.map().on('move.intro drawn.intro', null);
50262             context.on('enter.intro', null);
50263             context.history().on('change.intro', null);
50264             nextStep();
50265         }
50266     }
50267
50268
50269     function editorStreet() {
50270         var selector = '.entity-editor-pane button.preset-close svg use';
50271         var href = d3_select(selector).attr('href') || '#icon-close';
50272
50273         reveal('.entity-editor-pane',
50274             t('intro.navigation.editor_street', {
50275                 button: icon(href, 'pre-text'),
50276                 field1: onewayField.label(),
50277                 field2: maxspeedField.label()
50278             })
50279         );
50280
50281         context.on('exit.intro', function() {
50282             continueTo(play);
50283         });
50284
50285         context.history().on('change.intro', function() {
50286             // update the close icon in the tooltip if the user edits something.
50287             var selector = '.entity-editor-pane button.preset-close svg use';
50288             var href = d3_select(selector).attr('href') || '#icon-close';
50289
50290             reveal('.entity-editor-pane',
50291                 t('intro.navigation.editor_street', {
50292                     button: icon(href, 'pre-text'),
50293                     field1: onewayField.label().toLowerCase(),
50294                     field2: maxspeedField.label().toLowerCase()
50295                 }), { duration: 0 }
50296             );
50297         });
50298
50299         function continueTo(nextStep) {
50300             context.on('exit.intro', null);
50301             context.history().on('change.intro', null);
50302             nextStep();
50303         }
50304     }
50305
50306
50307     function play() {
50308         dispatch$$1.call('done');
50309         reveal('#id-container',
50310             t('intro.navigation.play', { next: t('intro.points.title') }), {
50311                 tooltipBox: '.intro-nav-wrap .chapter-point',
50312                 buttonText: t('intro.ok'),
50313                 buttonCallback: function() { reveal('#id-container'); }
50314             }
50315         );
50316     }
50317
50318
50319     chapter.enter = function() {
50320         dragMap();
50321     };
50322
50323
50324     chapter.exit = function() {
50325         timeouts.forEach(window.clearTimeout);
50326         context.on('enter.intro exit.intro', null);
50327         context.map().on('move.intro drawn.intro', null);
50328         context.history().on('change.intro', null);
50329         d3_select('.inspector-wrap').on('wheel.intro', null);
50330         d3_select('.search-header input').on('keydown.intro keyup.intro', null);
50331     };
50332
50333
50334     chapter.restart = function() {
50335         chapter.exit();
50336         chapter.enter();
50337     };
50338
50339
50340     return utilRebind(chapter, dispatch$$1, 'on');
50341 }
50342
50343 function uiIntroPoint(context, reveal) {
50344     var dispatch$$1 = dispatch('done'),
50345         timeouts = [],
50346         intersection = [-85.63279, 41.94394],
50347         building = [-85.632422, 41.944045],
50348         cafePreset = context.presets().item('amenity/cafe'),
50349         pointId = null;
50350
50351
50352     var chapter = {
50353         title: 'intro.points.title'
50354     };
50355
50356
50357     function timeout(f, t$$1) {
50358         timeouts.push(window.setTimeout(f, t$$1));
50359     }
50360
50361
50362     function revealEditMenu(loc, text, options) {
50363         var rect = context.surfaceRect();
50364         var point = context.curtainProjection(loc);
50365         var pad = 40;
50366         var width = 250 + (2 * pad);
50367         var height = 250;
50368         var startX = rect.left + point[0];
50369         var left = (textDirection === 'rtl') ? (startX - width + pad) : (startX - pad);
50370         var box = {
50371             left: left,
50372             top: point[1] + rect.top - 60,
50373             width: width,
50374             height: height
50375         };
50376         reveal(box, text, options);
50377     }
50378
50379
50380     function eventCancel() {
50381         event.stopPropagation();
50382         event.preventDefault();
50383     }
50384
50385
50386     function addPoint() {
50387         context.enter(modeBrowse(context));
50388         context.history().reset('initial');
50389
50390         var msec = transitionTime(intersection, context.map().center());
50391         if (msec) { reveal(null, null, { duration: 0 }); }
50392         context.map().zoom(19).centerEase(intersection, msec);
50393
50394         timeout(function() {
50395             var tooltip = reveal('button.add-point',
50396                 t('intro.points.add_point', { button: icon('#icon-point', 'pre-text') }));
50397
50398             pointId = null;
50399
50400             tooltip.selectAll('.tooltip-inner')
50401                 .insert('svg', 'span')
50402                 .attr('class', 'tooltip-illustration')
50403                 .append('use')
50404                 .attr('xlink:href', '#poi-images');
50405
50406             context.on('enter.intro', function(mode) {
50407                 if (mode.id !== 'add-point') return;
50408                 continueTo(placePoint);
50409             });
50410         }, msec + 100);
50411
50412         function continueTo(nextStep) {
50413             context.on('enter.intro', null);
50414             nextStep();
50415         }
50416     }
50417
50418
50419     function placePoint() {
50420         if (context.mode().id !== 'add-point') {
50421             return chapter.restart();
50422         }
50423
50424         var pointBox$$1 = pad$1(building, 150, context);
50425         reveal(pointBox$$1, t('intro.points.place_point'));
50426
50427         context.map().on('move.intro drawn.intro', function() {
50428             pointBox$$1 = pad$1(building, 150, context);
50429             reveal(pointBox$$1, t('intro.points.place_point'), { duration: 0 });
50430         });
50431
50432         context.on('enter.intro', function(mode) {
50433             if (mode.id !== 'select') return chapter.restart();
50434             pointId = context.mode().selectedIDs()[0];
50435             continueTo(searchPreset);
50436         });
50437
50438         function continueTo(nextStep) {
50439             context.map().on('move.intro drawn.intro', null);
50440             context.on('enter.intro', null);
50441             nextStep();
50442         }
50443     }
50444
50445
50446     function searchPreset() {
50447         if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
50448             return addPoint();
50449         }
50450
50451         // disallow scrolling
50452         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
50453
50454         d3_select('.preset-search-input')
50455             .on('keydown.intro', null)
50456             .on('keyup.intro', checkPresetSearch);
50457
50458         reveal('.preset-search-input',
50459             t('intro.points.search_cafe', { preset: cafePreset.name() })
50460         );
50461
50462         context.on('enter.intro', function(mode) {
50463             if (!pointId || !context.hasEntity(pointId)) {
50464                 return continueTo(addPoint);
50465             }
50466
50467             var ids = context.selectedIDs();
50468             if (mode.id !== 'select' || !ids.length || ids[0] !== pointId) {
50469                 // keep the user's point selected..
50470                 context.enter(modeSelect(context, [pointId]));
50471
50472                 // disallow scrolling
50473                 d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
50474
50475                 d3_select('.preset-search-input')
50476                     .on('keydown.intro', null)
50477                     .on('keyup.intro', checkPresetSearch);
50478
50479                 reveal('.preset-search-input',
50480                     t('intro.points.search_cafe', { preset: cafePreset.name() })
50481                 );
50482
50483                 context.history().on('change.intro', null);
50484             }
50485         });
50486
50487
50488         function checkPresetSearch() {
50489             var first = d3_select('.preset-list-item:first-child');
50490
50491             if (first.classed('preset-amenity-cafe')) {
50492                 d3_select('.preset-search-input')
50493                     .on('keydown.intro', eventCancel, true)
50494                     .on('keyup.intro', null);
50495
50496                 reveal(first.select('.preset-list-button').node(),
50497                     t('intro.points.choose_cafe', { preset: cafePreset.name() }),
50498                     { duration: 300 }
50499                 );
50500
50501                 context.history().on('change.intro', function() {
50502                     continueTo(aboutFeatureEditor);
50503                 });
50504             }
50505         }
50506
50507         function continueTo(nextStep) {
50508             context.on('enter.intro', null);
50509             context.history().on('change.intro', null);
50510             d3_select('.inspector-wrap').on('wheel.intro', null);
50511             d3_select('.preset-search-input').on('keydown.intro keyup.intro', null);
50512             nextStep();
50513         }
50514     }
50515
50516
50517     function aboutFeatureEditor() {
50518         if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
50519             return addPoint();
50520         }
50521
50522         timeout(function() {
50523             reveal('.entity-editor-pane', t('intro.points.feature_editor'), {
50524                 tooltipClass: 'intro-points-describe',
50525                 buttonText: t('intro.ok'),
50526                 buttonCallback: function() { continueTo(addName); }
50527             });
50528         }, 400);
50529
50530         context.on('exit.intro', function() {
50531             // if user leaves select mode here, just continue with the tutorial.
50532             continueTo(reselectPoint);
50533         });
50534
50535         function continueTo(nextStep) {
50536             context.on('exit.intro', null);
50537             nextStep();
50538         }
50539     }
50540
50541
50542     function addName() {
50543         if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
50544             return addPoint();
50545         }
50546
50547         // reset pane, in case user happened to change it..
50548         d3_select('.inspector-wrap .panewrap').style('right', '0%');
50549
50550         timeout(function() {
50551             // It's possible for the user to add a name in a previous step..
50552             // If so, don't tell them to add the name in this step.
50553             // Give them an OK button instead.
50554             var entity = context.entity(pointId);
50555             if (entity.tags.name) {
50556                 var tooltip = reveal('.entity-editor-pane', t('intro.points.add_name'), {
50557                     tooltipClass: 'intro-points-describe',
50558                     buttonText: t('intro.ok'),
50559                     buttonCallback: function() { continueTo(addCloseEditor); }
50560                 });
50561                 tooltip.select('.instruction').style('display', 'none');
50562
50563             } else {
50564                 reveal('.entity-editor-pane', t('intro.points.add_name'),
50565                     { tooltipClass: 'intro-points-describe' }
50566                 );
50567             }
50568         }, 400);
50569
50570         context.history().on('change.intro', function() {
50571             continueTo(addCloseEditor);
50572         });
50573
50574         context.on('exit.intro', function() {
50575             // if user leaves select mode here, just continue with the tutorial.
50576             continueTo(reselectPoint);
50577         });
50578
50579         function continueTo(nextStep) {
50580             context.on('exit.intro', null);
50581             context.history().on('change.intro', null);
50582             nextStep();
50583         }
50584     }
50585
50586
50587     function addCloseEditor() {
50588         // reset pane, in case user happened to change it..
50589         d3_select('.inspector-wrap .panewrap').style('right', '0%');
50590
50591         var selector = '.entity-editor-pane button.preset-close svg use';
50592         var href = d3_select(selector).attr('href') || '#icon-close';
50593
50594         context.on('exit.intro', function() {
50595             continueTo(reselectPoint);
50596         });
50597
50598         reveal('.entity-editor-pane',
50599             t('intro.points.add_close', { button: icon(href, 'pre-text') })
50600         );
50601
50602         function continueTo(nextStep) {
50603             context.on('exit.intro', null);
50604             nextStep();
50605         }
50606     }
50607
50608
50609     function reselectPoint() {
50610         if (!pointId) return chapter.restart();
50611         var entity = context.hasEntity(pointId);
50612         if (!entity) return chapter.restart();
50613
50614         // make sure it's still a cafe, in case user somehow changed it..
50615         var oldPreset = context.presets().match(entity, context.graph());
50616         context.replace(actionChangePreset(pointId, oldPreset, cafePreset));
50617
50618         context.enter(modeBrowse(context));
50619
50620         var msec = transitionTime(entity.loc, context.map().center());
50621         if (msec) { reveal(null, null, { duration: 0 }); }
50622         context.map().centerEase(entity.loc, msec);
50623
50624         timeout(function() {
50625             var box = pointBox(entity.loc, context);
50626             reveal(box, t('intro.points.reselect'), { duration: 600 });
50627
50628             timeout(function() {
50629                 context.map().on('move.intro drawn.intro', function() {
50630                     var entity = context.hasEntity(pointId);
50631                     if (!entity) return chapter.restart();
50632                     var box = pointBox(entity.loc, context);
50633                     reveal(box, t('intro.points.reselect'), { duration: 0 });
50634                 });
50635             }, 600); // after reveal..
50636
50637             context.on('enter.intro', function(mode) {
50638                 if (mode.id !== 'select') return;
50639                 continueTo(updatePoint);
50640             });
50641
50642         }, msec + 100);
50643
50644         function continueTo(nextStep) {
50645             context.map().on('move.intro drawn.intro', null);
50646             context.on('enter.intro', null);
50647             nextStep();
50648         }
50649     }
50650
50651
50652     function updatePoint() {
50653         if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
50654             return continueTo(reselectPoint);
50655         }
50656
50657         // reset pane, in case user happened to untag the point..
50658         d3_select('.inspector-wrap .panewrap').style('right', '0%');
50659
50660         context.on('exit.intro', function() {
50661             continueTo(reselectPoint);
50662         });
50663
50664         context.history().on('change.intro', function() {
50665             continueTo(updateCloseEditor);
50666         });
50667
50668         timeout(function() {
50669             reveal('.entity-editor-pane', t('intro.points.update'),
50670                 { tooltipClass: 'intro-points-describe' }
50671             );
50672         }, 400);
50673
50674         function continueTo(nextStep) {
50675             context.on('exit.intro', null);
50676             context.history().on('change.intro', null);
50677             nextStep();
50678         }
50679     }
50680
50681
50682     function updateCloseEditor() {
50683         if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
50684             return continueTo(reselectPoint);
50685         }
50686
50687         // reset pane, in case user happened to change it..
50688         d3_select('.inspector-wrap .panewrap').style('right', '0%');
50689
50690         context.on('exit.intro', function() {
50691             continueTo(rightClickPoint);
50692         });
50693
50694         timeout(function() {
50695             reveal('.entity-editor-pane',
50696                 t('intro.points.update_close', { button: icon('#icon-apply', 'pre-text') })
50697             );
50698         }, 500);
50699
50700         function continueTo(nextStep) {
50701             context.on('exit.intro', null);
50702             nextStep();
50703         }
50704     }
50705
50706
50707     function rightClickPoint() {
50708         if (!pointId) return chapter.restart();
50709         var entity = context.hasEntity(pointId);
50710         if (!entity) return chapter.restart();
50711
50712         context.enter(modeBrowse(context));
50713
50714         var box = pointBox(entity.loc, context);
50715         reveal(box, t('intro.points.rightclick'), { duration: 600 });
50716
50717         timeout(function() {
50718             context.map().on('move.intro drawn.intro', function() {
50719                 var entity = context.hasEntity(pointId);
50720                 if (!entity) return chapter.restart();
50721                 var box = pointBox(entity.loc, context);
50722                 reveal(box, t('intro.points.rightclick'), { duration: 0 });
50723             });
50724         }, 600); // after reveal
50725
50726         context.on('enter.intro', function(mode) {
50727             if (mode.id !== 'select') return;
50728             var ids = context.selectedIDs();
50729             if (ids.length !== 1 || ids[0] !== pointId) return;
50730
50731             timeout(function() {
50732                 var node = selectMenuItem('delete').node();
50733                 if (!node) return;
50734                 continueTo(enterDelete);
50735             }, 300);  // after menu visible
50736         });
50737
50738         function continueTo(nextStep) {
50739             context.on('enter.intro', null);
50740             context.map().on('move.intro drawn.intro', null);
50741             nextStep();
50742         }
50743     }
50744
50745
50746     function enterDelete() {
50747         if (!pointId) return chapter.restart();
50748         var entity = context.hasEntity(pointId);
50749         if (!entity) return chapter.restart();
50750
50751         var node = selectMenuItem('delete').node();
50752         if (!node) { return continueTo(rightClickPoint); }
50753
50754         revealEditMenu(entity.loc,
50755             t('intro.points.delete', { button: icon('#operation-delete', 'pre-text') })
50756         );
50757
50758         timeout(function() {
50759             context.map().on('move.intro drawn.intro', function() {
50760                 revealEditMenu(entity.loc,
50761                     t('intro.points.delete', { button: icon('#operation-delete', 'pre-text') }),
50762                     { duration: 0}
50763                 );
50764             });
50765         }, 300); // after menu visible
50766
50767         context.on('exit.intro', function() {
50768             if (!pointId) return chapter.restart();
50769             var entity = context.hasEntity(pointId);
50770             if (entity) return continueTo(rightClickPoint);  // point still exists
50771         });
50772
50773         context.history().on('change.intro', function(changed) {
50774             if (changed.deleted().length) {
50775                 continueTo(undo);
50776             }
50777         });
50778
50779         function continueTo(nextStep) {
50780             context.map().on('move.intro drawn.intro', null);
50781             context.history().on('change.intro', null);
50782             context.on('exit.intro', null);
50783             nextStep();
50784         }
50785     }
50786
50787
50788     function undo() {
50789         context.history().on('change.intro', function() {
50790             continueTo(play);
50791         });
50792
50793         var iconName = '#icon-' + (textDirection === 'rtl' ? 'redo' : 'undo');
50794         reveal('#bar button.undo-button',
50795             t('intro.points.undo', { button: icon(iconName, 'pre-text') })
50796         );
50797
50798         function continueTo(nextStep) {
50799             context.history().on('change.intro', null);
50800             nextStep();
50801         }
50802     }
50803
50804
50805     function play() {
50806         dispatch$$1.call('done');
50807         reveal('#id-container',
50808             t('intro.points.play', { next: t('intro.areas.title') }), {
50809                 tooltipBox: '.intro-nav-wrap .chapter-area',
50810                 buttonText: t('intro.ok'),
50811                 buttonCallback: function() { reveal('#id-container'); }
50812             }
50813         );
50814     }
50815
50816
50817     chapter.enter = function() {
50818         addPoint();
50819     };
50820
50821
50822     chapter.exit = function() {
50823         timeouts.forEach(window.clearTimeout);
50824         context.on('enter.intro exit.intro', null);
50825         context.map().on('move.intro drawn.intro', null);
50826         context.history().on('change.intro', null);
50827         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
50828         d3_select('.preset-search-input').on('keydown.intro keyup.intro', null);
50829     };
50830
50831
50832     chapter.restart = function() {
50833         chapter.exit();
50834         chapter.enter();
50835     };
50836
50837
50838     return utilRebind(chapter, dispatch$$1, 'on');
50839 }
50840
50841 function uiIntroArea(context, reveal) {
50842     var dispatch$$1 = dispatch('done'),
50843         playground = [-85.63552, 41.94159],
50844         playgroundPreset = context.presets().item('leisure/playground'),
50845         descriptionField = context.presets().field('description'),
50846         timeouts = [],
50847         areaId;
50848
50849
50850     var chapter = {
50851         title: 'intro.areas.title'
50852     };
50853
50854
50855     function timeout(f, t$$1) {
50856         timeouts.push(window.setTimeout(f, t$$1));
50857     }
50858
50859
50860     function eventCancel() {
50861         event.stopPropagation();
50862         event.preventDefault();
50863     }
50864
50865
50866     function revealPlayground(center, text, options) {
50867         var padding = 180 * Math.pow(2, context.map().zoom() - 19.5);
50868         var box = pad$1(center, padding, context);
50869         reveal(box, text, options);
50870     }
50871
50872
50873     function addArea() {
50874         context.enter(modeBrowse(context));
50875         context.history().reset('initial');
50876         areaId = null;
50877
50878         var msec = transitionTime(playground, context.map().center());
50879         if (msec) { reveal(null, null, { duration: 0 }); }
50880         context.map().zoom(19).centerEase(playground, msec);
50881
50882         timeout(function() {
50883             var tooltip = reveal('button.add-area',
50884                 t('intro.areas.add_playground', { button: icon('#icon-area', 'pre-text') }));
50885
50886             tooltip.selectAll('.tooltip-inner')
50887                 .insert('svg', 'span')
50888                 .attr('class', 'tooltip-illustration')
50889                 .append('use')
50890                 .attr('xlink:href', '#landuse-images');
50891
50892             context.on('enter.intro', function(mode) {
50893                 if (mode.id !== 'add-area') return;
50894                 continueTo(startPlayground);
50895             });
50896         }, msec + 100);
50897
50898         function continueTo(nextStep) {
50899             context.on('enter.intro', null);
50900             nextStep();
50901         }
50902     }
50903
50904
50905     function startPlayground() {
50906         if (context.mode().id !== 'add-area') {
50907             return chapter.restart();
50908         }
50909
50910         areaId = null;
50911         context.map().zoomEase(19.5, 500);
50912
50913         timeout(function() {
50914             revealPlayground(playground,
50915                 t('intro.areas.start_playground'), { duration: 250 }
50916             );
50917
50918             timeout(function() {
50919                 context.map().on('move.intro drawn.intro', function() {
50920                     revealPlayground(playground,
50921                         t('intro.areas.start_playground'), { duration: 0 }
50922                     );
50923                 });
50924                 context.on('enter.intro', function(mode) {
50925                     if (mode.id !== 'draw-area') return chapter.restart();
50926                     continueTo(continuePlayground);
50927                 });
50928             }, 250);  // after reveal
50929
50930         }, 550);  // after easing
50931
50932         function continueTo(nextStep) {
50933             context.map().on('move.intro drawn.intro', null);
50934             context.on('enter.intro', null);
50935             nextStep();
50936         }
50937     }
50938
50939
50940     function continuePlayground() {
50941         if (context.mode().id !== 'draw-area') {
50942             return chapter.restart();
50943         }
50944
50945         areaId = null;
50946         revealPlayground(playground,
50947             t('intro.areas.continue_playground', { alt: uiCmd.display('⌥') }),
50948             { duration: 250 }
50949         );
50950
50951         timeout(function() {
50952             context.map().on('move.intro drawn.intro', function() {
50953                 revealPlayground(playground,
50954                     t('intro.areas.continue_playground', { alt: uiCmd.display('⌥') }),
50955                     { duration: 0 }
50956                 );
50957             });
50958         }, 250);  // after reveal
50959
50960         context.on('enter.intro', function(mode) {
50961             if (mode.id === 'draw-area') {
50962                 var entity = context.hasEntity(context.selectedIDs()[0]);
50963                 if (entity && entity.nodes.length >= 6) {
50964                     return continueTo(finishPlayground);
50965                 } else {
50966                     return;
50967                 }
50968             } else if (mode.id === 'select') {
50969                 areaId = context.selectedIDs()[0];
50970                 return continueTo(searchPresets);
50971             } else {
50972                 return chapter.restart();
50973             }
50974         });
50975
50976         function continueTo(nextStep) {
50977             context.map().on('move.intro drawn.intro', null);
50978             context.on('enter.intro', null);
50979             nextStep();
50980         }
50981     }
50982
50983
50984     function finishPlayground() {
50985         if (context.mode().id !== 'draw-area') {
50986             return chapter.restart();
50987         }
50988
50989         areaId = null;
50990         revealPlayground(playground,
50991             t('intro.areas.finish_playground'), { duration: 250 }
50992         );
50993
50994         timeout(function() {
50995             context.map().on('move.intro drawn.intro', function() {
50996                 revealPlayground(playground,
50997                     t('intro.areas.finish_playground'), { duration: 0 }
50998                 );
50999             });
51000         }, 250);  // after reveal
51001
51002         context.on('enter.intro', function(mode) {
51003             if (mode.id === 'draw-area') {
51004                 return;
51005             } else if (mode.id === 'select') {
51006                 areaId = context.selectedIDs()[0];
51007                 return continueTo(searchPresets);
51008             } else {
51009                 return chapter.restart();
51010             }
51011         });
51012
51013         function continueTo(nextStep) {
51014             context.map().on('move.intro drawn.intro', null);
51015             context.on('enter.intro', null);
51016             nextStep();
51017         }
51018     }
51019
51020
51021     function searchPresets() {
51022         if (!areaId || !context.hasEntity(areaId)) {
51023             return addArea();
51024         }
51025         var ids = context.selectedIDs();
51026         if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
51027             context.enter(modeSelect(context, [areaId]));
51028         }
51029
51030         // disallow scrolling
51031         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
51032
51033         timeout(function() {
51034             // reset pane, in case user somehow happened to change it..
51035             d3_select('.inspector-wrap .panewrap').style('right', '-100%');
51036
51037             d3_select('.preset-search-input')
51038                 .on('keydown.intro', null)
51039                 .on('keyup.intro', checkPresetSearch);
51040
51041             reveal('.preset-search-input',
51042                 t('intro.areas.search_playground', { preset: playgroundPreset.name() })
51043             );
51044         }, 400);  // after preset list pane visible..
51045
51046         context.on('enter.intro', function(mode) {
51047             if (!areaId || !context.hasEntity(areaId)) {
51048                 return continueTo(addArea);
51049             }
51050
51051             var ids = context.selectedIDs();
51052             if (mode.id !== 'select' || !ids.length || ids[0] !== areaId) {
51053                 // keep the user's area selected..
51054                 context.enter(modeSelect(context, [areaId]));
51055
51056                 // reset pane, in case user somehow happened to change it..
51057                 d3_select('.inspector-wrap .panewrap').style('right', '-100%');
51058                 // disallow scrolling
51059                 d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
51060
51061                 d3_select('.preset-search-input')
51062                     .on('keydown.intro', null)
51063                     .on('keyup.intro', checkPresetSearch);
51064
51065                 reveal('.preset-search-input',
51066                     t('intro.areas.search_playground', { preset: playgroundPreset.name() })
51067                 );
51068
51069                 context.history().on('change.intro', null);
51070             }
51071         });
51072
51073         function checkPresetSearch() {
51074             var first = d3_select('.preset-list-item:first-child');
51075
51076             if (first.classed('preset-leisure-playground')) {
51077                 reveal(first.select('.preset-list-button').node(),
51078                     t('intro.areas.choose_playground', { preset: playgroundPreset.name() }),
51079                     { duration: 300 }
51080                 );
51081
51082                 d3_select('.preset-search-input')
51083                     .on('keydown.intro', eventCancel, true)
51084                     .on('keyup.intro', null);
51085
51086                 context.history().on('change.intro', function() {
51087                     continueTo(clickAddField);
51088                 });
51089             }
51090         }
51091
51092         function continueTo(nextStep) {
51093             d3_select('.inspector-wrap').on('wheel.intro', null);
51094             context.on('enter.intro', null);
51095             context.history().on('change.intro', null);
51096             d3_select('.preset-search-input').on('keydown.intro keyup.intro', null);
51097             nextStep();
51098         }
51099     }
51100
51101
51102     function clickAddField() {
51103         if (!areaId || !context.hasEntity(areaId)) {
51104             return addArea();
51105         }
51106         var ids = context.selectedIDs();
51107         if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
51108             return searchPresets();
51109         }
51110
51111         if (!d3_select('.form-field-description').empty()) {
51112             return continueTo(describePlayground);
51113         }
51114
51115         // disallow scrolling
51116         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
51117
51118         timeout(function() {
51119             // reset pane, in case user somehow happened to change it..
51120             d3_select('.inspector-wrap .panewrap').style('right', '0%');
51121
51122             // It's possible for the user to add a description in a previous step..
51123             // If they did this already, just continue to next step.
51124             var entity = context.entity(areaId);
51125             if (entity.tags.description) {
51126                 return continueTo(play);
51127             }
51128
51129             // scroll "Add field" into view
51130             var box = d3_select('.more-fields').node().getBoundingClientRect();
51131             if (box.top > 300) {
51132                 var pane = d3_select('.entity-editor-pane .inspector-body');
51133                 var start = pane.node().scrollTop;
51134                 var end = start + (box.top - 300);
51135
51136                 pane
51137                     .transition()
51138                     .duration(250)
51139                     .tween('scroll.inspector', function() {
51140                         var node = this;
51141                         var i = d3_interpolateNumber(start, end);
51142                         return function(t$$1) {
51143                             node.scrollTop = i(t$$1);
51144                         };
51145                     });
51146             }
51147
51148             timeout(function() {
51149                 reveal('.more-fields .combobox-input',
51150                     t('intro.areas.add_field'),
51151                     { duration: 300 }
51152                 );
51153
51154                 d3_select('.more-fields .combobox-input')
51155                     .on('click.intro', function() {
51156                         continueTo(chooseDescriptionField);
51157                     });
51158             }, 300);  // after "Add Field" visible
51159
51160         }, 400);  // after editor pane visible
51161
51162         context.on('exit.intro', function() {
51163             return continueTo(searchPresets);
51164         });
51165
51166         function continueTo(nextStep) {
51167             d3_select('.inspector-wrap').on('wheel.intro', null);
51168             d3_select('.more-fields .combobox-input').on('click.intro', null);
51169             context.on('exit.intro', null);
51170             nextStep();
51171         }
51172     }
51173
51174
51175     function chooseDescriptionField() {
51176         if (!areaId || !context.hasEntity(areaId)) {
51177             return addArea();
51178         }
51179         var ids = context.selectedIDs();
51180         if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
51181             return searchPresets();
51182         }
51183
51184         if (!d3_select('.form-field-description').empty()) {
51185             return continueTo(describePlayground);
51186         }
51187
51188         // Make sure combobox is ready..
51189         if (d3_select('div.combobox').empty()) {
51190             return continueTo(clickAddField);
51191         }
51192         // Watch for the combobox to go away..
51193         var watcher;
51194         watcher = window.setInterval(function() {
51195             if (d3_select('div.combobox').empty()) {
51196                 window.clearInterval(watcher);
51197                 timeout(function() {
51198                     if (d3_select('.form-field-description').empty()) {
51199                         continueTo(retryChooseDescription);
51200                     } else {
51201                         continueTo(describePlayground);
51202                     }
51203                 }, 300);  // after description field added.
51204             }
51205         }, 300);
51206
51207         reveal('div.combobox',
51208             t('intro.areas.choose_field', { field: descriptionField.label() }),
51209             { duration: 300 }
51210         );
51211
51212         context.on('exit.intro', function() {
51213             return continueTo(searchPresets);
51214         });
51215
51216         function continueTo(nextStep) {
51217             if (watcher) window.clearInterval(watcher);
51218             context.on('exit.intro', null);
51219             nextStep();
51220         }
51221     }
51222
51223
51224     function describePlayground() {
51225         if (!areaId || !context.hasEntity(areaId)) {
51226             return addArea();
51227         }
51228         var ids = context.selectedIDs();
51229         if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
51230             return searchPresets();
51231         }
51232
51233         // reset pane, in case user happened to change it..
51234         d3_select('.inspector-wrap .panewrap').style('right', '0%');
51235
51236         if (d3_select('.form-field-description').empty()) {
51237             return continueTo(retryChooseDescription);
51238         }
51239
51240         context.on('exit.intro', function() {
51241             continueTo(play);
51242         });
51243
51244         reveal('.entity-editor-pane',
51245             t('intro.areas.describe_playground', { button: icon('#icon-apply', 'pre-text') }),
51246             { duration: 300 }
51247         );
51248
51249         function continueTo(nextStep) {
51250             context.on('exit.intro', null);
51251             nextStep();
51252         }
51253     }
51254
51255
51256     function retryChooseDescription() {
51257         if (!areaId || !context.hasEntity(areaId)) {
51258             return addArea();
51259         }
51260         var ids = context.selectedIDs();
51261         if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
51262             return searchPresets();
51263         }
51264
51265         // reset pane, in case user happened to change it..
51266         d3_select('.inspector-wrap .panewrap').style('right', '0%');
51267
51268         reveal('.entity-editor-pane',
51269             t('intro.areas.retry_add_field', { field: descriptionField.label() }), {
51270             buttonText: t('intro.ok'),
51271             buttonCallback: function() { continueTo(clickAddField); }
51272         });
51273
51274         context.on('exit.intro', function() {
51275             return continueTo(searchPresets);
51276         });
51277
51278         function continueTo(nextStep) {
51279             context.on('exit.intro', null);
51280             nextStep();
51281         }
51282     }
51283
51284
51285     function play() {
51286         dispatch$$1.call('done');
51287         reveal('#id-container',
51288             t('intro.areas.play', { next: t('intro.lines.title') }), {
51289                 tooltipBox: '.intro-nav-wrap .chapter-line',
51290                 buttonText: t('intro.ok'),
51291                 buttonCallback: function() { reveal('#id-container'); }
51292             }
51293         );
51294     }
51295
51296
51297     chapter.enter = function() {
51298         addArea();
51299     };
51300
51301
51302     chapter.exit = function() {
51303         timeouts.forEach(window.clearTimeout);
51304         context.on('enter.intro exit.intro', null);
51305         context.map().on('move.intro drawn.intro', null);
51306         context.history().on('change.intro', null);
51307         d3_select('.inspector-wrap').on('wheel.intro', null);
51308         d3_select('.preset-search-input').on('keydown.intro keyup.intro', null);
51309         d3_select('.more-fields .combobox-input').on('click.intro', null);
51310     };
51311
51312
51313     chapter.restart = function() {
51314         chapter.exit();
51315         chapter.enter();
51316     };
51317
51318
51319     return utilRebind(chapter, dispatch$$1, 'on');
51320 }
51321
51322 function uiIntroLine(context, reveal) {
51323     var dispatch$$1 = dispatch('done'),
51324         timeouts = [],
51325         tulipRoadId = null,
51326         flowerRoadId = 'w646',
51327         tulipRoadStart = [-85.6297754121684, 41.95805253325314],
51328         tulipRoadMidpoint = [-85.62975395449628, 41.95787501510204],
51329         tulipRoadIntersection = [-85.62974496187628, 41.95742515554585],
51330         roadCategory = context.presets().item('category-road'),
51331         residentialPreset = context.presets().item('highway/residential'),
51332         woodRoadId = 'w525',
51333         woodRoadEndId = 'n2862',
51334         woodRoadAddNode = [-85.62390110349587, 41.95397111462291],
51335         woodRoadDragEndpoint = [-85.623867390213, 41.95466987786487],
51336         woodRoadDragMidpoint = [-85.62386254803509, 41.95430395953872],
51337         washingtonStreetId = 'w522',
51338         twelfthAvenueId = 'w1',
51339         eleventhAvenueEndId = 'n3550',
51340         twelfthAvenueEndId = 'n5',
51341         washingtonSegmentId = null,
51342         eleventhAvenueEnd = context.entity(eleventhAvenueEndId).loc,
51343         twelfthAvenueEnd = context.entity(twelfthAvenueEndId).loc,
51344         deleteLinesLoc = [-85.6219395542764, 41.95228033922477],
51345         twelfthAvenue = [-85.62219310052491, 41.952505413152956];
51346
51347
51348     var chapter = {
51349         title: 'intro.lines.title'
51350     };
51351
51352
51353     function timeout(f, t$$1) {
51354         timeouts.push(window.setTimeout(f, t$$1));
51355     }
51356
51357
51358     function eventCancel() {
51359         event.stopPropagation();
51360         event.preventDefault();
51361     }
51362
51363
51364     function revealEditMenu(loc, text, options) {
51365         var rect = context.surfaceRect();
51366         var point = context.curtainProjection(loc);
51367         var pad = 40;
51368         var width = 250 + (2 * pad);
51369         var height = 350;
51370         var startX = rect.left + point[0];
51371         var left = (textDirection === 'rtl') ? (startX - width + pad) : (startX - pad);
51372         var box = {
51373             left: left,
51374             top: point[1] + rect.top - 60,
51375             width: width,
51376             height: height
51377         };
51378         reveal(box, text, options);
51379     }
51380
51381
51382     function addLine() {
51383         context.enter(modeBrowse(context));
51384         context.history().reset('initial');
51385
51386         var msec = transitionTime(tulipRoadStart, context.map().center());
51387         if (msec) { reveal(null, null, { duration: 0 }); }
51388         context.map().zoom(18.5).centerEase(tulipRoadStart, msec);
51389
51390         timeout(function() {
51391             var tooltip = reveal('button.add-line',
51392                 t('intro.lines.add_line', { button: icon('#icon-line', 'pre-text') }));
51393
51394             tooltip.selectAll('.tooltip-inner')
51395                 .insert('svg', 'span')
51396                 .attr('class', 'tooltip-illustration')
51397                 .append('use')
51398                 .attr('xlink:href', '#feature-images');
51399
51400             context.on('enter.intro', function(mode) {
51401                 if (mode.id !== 'add-line') return;
51402                 continueTo(startLine);
51403             });
51404         }, msec + 100);
51405
51406         function continueTo(nextStep) {
51407             context.on('enter.intro', null);
51408             nextStep();
51409         }
51410     }
51411
51412
51413     function startLine() {
51414         if (context.mode().id !== 'add-line') {
51415             return chapter.restart();
51416         }
51417
51418         tulipRoadId = null;
51419
51420         var padding = 70 * Math.pow(2, context.map().zoom() - 18);
51421         var box = pad$1(tulipRoadStart, padding, context);
51422         box.height = box.height + 100;
51423         reveal(box, t('intro.lines.start_line'));
51424
51425         context.map().on('move.intro drawn.intro', function() {
51426             padding = 70 * Math.pow(2, context.map().zoom() - 18);
51427             box = pad$1(tulipRoadStart, padding, context);
51428             box.height = box.height + 100;
51429             reveal(box, t('intro.lines.start_line'), { duration: 0 });
51430         });
51431
51432         context.on('enter.intro', function(mode) {
51433             if (mode.id !== 'draw-line') return chapter.restart();
51434             continueTo(drawLine);
51435         });
51436
51437         function continueTo(nextStep) {
51438             context.map().on('move.intro drawn.intro', null);
51439             context.on('enter.intro', null);
51440             nextStep();
51441         }
51442     }
51443
51444
51445     function drawLine() {
51446         if (context.mode().id !== 'draw-line') {
51447             return chapter.restart();
51448         }
51449
51450         tulipRoadId = context.mode().selectedIDs()[0];
51451         context.map().centerEase(tulipRoadMidpoint, 500);
51452
51453         timeout(function() {
51454             var padding = 200 * Math.pow(2, context.map().zoom() - 18.5);
51455             var box = pad$1(tulipRoadMidpoint, padding, context);
51456             box.height = box.height * 2;
51457             reveal(box,
51458                 t('intro.lines.intersect', { name: t('intro.graph.name.flower-street') })
51459             );
51460
51461             context.map().on('move.intro drawn.intro', function() {
51462                 padding = 200 * Math.pow(2, context.map().zoom() - 18.5);
51463                 box = pad$1(tulipRoadMidpoint, padding, context);
51464                 box.height = box.height * 2;
51465                 reveal(box,
51466                     t('intro.lines.intersect', { name: t('intro.graph.name.flower-street') }),
51467                     { duration: 0 }
51468                 );
51469             });
51470         }, 550);  // after easing..
51471
51472         context.history().on('change.intro', function() {
51473             var entity = tulipRoadId && context.hasEntity(tulipRoadId);
51474             if (!entity) return chapter.restart();
51475
51476             if (isLineConnected()) {
51477                 continueTo(continueLine);
51478             }
51479         });
51480
51481         context.on('enter.intro', function(mode) {
51482             if (mode.id === 'draw-line')
51483                 return;
51484             else if (mode.id === 'select') {
51485                 continueTo(retryIntersect);
51486                 return;
51487             }
51488             else
51489                 return chapter.restart();
51490         });
51491
51492         function continueTo(nextStep) {
51493             context.map().on('move.intro drawn.intro', null);
51494             context.history().on('change.intro', null);
51495             context.on('enter.intro', null);
51496             nextStep();
51497         }
51498     }
51499
51500
51501     function isLineConnected() {
51502         var entity = tulipRoadId && context.hasEntity(tulipRoadId);
51503         if (!entity) return false;
51504
51505         var drawNodes = context.graph().childNodes(entity);
51506         return some(drawNodes, function(node) {
51507             return some(context.graph().parentWays(node), function(parent) {
51508                 return parent.id === flowerRoadId;
51509             });
51510         });
51511     }
51512
51513
51514     function retryIntersect() {
51515         d3_select(window).on('mousedown.intro', eventCancel, true);
51516
51517         var box = pad$1(tulipRoadIntersection, 80, context);
51518         reveal(box,
51519             t('intro.lines.retry_intersect', { name: t('intro.graph.name.flower-street') })
51520         );
51521
51522         timeout(chapter.restart, 3000);
51523     }
51524
51525
51526     function continueLine() {
51527         if (context.mode().id !== 'draw-line') return chapter.restart();
51528         var entity = tulipRoadId && context.hasEntity(tulipRoadId);
51529         if (!entity) return chapter.restart();
51530
51531         context.map().centerEase(tulipRoadIntersection, 500);
51532
51533         reveal('#surface', t('intro.lines.continue_line'));
51534
51535         context.on('enter.intro', function(mode) {
51536             if (mode.id === 'draw-line')
51537                 return;
51538             else if (mode.id === 'select')
51539                 return continueTo(chooseCategoryRoad);
51540             else
51541                 return chapter.restart();
51542         });
51543
51544         function continueTo(nextStep) {
51545             context.on('enter.intro', null);
51546             nextStep();
51547         }
51548     }
51549
51550
51551     function chooseCategoryRoad() {
51552         if (context.mode().id !== 'select') {
51553             return chapter.restart();
51554         }
51555
51556         context.on('exit.intro', function() {
51557             return chapter.restart();
51558         });
51559
51560         var button = d3_select('.preset-category-road .preset-list-button');
51561         if (button.empty()) return chapter.restart();
51562
51563         // disallow scrolling
51564         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
51565
51566         timeout(function() {
51567             // reset pane, in case user somehow happened to change it..
51568             d3_select('.inspector-wrap .panewrap').style('right', '-100%');
51569
51570             reveal(button.node(),
51571                 t('intro.lines.choose_category_road', { category: roadCategory.name() })
51572             );
51573
51574             button.on('click.intro', function() {
51575                 continueTo(choosePresetResidential);
51576             });
51577
51578         }, 400);  // after editor pane visible
51579
51580         function continueTo(nextStep) {
51581             d3_select('.inspector-wrap').on('wheel.intro', null);
51582             d3_select('.preset-list-button').on('click.intro', null);
51583             context.on('exit.intro', null);
51584             nextStep();
51585         }
51586     }
51587
51588
51589     function choosePresetResidential() {
51590         if (context.mode().id !== 'select') {
51591             return chapter.restart();
51592         }
51593
51594         context.on('exit.intro', function() {
51595             return chapter.restart();
51596         });
51597
51598         var subgrid = d3_select('.preset-category-road .subgrid');
51599         if (subgrid.empty()) return chapter.restart();
51600
51601         subgrid.selectAll(':not(.preset-highway-residential) .preset-list-button')
51602             .on('click.intro', function() {
51603                 continueTo(retryPresetResidential);
51604             });
51605
51606         subgrid.selectAll('.preset-highway-residential .preset-list-button')
51607             .on('click.intro', function() {
51608                 continueTo(nameRoad);
51609             });
51610
51611         timeout(function() {
51612             reveal(subgrid.node(),
51613                 t('intro.lines.choose_preset_residential', { preset: residentialPreset.name() }),
51614                 { tooltipBox: '.preset-highway-residential .preset-list-button', duration: 300 }
51615             );
51616         }, 300);
51617
51618         function continueTo(nextStep) {
51619             d3_select('.preset-list-button').on('click.intro', null);
51620             context.on('exit.intro', null);
51621             nextStep();
51622         }
51623     }
51624
51625
51626     // selected wrong road type
51627     function retryPresetResidential() {
51628         if (context.mode().id !== 'select') {
51629             return chapter.restart();
51630         }
51631
51632         context.on('exit.intro', function() {
51633             return chapter.restart();
51634         });
51635
51636         // disallow scrolling
51637         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
51638
51639         timeout(function() {
51640             var button = d3_select('.entity-editor-pane .preset-list-button');
51641
51642             reveal(button.node(),
51643                 t('intro.lines.retry_preset_residential', { preset: residentialPreset.name() })
51644             );
51645
51646             button.on('click.intro', function() {
51647                 continueTo(chooseCategoryRoad);
51648             });
51649
51650         }, 500);
51651
51652         function continueTo(nextStep) {
51653             d3_select('.inspector-wrap').on('wheel.intro', null);
51654             d3_select('.preset-list-button').on('click.intro', null);
51655             context.on('exit.intro', null);
51656             nextStep();
51657         }
51658     }
51659
51660
51661     function nameRoad() {
51662         context.on('exit.intro', function() {
51663             continueTo(didNameRoad);
51664         });
51665
51666         timeout(function() {
51667             reveal('.entity-editor-pane',
51668                 t('intro.lines.name_road', { button: icon('#icon-apply', 'pre-text') }),
51669                 { tooltipClass: 'intro-lines-name_road' }
51670             );
51671         }, 500);
51672
51673         function continueTo(nextStep) {
51674             context.on('exit.intro', null);
51675             nextStep();
51676         }
51677     }
51678
51679
51680     function didNameRoad() {
51681         context.history().checkpoint('doneAddLine');
51682
51683         timeout(function() {
51684             reveal('#surface', t('intro.lines.did_name_road'), {
51685                 buttonText: t('intro.ok'),
51686                 buttonCallback: function() { continueTo(updateLine); }
51687             });
51688         }, 500);
51689
51690         function continueTo(nextStep) {
51691             nextStep();
51692         }
51693     }
51694
51695
51696     function updateLine() {
51697         context.history().reset('doneAddLine');
51698         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
51699             return chapter.restart();
51700         }
51701
51702         var msec = transitionTime(woodRoadDragMidpoint, context.map().center());
51703         if (msec) { reveal(null, null, { duration: 0 }); }
51704         context.map().zoom(19).centerEase(woodRoadDragMidpoint, msec);
51705
51706         timeout(function() {
51707             var padding = 250 * Math.pow(2, context.map().zoom() - 19);
51708             var box = pad$1(woodRoadDragMidpoint, padding, context);
51709             var advance = function() { continueTo(addNode); };
51710
51711             reveal(box, t('intro.lines.update_line'),
51712                 { buttonText: t('intro.ok'), buttonCallback: advance }
51713             );
51714
51715             context.map().on('move.intro drawn.intro', function() {
51716                 var padding = 250 * Math.pow(2, context.map().zoom() - 19);
51717                 var box = pad$1(woodRoadDragMidpoint, padding, context);
51718                 reveal(box, t('intro.lines.update_line'),
51719                     { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance }
51720                 );
51721             });
51722         }, msec + 100);
51723
51724         function continueTo(nextStep) {
51725             context.map().on('move.intro drawn.intro', null);
51726             nextStep();
51727         }
51728     }
51729
51730
51731     function addNode() {
51732         context.history().reset('doneAddLine');
51733         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
51734             return chapter.restart();
51735         }
51736
51737         var padding = 40 * Math.pow(2, context.map().zoom() - 19);
51738         var box = pad$1(woodRoadAddNode, padding, context);
51739         reveal(box, t('intro.lines.add_node'));
51740
51741         context.map().on('move.intro drawn.intro', function() {
51742             var padding = 40 * Math.pow(2, context.map().zoom() - 19);
51743             var box = pad$1(woodRoadAddNode, padding, context);
51744             reveal(box, t('intro.lines.add_node'), { duration: 0 });
51745         });
51746
51747         context.history().on('change.intro', function(changed) {
51748             if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
51749                 return continueTo(updateLine);
51750             }
51751             if (changed.created().length === 1) {
51752                 timeout(function() { continueTo(startDragEndpoint); }, 500);
51753             }
51754         });
51755
51756         context.on('enter.intro', function(mode) {
51757             if (mode.id !== 'select') {
51758                 continueTo(updateLine);
51759             }
51760         });
51761
51762         function continueTo(nextStep) {
51763             context.map().on('move.intro drawn.intro', null);
51764             context.history().on('change.intro', null);
51765             context.on('enter.intro', null);
51766             nextStep();
51767         }
51768     }
51769
51770
51771     function startDragEndpoint() {
51772         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
51773             return continueTo(updateLine);
51774         }
51775         var padding = 100 * Math.pow(2, context.map().zoom() - 19);
51776         var box = pad$1(woodRoadDragEndpoint, padding, context);
51777         reveal(box, t('intro.lines.start_drag_endpoint'));
51778
51779         context.map().on('move.intro drawn.intro', function() {
51780             if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
51781                 return continueTo(updateLine);
51782             }
51783             var padding = 100 * Math.pow(2, context.map().zoom() - 19);
51784             var box = pad$1(woodRoadDragEndpoint, padding, context);
51785             reveal(box, t('intro.lines.start_drag_endpoint'), { duration: 0 });
51786
51787             var entity = context.entity(woodRoadEndId);
51788             if (geoSphericalDistance(entity.loc, woodRoadDragEndpoint) <= 4) {
51789                 continueTo(finishDragEndpoint);
51790             }
51791         });
51792
51793         function continueTo(nextStep) {
51794             context.map().on('move.intro drawn.intro', null);
51795             nextStep();
51796         }
51797     }
51798
51799
51800     function finishDragEndpoint() {
51801         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
51802             return continueTo(updateLine);
51803         }
51804
51805         var padding = 100 * Math.pow(2, context.map().zoom() - 19);
51806         var box = pad$1(woodRoadDragEndpoint, padding, context);
51807         reveal(box, t('intro.lines.finish_drag_endpoint'));
51808
51809         context.map().on('move.intro drawn.intro', function() {
51810             if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
51811                 return continueTo(updateLine);
51812             }
51813             var padding = 100 * Math.pow(2, context.map().zoom() - 19);
51814             var box = pad$1(woodRoadDragEndpoint, padding, context);
51815             reveal(box, t('intro.lines.finish_drag_endpoint'), { duration: 0 });
51816
51817             var entity = context.entity(woodRoadEndId);
51818             if (geoSphericalDistance(entity.loc, woodRoadDragEndpoint) > 4) {
51819                 continueTo(startDragEndpoint);
51820             }
51821         });
51822
51823         context.on('enter.intro', function() {
51824             continueTo(startDragMidpoint);
51825         });
51826
51827         function continueTo(nextStep) {
51828             context.map().on('move.intro drawn.intro', null);
51829             context.on('enter.intro', null);
51830             nextStep();
51831         }
51832     }
51833
51834
51835     function startDragMidpoint() {
51836         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
51837             return continueTo(updateLine);
51838         }
51839         if (context.selectedIDs().indexOf(woodRoadId) === -1) {
51840             context.enter(modeSelect(context, [woodRoadId]));
51841         }
51842
51843         var padding = 80 * Math.pow(2, context.map().zoom() - 19);
51844         var box = pad$1(woodRoadDragMidpoint, padding, context);
51845         reveal(box, t('intro.lines.start_drag_midpoint'));
51846
51847         context.map().on('move.intro drawn.intro', function() {
51848             if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
51849                 return continueTo(updateLine);
51850             }
51851             var padding = 80 * Math.pow(2, context.map().zoom() - 19);
51852             var box = pad$1(woodRoadDragMidpoint, padding, context);
51853             reveal(box, t('intro.lines.start_drag_midpoint'), { duration: 0 });
51854         });
51855
51856         context.history().on('change.intro', function(changed) {
51857             if (changed.created().length === 1) {
51858                 continueTo(continueDragMidpoint);
51859             }
51860         });
51861
51862         context.on('enter.intro', function(mode) {
51863             if (mode.id !== 'select') {
51864                 // keep Wood Road selected so midpoint triangles are drawn..
51865                 context.enter(modeSelect(context, [woodRoadId]));
51866             }
51867         });
51868
51869         function continueTo(nextStep) {
51870             context.map().on('move.intro drawn.intro', null);
51871             context.history().on('change.intro', null);
51872             context.on('enter.intro', null);
51873             nextStep();
51874         }
51875     }
51876
51877
51878     function continueDragMidpoint() {
51879         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
51880             return continueTo(updateLine);
51881         }
51882
51883         var padding = 100 * Math.pow(2, context.map().zoom() - 19);
51884         var box = pad$1(woodRoadDragEndpoint, padding, context);
51885         box.height += 400;
51886
51887         var advance = function() {
51888             context.history().checkpoint('doneUpdateLine');
51889             continueTo(deleteLines);
51890         };
51891
51892         reveal(box, t('intro.lines.continue_drag_midpoint'),
51893             { buttonText: t('intro.ok'), buttonCallback: advance }
51894         );
51895
51896         context.map().on('move.intro drawn.intro', function() {
51897             if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
51898                 return continueTo(updateLine);
51899             }
51900             var padding = 100 * Math.pow(2, context.map().zoom() - 19);
51901             var box = pad$1(woodRoadDragEndpoint, padding, context);
51902             box.height += 400;
51903             reveal(box, t('intro.lines.continue_drag_midpoint'),
51904                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance }
51905             );
51906         });
51907
51908         function continueTo(nextStep) {
51909             context.map().on('move.intro drawn.intro', null);
51910             nextStep();
51911         }
51912     }
51913
51914
51915     function deleteLines() {
51916         context.history().reset('doneUpdateLine');
51917         context.enter(modeBrowse(context));
51918
51919         if (!context.hasEntity(washingtonStreetId) ||
51920             !context.hasEntity(twelfthAvenueId) ||
51921             !context.hasEntity(eleventhAvenueEndId)) {
51922             return chapter.restart();
51923         }
51924
51925         var msec = transitionTime(deleteLinesLoc, context.map().center());
51926         if (msec) { reveal(null, null, { duration: 0 }); }
51927         context.map().zoom(18).centerEase(deleteLinesLoc, msec);
51928
51929         timeout(function() {
51930             var padding = 200 * Math.pow(2, context.map().zoom() - 18);
51931             var box = pad$1(deleteLinesLoc, padding, context);
51932             box.top -= 200;
51933             box.height += 400;
51934             var advance = function() { continueTo(rightClickIntersection); };
51935
51936             reveal(box, t('intro.lines.delete_lines', { street: t('intro.graph.name.12th-avenue') }),
51937                 { buttonText: t('intro.ok'), buttonCallback: advance }
51938             );
51939
51940             context.map().on('move.intro drawn.intro', function() {
51941                 var padding = 200 * Math.pow(2, context.map().zoom() - 18);
51942                 var box = pad$1(deleteLinesLoc, padding, context);
51943                 box.top -= 200;
51944                 box.height += 400;
51945                 reveal(box, t('intro.lines.delete_lines', { street: t('intro.graph.name.12th-avenue') }),
51946                     { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance }
51947                 );
51948             });
51949
51950             context.history().on('change.intro', function() {
51951                 timeout(function() {
51952                     continueTo(deleteLines);
51953                 }, 500);  // after any transition (e.g. if user deleted intersection)
51954             });
51955
51956         }, msec + 100);
51957
51958         function continueTo(nextStep) {
51959             context.map().on('move.intro drawn.intro', null);
51960             context.history().on('change.intro', null);
51961             nextStep();
51962         }
51963     }
51964
51965
51966     function rightClickIntersection() {
51967         context.history().reset('doneUpdateLine');
51968         context.enter(modeBrowse(context));
51969
51970         context.map().zoom(18).centerEase(eleventhAvenueEnd, 500);
51971
51972         timeout(function() {
51973             var padding = 60 * Math.pow(2, context.map().zoom() - 18);
51974             var box = pad$1(eleventhAvenueEnd, padding, context);
51975             reveal(box, t('intro.lines.rightclick_intersection',
51976                 { street1: t('intro.graph.name.11th-avenue'), street2: t('intro.graph.name.washington-street') })
51977             );
51978
51979             context.map().on('move.intro drawn.intro', function() {
51980                 var padding = 60 * Math.pow(2, context.map().zoom() - 18);
51981                 var box = pad$1(eleventhAvenueEnd, padding, context);
51982                 reveal(box, t('intro.lines.rightclick_intersection',
51983                     { street1: t('intro.graph.name.11th-avenue'), street2: t('intro.graph.name.washington-street') }),
51984                     { duration: 0 }
51985                 );
51986             });
51987
51988             context.on('enter.intro', function(mode) {
51989                 if (mode.id !== 'select') return;
51990                 var ids = context.selectedIDs();
51991                 if (ids.length !== 1 || ids[0] !== eleventhAvenueEndId) return;
51992
51993                 timeout(function() {
51994                     var node = selectMenuItem('split').node();
51995                     if (!node) return;
51996                     continueTo(splitIntersection);
51997                 }, 300);  // after menu visible
51998             });
51999
52000             context.history().on('change.intro', function() {
52001                 timeout(function() {
52002                     continueTo(deleteLines);
52003                 }, 300);  // after any transition (e.g. if user deleted intersection)
52004             });
52005
52006         }, 600);
52007
52008         function continueTo(nextStep) {
52009             context.map().on('move.intro drawn.intro', null);
52010             context.on('enter.intro', null);
52011             context.history().on('change.intro', null);
52012             nextStep();
52013         }
52014     }
52015
52016
52017     function splitIntersection() {
52018         if (!context.hasEntity(washingtonStreetId) ||
52019             !context.hasEntity(twelfthAvenueId) ||
52020             !context.hasEntity(eleventhAvenueEndId)) {
52021             return continueTo(deleteLines);
52022         }
52023
52024         var node = selectMenuItem('split').node();
52025         if (!node) { return continueTo(rightClickIntersection); }
52026
52027         var wasChanged = false;
52028         var menuCoords = context.map().mouseCoordinates();
52029         washingtonSegmentId = null;
52030
52031         revealEditMenu(menuCoords, t('intro.lines.split_intersection',
52032             { button: icon('#operation-split', 'pre-text'), street: t('intro.graph.name.washington-street') })
52033         );
52034
52035         context.map().on('move.intro drawn.intro', function() {
52036             var node = selectMenuItem('split').node();
52037             if (!wasChanged && !node) { return continueTo(rightClickIntersection); }
52038
52039             revealEditMenu(menuCoords, t('intro.lines.split_intersection',
52040                 { button: icon('#operation-split', 'pre-text'), street: t('intro.graph.name.washington-street') }),
52041                 { duration: 0 }
52042             );
52043         });
52044
52045         context.history().on('change.intro', function(changed) {
52046             wasChanged = true;
52047             timeout(function() {
52048                 if (context.history().undoAnnotation() === t('operations.split.annotation.line')) {
52049                     washingtonSegmentId = changed.created()[0].id;
52050                     continueTo(didSplit);
52051                 } else {
52052                     washingtonSegmentId = null;
52053                     continueTo(retrySplit);
52054                 }
52055             }, 300);  // after any transition (e.g. if user deleted intersection)
52056         });
52057
52058         function continueTo(nextStep) {
52059             context.map().on('move.intro drawn.intro', null);
52060             context.history().on('change.intro', null);
52061             nextStep();
52062         }
52063     }
52064
52065
52066     function retrySplit() {
52067         context.enter(modeBrowse(context));
52068         context.map().zoom(18).centerEase(eleventhAvenueEnd, 500);
52069         var advance = function() { continueTo(rightClickIntersection); };
52070
52071         var padding = 60 * Math.pow(2, context.map().zoom() - 18);
52072         var box = pad$1(eleventhAvenueEnd, padding, context);
52073         reveal(box, t('intro.lines.retry_split'),
52074             { buttonText: t('intro.ok'), buttonCallback: advance }
52075         );
52076
52077         context.map().on('move.intro drawn.intro', function() {
52078             var padding = 60 * Math.pow(2, context.map().zoom() - 18);
52079             var box = pad$1(eleventhAvenueEnd, padding, context);
52080             reveal(box, t('intro.lines.retry_split'),
52081                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance }
52082             );
52083         });
52084
52085         function continueTo(nextStep) {
52086             context.map().on('move.intro drawn.intro', null);
52087             nextStep();
52088         }
52089     }
52090
52091
52092     function didSplit() {
52093         if (!washingtonSegmentId ||
52094             !context.hasEntity(washingtonSegmentId) ||
52095             !context.hasEntity(washingtonStreetId) ||
52096             !context.hasEntity(twelfthAvenueId) ||
52097             !context.hasEntity(eleventhAvenueEndId)) {
52098             return continueTo(rightClickIntersection);
52099         }
52100
52101         var ids = context.selectedIDs();
52102         var string = 'intro.lines.did_split_' + (ids.length > 1 ? 'multi' : 'single');
52103         var street = t('intro.graph.name.washington-street');
52104
52105         var padding = 200 * Math.pow(2, context.map().zoom() - 18);
52106         var box = pad$1(twelfthAvenue, padding, context);
52107         box.width = box.width / 2;
52108         reveal(box, t(string, { street1: street, street2: street }),
52109             { duration: 500 }
52110         );
52111
52112         timeout(function() {
52113             context.map().zoom(18).centerEase(twelfthAvenue, 500);
52114
52115             context.map().on('move.intro drawn.intro', function() {
52116                 var padding = 200 * Math.pow(2, context.map().zoom() - 18);
52117                 var box = pad$1(twelfthAvenue, padding, context);
52118                 box.width = box.width / 2;
52119                 reveal(box, t(string, { street1: street, street2: street }),
52120                     { duration: 0 }
52121                 );
52122             });
52123         }, 600);  // after initial reveal and curtain cut
52124
52125         context.on('enter.intro', function() {
52126             var ids = context.selectedIDs();
52127             if (ids.length === 1 && ids[0] === washingtonSegmentId) {
52128                 continueTo(multiSelect);
52129             }
52130         });
52131
52132         context.history().on('change.intro', function() {
52133             if (!washingtonSegmentId ||
52134                 !context.hasEntity(washingtonSegmentId) ||
52135                 !context.hasEntity(washingtonStreetId) ||
52136                 !context.hasEntity(twelfthAvenueId) ||
52137                 !context.hasEntity(eleventhAvenueEndId)) {
52138                 return continueTo(rightClickIntersection);
52139             }
52140         });
52141
52142         function continueTo(nextStep) {
52143             context.map().on('move.intro drawn.intro', null);
52144             context.on('enter.intro', null);
52145             context.history().on('change.intro', null);
52146             nextStep();
52147         }
52148     }
52149
52150
52151     function multiSelect() {
52152         if (!washingtonSegmentId ||
52153             !context.hasEntity(washingtonSegmentId) ||
52154             !context.hasEntity(washingtonStreetId) ||
52155             !context.hasEntity(twelfthAvenueId) ||
52156             !context.hasEntity(eleventhAvenueEndId)) {
52157             return continueTo(rightClickIntersection);
52158         }
52159
52160         var ids = context.selectedIDs();
52161         var hasWashington = ids.indexOf(washingtonSegmentId) !== -1;
52162         var hasTwelfth = ids.indexOf(twelfthAvenueId) !== -1;
52163
52164         if (hasWashington && hasTwelfth) {
52165             return continueTo(multiRightClick);
52166         } else if (!hasWashington && !hasTwelfth) {
52167             return continueTo(didSplit);
52168         }
52169
52170         context.map().zoom(18).centerEase(twelfthAvenue, 500);
52171
52172         timeout(function() {
52173             var selected, other, padding, box;
52174             if (hasWashington) {
52175                 selected = t('intro.graph.name.washington-street');
52176                 other = t('intro.graph.name.12th-avenue');
52177                 padding = 60 * Math.pow(2, context.map().zoom() - 18);
52178                 box = pad$1(twelfthAvenueEnd, padding, context);
52179                 box.width *= 3;
52180             } else {
52181                 selected = t('intro.graph.name.12th-avenue');
52182                 other = t('intro.graph.name.washington-street');
52183                 padding = 200 * Math.pow(2, context.map().zoom() - 18);
52184                 box = pad$1(twelfthAvenue, padding, context);
52185                 box.width /= 2;
52186             }
52187
52188             reveal(box,
52189                 t('intro.lines.multi_select', { selected: selected, other1: other, other2: other })
52190             );
52191
52192             context.map().on('move.intro drawn.intro', function() {
52193                 if (hasWashington) {
52194                     selected = t('intro.graph.name.washington-street');
52195                     other = t('intro.graph.name.12th-avenue');
52196                     padding = 60 * Math.pow(2, context.map().zoom() - 18);
52197                     box = pad$1(twelfthAvenueEnd, padding, context);
52198                     box.width *= 3;
52199                 } else {
52200                     selected = t('intro.graph.name.12th-avenue');
52201                     other = t('intro.graph.name.washington-street');
52202                     padding = 200 * Math.pow(2, context.map().zoom() - 18);
52203                     box = pad$1(twelfthAvenue, padding, context);
52204                     box.width /= 2;
52205                 }
52206
52207                 reveal(box,
52208                     t('intro.lines.multi_select', { selected: selected, other1: other, other2: other }),
52209                     { duration: 0 }
52210                 );
52211             });
52212
52213             context.on('enter.intro', function() {
52214                 continueTo(multiSelect);
52215             });
52216
52217             context.history().on('change.intro', function() {
52218                 if (!washingtonSegmentId ||
52219                     !context.hasEntity(washingtonSegmentId) ||
52220                     !context.hasEntity(washingtonStreetId) ||
52221                     !context.hasEntity(twelfthAvenueId) ||
52222                     !context.hasEntity(eleventhAvenueEndId)) {
52223                     return continueTo(rightClickIntersection);
52224                 }
52225             });
52226         }, 600);
52227
52228         function continueTo(nextStep) {
52229             context.map().on('move.intro drawn.intro', null);
52230             context.on('enter.intro', null);
52231             context.history().on('change.intro', null);
52232             nextStep();
52233         }
52234     }
52235
52236
52237     function multiRightClick() {
52238         if (!washingtonSegmentId ||
52239             !context.hasEntity(washingtonSegmentId) ||
52240             !context.hasEntity(washingtonStreetId) ||
52241             !context.hasEntity(twelfthAvenueId) ||
52242             !context.hasEntity(eleventhAvenueEndId)) {
52243             return continueTo(rightClickIntersection);
52244         }
52245
52246         var padding = 200 * Math.pow(2, context.map().zoom() - 18);
52247         var box = pad$1(twelfthAvenue, padding, context);
52248         reveal(box, t('intro.lines.multi_rightclick'));
52249
52250         context.map().on('move.intro drawn.intro', function() {
52251             var padding = 200 * Math.pow(2, context.map().zoom() - 18);
52252             var box = pad$1(twelfthAvenue, padding, context);
52253             reveal(box, t('intro.lines.multi_rightclick'), { duration: 0 });
52254         });
52255
52256         d3_select(window).on('click.intro contextmenu.intro', function() {
52257             timeout(function() {
52258                 var ids = context.selectedIDs();
52259                 if (ids.length === 2 &&
52260                     ids.indexOf(twelfthAvenueId) !== -1 &&
52261                     ids.indexOf(washingtonSegmentId) !== -1) {
52262                         var node = selectMenuItem('delete').node();
52263                         if (!node) return;
52264                         continueTo(multiDelete);
52265                 } else if (ids.length === 1 &&
52266                     ids.indexOf(washingtonSegmentId) !== -1) {
52267                     return continueTo(multiSelect);
52268                 } else {
52269                     return continueTo(didSplit);
52270                 }
52271             }, 300);  // after edit menu visible
52272         }, true);
52273
52274         context.history().on('change.intro', function() {
52275             if (!washingtonSegmentId ||
52276                 !context.hasEntity(washingtonSegmentId) ||
52277                 !context.hasEntity(washingtonStreetId) ||
52278                 !context.hasEntity(twelfthAvenueId) ||
52279                 !context.hasEntity(eleventhAvenueEndId)) {
52280                 return continueTo(rightClickIntersection);
52281             }
52282         });
52283
52284         function continueTo(nextStep) {
52285             context.map().on('move.intro drawn.intro', null);
52286             d3_select(window).on('click.intro contextmenu.intro', null, true);
52287             context.history().on('change.intro', null);
52288             nextStep();
52289         }
52290     }
52291
52292
52293     function multiDelete() {
52294         if (!washingtonSegmentId ||
52295             !context.hasEntity(washingtonSegmentId) ||
52296             !context.hasEntity(washingtonStreetId) ||
52297             !context.hasEntity(twelfthAvenueId) ||
52298             !context.hasEntity(eleventhAvenueEndId)) {
52299             return continueTo(rightClickIntersection);
52300         }
52301
52302         var node = selectMenuItem('delete').node();
52303         if (!node) return continueTo(multiRightClick);
52304
52305         var menuCoords = context.map().mouseCoordinates();
52306         revealEditMenu(menuCoords,
52307             t('intro.lines.multi_delete', { button: icon('#operation-delete', 'pre-text') })
52308         );
52309
52310         context.map().on('move.intro drawn.intro', function() {
52311             revealEditMenu(menuCoords,
52312                 t('intro.lines.multi_delete', { button: icon('#operation-delete', 'pre-text') }),
52313                 { duration: 0 }
52314             );
52315         });
52316
52317         context.on('exit.intro', function() {
52318             if (context.hasEntity(washingtonSegmentId) || context.hasEntity(twelfthAvenueId)) {
52319                 return continueTo(multiSelect);  // left select mode but roads still exist
52320             }
52321         });
52322
52323         context.history().on('change.intro', function() {
52324             if (context.hasEntity(washingtonSegmentId) || context.hasEntity(twelfthAvenueId)) {
52325                 continueTo(retryDelete);         // changed something but roads still exist
52326             } else {
52327                 continueTo(play);
52328             }
52329         });
52330
52331         function continueTo(nextStep) {
52332             context.map().on('move.intro drawn.intro', null);
52333             context.on('exit.intro', null);
52334             context.history().on('change.intro', null);
52335             nextStep();
52336         }
52337     }
52338
52339
52340     function retryDelete() {
52341         context.enter(modeBrowse(context));
52342
52343         var padding = 200 * Math.pow(2, context.map().zoom() - 18);
52344         var box = pad$1(twelfthAvenue, padding, context);
52345         reveal(box, t('intro.lines.retry_delete'), {
52346             buttonText: t('intro.ok'),
52347             buttonCallback: function() { continueTo(multiSelect); }
52348         });
52349
52350         function continueTo(nextStep) {
52351             nextStep();
52352         }
52353     }
52354
52355
52356     function play() {
52357         dispatch$$1.call('done');
52358         reveal('#id-container',
52359             t('intro.lines.play', { next: t('intro.buildings.title') }), {
52360                 tooltipBox: '.intro-nav-wrap .chapter-building',
52361                 buttonText: t('intro.ok'),
52362                 buttonCallback: function() { reveal('#id-container'); }
52363             }
52364         );
52365    }
52366
52367
52368     chapter.enter = function() {
52369         addLine();
52370     };
52371
52372
52373     chapter.exit = function() {
52374         timeouts.forEach(window.clearTimeout);
52375         d3_select(window).on('mousedown.intro', null, true);
52376         context.on('enter.intro exit.intro', null);
52377         context.map().on('move.intro drawn.intro', null);
52378         context.history().on('change.intro', null);
52379         d3_select('.inspector-wrap').on('wheel.intro', null);
52380         d3_select('.preset-list-button').on('click.intro', null);
52381     };
52382
52383
52384     chapter.restart = function() {
52385         chapter.exit();
52386         chapter.enter();
52387     };
52388
52389
52390     return utilRebind(chapter, dispatch$$1, 'on');
52391 }
52392
52393 function uiIntroBuilding(context, reveal) {
52394     var dispatch$$1 = dispatch('done'),
52395         house = [-85.62815, 41.95638],
52396         tank = [-85.62732, 41.95347],
52397         buildingCatetory = context.presets().item('category-building'),
52398         housePreset = context.presets().item('building/house'),
52399         tankPreset = context.presets().item('man_made/storage_tank'),
52400         timeouts = [],
52401         houseId = null,
52402         tankId = null;
52403
52404
52405     var chapter = {
52406         title: 'intro.buildings.title'
52407     };
52408
52409
52410     function timeout(f, t$$1) {
52411         timeouts.push(window.setTimeout(f, t$$1));
52412     }
52413
52414
52415     function eventCancel() {
52416         event.stopPropagation();
52417         event.preventDefault();
52418     }
52419
52420
52421     function revealHouse(center, text, options) {
52422         var padding = 160 * Math.pow(2, context.map().zoom() - 20);
52423         var box = pad$1(center, padding, context);
52424         reveal(box, text, options);
52425     }
52426
52427
52428     function revealTank(center, text, options) {
52429         var padding = 190 * Math.pow(2, context.map().zoom() - 19.5);
52430         var box = pad$1(center, padding, context);
52431         reveal(box, text, options);
52432     }
52433
52434
52435     function revealEditMenu(loc, text, options) {
52436         var rect = context.surfaceRect();
52437         var point = context.curtainProjection(loc);
52438         var pad = 40;
52439         var width = 250 + (2 * pad);
52440         var height = 350;
52441         var startX = rect.left + point[0];
52442         var left = (textDirection === 'rtl') ? (startX - width + pad) : (startX - pad);
52443         var box = {
52444             left: left,
52445             top: point[1] + rect.top - 60,
52446             width: width,
52447             height: height
52448         };
52449         reveal(box, text, options);
52450     }
52451
52452
52453     function addHouse() {
52454         context.enter(modeBrowse(context));
52455         context.history().reset('initial');
52456         houseId = null;
52457
52458         var msec = transitionTime(house, context.map().center());
52459         if (msec) { reveal(null, null, { duration: 0 }); }
52460         context.map().zoom(19).centerEase(house, msec);
52461
52462         timeout(function() {
52463             var tooltip = reveal('button.add-area',
52464                 t('intro.buildings.add_building', { button: icon('#icon-area', 'pre-text') }));
52465
52466             tooltip.selectAll('.tooltip-inner')
52467                 .insert('svg', 'span')
52468                 .attr('class', 'tooltip-illustration')
52469                 .append('use')
52470                 .attr('xlink:href', '#building-images');
52471
52472             context.on('enter.intro', function(mode) {
52473                 if (mode.id !== 'add-area') return;
52474                 continueTo(startHouse);
52475             });
52476         }, msec + 100);
52477
52478         function continueTo(nextStep) {
52479             context.on('enter.intro', null);
52480             nextStep();
52481         }
52482     }
52483
52484
52485     function startHouse() {
52486         if (context.mode().id !== 'add-area') {
52487             return continueTo(addHouse);
52488         }
52489
52490         houseId = null;
52491         context.map().zoomEase(20, 500);
52492
52493         timeout(function() {
52494             revealHouse(house, t('intro.buildings.start_building'));
52495
52496             context.map().on('move.intro drawn.intro', function() {
52497                 revealHouse(house, t('intro.buildings.start_building'), { duration: 0 });
52498             });
52499
52500             context.on('enter.intro', function(mode) {
52501                 if (mode.id !== 'draw-area') return chapter.restart();
52502                 continueTo(continueHouse);
52503             });
52504
52505         }, 550);  // after easing
52506
52507         function continueTo(nextStep) {
52508             context.map().on('move.intro drawn.intro', null);
52509             context.on('enter.intro', null);
52510             nextStep();
52511         }
52512     }
52513
52514
52515     function continueHouse() {
52516         if (context.mode().id !== 'draw-area') {
52517             return continueTo(addHouse);
52518         }
52519
52520         houseId = null;
52521
52522         revealHouse(house, t('intro.buildings.continue_building'));
52523
52524         context.map().on('move.intro drawn.intro', function() {
52525             revealHouse(house, t('intro.buildings.continue_building'), { duration: 0 });
52526         });
52527
52528         context.on('enter.intro', function(mode) {
52529             if (mode.id === 'draw-area') {
52530                 return;
52531             } else if (mode.id === 'select') {
52532                 var graph = context.graph(),
52533                     way = context.entity(context.selectedIDs()[0]),
52534                     nodes = graph.childNodes(way),
52535                     points = uniq(nodes).map(function(n) { return context.projection(n.loc); });
52536
52537                 if (isMostlySquare(points)) {
52538                     houseId = way.id;
52539                     return continueTo(chooseCategoryBuilding);
52540                 } else {
52541                     return continueTo(retryHouse);
52542                 }
52543
52544             } else {
52545                 return chapter.restart();
52546             }
52547         });
52548
52549         function continueTo(nextStep) {
52550             context.map().on('move.intro drawn.intro', null);
52551             context.on('enter.intro', null);
52552             nextStep();
52553         }
52554     }
52555
52556
52557     function retryHouse() {
52558         var onClick = function() { continueTo(addHouse); };
52559
52560         revealHouse(house, t('intro.buildings.retry_building'),
52561             { buttonText: t('intro.ok'), buttonCallback: onClick }
52562         );
52563
52564         context.map().on('move.intro drawn.intro', function() {
52565             revealHouse(house, t('intro.buildings.retry_building'),
52566                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
52567             );
52568         });
52569
52570         function continueTo(nextStep) {
52571             context.map().on('move.intro drawn.intro', null);
52572             nextStep();
52573         }
52574     }
52575
52576
52577     function chooseCategoryBuilding() {
52578         if (!houseId || !context.hasEntity(houseId)) {
52579             return addHouse();
52580         }
52581         var ids = context.selectedIDs();
52582         if (context.mode().id !== 'select' || !ids.length || ids[0] !== houseId) {
52583             context.enter(modeSelect(context, [houseId]));
52584         }
52585
52586         // disallow scrolling
52587         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
52588
52589         timeout(function() {
52590             // reset pane, in case user somehow happened to change it..
52591             d3_select('.inspector-wrap .panewrap').style('right', '-100%');
52592
52593             var button = d3_select('.preset-category-building .preset-list-button');
52594
52595             reveal(button.node(),
52596                 t('intro.buildings.choose_category_building', { category: buildingCatetory.name() })
52597             );
52598
52599             button.on('click.intro', function() {
52600                 button.on('click.intro', null);
52601                 continueTo(choosePresetHouse);
52602             });
52603
52604         }, 400);  // after preset list pane visible..
52605
52606
52607         context.on('enter.intro', function(mode) {
52608             if (!houseId || !context.hasEntity(houseId)) {
52609                 return continueTo(addHouse);
52610             }
52611             var ids = context.selectedIDs();
52612             if (mode.id !== 'select' || !ids.length || ids[0] !== houseId) {
52613                 return continueTo(chooseCategoryBuilding);
52614             }
52615         });
52616
52617         function continueTo(nextStep) {
52618             d3_select('.inspector-wrap').on('wheel.intro', null);
52619             d3_select('.preset-list-button').on('click.intro', null);
52620             context.on('enter.intro', null);
52621             nextStep();
52622         }
52623     }
52624
52625
52626     function choosePresetHouse() {
52627         if (!houseId || !context.hasEntity(houseId)) {
52628             return addHouse();
52629         }
52630         var ids = context.selectedIDs();
52631         if (context.mode().id !== 'select' || !ids.length || ids[0] !== houseId) {
52632             context.enter(modeSelect(context, [houseId]));
52633         }
52634
52635         // disallow scrolling
52636         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
52637
52638         timeout(function() {
52639             // reset pane, in case user somehow happened to change it..
52640             d3_select('.inspector-wrap .panewrap').style('right', '-100%');
52641
52642             var button = d3_select('.preset-building-house .preset-list-button');
52643
52644             reveal(button.node(),
52645                 t('intro.buildings.choose_preset_house', { preset: housePreset.name() }),
52646                 { duration: 300 }
52647             );
52648
52649             button.on('click.intro', function() {
52650                 button.on('click.intro', null);
52651                 continueTo(closeEditorHouse);
52652             });
52653
52654
52655         }, 400);  // after preset list pane visible..
52656
52657         context.on('enter.intro', function(mode) {
52658             if (!houseId || !context.hasEntity(houseId)) {
52659                 return continueTo(addHouse);
52660             }
52661             var ids = context.selectedIDs();
52662             if (mode.id !== 'select' || !ids.length || ids[0] !== houseId) {
52663                 return continueTo(chooseCategoryBuilding);
52664             }
52665         });
52666
52667         function continueTo(nextStep) {
52668             d3_select('.inspector-wrap').on('wheel.intro', null);
52669             d3_select('.preset-list-button').on('click.intro', null);
52670             context.on('enter.intro', null);
52671             nextStep();
52672         }
52673     }
52674
52675
52676     function closeEditorHouse() {
52677         if (!houseId || !context.hasEntity(houseId)) {
52678             return addHouse();
52679         }
52680         var ids = context.selectedIDs();
52681         if (context.mode().id !== 'select' || !ids.length || ids[0] !== houseId) {
52682             context.enter(modeSelect(context, [houseId]));
52683         }
52684
52685         context.history().checkpoint('hasHouse');
52686
52687         context.on('exit.intro', function() {
52688             continueTo(rightClickHouse);
52689         });
52690
52691         timeout(function() {
52692             reveal('.entity-editor-pane',
52693                 t('intro.buildings.close', { button: icon('#icon-apply', 'pre-text') })
52694             );
52695         }, 500);
52696
52697         function continueTo(nextStep) {
52698             context.on('exit.intro', null);
52699             nextStep();
52700         }
52701     }
52702
52703
52704     function rightClickHouse() {
52705         if (!houseId) return chapter.restart();
52706
52707         context.enter(modeBrowse(context));
52708         context.history().reset('hasHouse');
52709         context.map().centerEase(house, 500);
52710
52711         timeout(function() {
52712             if (context.map().zoom() < 20) {
52713                 context.map().zoomEase(20, 500);
52714             }
52715         }, 520);
52716
52717         context.on('enter.intro', function(mode) {
52718             if (mode.id !== 'select') return;
52719             var ids = context.selectedIDs();
52720             if (ids.length !== 1 || ids[0] !== houseId) return;
52721
52722             timeout(function() {
52723                 var node = selectMenuItem('orthogonalize').node();
52724                 if (!node) return;
52725                 continueTo(clickSquare);
52726             }, 300);  // after menu visible
52727         });
52728
52729         context.map().on('move.intro drawn.intro', function() {
52730             revealHouse(house, t('intro.buildings.rightclick_building'), { duration: 0 });
52731         });
52732
52733         context.history().on('change.intro', function() {
52734             continueTo(rightClickHouse);
52735         });
52736
52737         function continueTo(nextStep) {
52738             context.on('enter.intro', null);
52739             context.map().on('move.intro drawn.intro', null);
52740             context.history().on('change.intro', null);
52741             nextStep();
52742         }
52743     }
52744
52745
52746     function clickSquare() {
52747         if (!houseId) return chapter.restart();
52748         var entity = context.hasEntity(houseId);
52749         if (!entity) return continueTo(rightClickHouse);
52750
52751         var node = selectMenuItem('orthogonalize').node();
52752         if (!node) { return continueTo(rightClickHouse); }
52753
52754         var wasChanged = false;
52755         var menuCoords = context.map().mouseCoordinates();
52756
52757         revealEditMenu(menuCoords,
52758             t('intro.buildings.square_building', { button: icon('#operation-orthogonalize', 'pre-text') })
52759         );
52760
52761         context.on('enter.intro', function(mode) {
52762             if (mode.id === 'browse') {
52763                 continueTo(rightClickHouse);
52764             } else if (mode.id === 'move' || mode.id === 'rotate') {
52765                 continueTo(retryClickSquare);
52766             }
52767         });
52768
52769         context.map().on('move.intro drawn.intro', function() {
52770             var node = selectMenuItem('orthogonalize').node();
52771             if (!wasChanged && !node) { return continueTo(rightClickHouse); }
52772
52773             revealEditMenu(menuCoords,
52774                 t('intro.buildings.square_building', { button: icon('#operation-orthogonalize', 'pre-text') }),
52775                 { duration: 0 }
52776             );
52777         });
52778
52779         context.history().on('change.intro', function() {
52780             wasChanged = true;
52781             context.history().on('change.intro', null);
52782
52783             // Something changed.  Wait for transition to complete and check undo annotation.
52784             timeout(function() {
52785                 if (context.history().undoAnnotation() === t('operations.orthogonalize.annotation.area')) {
52786                     continueTo(doneSquare);
52787                 } else {
52788                     continueTo(retryClickSquare);
52789                 }
52790             }, 500);  // after transitioned actions
52791         });
52792
52793         function continueTo(nextStep) {
52794             context.on('enter.intro', null);
52795             context.map().on('move.intro drawn.intro', null);
52796             context.history().on('change.intro', null);
52797             nextStep();
52798         }
52799     }
52800
52801
52802     function retryClickSquare() {
52803         context.enter(modeBrowse(context));
52804
52805         revealHouse(house, t('intro.buildings.retry_square'), {
52806             buttonText: t('intro.ok'),
52807             buttonCallback: function() { continueTo(rightClickHouse); }
52808         });
52809
52810         function continueTo(nextStep) {
52811             nextStep();
52812         }
52813     }
52814
52815
52816     function doneSquare() {
52817         context.history().checkpoint('doneSquare');
52818
52819         revealHouse(house, t('intro.buildings.done_square'), {
52820             buttonText: t('intro.ok'),
52821             buttonCallback: function() { continueTo(addTank); }
52822         });
52823
52824         function continueTo(nextStep) {
52825             nextStep();
52826         }
52827     }
52828
52829
52830     function addTank() {
52831         context.enter(modeBrowse(context));
52832         context.history().reset('doneSquare');
52833         tankId = null;
52834
52835         var msec = transitionTime(tank, context.map().center());
52836         if (msec) { reveal(null, null, { duration: 0 }); }
52837         context.map().zoom(19.5).centerEase(tank, msec);
52838
52839         timeout(function() {
52840             reveal('button.add-area',
52841                 t('intro.buildings.add_tank', { button: icon('#icon-area', 'pre-text') })
52842             );
52843
52844             context.on('enter.intro', function(mode) {
52845                 if (mode.id !== 'add-area') return;
52846                 continueTo(startTank);
52847             });
52848         }, msec + 100);
52849
52850         function continueTo(nextStep) {
52851             context.on('enter.intro', null);
52852             nextStep();
52853         }
52854     }
52855
52856
52857     function startTank() {
52858         if (context.mode().id !== 'add-area') {
52859             return continueTo(addTank);
52860         }
52861
52862         tankId = null;
52863
52864         timeout(function() {
52865             revealTank(tank, t('intro.buildings.start_tank'));
52866
52867             context.map().on('move.intro drawn.intro', function() {
52868                 revealTank(tank, t('intro.buildings.start_tank'), { duration: 0 });
52869             });
52870
52871             context.on('enter.intro', function(mode) {
52872                 if (mode.id !== 'draw-area') return chapter.restart();
52873                 continueTo(continueTank);
52874             });
52875
52876         }, 550);  // after easing
52877
52878         function continueTo(nextStep) {
52879             context.map().on('move.intro drawn.intro', null);
52880             context.on('enter.intro', null);
52881             nextStep();
52882         }
52883     }
52884
52885
52886     function continueTank() {
52887         if (context.mode().id !== 'draw-area') {
52888             return continueTo(addTank);
52889         }
52890
52891         tankId = null;
52892
52893         revealTank(tank, t('intro.buildings.continue_tank'));
52894
52895         context.map().on('move.intro drawn.intro', function() {
52896             revealTank(tank, t('intro.buildings.continue_tank'), { duration: 0 });
52897         });
52898
52899         context.on('enter.intro', function(mode) {
52900             if (mode.id === 'draw-area') {
52901                 return;
52902             } else if (mode.id === 'select') {
52903                 tankId = context.selectedIDs()[0];
52904                 return continueTo(searchPresetTank);
52905             } else {
52906                 return continueTo(addTank);
52907             }
52908         });
52909
52910         function continueTo(nextStep) {
52911             context.map().on('move.intro drawn.intro', null);
52912             context.on('enter.intro', null);
52913             nextStep();
52914         }
52915     }
52916
52917
52918     function searchPresetTank() {
52919         if (!tankId || !context.hasEntity(tankId)) {
52920             return addTank();
52921         }
52922         var ids = context.selectedIDs();
52923         if (context.mode().id !== 'select' || !ids.length || ids[0] !== tankId) {
52924             context.enter(modeSelect(context, [tankId]));
52925         }
52926
52927         // disallow scrolling
52928         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
52929
52930         timeout(function() {
52931             // reset pane, in case user somehow happened to change it..
52932             d3_select('.inspector-wrap .panewrap').style('right', '-100%');
52933
52934             d3_select('.preset-search-input')
52935                 .on('keydown.intro', null)
52936                 .on('keyup.intro', checkPresetSearch);
52937
52938             reveal('.preset-search-input',
52939                 t('intro.buildings.search_tank', { preset: tankPreset.name() })
52940             );
52941         }, 400);  // after preset list pane visible..
52942
52943         context.on('enter.intro', function(mode) {
52944             if (!tankId || !context.hasEntity(tankId)) {
52945                 return continueTo(addTank);
52946             }
52947
52948             var ids = context.selectedIDs();
52949             if (mode.id !== 'select' || !ids.length || ids[0] !== tankId) {
52950                 // keep the user's area selected..
52951                 context.enter(modeSelect(context, [tankId]));
52952
52953                 // reset pane, in case user somehow happened to change it..
52954                 d3_select('.inspector-wrap .panewrap').style('right', '-100%');
52955                 // disallow scrolling
52956                 d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
52957
52958                 d3_select('.preset-search-input')
52959                     .on('keydown.intro', null)
52960                     .on('keyup.intro', checkPresetSearch);
52961
52962                 reveal('.preset-search-input',
52963                     t('intro.buildings.search_tank', { preset: tankPreset.name() })
52964                 );
52965
52966                 context.history().on('change.intro', null);
52967             }
52968         });
52969
52970         function checkPresetSearch() {
52971             var first = d3_select('.preset-list-item:first-child');
52972
52973             if (first.classed('preset-man_made-storage_tank')) {
52974                 reveal(first.select('.preset-list-button').node(),
52975                     t('intro.buildings.choose_tank', { preset: tankPreset.name() }),
52976                     { duration: 300 }
52977                 );
52978
52979                 d3_select('.preset-search-input')
52980                     .on('keydown.intro', eventCancel, true)
52981                     .on('keyup.intro', null);
52982
52983                 context.history().on('change.intro', function() {
52984                     continueTo(closeEditorTank);
52985                 });
52986             }
52987         }
52988
52989         function continueTo(nextStep) {
52990             d3_select('.inspector-wrap').on('wheel.intro', null);
52991             context.on('enter.intro', null);
52992             context.history().on('change.intro', null);
52993             d3_select('.preset-search-input').on('keydown.intro keyup.intro', null);
52994             nextStep();
52995         }
52996     }
52997
52998
52999     function closeEditorTank() {
53000         if (!tankId || !context.hasEntity(tankId)) {
53001             return addTank();
53002         }
53003         var ids = context.selectedIDs();
53004         if (context.mode().id !== 'select' || !ids.length || ids[0] !== tankId) {
53005             context.enter(modeSelect(context, [tankId]));
53006         }
53007
53008         context.history().checkpoint('hasTank');
53009
53010         context.on('exit.intro', function() {
53011             continueTo(rightClickTank);
53012         });
53013
53014         timeout(function() {
53015             reveal('.entity-editor-pane',
53016                 t('intro.buildings.close', { button: icon('#icon-apply', 'pre-text') })
53017             );
53018         }, 500);
53019
53020         function continueTo(nextStep) {
53021             context.on('exit.intro', null);
53022             nextStep();
53023         }
53024     }
53025
53026
53027     function rightClickTank() {
53028         if (!tankId) return continueTo(addTank);
53029
53030         context.enter(modeBrowse(context));
53031         context.history().reset('hasTank');
53032         context.map().centerEase(tank, 500);
53033
53034         timeout(function() {
53035             context.on('enter.intro', function(mode) {
53036                 if (mode.id !== 'select') return;
53037                 var ids = context.selectedIDs();
53038                 if (ids.length !== 1 || ids[0] !== tankId) return;
53039
53040                 timeout(function() {
53041                     var node = selectMenuItem('circularize').node();
53042                     if (!node) return;
53043                     continueTo(clickCircle);
53044                 }, 300);  // after menu visible
53045             });
53046
53047             revealTank(tank, t('intro.buildings.rightclick_tank'));
53048
53049             context.map().on('move.intro drawn.intro', function() {
53050                 revealTank(tank, t('intro.buildings.rightclick_tank'), { duration: 0 });
53051             });
53052
53053             context.history().on('change.intro', function() {
53054                 continueTo(rightClickTank);
53055             });
53056
53057         }, 600);
53058
53059         function continueTo(nextStep) {
53060             context.on('enter.intro', null);
53061             context.map().on('move.intro drawn.intro', null);
53062             context.history().on('change.intro', null);
53063             nextStep();
53064         }
53065     }
53066
53067
53068     function clickCircle() {
53069         if (!tankId) return chapter.restart();
53070         var entity = context.hasEntity(tankId);
53071         if (!entity) return continueTo(rightClickTank);
53072
53073         var node = selectMenuItem('circularize').node();
53074         if (!node) { return continueTo(rightClickTank); }
53075
53076         var wasChanged = false;
53077         var menuCoords = context.map().mouseCoordinates();
53078
53079         revealEditMenu(menuCoords,
53080             t('intro.buildings.circle_tank', { button: icon('#operation-circularize', 'pre-text') })
53081         );
53082
53083         context.on('enter.intro', function(mode) {
53084             if (mode.id === 'browse') {
53085                 continueTo(rightClickTank);
53086             } else if (mode.id === 'move' || mode.id === 'rotate') {
53087                 continueTo(retryClickCircle);
53088             }
53089         });
53090
53091         context.map().on('move.intro drawn.intro', function() {
53092             var node = selectMenuItem('circularize').node();
53093             if (!wasChanged && !node) { return continueTo(rightClickTank); }
53094
53095             revealEditMenu(menuCoords,
53096                 t('intro.buildings.circle_tank', { button: icon('#operation-circularize', 'pre-text') }),
53097                 { duration: 0 }
53098             );
53099         });
53100
53101         context.history().on('change.intro', function() {
53102             wasChanged = true;
53103             context.history().on('change.intro', null);
53104
53105             // Something changed.  Wait for transition to complete and check undo annotation.
53106             timeout(function() {
53107                 if (context.history().undoAnnotation() === t('operations.circularize.annotation.area')) {
53108                     continueTo(play);
53109                 } else {
53110                     continueTo(retryClickCircle);
53111                 }
53112             }, 500);  // after transitioned actions
53113         });
53114
53115         function continueTo(nextStep) {
53116             context.on('enter.intro', null);
53117             context.map().on('move.intro drawn.intro', null);
53118             context.history().on('change.intro', null);
53119             nextStep();
53120         }
53121     }
53122
53123
53124     function retryClickCircle() {
53125         context.enter(modeBrowse(context));
53126
53127         revealTank(tank, t('intro.buildings.retry_circle'), {
53128             buttonText: t('intro.ok'),
53129             buttonCallback: function() { continueTo(rightClickTank); }
53130         });
53131
53132         function continueTo(nextStep) {
53133             nextStep();
53134         }
53135     }
53136
53137
53138     function play() {
53139         dispatch$$1.call('done');
53140         reveal('#id-container',
53141             t('intro.buildings.play', { next: t('intro.startediting.title') }), {
53142                 tooltipBox: '.intro-nav-wrap .chapter-startEditing',
53143                 buttonText: t('intro.ok'),
53144                 buttonCallback: function() { reveal('#id-container'); }
53145             }
53146         );
53147     }
53148
53149
53150     chapter.enter = function() {
53151         addHouse();
53152     };
53153
53154
53155     chapter.exit = function() {
53156         timeouts.forEach(window.clearTimeout);
53157         context.on('enter.intro exit.intro', null);
53158         context.map().on('move.intro drawn.intro', null);
53159         context.history().on('change.intro', null);
53160         d3_select('.inspector-wrap').on('wheel.intro', null);
53161         d3_select('.preset-search-input').on('keydown.intro keyup.intro', null);
53162         d3_select('.more-fields .combobox-input').on('click.intro', null);
53163     };
53164
53165
53166     chapter.restart = function() {
53167         chapter.exit();
53168         chapter.enter();
53169     };
53170
53171
53172     return utilRebind(chapter, dispatch$$1, 'on');
53173 }
53174
53175 function uiModal(selection, blocking) {
53176     var keybinding = d3keybinding('modal');
53177     var previous = selection.select('div.modal');
53178     var animate = previous.empty();
53179
53180     previous.transition()
53181         .duration(200)
53182         .style('opacity', 0)
53183         .remove();
53184
53185     var shaded = selection
53186         .append('div')
53187         .attr('class', 'shaded')
53188         .style('opacity', 0);
53189
53190     shaded.close = function() {
53191         shaded
53192             .transition()
53193             .duration(200)
53194             .style('opacity',0)
53195             .remove();
53196
53197         modal
53198             .transition()
53199             .duration(200)
53200             .style('top','0px');
53201
53202         keybinding.off();
53203     };
53204
53205
53206     var modal = shaded
53207         .append('div')
53208         .attr('class', 'modal fillL col6');
53209
53210     if (!blocking) {
53211         shaded.on('click.remove-modal', function() {
53212             if (event.target === this) {
53213                 shaded.close();
53214             }
53215         });
53216
53217         modal.append('button')
53218             .attr('class', 'close')
53219             .on('click', shaded.close)
53220             .call(svgIcon('#icon-close'));
53221
53222         keybinding
53223             .on('⌫', shaded.close)
53224             .on('⎋', shaded.close);
53225
53226         d3_select(document)
53227             .call(keybinding);
53228     }
53229
53230     modal
53231         .append('div')
53232         .attr('class', 'content');
53233
53234     if (animate) {
53235         shaded.transition().style('opacity', 1);
53236     } else {
53237         shaded.style('opacity', 1);
53238     }
53239
53240
53241     return shaded;
53242 }
53243
53244 function uiIntroStartEditing(context, reveal) {
53245     var dispatch$$1 = dispatch('done', 'startEditing'),
53246         modalSelection = d3_select(null);
53247
53248
53249     var chapter = {
53250         title: 'intro.startediting.title'
53251     };
53252
53253     function showHelp() {
53254         reveal('.map-control.help-control',
53255             t('intro.startediting.help', { button: icon('#icon-help', 'pre-text'), key: t('help.key') }), {
53256                 buttonText: t('intro.ok'),
53257                 buttonCallback: function() { shortcuts(); }
53258             }
53259         );
53260     }
53261
53262     function shortcuts() {
53263         reveal('.map-control.help-control',
53264             t('intro.startediting.shortcuts', { key: t('shortcuts.toggle.key') }), {
53265                 buttonText: t('intro.ok'),
53266                 buttonCallback: function() { showSave(); }
53267             }
53268         );
53269     }
53270
53271     function showSave() {
53272         d3_selectAll('.shaded').remove();  // in case user opened keyboard shortcuts
53273         reveal('#bar button.save',
53274             t('intro.startediting.save'), {
53275                 buttonText: t('intro.ok'),
53276                 buttonCallback: function() { showStart(); }
53277             }
53278         );
53279     }
53280
53281     function showStart() {
53282         d3_selectAll('.shaded').remove();  // in case user opened keyboard shortcuts
53283
53284         modalSelection = uiModal(context.container());
53285
53286         modalSelection.select('.modal')
53287             .attr('class', 'modal-splash modal col6');
53288
53289         modalSelection.selectAll('.close').remove();
53290
53291         var startbutton = modalSelection.select('.content')
53292             .attr('class', 'fillL')
53293             .append('button')
53294                 .attr('class', 'modal-section huge-modal-button')
53295                 .on('click', function() {
53296                     modalSelection.remove();
53297                 });
53298
53299             startbutton
53300                 .append('svg')
53301                 .attr('class', 'illustration')
53302                 .append('use')
53303                 .attr('xlink:href', '#logo-walkthrough');
53304
53305             startbutton
53306                 .append('h2')
53307                 .text(t('intro.startediting.start'));
53308
53309         dispatch$$1.call('startEditing');
53310     }
53311
53312
53313     chapter.enter = function() {
53314         showHelp();
53315     };
53316
53317
53318     chapter.exit = function() {
53319         modalSelection.remove();
53320         d3_selectAll('.shaded').remove();  // in case user opened keyboard shortcuts
53321     };
53322
53323
53324     return utilRebind(chapter, dispatch$$1, 'on');
53325 }
53326
53327 var chapterUi = {
53328     welcome: uiIntroWelcome,
53329     navigation: uiIntroNavigation,
53330     point: uiIntroPoint,
53331     area: uiIntroArea,
53332     line: uiIntroLine,
53333     building: uiIntroBuilding,
53334     startEditing: uiIntroStartEditing
53335 };
53336
53337 var chapterFlow = [
53338     'welcome',
53339     'navigation',
53340     'point',
53341     'area',
53342     'line',
53343     'building',
53344     'startEditing'
53345 ];
53346
53347
53348 function uiIntro(context) {
53349     var introGraph = {},
53350         currChapter;
53351
53352
53353     // create entities for intro graph and localize names
53354     for (var id in dataIntroGraph) {
53355         introGraph[id] = osmEntity(localize(dataIntroGraph[id]));
53356     }
53357
53358
53359     function intro(selection) {
53360         context.enter(modeBrowse(context));
53361
53362         // Save current map state
53363         var osm = context.connection(),
53364             history = context.history().toJSON(),
53365             hash = window.location.hash,
53366             center = context.map().center(),
53367             zoom = context.map().zoom(),
53368             background = context.background().baseLayerSource(),
53369             overlays = context.background().overlayLayerSources(),
53370             opacity = d3_selectAll('#map .layer-background').style('opacity'),
53371             loadedTiles = osm && osm.loadedTiles(),
53372             baseEntities = context.history().graph().base().entities,
53373             countryCode = services.geocoder.countryCode;
53374
53375         // Block saving
53376         context.inIntro(true);
53377
53378         // Load semi-real data used in intro
53379         if (osm) { osm.toggle(false).reset(); }
53380         context.history().reset();
53381         context.history().merge(values$1(coreGraph().load(introGraph).entities));
53382         context.history().checkpoint('initial');
53383
53384         var esri = context.background().findSource('EsriWorldImagery');
53385         if (esri) {
53386             context.background().baseLayerSource(esri);
53387         } else {
53388             context.background().bing();
53389         }
53390         overlays.forEach(function (d) {
53391             context.background().toggleOverlayLayer(d);
53392         });
53393
53394         // Mock geocoder
53395         services.geocoder.countryCode = function(location, callback) {
53396             callback(null, t('intro.graph.countrycode'));
53397         };
53398
53399         d3_selectAll('#map .layer-background').style('opacity', 1);
53400
53401         var curtain = uiCurtain();
53402         selection.call(curtain);
53403
53404         // store that the user started the walkthrough..
53405         context.storage('walkthrough_started', 'yes');
53406
53407         // restore previous walkthrough progress..
53408         var storedProgress = context.storage('walkthrough_progress') || '';
53409         var progress = storedProgress.split(';').filter(Boolean);
53410
53411         var chapters = chapterFlow.map(function(chapter, i) {
53412             var s = chapterUi[chapter](context, curtain.reveal)
53413                 .on('done', function() {
53414                     context.presets().init();  // clear away "recent" presets
53415
53416                     buttons.filter(function(d) {
53417                         return d.title === s.title;
53418                     }).classed('finished', true);
53419
53420                     if (i < chapterFlow.length - 1) {
53421                         var next = chapterFlow[i + 1];
53422                         d3_select('button.chapter-' + next)
53423                             .classed('next', true);
53424                     }
53425
53426                     // store walkthrough progress..
53427                     progress.push(chapter);
53428                     context.storage('walkthrough_progress', uniq(progress).join(';'));
53429                 });
53430             return s;
53431         });
53432
53433         chapters[chapters.length - 1].on('startEditing', function() {
53434             // store walkthrough progress..
53435             progress.push('startEditing');
53436             context.storage('walkthrough_progress', uniq(progress).join(';'));
53437
53438             // store if walkthrough is completed..
53439             var incomplete = difference(chapterFlow, progress);
53440             if (!incomplete.length) {
53441                 context.storage('walkthrough_completed', 'yes');
53442             }
53443
53444             curtain.remove();
53445             navwrap.remove();
53446             d3_selectAll('#map .layer-background').style('opacity', opacity);
53447             if (osm) { osm.toggle(true).reset().loadedTiles(loadedTiles); }
53448             context.history().reset().merge(values$1(baseEntities));
53449             context.background().baseLayerSource(background);
53450             overlays.forEach(function (d) { context.background().toggleOverlayLayer(d); });
53451             if (history) { context.history().fromJSON(history, false); }
53452             context.map().centerZoom(center, zoom);
53453             window.location.replace(hash);
53454             services.geocoder.countryCode = countryCode;
53455             context.inIntro(false);
53456         });
53457
53458         var navwrap = selection
53459             .append('div')
53460             .attr('class', 'intro-nav-wrap fillD');
53461
53462         navwrap
53463             .append('svg')
53464             .attr('class', 'intro-nav-wrap-logo')
53465             .append('use')
53466             .attr('xlink:href', '#logo-walkthrough');
53467
53468         var buttonwrap = navwrap
53469             .append('div')
53470             .attr('class', 'joined')
53471             .selectAll('button.chapter');
53472
53473         var buttons = buttonwrap
53474             .data(chapters)
53475             .enter()
53476             .append('button')
53477             .attr('class', function(d, i) { return 'chapter chapter-' + chapterFlow[i]; })
53478             .on('click', enterChapter);
53479
53480         buttons
53481             .append('span')
53482             .text(function(d) { return t(d.title); });
53483
53484         buttons
53485             .append('span')
53486             .attr('class', 'status')
53487             .call(svgIcon((textDirection === 'rtl' ? '#icon-backward' : '#icon-forward'), 'inline'));
53488
53489         enterChapter(chapters[0]);
53490
53491
53492         function enterChapter(newChapter) {
53493             if (currChapter) { currChapter.exit(); }
53494             context.enter(modeBrowse(context));
53495
53496             currChapter = newChapter;
53497             currChapter.enter();
53498
53499             buttons
53500                 .classed('next', false)
53501                 .classed('active', function(d) {
53502                     return d.title === currChapter.title;
53503                 });
53504         }
53505     }
53506
53507
53508     return intro;
53509 }
53510
53511 function uiTooltipHtml(text, key, heading) {
53512     var s = '';
53513
53514     if (heading) {
53515         s += '<div class="tooltip-heading"><span>' + heading + '</span></div>';
53516     }
53517     if (text) {
53518         s += '<div class="tooltip-text"><span>' + text + '</span></div>';
53519     }
53520     if (key) {
53521         s += '<div class="keyhint-wrap"><span>' + t('tooltip_keyhint') + '</span>' +
53522             '<span class="keyhint">' + key + '</span></div>';
53523     }
53524
53525     return s;
53526 }
53527
53528 function uiMapData(context) {
53529     var key = t('map_data.key');
53530     var features = context.features().keys();
53531     var layers = context.layers();
53532     var fills = ['wireframe', 'partial', 'full'];
53533
53534     var _fillSelected = context.storage('area-fill') || 'partial';
53535     var _shown = false;
53536     var _dataLayerContainer = d3_select(null);
53537     var _fillList = d3_select(null);
53538     var _featureList = d3_select(null);
53539
53540
53541     function showsFeature(d) {
53542         return context.features().enabled(d);
53543     }
53544
53545
53546     function autoHiddenFeature(d) {
53547         return context.features().autoHidden(d);
53548     }
53549
53550
53551     function clickFeature(d) {
53552         context.features().toggle(d);
53553         update();
53554     }
53555
53556
53557     function showsFill(d) {
53558         return _fillSelected === d;
53559     }
53560
53561
53562     function setFill(d) {
53563         fills.forEach(function(opt) {
53564             context.surface().classed('fill-' + opt, Boolean(opt === d));
53565         });
53566
53567         _fillSelected = d;
53568         context.storage('area-fill', d);
53569         if (d !== 'wireframe') {
53570             context.storage('area-fill-toggle', d);
53571         }
53572         update();
53573     }
53574
53575
53576     function showsLayer(which) {
53577         var layer = layers.layer(which);
53578         if (layer) {
53579             return layer.enabled();
53580         }
53581         return false;
53582     }
53583
53584
53585     function setLayer(which, enabled) {
53586         var layer = layers.layer(which);
53587         if (layer) {
53588             layer.enabled(enabled);
53589             update();
53590         }
53591     }
53592
53593
53594     function toggleLayer(which) {
53595         setLayer(which, !showsLayer(which));
53596     }
53597
53598
53599     function drawPhotoItems(selection) {
53600         var photoKeys = ['mapillary-images', 'mapillary-signs', 'openstreetcam-images'];
53601         var photoLayers = layers.all().filter(function(obj) { return photoKeys.indexOf(obj.id) !== -1; });
53602         var data = photoLayers.filter(function(obj) { return obj.layer.supported(); });
53603
53604         function layerSupported(d) {
53605             return d.layer && d.layer.supported();
53606         }
53607         function layerEnabled(d) {
53608             return layerSupported(d) && d.layer.enabled();
53609         }
53610
53611         var ul = selection
53612             .selectAll('.layer-list-photos')
53613             .data([0]);
53614
53615         ul = ul.enter()
53616             .append('ul')
53617             .attr('class', 'layer-list layer-list-photos')
53618             .merge(ul);
53619
53620         var li = ul.selectAll('.list-item-photos')
53621             .data(data);
53622
53623         li.exit()
53624             .remove();
53625
53626         var liEnter = li.enter()
53627             .append('li')
53628             .attr('class', function(d) { return 'list-item-photos list-item-' + d.id; });
53629
53630         var labelEnter = liEnter
53631             .append('label')
53632             .each(function(d) {
53633                 d3_select(this)
53634                     .call(tooltip()
53635                         .title(t(d.id.replace('-', '_') + '.tooltip'))
53636                         .placement('top')
53637                     );
53638             });
53639
53640         labelEnter
53641             .append('input')
53642             .attr('type', 'checkbox')
53643             .on('change', function(d) { toggleLayer(d.id); });
53644
53645         labelEnter
53646             .append('span')
53647             .text(function(d) { return t(d.id.replace('-', '_') + '.title'); });
53648
53649
53650         // Update
53651         li = li
53652             .merge(liEnter);
53653
53654         li
53655             .classed('active', layerEnabled)
53656             .selectAll('input')
53657             .property('checked', layerEnabled);
53658     }
53659
53660
53661     function drawOsmItem(selection) {
53662         var osm = layers.layer('osm'),
53663             showsOsm = osm.enabled();
53664
53665         var ul = selection
53666             .selectAll('.layer-list-osm')
53667             .data(osm ? [0] : []);
53668
53669         // Exit
53670         ul.exit()
53671             .remove();
53672
53673         // Enter
53674         var ulEnter = ul.enter()
53675             .append('ul')
53676             .attr('class', 'layer-list layer-list-osm');
53677
53678         var liEnter = ulEnter
53679             .append('li')
53680             .attr('class', 'list-item-osm');
53681
53682         var labelEnter = liEnter
53683             .append('label')
53684             .call(tooltip()
53685                 .title(t('map_data.layers.osm.tooltip'))
53686                 .placement('top')
53687             );
53688
53689         labelEnter
53690             .append('input')
53691             .attr('type', 'checkbox')
53692             .on('change', function() { toggleLayer('osm'); });
53693
53694         labelEnter
53695             .append('span')
53696             .text(t('map_data.layers.osm.title'));
53697
53698         // Update
53699         ul = ul
53700             .merge(ulEnter);
53701
53702         ul.selectAll('.list-item-osm')
53703             .classed('active', showsOsm)
53704             .selectAll('input')
53705             .property('checked', showsOsm);
53706     }
53707
53708
53709     function drawGpxItem(selection) {
53710         var gpx = layers.layer('gpx'),
53711             hasGpx = gpx && gpx.hasGpx(),
53712             showsGpx = hasGpx && gpx.enabled();
53713
53714         var ul = selection
53715             .selectAll('.layer-list-gpx')
53716             .data(gpx ? [0] : []);
53717
53718         // Exit
53719         ul.exit()
53720             .remove();
53721
53722         // Enter
53723         var ulEnter = ul.enter()
53724             .append('ul')
53725             .attr('class', 'layer-list layer-list-gpx');
53726
53727         var liEnter = ulEnter
53728             .append('li')
53729             .attr('class', 'list-item-gpx');
53730
53731         liEnter
53732             .append('button')
53733             .attr('class', 'list-item-gpx-extent')
53734             .call(tooltip()
53735                 .title(t('gpx.zoom'))
53736                 .placement((textDirection === 'rtl') ? 'right' : 'left')
53737             )
53738             .on('click', function() {
53739                 event.preventDefault();
53740                 event.stopPropagation();
53741                 gpx.fitZoom();
53742             })
53743             .call(svgIcon('#icon-search'));
53744
53745         liEnter
53746             .append('button')
53747             .attr('class', 'list-item-gpx-browse')
53748             .call(tooltip()
53749                 .title(t('gpx.browse'))
53750                 .placement((textDirection === 'rtl') ? 'right' : 'left')
53751             )
53752             .on('click', function() {
53753                 d3_select(document.createElement('input'))
53754                     .attr('type', 'file')
53755                     .on('change', function() {
53756                         gpx.files(event.target.files);
53757                     })
53758                     .node().click();
53759             })
53760             .call(svgIcon('#icon-geolocate'));
53761
53762         var labelEnter = liEnter
53763             .append('label')
53764             .call(tooltip()
53765                 .title(t('gpx.drag_drop'))
53766                 .placement('top')
53767             );
53768
53769         labelEnter
53770             .append('input')
53771             .attr('type', 'checkbox')
53772             .on('change', function() { toggleLayer('gpx'); });
53773
53774         labelEnter
53775             .append('span')
53776             .text(t('gpx.local_layer'));
53777
53778         // Update
53779         ul = ul
53780             .merge(ulEnter);
53781
53782         ul.selectAll('.list-item-gpx')
53783             .classed('active', showsGpx)
53784             .selectAll('label')
53785             .classed('deemphasize', !hasGpx)
53786             .selectAll('input')
53787             .property('disabled', !hasGpx)
53788             .property('checked', showsGpx);
53789     }
53790
53791
53792     function drawListItems(selection, data, type, name, change, active) {
53793         var items = selection.selectAll('li')
53794             .data(data);
53795
53796         // Exit
53797         items.exit()
53798             .remove();
53799
53800         // Enter
53801         var enter = items.enter()
53802             .append('li')
53803             .attr('class', 'layer')
53804             .call(tooltip()
53805                 .html(true)
53806                 .title(function(d) {
53807                     var tip = t(name + '.' + d + '.tooltip'),
53808                         key = (d === 'wireframe' ? t('area_fill.wireframe.key') : null);
53809
53810                     if (name === 'feature' && autoHiddenFeature(d)) {
53811                         var msg = showsLayer('osm') ? t('map_data.autohidden') : t('map_data.osmhidden');
53812                         tip += '<div>' + msg + '</div>';
53813                     }
53814                     return uiTooltipHtml(tip, key);
53815                 })
53816                 .placement('top')
53817             );
53818
53819         var label = enter
53820             .append('label');
53821
53822         label
53823             .append('input')
53824             .attr('type', type)
53825             .attr('name', name)
53826             .on('change', change);
53827
53828         label
53829             .append('span')
53830             .text(function(d) { return t(name + '.' + d + '.description'); });
53831
53832         // Update
53833         items = items
53834             .merge(enter);
53835
53836         items
53837             .classed('active', active)
53838             .selectAll('input')
53839             .property('checked', active)
53840             .property('indeterminate', function(d) {
53841                 return (name === 'feature' && autoHiddenFeature(d));
53842             });
53843     }
53844
53845
53846     function renderDataLayers(selection) {
53847         var container = selection.selectAll('data-layer-container')
53848             .data([0]);
53849
53850         _dataLayerContainer = container.enter()
53851             .append('div')
53852             .attr('class', 'data-layer-container')
53853             .merge(container);
53854     }
53855
53856
53857     function renderFillList(selection) {
53858         var container = selection.selectAll('layer-fill-list')
53859             .data([0]);
53860
53861         _fillList = container.enter()
53862             .append('ul')
53863             .attr('class', 'layer-list layer-fill-list')
53864             .merge(container);
53865     }
53866
53867
53868     function renderFeatureList(selection) {
53869         var container = selection.selectAll('layer-feature-list')
53870             .data([0]);
53871
53872         _featureList = container.enter()
53873             .append('ul')
53874             .attr('class', 'layer-list layer-feature-list')
53875             .merge(container);
53876     }
53877
53878
53879     function update() {
53880         _dataLayerContainer
53881             .call(drawOsmItem)
53882             .call(drawPhotoItems)
53883             .call(drawGpxItem);
53884
53885         _fillList
53886             .call(drawListItems, fills, 'radio', 'area_fill', setFill, showsFill);
53887
53888         _featureList
53889             .call(drawListItems, features, 'checkbox', 'feature', clickFeature, showsFeature);
53890     }
53891
53892
53893     function toggleWireframe() {
53894         if (event) {
53895             event.preventDefault();
53896             event.stopPropagation();
53897         }
53898
53899         if (_fillSelected === 'wireframe') {
53900             _fillSelected = context.storage('area-fill-toggle') || 'partial';
53901         } else {
53902             _fillSelected = 'wireframe';
53903         }
53904
53905         setFill(_fillSelected);
53906         context.map().pan([0,0]);  // trigger a redraw
53907     }
53908
53909
53910     function mapData(selection) {
53911
53912         function hidePane() {
53913             setVisible(false);
53914         }
53915
53916         function togglePane() {
53917             if (event) event.preventDefault();
53918             paneTooltip.hide(button);
53919             setVisible(!button.classed('active'));
53920         }
53921
53922         function setVisible(show) {
53923             if (show !== _shown) {
53924                 button.classed('active', show);
53925                 _shown = show;
53926
53927                 if (show) {
53928                     uiBackground.hidePane();
53929                     uiHelp.hidePane();
53930                     update();
53931
53932                     pane
53933                         .style('display', 'block')
53934                         .style('right', '-300px')
53935                         .transition()
53936                         .duration(200)
53937                         .style('right', '0px');
53938
53939                 } else {
53940                     pane
53941                         .style('display', 'block')
53942                         .style('right', '0px')
53943                         .transition()
53944                         .duration(200)
53945                         .style('right', '-300px')
53946                         .on('end', function() {
53947                             d3_select(this).style('display', 'none');
53948                         });
53949                 }
53950             }
53951         }
53952
53953
53954         var pane = selection
53955             .append('div')
53956             .attr('class', 'fillL map-overlay col3 content hide');
53957
53958         var paneTooltip = tooltip()
53959             .placement((textDirection === 'rtl') ? 'right' : 'left')
53960             .html(true)
53961             .title(uiTooltipHtml(t('map_data.description'), key));
53962
53963         var button = selection
53964             .append('button')
53965             .attr('tabindex', -1)
53966             .on('click', togglePane)
53967             .call(svgIcon('#icon-data', 'light'))
53968             .call(paneTooltip);
53969
53970
53971         pane
53972             .append('h2')
53973             .text(t('map_data.title'));
53974
53975
53976         // data layers
53977         pane
53978             .append('div')
53979             .attr('class', 'map-data-data-layers')
53980             .call(uiDisclosure(context, 'data_layers', true)
53981                 .title(t('map_data.data_layers'))
53982                 .content(renderDataLayers)
53983             );
53984
53985         // area fills
53986         pane
53987             .append('div')
53988             .attr('class', 'map-data-area-fills')
53989             .call(uiDisclosure(context, 'fill_area', false)
53990                 .title(t('map_data.fill_area'))
53991                 .content(renderFillList)
53992             );
53993
53994         // feature filters
53995         pane
53996             .append('div')
53997             .attr('class', 'map-data-feature-filters')
53998             .call(uiDisclosure(context, 'map_features', false)
53999                 .title(t('map_data.map_features'))
54000                 .content(renderFeatureList)
54001             );
54002
54003
54004         // add listeners
54005         context.features()
54006             .on('change.map_data-update', update);
54007
54008         update();
54009         setFill(_fillSelected);
54010
54011         var keybinding = d3keybinding('features')
54012             .on(key, togglePane)
54013             .on(t('area_fill.wireframe.key'), toggleWireframe)
54014             .on([t('background.key'), t('help.key')], hidePane);
54015
54016         d3_select(document)
54017             .call(keybinding);
54018
54019         uiMapData.hidePane = hidePane;
54020         uiMapData.togglePane = togglePane;
54021         uiMapData.setVisible = setVisible;
54022     }
54023
54024     return mapData;
54025 }
54026
54027 function uiShortcuts() {
54028     var detected = utilDetect();
54029     var activeTab = 0;
54030     var modalSelection;
54031     var savedSelection;
54032
54033
54034     var keybinding = d3keybinding('shortcuts')
54035         .on(t('shortcuts.toggle.key'), function () {
54036             if (d3_selectAll('.modal-shortcuts').size()) {  // already showing
54037                 if (modalSelection) {
54038                     modalSelection.close();
54039                     modalSelection = null;
54040                 }
54041             } else {
54042                 modalSelection = uiModal(savedSelection);
54043                 shortcutsModal(modalSelection);
54044             }
54045         });
54046
54047     d3_select(document)
54048         .call(keybinding);
54049
54050
54051
54052     function shortcutsModal(modalSelection) {
54053         modalSelection.select('.modal')
54054             .classed('modal-shortcuts', true);
54055
54056         var shortcutsModal = modalSelection.select('.content');
54057
54058         shortcutsModal
54059             .append('div')
54060             .attr('class', 'modal-section')
54061             .append('h3')
54062             .text(t('shortcuts.title'));
54063
54064         shortcutsModal
54065             .call(render);
54066     }
54067
54068
54069     function render(selection) {
54070         var wrapper = selection
54071             .selectAll('.wrapper')
54072             .data([0]);
54073
54074         var wrapperEnter = wrapper
54075             .enter()
54076             .append('div')
54077             .attr('class', 'wrapper modal-section');
54078
54079         var tabsBar = wrapperEnter
54080             .append('div')
54081             .attr('class', 'tabs-bar');
54082
54083         var shortcutsList = wrapperEnter
54084             .append('div')
54085             .attr('class', 'shortcuts-list');
54086
54087         wrapper = wrapper.merge(wrapperEnter);
54088
54089         var tabs = tabsBar
54090             .selectAll('.tab')
54091             .data(dataShortcuts);
54092
54093         var tabsEnter = tabs
54094             .enter()
54095             .append('div')
54096             .attr('class', 'tab')
54097             .on('click', function (d, i) {
54098                 activeTab = i;
54099                 render(selection);
54100             });
54101
54102         tabsEnter
54103             .append('span')
54104             .text(function (d) { return t(d.text); });
54105
54106         tabs = tabs
54107             .merge(tabsEnter);
54108
54109         // Update
54110         wrapper.selectAll('.tab')
54111             .classed('active', function (d, i) {
54112                 return i === activeTab;
54113             });
54114
54115
54116         var shortcuts = shortcutsList
54117             .selectAll('.shortcut-tab')
54118             .data(dataShortcuts);
54119
54120         var shortcutsEnter = shortcuts
54121             .enter()
54122             .append('div')
54123             .attr('class', function(d) { return 'shortcut-tab shortcut-tab-' + d.tab; });
54124
54125         var columnsEnter = shortcutsEnter
54126             .selectAll('.shortcut-column')
54127             .data(function (d) { return d.columns; })
54128             .enter()
54129             .append('table')
54130             .attr('class', 'shortcut-column');
54131
54132         var rowsEnter = columnsEnter
54133             .selectAll('.shortcut-row')
54134             .data(function (d) { return d.rows; })
54135             .enter()
54136             .append('tr')
54137             .attr('class', 'shortcut-row');
54138
54139
54140         var sectionRows = rowsEnter
54141             .filter(function (d) { return !d.shortcuts; });
54142
54143         sectionRows
54144             .append('td');
54145
54146         sectionRows
54147             .append('td')
54148             .attr('class', 'shortcut-section')
54149             .append('h3')
54150             .text(function (d) { return t(d.text); });
54151
54152
54153         var shortcutRows = rowsEnter
54154             .filter(function (d) { return d.shortcuts; });
54155
54156         var shortcutKeys = shortcutRows
54157             .append('td')
54158             .attr('class', 'shortcut-keys');
54159
54160         var modifierKeys = shortcutKeys
54161             .filter(function (d) { return d.modifiers; });
54162
54163         modifierKeys
54164             .selectAll('kbd.modifier')
54165             .data(function (d) {
54166                 if (detected.os === 'win' && d.text === 'shortcuts.editing.commands.redo') {
54167                     return ['⌘'];
54168                 } else if (detected.os !== 'mac' && d.text === 'shortcuts.browsing.display_options.fullscreen') {
54169                     return [];
54170                 } else {
54171                     return d.modifiers;
54172                 }
54173             })
54174             .enter()
54175             .each(function () {
54176                 var selection = d3_select(this);
54177
54178                 selection
54179                     .append('kbd')
54180                     .attr('class', 'modifier')
54181                     .text(function (d) { return uiCmd.display(d); });
54182
54183                 selection
54184                     .append('span')
54185                     .text('+');
54186             });
54187
54188
54189         shortcutKeys
54190             .selectAll('kbd.shortcut')
54191             .data(function (d) {
54192                 var arr = d.shortcuts;
54193                 if (detected.os === 'win' && d.text === 'shortcuts.editing.commands.redo') {
54194                     arr = ['Y'];
54195                 } else if (detected.os !== 'mac' && d.text === 'shortcuts.browsing.display_options.fullscreen') {
54196                     arr = ['F11'];
54197                 }
54198
54199                 return arr.map(function(s) {
54200                     return {
54201                         shortcut: s,
54202                         separator: d.separator
54203                     };
54204                 });
54205             })
54206             .enter()
54207             .each(function (d, i, nodes) {
54208                 var selection = d3_select(this);
54209                 var click = d.shortcut.toLowerCase().match(/(.*).click/);
54210
54211                 if (click && click[1]) {
54212                     selection
54213                         .call(svgIcon('#walkthrough-mouse', 'mouseclick', click[1]));
54214                 } else {
54215                     selection
54216                         .append('kbd')
54217                         .attr('class', 'shortcut')
54218                         .text(function (d) {
54219                             var key = d.shortcut;
54220                             return key.indexOf('.') !== -1 ? uiCmd.display(t(key)) : uiCmd.display(key);
54221                         });
54222                 }
54223
54224                 if (i < nodes.length - 1) {
54225                     selection
54226                         .append('span')
54227                         .text(d.separator || '\u00a0' + t('shortcuts.or') + '\u00a0');
54228                 }
54229             });
54230
54231
54232         shortcutKeys
54233             .filter(function(d) { return d.gesture; })
54234             .each(function () {
54235                 var selection = d3_select(this);
54236
54237                 selection
54238                     .append('span')
54239                     .text('+');
54240
54241                 selection
54242                     .append('span')
54243                     .attr('class', 'gesture')
54244                     .text(function (d) { return t(d.gesture); });
54245             });
54246
54247
54248         shortcutRows
54249             .append('td')
54250             .attr('class', 'shortcut-desc')
54251             .text(function (d) { return d.text ? t(d.text) : '\u00a0'; });
54252
54253
54254         shortcuts = shortcuts
54255             .merge(shortcutsEnter);
54256
54257         // Update
54258         wrapper.selectAll('.shortcut-tab')
54259             .style('display', function (d, i) {
54260                 return i === activeTab ? 'flex' : 'none';
54261             });
54262     }
54263
54264
54265     return function(selection, show) {
54266         savedSelection = selection;
54267         if (show) {
54268             modalSelection = uiModal(selection);
54269             shortcutsModal(modalSelection);
54270         }
54271     };
54272 }
54273
54274 function uiHelp(context) {
54275     var key = t('help.key');
54276
54277     var docKeys = [
54278         ['help', [
54279             'welcome',
54280             'open_data_h',
54281             'open_data',
54282             'before_start_h',
54283             'before_start',
54284             'open_source_h',
54285             'open_source',
54286             'open_source_help'
54287         ]],
54288         ['overview', [
54289             'navigation_h',
54290             'navigation_drag',
54291             'navigation_zoom',
54292             'features_h',
54293             'features',
54294             'nodes_ways'
54295         ]],
54296         ['editing', [
54297             'select_h',
54298             'select_left_click',
54299             'select_right_click',
54300             'multiselect_h',
54301             'multiselect_shift_click',
54302             'multiselect_lasso',
54303             'undo_redo_h',
54304             'undo_redo',
54305             'save_h',
54306             'save',
54307             'save_validation',
54308             'upload_h',
54309             'upload',
54310             'backups_h',
54311             'backups',
54312             'keyboard_h',
54313             'keyboard'
54314         ]],
54315         ['feature_editor', [
54316             'intro',
54317             'definitions',
54318             'type_h',
54319             'type',
54320             'type_picker',
54321             'fields_h',
54322             'fields_all_fields',
54323             'fields_example',
54324             'fields_add_field',
54325             'tags_h',
54326             'tags_all_tags',
54327             'tags_resources'
54328         ]],
54329         ['points', [
54330             'intro',
54331             'add_point_h',
54332             'add_point',
54333             'add_point_finish',
54334             'move_point_h',
54335             'move_point',
54336             'delete_point_h',
54337             'delete_point',
54338             'delete_point_command'
54339         ]],
54340         ['lines', [
54341             'intro',
54342             'add_line_h',
54343             'add_line',
54344             'add_line_draw',
54345             'add_line_finish',
54346             'modify_line_h',
54347             'modify_line_dragnode',
54348             'modify_line_addnode',
54349             'connect_line_h',
54350             'connect_line',
54351             'connect_line_display',
54352             'connect_line_drag',
54353             'connect_line_tag',
54354             'disconnect_line_h',
54355             'disconnect_line_command',
54356             'move_line_h',
54357             'move_line_command',
54358             'move_line_connected',
54359             'delete_line_h',
54360             'delete_line',
54361             'delete_line_command'
54362         ]],
54363         ['areas', [
54364             'intro',
54365             'point_or_area_h',
54366             'point_or_area',
54367             'add_area_h',
54368             'add_area_command',
54369             'add_area_draw',
54370             'add_area_finish',
54371             'square_area_h',
54372             'square_area_command',
54373             'modify_area_h',
54374             'modify_area_dragnode',
54375             'modify_area_addnode',
54376             'delete_area_h',
54377             'delete_area',
54378             'delete_area_command'
54379         ]],
54380         ['relations', [
54381             'intro',
54382             'edit_relation_h',
54383             'edit_relation',
54384             'edit_relation_add',
54385             'edit_relation_delete',
54386             'maintain_relation_h',
54387             'maintain_relation',
54388             'relation_types_h',
54389             'multipolygon_h',
54390             'multipolygon',
54391             'multipolygon_create',
54392             'multipolygon_merge',
54393             'turn_restriction_h',
54394             'turn_restriction',
54395             'turn_restriction_field',
54396             'turn_restriction_editing',
54397             'route_h',
54398             'route',
54399             'route_add',
54400             'boundary_h',
54401             'boundary',
54402             'boundary_add'
54403         ]],
54404         ['imagery', [
54405             'intro',
54406             'sources_h',
54407             'choosing',
54408             'sources',
54409             'offsets_h',
54410             'offset',
54411             'offset_change'
54412         ]],
54413         ['streetlevel', [
54414             'intro',
54415             'using_h',
54416             'using',
54417             'photos',
54418             'viewer'
54419         ]],
54420         ['gps', [
54421             'intro',
54422             'survey',
54423             'using_h',
54424             'using',
54425             'tracing',
54426             'upload'
54427         ]]
54428     ];
54429
54430     var headings = {
54431         'help.help.open_data_h': 3,
54432         'help.help.before_start_h': 3,
54433         'help.help.open_source_h': 3,
54434         'help.overview.navigation_h': 3,
54435         'help.overview.features_h': 3,
54436         'help.editing.select_h': 3,
54437         'help.editing.multiselect_h': 3,
54438         'help.editing.undo_redo_h': 3,
54439         'help.editing.save_h': 3,
54440         'help.editing.upload_h': 3,
54441         'help.editing.backups_h': 3,
54442         'help.editing.keyboard_h': 3,
54443         'help.feature_editor.type_h': 3,
54444         'help.feature_editor.fields_h': 3,
54445         'help.feature_editor.tags_h': 3,
54446         'help.points.add_point_h': 3,
54447         'help.points.move_point_h': 3,
54448         'help.points.delete_point_h': 3,
54449         'help.lines.add_line_h': 3,
54450         'help.lines.modify_line_h': 3,
54451         'help.lines.connect_line_h': 3,
54452         'help.lines.disconnect_line_h': 3,
54453         'help.lines.move_line_h': 3,
54454         'help.lines.delete_line_h': 3,
54455         'help.areas.point_or_area_h': 3,
54456         'help.areas.add_area_h': 3,
54457         'help.areas.square_area_h': 3,
54458         'help.areas.modify_area_h': 3,
54459         'help.areas.delete_area_h': 3,
54460         'help.relations.edit_relation_h': 3,
54461         'help.relations.maintain_relation_h': 3,
54462         'help.relations.relation_types_h': 2,
54463         'help.relations.multipolygon_h': 3,
54464         'help.relations.turn_restriction_h': 3,
54465         'help.relations.route_h': 3,
54466         'help.relations.boundary_h': 3,
54467         'help.imagery.sources_h': 3,
54468         'help.imagery.offsets_h': 3,
54469         'help.streetlevel.using_h': 3,
54470         'help.gps.using_h': 3,
54471     };
54472
54473     var replacements = {
54474         point: icon('#icon-point', 'pre-text'),
54475         line: icon('#icon-line', 'pre-text'),
54476         area: icon('#icon-area', 'pre-text'),
54477         plus: icon('#icon-plus', 'pre-text'),
54478         minus: icon('#icon-minus', 'pre-text'),
54479         orthogonalize: icon('#operation-orthogonalize', 'pre-text'),
54480         disconnect: icon('#operation-disconnect', 'pre-text'),
54481         layers: icon('#icon-layers', 'pre-text'),
54482         data: icon('#icon-data', 'pre-text'),
54483         inspect: icon('#icon-inspect', 'pre-text'),
54484         move: icon('#operation-move', 'pre-text'),
54485         merge: icon('#operation-merge', 'pre-text'),
54486         delete: icon('#operation-delete', 'pre-text'),
54487         close: icon('#icon-close', 'pre-text'),
54488         undo: icon(textDirection === 'rtl' ? '#icon-redo' : '#icon-undo', 'pre-text'),
54489         redo: icon(textDirection === 'rtl' ? '#icon-undo' : '#icon-redo', 'pre-text'),
54490         save: icon('#icon-save', 'pre-text'),
54491         leftclick: icon('#walkthrough-mouse', 'pre-text mouseclick', 'left'),
54492         rightclick: icon('#walkthrough-mouse', 'pre-text mouseclick', 'right'),
54493         shift: uiCmd.display('⇧'),
54494         alt: uiCmd.display('⌥'),
54495         return: uiCmd.display('↵'),
54496         version: context.version
54497     };
54498
54499     // For each section, squash all the texts into a single markdown document
54500     var docs = docKeys.map(function(key) {
54501         var helpkey = 'help.' + key[0];
54502         var text = key[1].reduce(function(all, part) {
54503             var subkey = helpkey + '.' + part;
54504             var depth = headings[subkey];                              // is this subkey a heading?
54505             var hhh = depth ? Array(depth + 1).join('#') + ' ' : '';   // if so, prepend with some ##'s
54506             return all + hhh + t(subkey, replacements) + '\n\n';
54507         }, '');
54508
54509         return {
54510             title: t(helpkey + '.title'),
54511             html: marked(text.trim())
54512         };
54513     });
54514
54515
54516     function help(selection) {
54517
54518         function hidePane() {
54519             setVisible(false);
54520         }
54521
54522
54523         function togglePane() {
54524             if (event) event.preventDefault();
54525             tooltipBehavior.hide(button);
54526             setVisible(!button.classed('active'));
54527         }
54528
54529
54530         function setVisible(show) {
54531             if (show !== shown) {
54532                 button.classed('active', show);
54533                 shown = show;
54534
54535                 if (show) {
54536                     uiBackground.hidePane();
54537                     uiMapData.hidePane();
54538
54539                     pane.style('display', 'block')
54540                         .style('right', '-500px')
54541                         .transition()
54542                         .duration(200)
54543                         .style('right', '0px');
54544
54545                 } else {
54546                     pane.style('right', '0px')
54547                         .transition()
54548                         .duration(200)
54549                         .style('right', '-500px')
54550                         .on('end', function() {
54551                             d3_select(this).style('display', 'none');
54552                         });
54553                 }
54554             }
54555         }
54556
54557
54558         function clickHelp(d, i) {
54559             var rtl = (textDirection === 'rtl');
54560             pane.property('scrollTop', 0);
54561             doctitle.html(d.title);
54562
54563             body.html(d.html);
54564             body.selectAll('a')
54565                 .attr('target', '_blank');
54566             menuItems.classed('selected', function(m) {
54567                 return m.title === d.title;
54568             });
54569
54570             nav.html('');
54571             if (rtl) {
54572                 nav.call(drawNext).call(drawPrevious);
54573             } else {
54574                 nav.call(drawPrevious).call(drawNext);
54575             }
54576
54577
54578             function drawNext(selection) {
54579                 if (i < docs.length - 1) {
54580                     var nextLink = selection
54581                         .append('a')
54582                         .attr('class', 'next')
54583                         .on('click', function() {
54584                             clickHelp(docs[i + 1], i + 1);
54585                         });
54586
54587                     nextLink
54588                         .append('span')
54589                         .text(docs[i + 1].title)
54590                         .call(svgIcon((rtl ? '#icon-backward' : '#icon-forward'), 'inline'));
54591                 }
54592             }
54593
54594
54595             function drawPrevious(selection) {
54596                 if (i > 0) {
54597                     var prevLink = selection
54598                         .append('a')
54599                         .attr('class', 'previous')
54600                         .on('click', function() {
54601                             clickHelp(docs[i - 1], i - 1);
54602                         });
54603
54604                     prevLink
54605                         .call(svgIcon((rtl ? '#icon-forward' : '#icon-backward'), 'inline'))
54606                         .append('span')
54607                         .text(docs[i - 1].title);
54608                 }
54609             }
54610         }
54611
54612
54613         function clickWalkthrough() {
54614             if (context.inIntro()) return;
54615             context.container().call(uiIntro(context));
54616             setVisible(false);
54617         }
54618
54619
54620         function clickShortcuts() {
54621             context.container().call(uiShortcuts(context), true);
54622         }
54623
54624
54625         var pane = selection.append('div')
54626             .attr('class', 'help-wrap map-overlay fillL col6 content hide');
54627         var tooltipBehavior = tooltip()
54628             .placement((textDirection === 'rtl') ? 'right' : 'left')
54629             .html(true)
54630             .title(uiTooltipHtml(t('help.title'), key));
54631         var button = selection.append('button')
54632             .attr('tabindex', -1)
54633             .on('click', togglePane)
54634             .call(svgIcon('#icon-help', 'light'))
54635             .call(tooltipBehavior);
54636         var shown = false;
54637
54638
54639         var toc = pane
54640             .append('ul')
54641             .attr('class', 'toc');
54642
54643         var menuItems = toc.selectAll('li')
54644             .data(docs)
54645             .enter()
54646             .append('li')
54647             .append('a')
54648             .html(function(d) { return d.title; })
54649             .on('click', clickHelp);
54650
54651         var shortcuts = toc
54652             .append('li')
54653             .attr('class', 'shortcuts')
54654             .call(tooltip()
54655                 .html(true)
54656                 .title(uiTooltipHtml(t('shortcuts.tooltip'), '?'))
54657                 .placement('top')
54658             )
54659             .append('a')
54660             .on('click', clickShortcuts);
54661
54662         shortcuts
54663             .append('div')
54664             .text(t('shortcuts.title'));
54665
54666         var walkthrough = toc
54667             .append('li')
54668             .attr('class', 'walkthrough')
54669             .append('a')
54670             .on('click', clickWalkthrough);
54671
54672         walkthrough
54673             .append('svg')
54674             .attr('class', 'logo logo-walkthrough')
54675             .append('use')
54676             .attr('xlink:href', '#logo-walkthrough');
54677
54678         walkthrough
54679             .append('div')
54680             .text(t('splash.walkthrough'));
54681
54682
54683         var content = pane
54684             .append('div')
54685             .attr('class', 'left-content');
54686
54687         var doctitle = content
54688             .append('h2')
54689             .text(t('help.title'));
54690
54691         var body = content
54692             .append('div')
54693             .attr('class', 'body');
54694
54695         var nav = content
54696             .append('div')
54697             .attr('class', 'nav');
54698
54699         clickHelp(docs[0], 0);
54700
54701         var keybinding = d3keybinding('help')
54702             .on(key, togglePane)
54703             .on([t('background.key'), t('map_data.key')], hidePane);
54704
54705         d3_select(document)
54706             .call(keybinding);
54707
54708         uiHelp.hidePane = hidePane;
54709         uiHelp.togglePane = togglePane;
54710         uiHelp.setVisible = setVisible;
54711     }
54712
54713     return help;
54714 }
54715
54716 function localeDateString(s) {
54717     if (!s) return null;
54718     var detected = utilDetect();
54719     var options = { day: 'numeric', month: 'short', year: 'numeric' };
54720     var d = new Date(s);
54721     if (isNaN(d.getTime())) return null;
54722     return d.toLocaleDateString(detected.locale, options);
54723 }
54724
54725 function vintageRange(vintage) {
54726     var s;
54727     if (vintage.start || vintage.end) {
54728         s = (vintage.start || '?');
54729         if (vintage.start !== vintage.end) {
54730             s += ' - ' + (vintage.end || '?');
54731         }
54732     }
54733     return s;
54734 }
54735
54736
54737 function rendererBackgroundSource(data) {
54738     var source = clone(data);
54739     var offset = [0, 0];
54740     var name = source.name;
54741     var description = source.description;
54742     var best = !!source.best;
54743     var template = source.template;
54744
54745     source.scaleExtent = data.scaleExtent || [0, 22];
54746     source.overzoom = data.overzoom !== false;
54747
54748
54749     source.offset = function(_) {
54750         if (!arguments.length) return offset;
54751         offset = _;
54752         return source;
54753     };
54754
54755
54756     source.nudge = function(_, zoomlevel) {
54757         offset[0] += _[0] / Math.pow(2, zoomlevel);
54758         offset[1] += _[1] / Math.pow(2, zoomlevel);
54759         return source;
54760     };
54761
54762
54763     source.name = function() {
54764         var id_safe = source.id.replace('.', '<TX_DOT>');
54765         return t('imagery.' + id_safe + '.name', { default: name });
54766     };
54767
54768
54769     source.description = function() {
54770         var id_safe = source.id.replace('.', '<TX_DOT>');
54771         return t('imagery.' + id_safe + '.description', { default: description });
54772     };
54773
54774
54775     source.best = function() {
54776         return best;
54777     };
54778
54779
54780     source.area = function() {
54781         if (!data.polygon) return Number.MAX_VALUE;  // worldwide
54782         var area = d3_geoArea({ type: 'MultiPolygon', coordinates: [ data.polygon ] });
54783         return isNaN(area) ? 0 : area;
54784     };
54785
54786
54787     source.imageryUsed = function() {
54788         return name || source.id;
54789     };
54790
54791
54792     source.template = function(_) {
54793         if (!arguments.length) return template;
54794         if (source.id === 'custom') template = _;
54795         return source;
54796     };
54797
54798
54799     source.url = function(coord) {
54800         return template
54801             .replace('{x}', coord[0])
54802             .replace('{y}', coord[1])
54803             // TMS-flipped y coordinate
54804             .replace(/\{[t-]y\}/, Math.pow(2, coord[2]) - coord[1] - 1)
54805             .replace(/\{z(oom)?\}/, coord[2])
54806             .replace(/\{switch:([^}]+)\}/, function(s, r) {
54807                 var subdomains = r.split(',');
54808                 return subdomains[(coord[0] + coord[1]) % subdomains.length];
54809             })
54810             .replace('{u}', function() {
54811                 var u = '';
54812                 for (var zoom = coord[2]; zoom > 0; zoom--) {
54813                     var b = 0;
54814                     var mask = 1 << (zoom - 1);
54815                     if ((coord[0] & mask) !== 0) b++;
54816                     if ((coord[1] & mask) !== 0) b += 2;
54817                     u += b.toString();
54818                 }
54819                 return u;
54820             });
54821     };
54822
54823
54824     source.intersects = function(extent) {
54825         extent = extent.polygon();
54826         return !data.polygon || data.polygon.some(function(polygon) {
54827             return geoPolygonIntersectsPolygon(polygon, extent, true);
54828         });
54829     };
54830
54831
54832     source.validZoom = function(z) {
54833         return source.scaleExtent[0] <= z &&
54834             (source.overzoom || source.scaleExtent[1] > z);
54835     };
54836
54837
54838     source.isLocatorOverlay = function() {
54839         return source.id === 'mapbox_locator_overlay';
54840     };
54841
54842
54843     /* hides a source from the list, but leaves it available for use */
54844     source.isHidden = function() {
54845         return source.id === 'DigitalGlobe-Premium-vintage' ||
54846             source.id === 'DigitalGlobe-Standard-vintage';
54847     };
54848
54849
54850     source.copyrightNotices = function() {};
54851
54852
54853     source.getMetadata = function(center, tileCoord, callback) {
54854         var vintage = {
54855             start: localeDateString(source.startDate),
54856             end: localeDateString(source.endDate)
54857         };
54858         vintage.range = vintageRange(vintage);
54859
54860         var metadata = { vintage: vintage };
54861         callback(null, metadata);
54862     };
54863
54864
54865     return source;
54866 }
54867
54868
54869 rendererBackgroundSource.Bing = function(data, dispatch) {
54870     // http://msdn.microsoft.com/en-us/library/ff701716.aspx
54871     // http://msdn.microsoft.com/en-us/library/ff701701.aspx
54872
54873     data.template = 'https://ecn.t{switch:0,1,2,3}.tiles.virtualearth.net/tiles/a{u}.jpeg?g=587&mkt=en-gb&n=z';
54874
54875     var bing = rendererBackgroundSource(data),
54876         key = 'Arzdiw4nlOJzRwOz__qailc8NiR31Tt51dN2D7cm57NrnceZnCpgOkmJhNpGoppU', // Same as P2 and JOSM
54877         url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial?include=ImageryProviders&key=' +
54878             key + '&jsonp={callback}',
54879         cache = {},
54880         inflight = {},
54881         providers = [];
54882
54883     jsonpRequest(url, function(json) {
54884         providers = json.resourceSets[0].resources[0].imageryProviders.map(function(provider) {
54885             return {
54886                 attribution: provider.attribution,
54887                 areas: provider.coverageAreas.map(function(area) {
54888                     return {
54889                         zoom: [area.zoomMin, area.zoomMax],
54890                         extent: geoExtent([area.bbox[1], area.bbox[0]], [area.bbox[3], area.bbox[2]])
54891                     };
54892                 })
54893             };
54894         });
54895         dispatch.call('change');
54896     });
54897
54898
54899     bing.copyrightNotices = function(zoom, extent) {
54900         zoom = Math.min(zoom, 21);
54901         return providers.filter(function(provider) {
54902             return some(provider.areas, function(area) {
54903                 return extent.intersects(area.extent) &&
54904                     area.zoom[0] <= zoom &&
54905                     area.zoom[1] >= zoom;
54906             });
54907         }).map(function(provider) {
54908             return provider.attribution;
54909         }).join(', ');
54910     };
54911
54912
54913     bing.getMetadata = function(center, tileCoord, callback) {
54914         var tileId = tileCoord.slice(0, 3).join('/'),
54915             zoom = Math.min(tileCoord[2], 21),
54916             centerPoint = center[1] + ',' + center[0],  // lat,lng
54917             url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial/' + centerPoint +
54918                 '?zl=' + zoom + '&key=' + key + '&jsonp={callback}';
54919
54920         if (inflight[tileId]) return;
54921
54922         if (!cache[tileId]) {
54923             cache[tileId] = {};
54924         }
54925         if (cache[tileId] && cache[tileId].metadata) {
54926             return callback(null, cache[tileId].metadata);
54927         }
54928
54929         inflight[tileId] = true;
54930         jsonpRequest(url, function(result) {
54931             delete inflight[tileId];
54932
54933             var err = (!result && 'Unknown Error') || result.errorDetails;
54934             if (err) {
54935                 return callback(err);
54936             } else {
54937                 var vintage = {
54938                     start: localeDateString(result.resourceSets[0].resources[0].vintageStart),
54939                     end: localeDateString(result.resourceSets[0].resources[0].vintageEnd)
54940                 };
54941                 vintage.range = vintageRange(vintage);
54942
54943                 var metadata = { vintage: vintage };
54944                 cache[tileId].metadata = metadata;
54945                 return callback(null, metadata);
54946             }
54947         });
54948     };
54949
54950
54951     bing.terms_url = 'https://blog.openstreetmap.org/2010/11/30/microsoft-imagery-details';
54952
54953
54954     return bing;
54955 };
54956
54957
54958
54959 rendererBackgroundSource.Esri = function(data) {
54960
54961     // don't request blank tiles, instead overzoom real tiles - #4327
54962     // deprecated technique, but it works (for now)
54963     if (data.template.match(/blankTile/) === null) {
54964         data.template = data.template + '?blankTile=false';
54965     }
54966
54967     var esri = rendererBackgroundSource(data),
54968         cache = {},
54969         inflight = {};
54970
54971     esri.getMetadata = function(center, tileCoord, callback) {
54972         var tileId = tileCoord.slice(0, 3).join('/'),
54973             zoom = Math.min(tileCoord[2], esri.scaleExtent[1]),
54974             centerPoint = center[0] + ',' + center[1],  // long, lat (as it should be)
54975             unknown = t('info_panels.background.unknown'),
54976             metadataLayer,
54977             vintage = {},
54978             metadata = {};
54979
54980         if (inflight[tileId]) return;
54981
54982         switch (true) {
54983             case zoom >= 19:
54984                 metadataLayer = 3;
54985                 break;
54986             case zoom >= 17:
54987                 metadataLayer = 2;
54988                 break;
54989             case zoom >= 13:
54990                 metadataLayer = 0;
54991                 break;
54992             default:
54993                 metadataLayer = 99;
54994         }
54995
54996         // build up query using the layer appropriate to the current zoom
54997         var url = 'https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/' + metadataLayer + '/query?returnGeometry=false&geometry=' + centerPoint + '&inSR=4326&geometryType=esriGeometryPoint&outFields=*&f=json&callback={callback}';
54998
54999         if (!cache[tileId]) {
55000             cache[tileId] = {};
55001         }
55002         if (cache[tileId] && cache[tileId].metadata) {
55003             return callback(null, cache[tileId].metadata);
55004         }
55005
55006         // accurate metadata is only available >= 13
55007         if (metadataLayer === 99) {
55008             vintage = {
55009                 start: null,
55010                 end: null,
55011                 range: null
55012             };
55013             metadata = {
55014                 vintage: null,
55015                 source: unknown,
55016                 description: unknown,
55017                 resolution: unknown,
55018                 accuracy: unknown
55019             };
55020
55021             callback(null, metadata);
55022
55023         } else {
55024             inflight[tileId] = true;
55025             jsonpRequest(url, function(result) {
55026                 delete inflight[tileId];
55027
55028                 var err;
55029                 if (!result) {
55030                     err = 'Unknown Error';
55031                 } else if (result.features && result.features.length < 1) {
55032                     err = 'No Results';
55033                 } else if (result.error && result.error.message) {
55034                     err = result.error.message;
55035                 }
55036
55037                 if (err) {
55038                     return callback(err);
55039                 } else {
55040                     // pass through the discrete capture date from metadata
55041                     var captureDate = localeDateString(result.features[0].attributes.SRC_DATE2);
55042                     vintage = {
55043                         start: captureDate,
55044                         end: captureDate,
55045                         range: captureDate
55046                     };
55047                     metadata = {
55048                         vintage: vintage,
55049                         source: clean(result.features[0].attributes.NICE_NAME),
55050                         description: clean(result.features[0].attributes.NICE_DESC),
55051                         resolution: clean(result.features[0].attributes.SRC_RES),
55052                         accuracy: clean(result.features[0].attributes.SRC_ACC)
55053                     };
55054
55055                     // append units - meters
55056                     if (isFinite(metadata.resolution)) {
55057                         metadata.resolution += ' m';
55058                     }
55059                     if (isFinite(metadata.accuracy)) {
55060                         metadata.accuracy += ' m';
55061                     }
55062
55063                     cache[tileId].metadata = metadata;
55064                     return callback(null, metadata);
55065                 }
55066             });
55067         }
55068
55069
55070         function clean(val) {
55071             return String(val).trim() || unknown;
55072         }
55073     };
55074
55075     return esri;
55076 };
55077
55078
55079 rendererBackgroundSource.None = function() {
55080     var source = rendererBackgroundSource({ id: 'none', template: '' });
55081
55082
55083     source.name = function() {
55084         return t('background.none');
55085     };
55086
55087
55088     source.imageryUsed = function() {
55089         return 'None';
55090     };
55091
55092
55093     source.area = function() {
55094         return -1;  // sources in background pane are sorted by area
55095     };
55096
55097
55098     return source;
55099 };
55100
55101
55102 rendererBackgroundSource.Custom = function(template) {
55103     var source = rendererBackgroundSource({ id: 'custom', template: template });
55104
55105
55106     source.name = function() {
55107         return t('background.custom');
55108     };
55109
55110
55111     source.imageryUsed = function() {
55112         return 'Custom (' + source.template() + ')';
55113     };
55114
55115
55116     source.area = function() {
55117         return -2;  // sources in background pane are sorted by area
55118     };
55119
55120
55121     return source;
55122 };
55123
55124 function rendererTileLayer(context) {
55125     var tileSize = 256;
55126     var transformProp = utilPrefixCSSProperty('Transform');
55127     var geotile = d3geoTile();
55128
55129     var _projection;
55130     var _cache = {};
55131     var _tileOrigin;
55132     var _zoom;
55133     var _source;
55134
55135
55136     // blacklist overlay tiles around Null Island..
55137     function nearNullIsland(x, y, z) {
55138         if (z >= 7) {
55139             var center = Math.pow(2, z - 1);
55140             var width = Math.pow(2, z - 6);
55141             var min = center - (width / 2);
55142             var max = center + (width / 2) - 1;
55143             return x >= min && x <= max && y >= min && y <= max;
55144         }
55145         return false;
55146     }
55147
55148
55149     function tileSizeAtZoom(d, z) {
55150         var EPSILON = 0.002;
55151         return ((tileSize * Math.pow(2, z - d[2])) / tileSize) + EPSILON;
55152     }
55153
55154
55155     function atZoom(t$$1, distance) {
55156         var power = Math.pow(2, distance);
55157         return [
55158             Math.floor(t$$1[0] * power),
55159             Math.floor(t$$1[1] * power),
55160             t$$1[2] + distance
55161         ];
55162     }
55163
55164
55165     function lookUp(d) {
55166         for (var up = -1; up > -d[2]; up--) {
55167             var tile = atZoom(d, up);
55168             if (_cache[_source.url(tile)] !== false) {
55169                 return tile;
55170             }
55171         }
55172     }
55173
55174
55175     function uniqueBy(a, n) {
55176         var o = [];
55177         var seen = {};
55178         for (var i = 0; i < a.length; i++) {
55179             if (seen[a[i][n]] === undefined) {
55180                 o.push(a[i]);
55181                 seen[a[i][n]] = true;
55182             }
55183         }
55184         return o;
55185     }
55186
55187
55188     function addSource(d) {
55189         d.push(_source.url(d));
55190         return d;
55191     }
55192
55193
55194     // Update tiles based on current state of `projection`.
55195     function background(selection) {
55196         _zoom = geoScaleToZoom(_projection.scale(), tileSize);
55197
55198         var pixelOffset;
55199         if (_source) {
55200             pixelOffset = [
55201                 _source.offset()[0] * Math.pow(2, _zoom),
55202                 _source.offset()[1] * Math.pow(2, _zoom)
55203             ];
55204         } else {
55205             pixelOffset = [0, 0];
55206         }
55207
55208         var translate = [
55209             _projection.translate()[0] + pixelOffset[0],
55210             _projection.translate()[1] + pixelOffset[1]
55211         ];
55212
55213         geotile
55214             .scale(_projection.scale() * 2 * Math.PI)
55215             .translate(translate);
55216
55217         _tileOrigin = [
55218             _projection.scale() * Math.PI - translate[0],
55219             _projection.scale() * Math.PI - translate[1]
55220         ];
55221
55222         render(selection);
55223     }
55224
55225
55226     // Derive the tiles onscreen, remove those offscreen and position them.
55227     // Important that this part not depend on `_projection` because it's
55228     // rentered when tiles load/error (see #644).
55229     function render(selection) {
55230         if (!_source) return;
55231         var requests = [];
55232         var showDebug = context.getDebug('tile') && !_source.overlay;
55233
55234         if (_source.validZoom(_zoom)) {
55235             geotile().forEach(function(d) {
55236                 addSource(d);
55237                 if (d[3] === '') return;
55238                 if (typeof d[3] !== 'string') return; // Workaround for #2295
55239                 requests.push(d);
55240                 if (_cache[d[3]] === false && lookUp(d)) {
55241                     requests.push(addSource(lookUp(d)));
55242                 }
55243             });
55244
55245             requests = uniqueBy(requests, 3).filter(function(r) {
55246                 if (!!_source.overlay && nearNullIsland(r[0], r[1], r[2])) {
55247                     return false;
55248                 }
55249                 // don't re-request tiles which have failed in the past
55250                 return _cache[r[3]] !== false;
55251             });
55252         }
55253
55254
55255         function load(d) {
55256             _cache[d[3]] = true;
55257             d3_select(this)
55258                 .on('error', null)
55259                 .on('load', null)
55260                 .classed('tile-loaded', true);
55261             render(selection);
55262         }
55263
55264         function error(d) {
55265             _cache[d[3]] = false;
55266             d3_select(this)
55267                 .on('error', null)
55268                 .on('load', null)
55269                 .remove();
55270             render(selection);
55271         }
55272
55273         function imageTransform(d) {
55274             var ts = tileSize * Math.pow(2, _zoom - d[2]);
55275             var scale = tileSizeAtZoom(d, _zoom);
55276             return 'translate(' +
55277                 ((d[0] * ts) - _tileOrigin[0]) + 'px,' +
55278                 ((d[1] * ts) - _tileOrigin[1]) + 'px) ' +
55279                 'scale(' + scale + ',' + scale + ')';
55280         }
55281
55282         function tileCenter(d) {
55283             var ts = tileSize * Math.pow(2, _zoom - d[2]);
55284             return [
55285                 ((d[0] * ts) - _tileOrigin[0] + (ts / 2)),
55286                 ((d[1] * ts) - _tileOrigin[1] + (ts / 2))
55287             ];
55288         }
55289
55290         function debugTransform(d) {
55291             var coord = tileCenter(d);
55292             return 'translate(' + coord[0] + 'px,' + coord[1] + 'px)';
55293         }
55294
55295
55296         // Pick a representative tile near the center of the viewport
55297         // (This is useful for sampling the imagery vintage)
55298         var dims = geotile.size();
55299         var mapCenter = [dims[0] / 2, dims[1] / 2];
55300         var minDist = Math.max(dims[0], dims[1]);
55301         var nearCenter;
55302
55303         requests.forEach(function(d) {
55304             var c = tileCenter(d);
55305             var dist = geoVecLength(c, mapCenter);
55306             if (dist < minDist) {
55307                 minDist = dist;
55308                 nearCenter = d;
55309             }
55310         });
55311
55312
55313         var image = selection.selectAll('img')
55314             .data(requests, function(d) { return d[3]; });
55315
55316         image.exit()
55317             .style(transformProp, imageTransform)
55318             .classed('tile-removing', true)
55319             .classed('tile-center', false)
55320             .each(function() {
55321                 var tile = d3_select(this);
55322                 window.setTimeout(function() {
55323                     if (tile.classed('tile-removing')) {
55324                         tile.remove();
55325                     }
55326                 }, 300);
55327             });
55328
55329         image.enter()
55330           .append('img')
55331             .attr('class', 'tile')
55332             .attr('src', function(d) { return d[3]; })
55333             .on('error', error)
55334             .on('load', load)
55335           .merge(image)
55336             .style(transformProp, imageTransform)
55337             .classed('tile-debug', showDebug)
55338             .classed('tile-removing', false)
55339             .classed('tile-center', function(d) { return d === nearCenter; });
55340
55341
55342
55343         var debug = selection.selectAll('.tile-label-debug')
55344             .data(showDebug ? requests : [], function(d) { return d[3]; });
55345
55346         debug.exit()
55347             .remove();
55348
55349         if (showDebug) {
55350             var debugEnter = debug.enter()
55351                 .append('div')
55352                 .attr('class', 'tile-label-debug');
55353
55354             debugEnter
55355                 .append('div')
55356                 .attr('class', 'tile-label-debug-coord');
55357
55358             debugEnter
55359                 .append('div')
55360                 .attr('class', 'tile-label-debug-vintage');
55361
55362             debug = debug.merge(debugEnter);
55363
55364             debug
55365                 .style(transformProp, debugTransform);
55366
55367             debug
55368                 .selectAll('.tile-label-debug-coord')
55369                 .text(function(d) { return d[2] + ' / ' + d[0] + ' / ' + d[1]; });
55370
55371             debug
55372                 .selectAll('.tile-label-debug-vintage')
55373                 .each(function(d) {
55374                     var span = d3_select(this);
55375                     var center = context.projection.invert(tileCenter(d));
55376                     _source.getMetadata(center, d, function(err, result) {
55377                         span.text((result && result.vintage && result.vintage.range) ||
55378                             t('info_panels.background.vintage') + ': ' + t('info_panels.background.unknown')
55379                         );
55380                     });
55381                 });
55382         }
55383
55384     }
55385
55386
55387     background.projection = function(_) {
55388         if (!arguments.length) return _projection;
55389         _projection = _;
55390         return background;
55391     };
55392
55393
55394     background.dimensions = function(_) {
55395         if (!arguments.length) return geotile.size();
55396         geotile.size(_);
55397         return background;
55398     };
55399
55400
55401     background.source = function(_) {
55402         if (!arguments.length) return _source;
55403         _source = _;
55404         _cache = {};
55405         geotile.scaleExtent(_source.scaleExtent);
55406         return background;
55407     };
55408
55409
55410     return background;
55411 }
55412
55413 function rendererBackground(context) {
55414     var dispatch$$1 = dispatch('change');
55415     var detected = utilDetect();
55416     var baseLayer = rendererTileLayer(context).projection(context.projection);
55417     var _overlayLayers = [];
55418     var _backgroundSources = [];
55419     var _brightness = 1;
55420     var _contrast = 1;
55421     var _saturation = 1;
55422     var _sharpness = 1;
55423
55424
55425     function background(selection) {
55426
55427         var baseFilter = '';
55428         if (detected.cssfilters) {
55429             if (_brightness !== 1) {
55430                 baseFilter += 'brightness(' + _brightness + ')';
55431             }
55432             if (_contrast !== 1) {
55433                 baseFilter += 'contrast(' + _contrast + ')';
55434             }
55435             if (_saturation !== 1) {
55436                 baseFilter += 'saturate(' + _saturation + ')';
55437             }
55438             if (_sharpness < 1) {  // gaussian blur
55439                 var blur = d3_interpolateNumber(0.5, 5)(1 - _sharpness);
55440                 baseFilter += 'blur(' + blur + 'px)';
55441             }
55442         }
55443
55444         var base = selection.selectAll('.layer-background')
55445             .data([0]);
55446
55447         base = base.enter()
55448             .insert('div', '.layer-data')
55449             .attr('class', 'layer layer-background')
55450             .merge(base);
55451
55452         if (detected.cssfilters) {
55453             base.style('filter', baseFilter || null);
55454         } else {
55455             base.style('opacity', _brightness);
55456         }
55457
55458
55459         var imagery = base.selectAll('.layer-imagery')
55460             .data([0]);
55461
55462         imagery.enter()
55463             .append('div')
55464             .attr('class', 'layer layer-imagery')
55465             .merge(imagery)
55466             .call(baseLayer);
55467
55468
55469         var maskFilter = '';
55470         var mixBlendMode = '';
55471         if (detected.cssfilters && _sharpness > 1) {  // apply unsharp mask
55472             mixBlendMode = 'overlay';
55473             maskFilter = 'saturate(0) blur(3px) invert(1)';
55474
55475             var contrast = _sharpness - 1;
55476             maskFilter += ' contrast(' + contrast + ')';
55477
55478             var brightness = d3_interpolateNumber(1, 0.85)(_sharpness - 1);
55479             maskFilter += ' brightness(' + brightness + ')';
55480         }
55481
55482         var mask = base.selectAll('.layer-unsharp-mask')
55483             .data(detected.cssfilters && _sharpness > 1 ? [0] : []);
55484
55485         mask.exit()
55486             .remove();
55487
55488         mask.enter()
55489             .append('div')
55490             .attr('class', 'layer layer-mask layer-unsharp-mask')
55491             .merge(mask)
55492             .call(baseLayer)
55493             .style('filter', maskFilter || null)
55494             .style('mix-blend-mode', mixBlendMode || null);
55495
55496
55497         var overlays = selection.selectAll('.layer-overlay')
55498             .data(_overlayLayers, function(d) { return d.source().name(); });
55499
55500         overlays.exit()
55501             .remove();
55502
55503         overlays.enter()
55504             .insert('div', '.layer-data')
55505             .attr('class', 'layer layer-overlay')
55506             .merge(overlays)
55507             .each(function(layer) { d3_select(this).call(layer); });
55508     }
55509
55510
55511     background.updateImagery = function() {
55512         if (context.inIntro()) return;
55513
55514         var b = background.baseLayerSource(),
55515             o = _overlayLayers
55516                 .filter(function (d) { return !d.source().isLocatorOverlay() && !d.source().isHidden(); })
55517                 .map(function (d) { return d.source().id; })
55518                 .join(','),
55519             meters = geoOffsetToMeters(b.offset()),
55520             epsilon = 0.01,
55521             x = +meters[0].toFixed(2),
55522             y = +meters[1].toFixed(2),
55523             q = utilStringQs(window.location.hash.substring(1));
55524
55525         var id = b.id;
55526         if (id === 'custom') {
55527             id = 'custom:' + b.template();
55528         }
55529
55530         if (id) {
55531             q.background = id;
55532         } else {
55533             delete q.background;
55534         }
55535
55536         if (o) {
55537             q.overlays = o;
55538         } else {
55539             delete q.overlays;
55540         }
55541
55542         if (Math.abs(x) > epsilon || Math.abs(y) > epsilon) {
55543             q.offset = x + ',' + y;
55544         } else {
55545             delete q.offset;
55546         }
55547
55548         if (!window.mocha) {
55549             window.location.replace('#' + utilQsString(q, true));
55550         }
55551
55552         var imageryUsed = [b.imageryUsed()];
55553
55554         _overlayLayers
55555             .filter(function (d) { return !d.source().isLocatorOverlay() && !d.source().isHidden(); })
55556             .forEach(function (d) { imageryUsed.push(d.source().imageryUsed()); });
55557
55558         var gpx = context.layers().layer('gpx');
55559         if (gpx && gpx.enabled() && gpx.hasGpx()) {
55560             // Include a string like '.gpx data file' or '.geojson data file'
55561             var match = gpx.getSrc().match(/(kml|gpx|(?:geo)?json)$/i);
55562             var extension = match ? ('.' + match[0].toLowerCase() + ' ') : '';
55563             imageryUsed.push(extension + 'data file');
55564         }
55565
55566         var mapillary_images = context.layers().layer('mapillary-images');
55567         if (mapillary_images && mapillary_images.enabled()) {
55568             imageryUsed.push('Mapillary Images');
55569         }
55570
55571         var mapillary_signs = context.layers().layer('mapillary-signs');
55572         if (mapillary_signs && mapillary_signs.enabled()) {
55573             imageryUsed.push('Mapillary Signs');
55574         }
55575
55576         var openstreetcam_images = context.layers().layer('openstreetcam-images');
55577         if (openstreetcam_images && openstreetcam_images.enabled()) {
55578             imageryUsed.push('OpenStreetCam Images');
55579         }
55580
55581         context.history().imageryUsed(imageryUsed);
55582     };
55583
55584
55585     background.sources = function(extent) {
55586         return _backgroundSources.filter(function(source) {
55587             return source.intersects(extent);
55588         });
55589     };
55590
55591
55592     background.dimensions = function(_) {
55593         if (!_) return;
55594         baseLayer.dimensions(_);
55595
55596         _overlayLayers.forEach(function(layer) {
55597             layer.dimensions(_);
55598         });
55599     };
55600
55601
55602     background.baseLayerSource = function(d) {
55603         if (!arguments.length) return baseLayer.source();
55604
55605         // test source against OSM imagery blacklists..
55606         var osm = context.connection();
55607         if (!osm) return background;
55608
55609         var blacklists = context.connection().imageryBlacklists();
55610
55611         var template = d.template(),
55612             fail = false,
55613             tested = 0,
55614             regex, i;
55615
55616         for (i = 0; i < blacklists.length; i++) {
55617             try {
55618                 regex = new RegExp(blacklists[i]);
55619                 fail = regex.test(template);
55620                 tested++;
55621                 if (fail) break;
55622             } catch (e) {
55623                 /* noop */
55624             }
55625         }
55626
55627         // ensure at least one test was run.
55628         if (!tested) {
55629             regex = new RegExp('.*\.google(apis)?\..*/(vt|kh)[\?/].*([xyz]=.*){3}.*');
55630             fail = regex.test(template);
55631         }
55632
55633         baseLayer.source(!fail ? d : background.findSource('none'));
55634         dispatch$$1.call('change');
55635         background.updateImagery();
55636         return background;
55637     };
55638
55639
55640     background.findSource = function(id) {
55641         return find$1(_backgroundSources, function(d) {
55642             return d.id && d.id === id;
55643         });
55644     };
55645
55646
55647     background.bing = function() {
55648         background.baseLayerSource(background.findSource('Bing'));
55649     };
55650
55651
55652     background.showsLayer = function(d) {
55653         return d.id === baseLayer.source().id ||
55654             _overlayLayers.some(function(layer) { return d.id === layer.source().id; });
55655     };
55656
55657
55658     background.overlayLayerSources = function() {
55659         return _overlayLayers.map(function (l) { return l.source(); });
55660     };
55661
55662
55663     background.toggleOverlayLayer = function(d) {
55664         var layer;
55665
55666         for (var i = 0; i < _overlayLayers.length; i++) {
55667             layer = _overlayLayers[i];
55668             if (layer.source() === d) {
55669                 _overlayLayers.splice(i, 1);
55670                 dispatch$$1.call('change');
55671                 background.updateImagery();
55672                 return;
55673             }
55674         }
55675
55676         layer = rendererTileLayer(context)
55677             .source(d)
55678             .projection(context.projection)
55679             .dimensions(baseLayer.dimensions()
55680         );
55681
55682         _overlayLayers.push(layer);
55683         dispatch$$1.call('change');
55684         background.updateImagery();
55685     };
55686
55687
55688     background.nudge = function(d, zoom) {
55689         baseLayer.source().nudge(d, zoom);
55690         dispatch$$1.call('change');
55691         background.updateImagery();
55692         return background;
55693     };
55694
55695
55696     background.offset = function(d) {
55697         if (!arguments.length) return baseLayer.source().offset();
55698         baseLayer.source().offset(d);
55699         dispatch$$1.call('change');
55700         background.updateImagery();
55701         return background;
55702     };
55703
55704
55705     background.brightness = function(d) {
55706         if (!arguments.length) return _brightness;
55707         _brightness = d;
55708         if (context.mode()) dispatch$$1.call('change');
55709         return background;
55710     };
55711
55712
55713     background.contrast = function(d) {
55714         if (!arguments.length) return _contrast;
55715         _contrast = d;
55716         if (context.mode()) dispatch$$1.call('change');
55717         return background;
55718     };
55719
55720
55721     background.saturation = function(d) {
55722         if (!arguments.length) return _saturation;
55723         _saturation = d;
55724         if (context.mode()) dispatch$$1.call('change');
55725         return background;
55726     };
55727
55728
55729     background.sharpness = function(d) {
55730         if (!arguments.length) return _sharpness;
55731         _sharpness = d;
55732         if (context.mode()) dispatch$$1.call('change');
55733         return background;
55734     };
55735
55736
55737     background.init = function() {
55738         function parseMap(qmap) {
55739             if (!qmap) return false;
55740             var args = qmap.split('/').map(Number);
55741             if (args.length < 3 || args.some(isNaN)) return false;
55742             return geoExtent([args[2], args[1]]);
55743         }
55744
55745         var dataImagery = data.imagery || [],
55746             q = utilStringQs(window.location.hash.substring(1)),
55747             requested = q.background || q.layer,
55748             extent = parseMap(q.map),
55749             first,
55750             best;
55751
55752         // Add all the available imagery sources
55753         _backgroundSources = dataImagery.map(function(source) {
55754             if (source.type === 'bing') {
55755                 return rendererBackgroundSource.Bing(source, dispatch$$1);
55756             } else if (/^EsriWorldImagery/.test(source.id)) {
55757                 return rendererBackgroundSource.Esri(source);
55758             } else {
55759                 return rendererBackgroundSource(source);
55760             }
55761         });
55762
55763         first = _backgroundSources.length && _backgroundSources[0];
55764
55765         // Add 'None'
55766         _backgroundSources.unshift(rendererBackgroundSource.None());
55767
55768         // Add 'Custom'
55769         var template = context.storage('background-custom-template') || '';
55770         var custom = rendererBackgroundSource.Custom(template);
55771         _backgroundSources.unshift(custom);
55772
55773
55774         // Decide which background layer to display
55775         if (!requested && extent) {
55776             best = find$1(this.sources(extent), function(s) { return s.best(); });
55777         }
55778         if (requested && requested.indexOf('custom:') === 0) {
55779             template = requested.replace(/^custom:/, '');
55780             background.baseLayerSource(custom.template(template));
55781             context.storage('background-custom-template', template);
55782         } else {
55783             background.baseLayerSource(
55784                 background.findSource(requested) ||
55785                 best ||
55786                 background.findSource(context.storage('background-last-used')) ||
55787                 background.findSource('Bing') ||
55788                 first ||
55789                 background.findSource('none')
55790             );
55791         }
55792
55793         var locator = find$1(_backgroundSources, function(d) {
55794             return d.overlay && d.default;
55795         });
55796
55797         if (locator) {
55798             background.toggleOverlayLayer(locator);
55799         }
55800
55801         var overlays = (q.overlays || '').split(',');
55802         overlays.forEach(function(overlay) {
55803             overlay = background.findSource(overlay);
55804             if (overlay) {
55805                 background.toggleOverlayLayer(overlay);
55806             }
55807         });
55808
55809         if (q.gpx) {
55810             var gpx = context.layers().layer('gpx');
55811             if (gpx) {
55812                 gpx.url(q.gpx);
55813             }
55814         }
55815
55816         if (q.offset) {
55817             var offset = q.offset.replace(/;/g, ',').split(',').map(function(n) {
55818                 return !isNaN(n) && n;
55819             });
55820
55821             if (offset.length === 2) {
55822                 background.offset(geoMetersToOffset(offset));
55823             }
55824         }
55825     };
55826
55827
55828     return utilRebind(background, dispatch$$1, 'on');
55829 }
55830
55831 function rendererFeatures(context) {
55832     var traffic_roads = {
55833         'motorway': true,
55834         'motorway_link': true,
55835         'trunk': true,
55836         'trunk_link': true,
55837         'primary': true,
55838         'primary_link': true,
55839         'secondary': true,
55840         'secondary_link': true,
55841         'tertiary': true,
55842         'tertiary_link': true,
55843         'residential': true,
55844         'unclassified': true,
55845         'living_street': true
55846     };
55847
55848     var service_roads = {
55849         'service': true,
55850         'road': true,
55851         'track': true
55852     };
55853
55854     var paths = {
55855         'path': true,
55856         'footway': true,
55857         'cycleway': true,
55858         'bridleway': true,
55859         'steps': true,
55860         'pedestrian': true,
55861         'corridor': true
55862     };
55863
55864     var past_futures = {
55865         'proposed': true,
55866         'construction': true,
55867         'abandoned': true,
55868         'dismantled': true,
55869         'disused': true,
55870         'razed': true,
55871         'demolished': true,
55872         'obliterated': true
55873     };
55874
55875     var dispatch$$1 = dispatch('change', 'redraw'),
55876         _cullFactor = 1,
55877         _cache = {},
55878         _features = {},
55879         _stats = {},
55880         _keys = [],
55881         _hidden = [];
55882
55883
55884     function update() {
55885         if (!window.mocha) {
55886             var q = utilStringQs(window.location.hash.substring(1));
55887             var disabled = features.disabled();
55888             if (disabled.length) {
55889                 q.disable_features = disabled.join(',');
55890             } else {
55891                 delete q.disable_features;
55892             }
55893             window.location.replace('#' + utilQsString(q, true));
55894             context.storage('disabled-features', disabled.join(','));
55895         }
55896         _hidden = features.hidden();
55897         dispatch$$1.call('change');
55898         dispatch$$1.call('redraw');
55899     }
55900
55901
55902     function defineFeature(k, filter, max) {
55903         var isEnabled = true;
55904
55905         _keys.push(k);
55906         _features[k] = {
55907             filter: filter,
55908             enabled: isEnabled,   // whether the user wants it enabled..
55909             count: 0,
55910             currentMax: (max || Infinity),
55911             defaultMax: (max || Infinity),
55912             enable: function() { this.enabled = true; this.currentMax = this.defaultMax; },
55913             disable: function() { this.enabled = false; this.currentMax = 0; },
55914             hidden: function() { return !context.editable() || this.count > this.currentMax * _cullFactor; },
55915             autoHidden: function() { return this.hidden() && this.currentMax > 0; }
55916         };
55917     }
55918
55919
55920     defineFeature('points', function isPoint(entity, resolver, geometry) {
55921         return geometry === 'point';
55922     }, 200);
55923
55924     defineFeature('traffic_roads', function isTrafficRoad(entity) {
55925         return traffic_roads[entity.tags.highway];
55926     });
55927
55928     defineFeature('service_roads', function isServiceRoad(entity) {
55929         return service_roads[entity.tags.highway];
55930     });
55931
55932     defineFeature('paths', function isPath(entity) {
55933         return paths[entity.tags.highway];
55934     });
55935
55936     defineFeature('buildings', function isBuilding(entity) {
55937         return (
55938             !!entity.tags['building:part'] ||
55939             (!!entity.tags.building && entity.tags.building !== 'no') ||
55940             entity.tags.amenity === 'shelter' ||
55941             entity.tags.parking === 'multi-storey' ||
55942             entity.tags.parking === 'sheds' ||
55943             entity.tags.parking === 'carports' ||
55944             entity.tags.parking === 'garage_boxes'
55945         );
55946     }, 250);
55947
55948     defineFeature('landuse', function isLanduse(entity, resolver, geometry) {
55949         return geometry === 'area' &&
55950             !_features.buildings.filter(entity) &&
55951             !_features.water.filter(entity);
55952     });
55953
55954     defineFeature('boundaries', function isBoundary(entity) {
55955         return !!entity.tags.boundary;
55956     });
55957
55958     defineFeature('water', function isWater(entity) {
55959         return (
55960             !!entity.tags.waterway ||
55961             entity.tags.natural === 'water' ||
55962             entity.tags.natural === 'coastline' ||
55963             entity.tags.natural === 'bay' ||
55964             entity.tags.landuse === 'pond' ||
55965             entity.tags.landuse === 'basin' ||
55966             entity.tags.landuse === 'reservoir' ||
55967             entity.tags.landuse === 'salt_pond'
55968         );
55969     });
55970
55971     defineFeature('rail', function isRail(entity) {
55972         return (
55973             !!entity.tags.railway ||
55974             entity.tags.landuse === 'railway'
55975         ) && !(
55976             traffic_roads[entity.tags.highway] ||
55977             service_roads[entity.tags.highway] ||
55978             paths[entity.tags.highway]
55979         );
55980     });
55981
55982     defineFeature('power', function isPower(entity) {
55983         return !!entity.tags.power;
55984     });
55985
55986     // contains a past/future tag, but not in active use as a road/path/cycleway/etc..
55987     defineFeature('past_future', function isPastFuture(entity) {
55988         if (
55989             traffic_roads[entity.tags.highway] ||
55990             service_roads[entity.tags.highway] ||
55991             paths[entity.tags.highway]
55992         ) { return false; }
55993
55994         var strings = Object.keys(entity.tags);
55995
55996         for (var i = 0; i < strings.length; i++) {
55997             var s = strings[i];
55998             if (past_futures[s] || past_futures[entity.tags[s]]) { return true; }
55999         }
56000         return false;
56001     });
56002
56003     // Lines or areas that don't match another feature filter.
56004     // IMPORTANT: The 'others' feature must be the last one defined,
56005     //   so that code in getMatches can skip this test if `hasMatch = true`
56006     defineFeature('others', function isOther(entity, resolver, geometry) {
56007         return (geometry === 'line' || geometry === 'area');
56008     });
56009
56010
56011     function features() {}
56012
56013
56014     features.features = function() {
56015         return _features;
56016     };
56017
56018
56019     features.keys = function() {
56020         return _keys;
56021     };
56022
56023
56024     features.enabled = function(k) {
56025         if (!arguments.length) {
56026             return _keys.filter(function(k) { return _features[k].enabled; });
56027         }
56028         return _features[k] && _features[k].enabled;
56029     };
56030
56031
56032     features.disabled = function(k) {
56033         if (!arguments.length) {
56034             return _keys.filter(function(k) { return !_features[k].enabled; });
56035         }
56036         return _features[k] && !_features[k].enabled;
56037     };
56038
56039
56040     features.hidden = function(k) {
56041         if (!arguments.length) {
56042             return _keys.filter(function(k) { return _features[k].hidden(); });
56043         }
56044         return _features[k] && _features[k].hidden();
56045     };
56046
56047
56048     features.autoHidden = function(k) {
56049         if (!arguments.length) {
56050             return _keys.filter(function(k) { return _features[k].autoHidden(); });
56051         }
56052         return _features[k] && _features[k].autoHidden();
56053     };
56054
56055
56056     features.enable = function(k) {
56057         if (_features[k] && !_features[k].enabled) {
56058             _features[k].enable();
56059             update();
56060         }
56061     };
56062
56063
56064     features.disable = function(k) {
56065         if (_features[k] && _features[k].enabled) {
56066             _features[k].disable();
56067             update();
56068         }
56069     };
56070
56071
56072     features.toggle = function(k) {
56073         if (_features[k]) {
56074             (function(f) { return f.enabled ? f.disable() : f.enable(); }(_features[k]));
56075             update();
56076         }
56077     };
56078
56079
56080     features.resetStats = function() {
56081         for (var i = 0; i < _keys.length; i++) {
56082             _features[_keys[i]].count = 0;
56083         }
56084         dispatch$$1.call('change');
56085     };
56086
56087
56088     features.gatherStats = function(d, resolver, dimensions) {
56089         var needsRedraw = false,
56090             type = groupBy(d, function(ent) { return ent.type; }),
56091             entities = [].concat(type.relation || [], type.way || [], type.node || []),
56092             currHidden, geometry, matches, i, j;
56093
56094         for (i = 0; i < _keys.length; i++) {
56095             _features[_keys[i]].count = 0;
56096         }
56097
56098         // adjust the threshold for point/building culling based on viewport size..
56099         // a _cullFactor of 1 corresponds to a 1000x1000px viewport..
56100         _cullFactor = dimensions[0] * dimensions[1] / 1000000;
56101
56102         for (i = 0; i < entities.length; i++) {
56103             geometry = entities[i].geometry(resolver);
56104             if (!(geometry === 'vertex' || geometry === 'relation')) {
56105                 matches = Object.keys(features.getMatches(entities[i], resolver, geometry));
56106                 for (j = 0; j < matches.length; j++) {
56107                     _features[matches[j]].count++;
56108                 }
56109             }
56110         }
56111
56112         currHidden = features.hidden();
56113         if (currHidden !== _hidden) {
56114             _hidden = currHidden;
56115             needsRedraw = true;
56116             dispatch$$1.call('change');
56117         }
56118
56119         return needsRedraw;
56120     };
56121
56122
56123     features.stats = function() {
56124         for (var i = 0; i < _keys.length; i++) {
56125             _stats[_keys[i]] = _features[_keys[i]].count;
56126         }
56127
56128         return _stats;
56129     };
56130
56131
56132     features.clear = function(d) {
56133         for (var i = 0; i < d.length; i++) {
56134             features.clearEntity(d[i]);
56135         }
56136     };
56137
56138
56139     features.clearEntity = function(entity) {
56140         delete _cache[osmEntity.key(entity)];
56141     };
56142
56143
56144     features.reset = function() {
56145         _cache = {};
56146     };
56147
56148
56149     features.getMatches = function(entity, resolver, geometry) {
56150         if (geometry === 'vertex' || geometry === 'relation') return {};
56151
56152         var ent = osmEntity.key(entity);
56153         if (!_cache[ent]) {
56154             _cache[ent] = {};
56155         }
56156
56157         if (!_cache[ent].matches) {
56158             var matches = {},
56159                 hasMatch = false;
56160
56161             for (var i = 0; i < _keys.length; i++) {
56162                 if (_keys[i] === 'others') {
56163                     if (hasMatch) continue;
56164
56165                     // Multipolygon members:
56166                     // If an entity...
56167                     //   1. is a way that hasn't matched other 'interesting' feature rules,
56168                     //   2. and it belongs to a single parent multipolygon relation
56169                     // ...then match whatever feature rules the parent multipolygon has matched.
56170                     // see #2548, #2887
56171                     //
56172                     // IMPORTANT:
56173                     // For this to work, getMatches must be called on relations before ways.
56174                     //
56175                     if (entity.type === 'way') {
56176                         var parents = features.getParents(entity, resolver, geometry);
56177                         if (parents.length === 1 && parents[0].isMultipolygon()) {
56178                             var pkey = osmEntity.key(parents[0]);
56179                             if (_cache[pkey] && _cache[pkey].matches) {
56180                                 matches = clone(_cache[pkey].matches);
56181                                 continue;
56182                             }
56183                         }
56184                     }
56185                 }
56186
56187                 if (_features[_keys[i]].filter(entity, resolver, geometry)) {
56188                     matches[_keys[i]] = hasMatch = true;
56189                 }
56190             }
56191             _cache[ent].matches = matches;
56192         }
56193
56194         return _cache[ent].matches;
56195     };
56196
56197
56198     features.getParents = function(entity, resolver, geometry) {
56199         if (geometry === 'point') return [];
56200
56201         var ent = osmEntity.key(entity);
56202         if (!_cache[ent]) {
56203             _cache[ent] = {};
56204         }
56205
56206         if (!_cache[ent].parents) {
56207             var parents = [];
56208             if (geometry === 'vertex') {
56209                 parents = resolver.parentWays(entity);
56210             } else {   // 'line', 'area', 'relation'
56211                 parents = resolver.parentRelations(entity);
56212             }
56213             _cache[ent].parents = parents;
56214         }
56215         return _cache[ent].parents;
56216     };
56217
56218
56219     features.isHiddenFeature = function(entity, resolver, geometry) {
56220         if (!_hidden.length) return false;
56221         if (!entity.version) return false;
56222
56223         var matches = features.getMatches(entity, resolver, geometry);
56224
56225         for (var i = 0; i < _hidden.length; i++) {
56226             if (matches[_hidden[i]]) return true;
56227         }
56228         return false;
56229     };
56230
56231
56232     features.isHiddenChild = function(entity, resolver, geometry) {
56233         if (!_hidden.length) return false;
56234         if (!entity.version || geometry === 'point') return false;
56235
56236         var parents = features.getParents(entity, resolver, geometry);
56237         if (!parents.length) return false;
56238
56239         for (var i = 0; i < parents.length; i++) {
56240             if (!features.isHidden(parents[i], resolver, parents[i].geometry(resolver))) {
56241                 return false;
56242             }
56243         }
56244         return true;
56245     };
56246
56247
56248     features.hasHiddenConnections = function(entity, resolver) {
56249         if (!_hidden.length) return false;
56250         var childNodes, connections;
56251
56252         if (entity.type === 'midpoint') {
56253             childNodes = [resolver.entity(entity.edge[0]), resolver.entity(entity.edge[1])];
56254             connections = [];
56255         } else {
56256             childNodes = entity.nodes ? resolver.childNodes(entity) : [];
56257             connections = features.getParents(entity, resolver, entity.geometry(resolver));
56258         }
56259
56260         // gather ways connected to child nodes..
56261         connections = reduce(childNodes, function(result, e) {
56262             return resolver.isShared(e) ? union(result, resolver.parentWays(e)) : result;
56263         }, connections);
56264
56265         return connections.length ? some(connections, function(e) {
56266             return features.isHidden(e, resolver, e.geometry(resolver));
56267         }) : false;
56268     };
56269
56270
56271     features.isHidden = function(entity, resolver, geometry) {
56272         if (!_hidden.length) return false;
56273         if (!entity.version) return false;
56274
56275         var fn = (geometry === 'vertex' ? features.isHiddenChild : features.isHiddenFeature);
56276         return fn(entity, resolver, geometry);
56277     };
56278
56279
56280     features.filter = function(d, resolver) {
56281         if (!_hidden.length) return d;
56282
56283         var result = [];
56284         for (var i = 0; i < d.length; i++) {
56285             var entity = d[i];
56286             if (!features.isHidden(entity, resolver, entity.geometry(resolver))) {
56287                 result.push(entity);
56288             }
56289         }
56290         return result;
56291     };
56292
56293
56294     features.init = function() {
56295         var storage = context.storage('disabled-features');
56296         if (storage) {
56297             var storageDisabled = storage.replace(/;/g, ',').split(',');
56298             storageDisabled.forEach(features.disable);
56299         }
56300         
56301         var q = utilStringQs(window.location.hash.substring(1));
56302         if (q.disable_features) {
56303             var hashDisabled = q.disable_features.replace(/;/g, ',').split(',');
56304             hashDisabled.forEach(features.disable);
56305         }
56306     };
56307
56308     return utilRebind(features, dispatch$$1, 'on');
56309 }
56310
56311 function utilBindOnce(target, type, listener, capture) {
56312     var typeOnce = type + '.once';
56313     function one() {
56314         target.on(typeOnce, null);
56315         listener.apply(this, arguments);
56316     }
56317     target.on(typeOnce, one, capture);
56318     return this;
56319 }
56320
56321 function rendererMap(context) {
56322
56323     var dimensions = [1, 1],
56324         dispatch$$1 = dispatch('move', 'drawn'),
56325         projection = context.projection,
56326         curtainProjection = context.curtainProjection,
56327         dblclickEnabled = true,
56328         redrawEnabled = true,
56329         transformStart = projection.transform(),
56330         transformLast,
56331         transformed = false,
56332         minzoom = 0,
56333         drawLayers = svgLayers(projection, context),
56334         drawPoints = svgPoints(projection, context),
56335         drawVertices = svgVertices(projection, context),
56336         drawLines = svgLines(projection, context),
56337         drawAreas = svgAreas(projection, context),
56338         drawMidpoints = svgMidpoints(projection, context),
56339         drawLabels = svgLabels(projection, context),
56340         supersurface = d3_select(null),
56341         wrapper = d3_select(null),
56342         surface = d3_select(null),
56343         mouse,
56344         mousemove;
56345
56346     var zoom$$1 = d3_zoom()
56347         .scaleExtent([ztok(2), ztok(24)])
56348         .interpolate(d3_interpolate)
56349         .filter(zoomEventFilter)
56350         .on('zoom', zoomPan);
56351
56352     var _selection = d3_select(null);
56353
56354     var scheduleRedraw = throttle(redraw, 750);
56355     // var isRedrawScheduled = false;
56356     // var pendingRedrawCall;
56357     // function scheduleRedraw() {
56358     //     // Only schedule the redraw if one has not already been set.
56359     //     if (isRedrawScheduled) return;
56360     //     isRedrawScheduled = true;
56361     //     var that = this;
56362     //     var args = arguments;
56363     //     pendingRedrawCall = window.requestIdleCallback(function () {
56364     //         // Reset the boolean so future redraws can be set.
56365     //         isRedrawScheduled = false;
56366     //         redraw.apply(that, args);
56367     //     }, { timeout: 1400 });
56368     // }
56369
56370     function cancelPendingRedraw() {
56371         scheduleRedraw.cancel();
56372         // isRedrawScheduled = false;
56373         // window.cancelIdleCallback(pendingRedrawCall);
56374     }
56375
56376     function map(selection) {
56377
56378         _selection = selection;
56379
56380         context
56381             .on('change.map', immediateRedraw);
56382
56383         var osm = context.connection();
56384         if (osm) {
56385             osm.on('change.map', immediateRedraw);
56386         }
56387
56388         context.history()
56389             .on('change.map', immediateRedraw)
56390             .on('undone.map redone.map', function(stack) {
56391                 var mode = context.mode().id;
56392                 if (mode !== 'browse' && mode !== 'select') return;
56393
56394                 var followSelected = false;
56395                 if (Array.isArray(stack.selectedIDs)) {
56396                     followSelected = (stack.selectedIDs.length === 1 && stack.selectedIDs[0][0] === 'n');
56397                     context.enter(
56398                         modeSelect(context, stack.selectedIDs).follow(followSelected)
56399                     );
56400                 }
56401                 if (!followSelected && stack.transform) {
56402                     map.transformEase(stack.transform);
56403                 }
56404             });
56405
56406         context.background()
56407             .on('change.map', immediateRedraw);
56408
56409         context.features()
56410             .on('redraw.map', immediateRedraw);
56411
56412         drawLayers
56413             .on('change.map', function() {
56414                 context.background().updateImagery();
56415                 immediateRedraw();
56416             });
56417
56418         selection
56419             .on('dblclick.map', dblClick)
56420             .call(zoom$$1)
56421             .call(zoom$$1.transform, projection.transform());
56422
56423         supersurface = selection.append('div')
56424             .attr('id', 'supersurface')
56425             .call(utilSetTransform, 0, 0);
56426
56427         // Need a wrapper div because Opera can't cope with an absolutely positioned
56428         // SVG element: http://bl.ocks.org/jfirebaugh/6fbfbd922552bf776c16
56429         wrapper = supersurface
56430             .append('div')
56431             .attr('class', 'layer layer-data');
56432
56433         map.surface = surface = wrapper
56434             .call(drawLayers)
56435             .selectAll('.surface')
56436             .attr('id', 'surface');
56437
56438         surface
56439             .call(drawLabels.observe)
56440             .on('mousedown.zoom', function() {
56441                 if (event.button === 2) {
56442                     event.stopPropagation();
56443                 }
56444             }, true)
56445             .on('mouseup.zoom', function() {
56446                 if (resetTransform()) immediateRedraw();
56447             })
56448             .on('mousemove.map', function() {
56449                 mousemove = event;
56450             })
56451             .on('mouseover.vertices', function() {
56452                 if (map.editable() && !transformed) {
56453                     var hover = event.target.__data__;
56454                     surface.selectAll('.data-layer-osm')
56455                         .call(drawVertices.drawHover, context.graph(), hover, map.extent());
56456                     dispatch$$1.call('drawn', this, { full: false });
56457                 }
56458             })
56459             .on('mouseout.vertices', function() {
56460                 if (map.editable() && !transformed) {
56461                     var hover = event.relatedTarget && event.relatedTarget.__data__;
56462                     surface.selectAll('.data-layer-osm')
56463                         .call(drawVertices.drawHover, context.graph(), hover, map.extent());
56464                     dispatch$$1.call('drawn', this, { full: false });
56465                 }
56466             });
56467
56468         supersurface
56469             .call(context.background());
56470
56471         context.on('enter.map',  function() {
56472             if (map.editable() && !transformed) {
56473
56474                 // redraw immediately any objects affected by a change in selectedIDs.
56475                 var graph = context.graph();
56476                 var selectedAndParents = {};
56477                 context.selectedIDs().forEach(function(id) {
56478                     var entity = graph.hasEntity(id);
56479                     if (entity) {
56480                         selectedAndParents[entity.id] = entity;
56481                         if (entity.type === 'node') {
56482                             graph.parentWays(entity).forEach(function(parent) {
56483                                 selectedAndParents[parent.id] = parent;
56484                             });
56485                         }
56486                     }
56487                 });
56488                 var data = values$1(selectedAndParents);
56489                 var filter = function(d) { return d.id in selectedAndParents; };
56490
56491                 data = context.features().filter(data, graph);
56492
56493                 surface.selectAll('.data-layer-osm')
56494                     .call(drawVertices.drawSelected, graph, map.extent())
56495                     .call(drawLines, graph, data, filter)
56496                     .call(drawAreas, graph, data, filter)
56497                     .call(drawMidpoints, graph, data, filter, map.trimmedExtent());
56498
56499                 dispatch$$1.call('drawn', this, { full: false });
56500
56501
56502                 // redraw everything else later
56503                 scheduleRedraw();
56504             }
56505         });
56506
56507         map.dimensions(utilGetDimensions(selection));
56508     }
56509
56510
56511     function zoomEventFilter() {
56512         // Fix for #2151, (see also d3/d3-zoom#60, d3/d3-brush#18)
56513         // Intercept `mousedown` and check if there is an orphaned zoom gesture.
56514         // This can happen if a previous `mousedown` occurred without a `mouseup`.
56515         // If we detect this, dispatch `mouseup` to complete the orphaned gesture,
56516         // so that d3-zoom won't stop propagation of new `mousedown` events.
56517         if (event.type === 'mousedown') {
56518             var hasOrphan = false;
56519             var listeners = window.__on;
56520             for (var i = 0; i < listeners.length; i++) {
56521                 var listener = listeners[i];
56522                 if (listener.name === 'zoom' && listener.type === 'mouseup') {
56523                     hasOrphan = true;
56524                     break;
56525                 }
56526             }
56527             if (hasOrphan) {
56528                 var event$$1 = window.CustomEvent;
56529                 if (event$$1) {
56530                     event$$1 = new event$$1('mouseup');
56531                 } else {
56532                     event$$1 = window.document.createEvent('Event');
56533                     event$$1.initEvent('mouseup', false, false);
56534                 }
56535                 // Event needs to be dispatched with an event.view property.
56536                 event$$1.view = window;
56537                 window.dispatchEvent(event$$1);
56538             }
56539         }
56540
56541         return event.button !== 2;   // ignore right clicks
56542     }
56543
56544
56545     function ztok(z) {
56546         return 256 * Math.pow(2, z);
56547     }
56548
56549     function ktoz(k) {
56550         return Math.max(Math.log(k) / Math.LN2 - 8, 0);
56551     }
56552
56553     function pxCenter() {
56554         return [dimensions[0] / 2, dimensions[1] / 2];
56555     }
56556
56557
56558     function drawVector(difference, extent) {
56559         var mode = context.mode();
56560         var graph = context.graph();
56561         var features = context.features();
56562         var all = context.intersects(map.extent());
56563         var fullRedraw = false;
56564         var data;
56565         var filter;
56566
56567         if (difference) {
56568             var complete = difference.complete(map.extent());
56569             data = compact(values$1(complete));
56570             filter = function(d) { return d.id in complete; };
56571             features.clear(data);
56572
56573         } else {
56574             // force a full redraw if gatherStats detects that a feature
56575             // should be auto-hidden (e.g. points or buildings)..
56576             if (features.gatherStats(all, graph, dimensions)) {
56577                 extent = undefined;
56578             }
56579
56580             if (extent) {
56581                 data = context.intersects(map.extent().intersection(extent));
56582                 var set$$1 = set$2(map$4(data, 'id'));
56583                 filter = function(d) { return set$$1.has(d.id); };
56584
56585             } else {
56586                 data = all;
56587                 fullRedraw = true;
56588                 filter = utilFunctor(true);
56589             }
56590         }
56591
56592         data = features.filter(data, graph);
56593
56594         if (mode && mode.id === 'select') {
56595             // update selected vertices - the user might have just double-clicked a way,
56596             // creating a new vertex, triggering a partial redraw without a mode change
56597             surface.selectAll('.data-layer-osm')
56598                 .call(drawVertices.drawSelected, graph, map.extent());
56599         }
56600
56601         surface.selectAll('.data-layer-osm')
56602             .call(drawVertices, graph, data, filter, map.extent(), fullRedraw)
56603             .call(drawLines, graph, data, filter)
56604             .call(drawAreas, graph, data, filter)
56605             .call(drawMidpoints, graph, data, filter, map.trimmedExtent())
56606             .call(drawLabels, graph, data, filter, dimensions, fullRedraw)
56607             .call(drawPoints, graph, data, filter);
56608
56609         dispatch$$1.call('drawn', this, {full: true});
56610     }
56611
56612
56613     function editOff() {
56614         context.features().resetStats();
56615         surface.selectAll('.layer-osm *').remove();
56616
56617         var mode = context.mode();
56618         if (mode && mode.id !== 'save') {
56619             context.enter(modeBrowse(context));
56620         }
56621
56622         dispatch$$1.call('drawn', this, {full: true});
56623     }
56624
56625
56626     function dblClick() {
56627         if (!dblclickEnabled) {
56628             event.preventDefault();
56629             event.stopImmediatePropagation();
56630         }
56631     }
56632
56633
56634     function zoomPan(manualEvent) {
56635         var event$$1 = (manualEvent || event);
56636         var source = event$$1.sourceEvent;
56637         var eventTransform = event$$1.transform;
56638
56639         if (transformStart.x === eventTransform.x &&
56640             transformStart.y === eventTransform.y &&
56641             transformStart.k === eventTransform.k) {
56642             return;  // no change
56643         }
56644
56645         // Normalize mousewheel - #3029
56646         // If wheel delta is provided in LINE units, recalculate it in PIXEL units
56647         // We are essentially redoing the calculations that occur here:
56648         //   https://github.com/d3/d3-zoom/blob/78563a8348aa4133b07cac92e2595c2227ca7cd7/src/zoom.js#L203
56649         // See this for more info:
56650         //   https://github.com/basilfx/normalize-wheel/blob/master/src/normalizeWheel.js
56651         if (source && source.type === 'wheel' && source.deltaMode === 1 /* LINE */) {
56652             // pick sensible scroll amount if user scrolling fast or slow..
56653             var lines = Math.abs(source.deltaY);
56654             var scroll = lines > 2 ? 40 : lines * 10;
56655
56656             var t0 = transformed ? transformLast : transformStart;
56657             var p0 = mouse(source);
56658             var p1 = t0.invert(p0);
56659             var k2 = t0.k * Math.pow(2, -source.deltaY * scroll / 500);
56660             var x2 = p0[0] - p1[0] * k2;
56661             var y2 = p0[1] - p1[1] * k2;
56662
56663             eventTransform = identity$7.translate(x2,y2).scale(k2);
56664             _selection.node().__zoom = eventTransform;
56665         }
56666
56667         if (ktoz(eventTransform.k * 2 * Math.PI) < minzoom) {
56668             surface.interrupt();
56669             uiFlash().text(t('cannot_zoom'))();
56670             setZoom(context.minEditableZoom(), true);
56671             scheduleRedraw();
56672             dispatch$$1.call('move', this, map);
56673             return;
56674         }
56675
56676         projection.transform(eventTransform);
56677
56678         var scale = eventTransform.k / transformStart.k;
56679         var tX = (eventTransform.x / scale - transformStart.x) * scale;
56680         var tY = (eventTransform.y / scale - transformStart.y) * scale;
56681
56682         if (context.inIntro()) {
56683             curtainProjection.transform({
56684                 x: eventTransform.x - tX,
56685                 y: eventTransform.y - tY,
56686                 k: eventTransform.k
56687             });
56688         }
56689
56690         if (source) mousemove = event$$1;
56691         transformed = true;
56692         transformLast = eventTransform;
56693         utilSetTransform(supersurface, tX, tY, scale);
56694         scheduleRedraw();
56695
56696         dispatch$$1.call('move', this, map);
56697     }
56698
56699
56700     function resetTransform() {
56701         if (!transformed) return false;
56702
56703         // deprecation warning - Radial Menu to be removed in iD v3
56704         surface.selectAll('.edit-menu, .radial-menu').interrupt().remove();
56705         utilSetTransform(supersurface, 0, 0);
56706         transformed = false;
56707         if (context.inIntro()) {
56708             curtainProjection.transform(projection.transform());
56709         }
56710         return true;
56711     }
56712
56713
56714     function redraw(difference, extent) {
56715         if (surface.empty() || !redrawEnabled) return;
56716
56717         // If we are in the middle of a zoom/pan, we can't do differenced redraws.
56718         // It would result in artifacts where differenced entities are redrawn with
56719         // one transform and unchanged entities with another.
56720         if (resetTransform()) {
56721             difference = extent = undefined;
56722         }
56723
56724         var z = String(~~map.zoom());
56725         if (surface.attr('data-zoom') !== z) {
56726             surface.attr('data-zoom', z)
56727                 .classed('low-zoom', z <= 16);
56728         }
56729
56730         if (!difference) {
56731             supersurface.call(context.background());
56732         }
56733
56734         wrapper
56735             .call(drawLayers);
56736
56737         // OSM
56738         if (map.editable()) {
56739             context.loadTiles(projection, dimensions);
56740             drawVector(difference, extent);
56741         } else {
56742             editOff();
56743         }
56744
56745         transformStart = projection.transform();
56746
56747         return map;
56748     }
56749
56750
56751
56752     var immediateRedraw = function(difference, extent) {
56753         if (!difference && !extent) cancelPendingRedraw();
56754         redraw(difference, extent);
56755     };
56756
56757
56758     function pointLocation(p) {
56759         var translate = projection.translate(),
56760             scale = projection.scale() * 2 * Math.PI;
56761         return [(p[0] - translate[0]) / scale, (p[1] - translate[1]) / scale];
56762     }
56763
56764
56765     function locationPoint(l) {
56766         var translate = projection.translate(),
56767             scale = projection.scale() * 2 * Math.PI;
56768         return [l[0] * scale + translate[0], l[1] * scale + translate[1]];
56769     }
56770
56771
56772     map.mouse = function() {
56773         var event$$1 = mousemove || event;
56774         if (event$$1) {
56775             var s;
56776             while ((s = event$$1.sourceEvent)) { event$$1 = s; }
56777             return mouse(event$$1);
56778         }
56779         return null;
56780     };
56781
56782
56783     // returns Lng/Lat
56784     map.mouseCoordinates = function() {
56785         var coord = map.mouse() || pxCenter();
56786         return projection.invert(coord);
56787     };
56788
56789
56790     map.dblclickEnable = function(_) {
56791         if (!arguments.length) return dblclickEnabled;
56792         dblclickEnabled = _;
56793         return map;
56794     };
56795
56796
56797     map.redrawEnable = function(_) {
56798         if (!arguments.length) return redrawEnabled;
56799         redrawEnabled = _;
56800         return map;
56801     };
56802
56803
56804     function setTransform(t2, duration, force) {
56805         var t$$1 = projection.transform();
56806         if (!force && t2.k === t$$1.k && t2.x === t$$1.x && t2.y === t$$1.y) {
56807             return false;
56808         }
56809
56810         if (duration) {
56811             _selection
56812                 .transition()
56813                 .duration(duration)
56814                 .on('start', function() { map.startEase(); })
56815                 .call(zoom$$1.transform, identity$7.translate(t2.x, t2.y).scale(t2.k));
56816         } else {
56817             projection.transform(t2);
56818             transformStart = t2;
56819             _selection.call(zoom$$1.transform, transformStart);
56820         }
56821     }
56822
56823
56824     function setZoom(z2, force, duration) {
56825         if (z2 === map.zoom() && !force) {
56826             return false;
56827         }
56828
56829         var k = projection.scale(),
56830             k2 = Math.max(ztok(2), Math.min(ztok(24), ztok(z2))) / (2 * Math.PI),
56831             center = pxCenter(),
56832             l = pointLocation(center);
56833
56834         projection.scale(k2);
56835
56836         var t$$1 = projection.translate();
56837         l = locationPoint(l);
56838
56839         t$$1[0] += center[0] - l[0];
56840         t$$1[1] += center[1] - l[1];
56841
56842         if (duration) {
56843             projection.scale(k);  // reset scale
56844             _selection
56845                 .transition()
56846                 .duration(duration)
56847                 .on('start', function() { map.startEase(); })
56848                 .call(zoom$$1.transform, identity$7.translate(t$$1[0], t$$1[1]).scale(k2));
56849         } else {
56850             projection.translate(t$$1);
56851             transformStart = projection.transform();
56852             _selection.call(zoom$$1.transform, transformStart);
56853         }
56854
56855         return true;
56856     }
56857
56858
56859     function setCenter(loc2, duration) {
56860         var c = map.center();
56861         if (loc2[0] === c[0] && loc2[1] === c[1]) {
56862             return false;
56863         }
56864
56865         var t$$1 = projection.translate(),
56866             k = projection.scale(),
56867             pxC = pxCenter(),
56868             ll = projection(loc2);
56869
56870         t$$1[0] = t$$1[0] - ll[0] + pxC[0];
56871         t$$1[1] = t$$1[1] - ll[1] + pxC[1];
56872
56873         if (duration) {
56874             _selection
56875                 .transition()
56876                 .duration(duration)
56877                 .on('start', function() { map.startEase(); })
56878                 .call(zoom$$1.transform, identity$7.translate(t$$1[0], t$$1[1]).scale(k));
56879         } else {
56880             projection.translate(t$$1);
56881             transformStart = projection.transform();
56882             _selection.call(zoom$$1.transform, transformStart);
56883         }
56884
56885         return true;
56886     }
56887
56888
56889     map.pan = function(delta, duration) {
56890         var t$$1 = projection.translate(),
56891             k = projection.scale();
56892
56893         t$$1[0] += delta[0];
56894         t$$1[1] += delta[1];
56895
56896         if (duration) {
56897             _selection
56898                 .transition()
56899                 .duration(duration)
56900                 .on('start', function() { map.startEase(); })
56901                 .call(zoom$$1.transform, identity$7.translate(t$$1[0], t$$1[1]).scale(k));
56902         } else {
56903             projection.translate(t$$1);
56904             transformStart = projection.transform();
56905             _selection.call(zoom$$1.transform, transformStart);
56906             dispatch$$1.call('move', this, map);
56907             immediateRedraw();
56908         }
56909
56910         return map;
56911     };
56912
56913
56914     map.dimensions = function(_) {
56915         if (!arguments.length) return dimensions;
56916         var center = map.center();
56917         dimensions = _;
56918         drawLayers.dimensions(dimensions);
56919         context.background().dimensions(dimensions);
56920         projection.clipExtent([[0, 0], dimensions]);
56921         mouse = utilFastMouse(supersurface.node());
56922         setCenter(center);
56923
56924         scheduleRedraw();
56925         return map;
56926     };
56927
56928
56929     function zoomIn(delta) {
56930         setZoom(~~map.zoom() + delta, true, 250);
56931     }
56932
56933     function zoomOut(delta) {
56934         setZoom(~~map.zoom() - delta, true, 250);
56935     }
56936
56937     map.zoomIn = function() { zoomIn(1); };
56938     map.zoomInFurther = function() { zoomIn(4); };
56939
56940     map.zoomOut = function() { zoomOut(1); };
56941     map.zoomOutFurther = function() { zoomOut(4); };
56942
56943
56944     map.center = function(loc2) {
56945         if (!arguments.length) {
56946             return projection.invert(pxCenter());
56947         }
56948
56949         if (setCenter(loc2)) {
56950             dispatch$$1.call('move', this, map);
56951         }
56952
56953         scheduleRedraw();
56954         return map;
56955     };
56956
56957
56958     map.zoom = function(z2) {
56959         if (!arguments.length) {
56960             return Math.max(ktoz(projection.scale() * 2 * Math.PI), 0);
56961         }
56962
56963         if (z2 < minzoom) {
56964             surface.interrupt();
56965             uiFlash().text(t('cannot_zoom'))();
56966             z2 = context.minEditableZoom();
56967         }
56968
56969         if (setZoom(z2)) {
56970             dispatch$$1.call('move', this, map);
56971         }
56972
56973         scheduleRedraw();
56974         return map;
56975     };
56976
56977
56978     map.zoomTo = function(entity, zoomLimits) {
56979         var extent = entity.extent(context.graph());
56980         if (!isFinite(extent.area())) return;
56981
56982         var z2 = map.trimmedExtentZoom(extent);
56983         zoomLimits = zoomLimits || [context.minEditableZoom(), 20];
56984         map.centerZoom(extent.center(), Math.min(Math.max(z2, zoomLimits[0]), zoomLimits[1]));
56985     };
56986
56987
56988     map.centerZoom = function(loc2, z2) {
56989         var centered = setCenter(loc2),
56990             zoomed   = setZoom(z2);
56991
56992         if (centered || zoomed) {
56993             dispatch$$1.call('move', this, map);
56994         }
56995
56996         scheduleRedraw();
56997         return map;
56998     };
56999
57000
57001     map.centerEase = function(loc2, duration) {
57002         duration = duration || 250;
57003         setCenter(loc2, duration);
57004         return map;
57005     };
57006
57007
57008     map.zoomEase = function(z2, duration) {
57009         duration = duration || 250;
57010         setZoom(z2, false, duration);
57011         return map;
57012     };
57013
57014
57015     map.transformEase = function(t2, duration) {
57016         duration = duration || 250;
57017         setTransform(t2, duration, false);
57018         return map;
57019     };
57020
57021
57022     map.startEase = function() {
57023         utilBindOnce(surface, 'mousedown.ease', function() {
57024             map.cancelEase();
57025         });
57026         return map;
57027     };
57028
57029
57030     map.cancelEase = function() {
57031         _selection.interrupt();
57032         return map;
57033     };
57034
57035
57036     map.extent = function(_) {
57037         if (!arguments.length) {
57038             return new geoExtent(projection.invert([0, dimensions[1]]),
57039                                  projection.invert([dimensions[0], 0]));
57040         } else {
57041             var extent = geoExtent(_);
57042             map.centerZoom(extent.center(), map.extentZoom(extent));
57043         }
57044     };
57045
57046
57047     map.trimmedExtent = function(_) {
57048         if (!arguments.length) {
57049             var headerY = 60, footerY = 30, pad = 10;
57050             return new geoExtent(projection.invert([pad, dimensions[1] - footerY - pad]),
57051                                  projection.invert([dimensions[0] - pad, headerY + pad]));
57052         } else {
57053             var extent = geoExtent(_);
57054             map.centerZoom(extent.center(), map.trimmedExtentZoom(extent));
57055         }
57056     };
57057
57058
57059     function calcZoom(extent, dim) {
57060         var tl = projection([extent[0][0], extent[1][1]]),
57061             br = projection([extent[1][0], extent[0][1]]);
57062
57063         // Calculate maximum zoom that fits extent
57064         var hFactor = (br[0] - tl[0]) / dim[0],
57065             vFactor = (br[1] - tl[1]) / dim[1],
57066             hZoomDiff = Math.log(Math.abs(hFactor)) / Math.LN2,
57067             vZoomDiff = Math.log(Math.abs(vFactor)) / Math.LN2,
57068             newZoom = map.zoom() - Math.max(hZoomDiff, vZoomDiff);
57069
57070         return newZoom;
57071     }
57072
57073
57074     map.extentZoom = function(_) {
57075         return calcZoom(geoExtent(_), dimensions);
57076     };
57077
57078
57079     map.trimmedExtentZoom = function(_) {
57080         var trimY = 120, trimX = 40,
57081             trimmed = [dimensions[0] - trimX, dimensions[1] - trimY];
57082         return calcZoom(geoExtent(_), trimmed);
57083     };
57084
57085
57086     map.editable = function() {
57087         var osmLayer = surface.selectAll('.data-layer-osm');
57088         if (!osmLayer.empty() && osmLayer.classed('disabled')) return false;
57089
57090         return map.zoom() >= context.minEditableZoom();
57091     };
57092
57093
57094     map.minzoom = function(_) {
57095         if (!arguments.length) return minzoom;
57096         minzoom = _;
57097         return map;
57098     };
57099
57100
57101     map.layers = drawLayers;
57102
57103
57104     return utilRebind(map, dispatch$$1, 'on');
57105 }
57106
57107 function uiMapInMap(context) {
57108
57109     function map_in_map(selection) {
57110         var backgroundLayer = rendererTileLayer(context);
57111         var overlayLayers = {};
57112         var projection = geoRawMercator();
57113         var gpxLayer = svgGpx(projection, context).showLabels(false);
57114         var debugLayer = svgDebug(projection, context);
57115         var zoom$$1 = d3_zoom()
57116             .scaleExtent([geoZoomToScale(0.5), geoZoomToScale(24)])
57117             .on('start', zoomStarted)
57118             .on('zoom', zoomed)
57119             .on('end', zoomEnded);
57120         var isTransformed = false;
57121         var isHidden = true;
57122         var skipEvents = false;
57123         var gesture = null;
57124         var zDiff = 6;    // by default, minimap renders at (main zoom - 6)
57125         var wrap = d3_select(null);
57126         var tiles = d3_select(null);
57127         var viewport = d3_select(null);
57128         var tStart;    // transform at start of gesture
57129         var tCurr;     // transform at most recent event
57130         var timeoutId;
57131
57132
57133         function zoomStarted() {
57134             if (skipEvents) return;
57135             tStart = tCurr = projection.transform();
57136             gesture = null;
57137         }
57138
57139
57140         function zoomed() {
57141             if (skipEvents) return;
57142
57143             var x = event.transform.x;
57144             var y = event.transform.y;
57145             var k = event.transform.k;
57146             var isZooming = (k !== tStart.k);
57147             var isPanning = (x !== tStart.x || y !== tStart.y);
57148
57149             if (!isZooming && !isPanning) {
57150                 return;  // no change
57151             }
57152
57153             // lock in either zooming or panning, don't allow both in minimap.
57154             if (!gesture) {
57155                 gesture = isZooming ? 'zoom' : 'pan';
57156             }
57157
57158             var tMini = projection.transform();
57159             var tX, tY, scale;
57160
57161             if (gesture === 'zoom') {
57162                 var dMini = utilGetDimensions(wrap);
57163                 var cMini = geoVecScale(dMini, 0.5);
57164                 scale = k / tMini.k;
57165                 tX = (cMini[0] / scale - cMini[0]) * scale;
57166                 tY = (cMini[1] / scale - cMini[1]) * scale;
57167             } else {
57168                 k = tMini.k;
57169                 scale = 1;
57170                 tX = x - tMini.x;
57171                 tY = y - tMini.y;
57172             }
57173
57174             utilSetTransform(tiles, tX, tY, scale);
57175             utilSetTransform(viewport, 0, 0, scale);
57176             isTransformed = true;
57177             tCurr = identity$7.translate(x, y).scale(k);
57178
57179             var zMain = geoScaleToZoom(context.projection.scale());
57180             var zMini = geoScaleToZoom(k);
57181
57182             zDiff = zMain - zMini;
57183
57184             queueRedraw();
57185         }
57186
57187
57188         function zoomEnded() {
57189             if (skipEvents) return;
57190             if (gesture !== 'pan') return;
57191
57192             updateProjection();
57193             gesture = null;
57194             var dMini = utilGetDimensions(wrap);
57195             var cMini = geoVecScale(dMini, 0.5);
57196             context.map().center(projection.invert(cMini));   // recenter main map..
57197         }
57198
57199
57200         function updateProjection() {
57201             var loc = context.map().center();
57202             var dMini = utilGetDimensions(wrap);
57203             var cMini = geoVecScale(dMini, 0.5);
57204             var tMain = context.projection.transform();
57205             var zMain = geoScaleToZoom(tMain.k);
57206             var zMini = Math.max(zMain - zDiff, 0.5);
57207             var kMini = geoZoomToScale(zMini);
57208
57209             projection
57210                 .translate([tMain.x, tMain.y])
57211                 .scale(kMini);
57212
57213             var point = projection(loc);
57214             var mouse = (gesture === 'pan') ? geoVecSubtract([tCurr.x, tCurr.y], [tStart.x, tStart.y]) : [0, 0];
57215             var xMini = cMini[0] - point[0] + tMain.x + mouse[0];
57216             var yMini = cMini[1] - point[1] + tMain.y + mouse[1];
57217
57218             projection
57219                 .translate([xMini, yMini])
57220                 .clipExtent([[0, 0], dMini]);
57221
57222             tCurr = projection.transform();
57223
57224             if (isTransformed) {
57225                 utilSetTransform(tiles, 0, 0);
57226                 utilSetTransform(viewport, 0, 0);
57227                 isTransformed = false;
57228             }
57229
57230             zoom$$1
57231                 .scaleExtent([geoZoomToScale(0.5), geoZoomToScale(zMain - 3)]);
57232
57233             skipEvents = true;
57234             wrap.call(zoom$$1.transform, tCurr);
57235             skipEvents = false;
57236         }
57237
57238
57239         function redraw() {
57240             clearTimeout(timeoutId);
57241             if (isHidden) return;
57242
57243             updateProjection();
57244
57245             var dMini = utilGetDimensions(wrap);
57246             var zMini = geoScaleToZoom(projection.scale());
57247
57248             // setup tile container
57249             tiles = wrap
57250                 .selectAll('.map-in-map-tiles')
57251                 .data([0]);
57252
57253             tiles = tiles.enter()
57254                 .append('div')
57255                 .attr('class', 'map-in-map-tiles')
57256                 .merge(tiles);
57257
57258             // redraw background
57259             backgroundLayer
57260                 .source(context.background().baseLayerSource())
57261                 .projection(projection)
57262                 .dimensions(dMini);
57263
57264             var background = tiles
57265                 .selectAll('.map-in-map-background')
57266                 .data([0]);
57267
57268             background.enter()
57269                 .append('div')
57270                 .attr('class', 'map-in-map-background')
57271                 .merge(background)
57272                 .call(backgroundLayer);
57273
57274
57275             // redraw overlay
57276             var overlaySources = context.background().overlayLayerSources();
57277             var activeOverlayLayers = [];
57278             for (var i = 0; i < overlaySources.length; i++) {
57279                 if (overlaySources[i].validZoom(zMini)) {
57280                     if (!overlayLayers[i]) overlayLayers[i] = rendererTileLayer(context);
57281                     activeOverlayLayers.push(overlayLayers[i]
57282                         .source(overlaySources[i])
57283                         .projection(projection)
57284                         .dimensions(dMini));
57285                 }
57286             }
57287
57288             var overlay = tiles
57289                 .selectAll('.map-in-map-overlay')
57290                 .data([0]);
57291
57292             overlay = overlay.enter()
57293                 .append('div')
57294                 .attr('class', 'map-in-map-overlay')
57295                 .merge(overlay);
57296
57297
57298             var overlays = overlay
57299                 .selectAll('div')
57300                 .data(activeOverlayLayers, function(d) { return d.source().name(); });
57301
57302             overlays.exit()
57303                 .remove();
57304
57305             overlays = overlays.enter()
57306                 .append('div')
57307                 .merge(overlays)
57308                 .each(function(layer) { d3_select(this).call(layer); });
57309
57310
57311             var dataLayers = tiles
57312                 .selectAll('.map-in-map-data')
57313                 .data([0]);
57314
57315             dataLayers.exit()
57316                 .remove();
57317
57318             dataLayers = dataLayers.enter()
57319                 .append('svg')
57320                 .attr('class', 'map-in-map-data')
57321                 .merge(dataLayers)
57322                 .call(gpxLayer)
57323                 .call(debugLayer);
57324
57325
57326             // redraw viewport bounding box
57327             if (gesture !== 'pan') {
57328                 var getPath = d3_geoPath(projection);
57329                 var bbox = { type: 'Polygon', coordinates: [context.map().extent().polygon()] };
57330
57331                 viewport = wrap.selectAll('.map-in-map-viewport')
57332                     .data([0]);
57333
57334                 viewport = viewport.enter()
57335                     .append('svg')
57336                     .attr('class', 'map-in-map-viewport')
57337                     .merge(viewport);
57338
57339
57340                 var path = viewport.selectAll('.map-in-map-bbox')
57341                     .data([bbox]);
57342
57343                 path.enter()
57344                     .append('path')
57345                     .attr('class', 'map-in-map-bbox')
57346                     .merge(path)
57347                     .attr('d', getPath)
57348                     .classed('thick', function(d) { return getPath.area(d) < 30; });
57349             }
57350         }
57351
57352
57353         function queueRedraw() {
57354             clearTimeout(timeoutId);
57355             timeoutId = setTimeout(function() { redraw(); }, 750);
57356         }
57357
57358
57359         function toggle() {
57360             if (event) event.preventDefault();
57361
57362             isHidden = !isHidden;
57363
57364             d3_select('.minimap-toggle-item')
57365                 .classed('active', !isHidden)
57366                 .select('input')
57367                 .property('checked', !isHidden);
57368
57369             if (isHidden) {
57370                 wrap
57371                     .style('display', 'block')
57372                     .style('opacity', '1')
57373                     .transition()
57374                     .duration(200)
57375                     .style('opacity', '0')
57376                     .on('end', function() {
57377                         selection.selectAll('.map-in-map')
57378                             .style('display', 'none');
57379                     });
57380             } else {
57381                 wrap
57382                     .style('display', 'block')
57383                     .style('opacity', '0')
57384                     .transition()
57385                     .duration(200)
57386                     .style('opacity', '1')
57387                     .on('end', function() {
57388                         redraw();
57389                     });
57390             }
57391         }
57392
57393
57394         uiMapInMap.toggle = toggle;
57395
57396         wrap = selection.selectAll('.map-in-map')
57397             .data([0]);
57398
57399         wrap = wrap.enter()
57400             .append('div')
57401             .attr('class', 'map-in-map')
57402             .style('display', (isHidden ? 'none' : 'block'))
57403             .call(zoom$$1)
57404             .on('dblclick.zoom', null)
57405             .merge(wrap);
57406
57407         context.map()
57408             .on('drawn.map-in-map', function(drawn) {
57409                 if (drawn.full === true) {
57410                     redraw();
57411                 }
57412             });
57413
57414         redraw();
57415
57416         var keybinding = d3keybinding('map-in-map')
57417             .on(t('background.minimap.key'), toggle);
57418
57419         d3_select(document)
57420             .call(keybinding);
57421     }
57422
57423     return map_in_map;
57424 }
57425
57426 function uiBackground(context) {
57427     var key = t('background.key');
57428
57429     var _customSource = context.background().findSource('custom');
57430     var _previousBackground = context.background().findSource(context.storage('background-last-used-toggle'));
57431     var _shown = false;
57432
57433     var _backgroundList = d3_select(null);
57434     var _overlayList = d3_select(null);
57435     var _displayOptionsContainer = d3_select(null);
57436     var _offsetContainer = d3_select(null);
57437
57438     var backgroundDisplayOptions = uiBackgroundDisplayOptions(context);
57439     var backgroundOffset = uiBackgroundOffset(context);
57440
57441
57442     function setTooltips(selection) {
57443         selection.each(function(d, i, nodes) {
57444             var item = d3_select(this).select('label');
57445             var span = item.select('span');
57446             var placement = (i < nodes.length / 2) ? 'bottom' : 'top';
57447             var description = d.description();
57448             var isOverflowing = (span.property('clientWidth') !== span.property('scrollWidth'));
57449
57450             if (d === _previousBackground) {
57451                 item.call(tooltip()
57452                     .placement(placement)
57453                     .html(true)
57454                     .title(function() {
57455                         var tip = '<div>' + t('background.switch') + '</div>';
57456                         return uiTooltipHtml(tip, uiCmd('⌘' + key));
57457                     })
57458                 );
57459             } else if (description || isOverflowing) {
57460                 item.call(tooltip()
57461                     .placement(placement)
57462                     .title(description || d.name())
57463                 );
57464             } else {
57465                 item.call(tooltip().destroy);
57466             }
57467         });
57468     }
57469
57470
57471     function updateLayerSelections(selection) {
57472         function active(d) {
57473             return context.background().showsLayer(d);
57474         }
57475
57476         selection.selectAll('.layer')
57477             .classed('active', active)
57478             .classed('switch', function(d) { return d === _previousBackground; })
57479             .call(setTooltips)
57480             .selectAll('input')
57481             .property('checked', active);
57482     }
57483
57484
57485     function chooseBackground(d) {
57486         if (d.id === 'custom' && !d.template()) {
57487             return editCustom();
57488         }
57489
57490         event.preventDefault();
57491         _previousBackground = context.background().baseLayerSource();
57492         context.storage('background-last-used-toggle', _previousBackground.id);
57493         context.storage('background-last-used', d.id);
57494         context.background().baseLayerSource(d);
57495         _backgroundList.call(updateLayerSelections);
57496         document.activeElement.blur();
57497     }
57498
57499
57500     function editCustom() {
57501         event.preventDefault();
57502         var example = 'https://{switch:a,b,c}.tile.openstreetmap.org/{zoom}/{x}/{y}.png';
57503         var template = window.prompt(
57504             t('background.custom_prompt', { example: example }),
57505             _customSource.template() || example
57506         );
57507
57508         if (template) {
57509             context.storage('background-custom-template', template);
57510             _customSource.template(template);
57511             chooseBackground(_customSource);
57512         } else {
57513             _backgroundList.call(updateLayerSelections);
57514         }
57515     }
57516
57517
57518     function chooseOverlay(d) {
57519         event.preventDefault();
57520         context.background().toggleOverlayLayer(d);
57521         _overlayList.call(updateLayerSelections);
57522         document.activeElement.blur();
57523     }
57524
57525
57526     function drawListItems(layerList, type, change, filter) {
57527         var sources = context.background()
57528             .sources(context.map().extent())
57529             .filter(filter);
57530
57531         var layerLinks = layerList.selectAll('li.layer')
57532             .data(sources, function(d) { return d.name(); });
57533
57534         layerLinks.exit()
57535             .remove();
57536
57537         var enter = layerLinks.enter()
57538             .append('li')
57539             .attr('class', 'layer')
57540             .classed('layer-custom', function(d) { return d.id === 'custom'; })
57541             .classed('best', function(d) { return d.best(); });
57542
57543         enter.filter(function(d) { return d.id === 'custom'; })
57544             .append('button')
57545             .attr('class', 'layer-browse')
57546             .call(tooltip()
57547                 .title(t('background.custom_button'))
57548                 .placement((textDirection === 'rtl') ? 'right' : 'left')
57549             )
57550             .on('click', editCustom)
57551             .call(svgIcon('#icon-search'));
57552
57553         enter.filter(function(d) { return d.best(); })
57554             .append('div')
57555             .attr('class', 'best')
57556             .call(tooltip()
57557                 .title(t('background.best_imagery'))
57558                 .placement((textDirection === 'rtl') ? 'right' : 'left')
57559             )
57560             .append('span')
57561             .html('&#9733;');
57562
57563         var label = enter
57564             .append('label');
57565
57566         label
57567             .append('input')
57568             .attr('type', type)
57569             .attr('name', 'layers')
57570             .on('change', change);
57571
57572         label
57573             .append('span')
57574             .text(function(d) { return d.name(); });
57575
57576
57577         layerList.selectAll('li.layer')
57578             .sort(sortSources)
57579             .style('display', layerList.selectAll('li.layer').data().length > 0 ? 'block' : 'none');
57580
57581         layerList
57582             .call(updateLayerSelections);
57583
57584
57585         function sortSources(a, b) {
57586             return a.best() && !b.best() ? -1
57587                 : b.best() && !a.best() ? 1
57588                 : d3_descending(a.area(), b.area()) || d3_ascending(a.name(), b.name()) || 0;
57589         }
57590     }
57591
57592
57593     function renderBackgroundList(selection) {
57594
57595         // the background list
57596         var container = selection.selectAll('.layer-background-list')
57597             .data([0]);
57598
57599         _backgroundList = container.enter()
57600             .append('ul')
57601             .attr('class', 'layer-list layer-background-list')
57602             .attr('dir', 'auto')
57603             .merge(container);
57604
57605
57606         // add minimap toggle below list
57607         var minimapEnter = selection.selectAll('.minimap-toggle-list')
57608             .data([0])
57609             .enter()
57610             .append('ul')
57611             .attr('class', 'layer-list minimap-toggle-list')
57612             .append('li')
57613             .attr('class', 'layer minimap-toggle-item');
57614
57615         var minimapLabelEnter = minimapEnter
57616             .append('label')
57617             .call(tooltip()
57618                 .html(true)
57619                 .title(uiTooltipHtml(t('background.minimap.tooltip'), t('background.minimap.key')))
57620                 .placement('top')
57621             );
57622
57623         minimapLabelEnter
57624             .append('input')
57625             .attr('type', 'checkbox')
57626             .on('change', function() {
57627                 event.preventDefault();
57628                 uiMapInMap.toggle();
57629             });
57630
57631         minimapLabelEnter
57632             .append('span')
57633             .text(t('background.minimap.description'));
57634
57635
57636         // "Info / Report a Problem" link
57637         selection.selectAll('.imagery-faq')
57638             .data([0])
57639             .enter()
57640             .append('div')
57641             .attr('class', 'imagery-faq')
57642             .append('a')
57643             .attr('target', '_blank')
57644             .attr('tabindex', -1)
57645             .call(svgIcon('#icon-out-link', 'inline'))
57646             .attr('href', 'https://github.com/openstreetmap/iD/blob/master/FAQ.md#how-can-i-report-an-issue-with-background-imagery')
57647             .append('span')
57648             .text(t('background.imagery_source_faq'));
57649     }
57650
57651
57652     function renderOverlayList(selection) {
57653         var container = selection.selectAll('.layer-overlay-list')
57654             .data([0]);
57655
57656         _overlayList = container.enter()
57657             .append('ul')
57658             .attr('class', 'layer-list layer-overlay-list')
57659             .attr('dir', 'auto')
57660             .merge(container);
57661     }
57662
57663
57664     function update() {
57665         _backgroundList
57666             .call(drawListItems, 'radio', chooseBackground, function(d) { return !d.isHidden() && !d.overlay; });
57667
57668         _overlayList
57669             .call(drawListItems, 'checkbox', chooseOverlay, function(d) { return !d.isHidden() && d.overlay; });
57670
57671         _displayOptionsContainer
57672             .call(backgroundDisplayOptions);
57673
57674         _offsetContainer
57675             .call(backgroundOffset);
57676     }
57677
57678
57679     function quickSwitch() {
57680         if (event) {
57681             event.stopImmediatePropagation();
57682             event.preventDefault();
57683         }
57684         if (_previousBackground) {
57685             chooseBackground(_previousBackground);
57686         }
57687     }
57688
57689
57690     function background(selection) {
57691
57692         function hidePane() {
57693             setVisible(false);
57694         }
57695
57696         function togglePane() {
57697             if (event) event.preventDefault();
57698             paneTooltip.hide(button);
57699             setVisible(!button.classed('active'));
57700         }
57701
57702         function setVisible(show) {
57703             if (show !== _shown) {
57704                 button.classed('active', show);
57705                 _shown = show;
57706
57707                 if (show) {
57708                     uiMapData.hidePane();
57709                     uiHelp.hidePane();
57710                     update();
57711
57712                     pane
57713                         .style('display', 'block')
57714                         .style('right', '-300px')
57715                         .transition()
57716                         .duration(200)
57717                         .style('right', '0px');
57718
57719                 } else {
57720                     pane
57721                         .style('display', 'block')
57722                         .style('right', '0px')
57723                         .transition()
57724                         .duration(200)
57725                         .style('right', '-300px')
57726                         .on('end', function() {
57727                             d3_select(this).style('display', 'none');
57728                         });
57729                 }
57730             }
57731         }
57732
57733
57734         var pane = selection
57735             .append('div')
57736             .attr('class', 'fillL map-overlay col3 content hide');
57737
57738         var paneTooltip = tooltip()
57739             .placement((textDirection === 'rtl') ? 'right' : 'left')
57740             .html(true)
57741             .title(uiTooltipHtml(t('background.description'), key));
57742
57743         var button = selection
57744             .append('button')
57745             .attr('tabindex', -1)
57746             .on('click', togglePane)
57747             .call(svgIcon('#icon-layers', 'light'))
57748             .call(paneTooltip);
57749
57750         pane
57751             .append('h2')
57752             .text(t('background.title'));
57753
57754         // background list
57755         pane
57756             .append('div')
57757             .attr('class', 'background-background-list-container')
57758             .call(uiDisclosure(context, 'background_list', true)
57759                 .title(t('background.backgrounds'))
57760                 .content(renderBackgroundList)
57761             );
57762
57763         // overlay list
57764         pane
57765             .append('div')
57766             .attr('class', 'background-overlay-list-container')
57767             .call(uiDisclosure(context, 'overlay_list', true)
57768                 .title(t('background.overlays'))
57769                 .content(renderOverlayList)
57770             );
57771
57772         // display options
57773         _displayOptionsContainer = pane
57774             .append('div')
57775             .attr('class', 'background-display-options');
57776
57777         // offset controls
57778         _offsetContainer = pane
57779             .append('div')
57780             .attr('class', 'background-offset');
57781
57782
57783         // add listeners
57784         context.map()
57785             .on('move.background-update', debounce(utilCallWhenIdle(update), 1000));
57786
57787         context.background()
57788             .on('change.background-update', update);
57789
57790
57791         update();
57792
57793         var keybinding = d3keybinding('background')
57794             .on(key, togglePane)
57795             .on(uiCmd('⌘' + key), quickSwitch)
57796             .on([t('map_data.key'), t('help.key')], hidePane);
57797
57798         d3_select(document)
57799             .call(keybinding);
57800
57801         uiBackground.hidePane = hidePane;
57802         uiBackground.togglePane = togglePane;
57803         uiBackground.setVisible = setVisible;
57804     }
57805
57806     return background;
57807 }
57808
57809 function uiContributors(context) {
57810     var osm = context.connection(),
57811         debouncedUpdate = debounce(function() { update(); }, 1000),
57812         limit = 4,
57813         hidden = false,
57814         wrap = d3_select(null);
57815
57816
57817     function update() {
57818         if (!osm) return;
57819
57820         var users = {},
57821             entities = context.intersects(context.map().extent());
57822
57823         entities.forEach(function(entity) {
57824             if (entity && entity.user) users[entity.user] = true;
57825         });
57826
57827         var u = Object.keys(users),
57828             subset = u.slice(0, u.length > limit ? limit - 1 : limit);
57829
57830         wrap.html('')
57831             .call(svgIcon('#icon-nearby', 'pre-text light'));
57832
57833         var userList = d3_select(document.createElement('span'));
57834
57835         userList.selectAll()
57836             .data(subset)
57837             .enter()
57838             .append('a')
57839             .attr('class', 'user-link')
57840             .attr('href', function(d) { return osm.userURL(d); })
57841             .attr('target', '_blank')
57842             .attr('tabindex', -1)
57843             .text(String);
57844
57845         if (u.length > limit) {
57846             var count = d3_select(document.createElement('span'));
57847
57848             count.append('a')
57849                 .attr('target', '_blank')
57850                 .attr('tabindex', -1)
57851                 .attr('href', function() {
57852                     return osm.changesetsURL(context.map().center(), context.map().zoom());
57853                 })
57854                 .text(u.length - limit + 1);
57855
57856             wrap.append('span')
57857                 .html(t('contributors.truncated_list', { users: userList.html(), count: count.html() }));
57858
57859         } else {
57860             wrap.append('span')
57861                 .html(t('contributors.list', { users: userList.html() }));
57862         }
57863
57864         if (!u.length) {
57865             hidden = true;
57866             wrap
57867                 .transition()
57868                 .style('opacity', 0);
57869
57870         } else if (hidden) {
57871             wrap
57872                 .transition()
57873                 .style('opacity', 1);
57874         }
57875     }
57876
57877
57878     return function(selection) {
57879         if (!osm) return;
57880         wrap = selection;
57881         update();
57882
57883         osm.on('loaded.contributors', debouncedUpdate);
57884         context.map().on('move.contributors', debouncedUpdate);
57885     };
57886 }
57887
57888 function uiFeatureInfo(context) {
57889     function update(selection) {
57890         var features = context.features(),
57891             stats = features.stats(),
57892             count = 0,
57893             hiddenList = compact(map$4(features.hidden(), function(k) {
57894                 if (stats[k]) {
57895                     count += stats[k];
57896                     return String(stats[k]) + ' ' + t('feature.' + k + '.description');
57897                 }
57898             }));
57899
57900         selection.html('');
57901
57902         if (hiddenList.length) {
57903             var tooltipBehavior = tooltip()
57904                 .placement('top')
57905                 .html(true)
57906                 .title(function() {
57907                     return uiTooltipHtml(hiddenList.join('<br/>'));
57908                 });
57909
57910             var warning = selection.append('a')
57911                 .attr('href', '#')
57912                 .attr('tabindex', -1)
57913                 .html(t('feature_info.hidden_warning', { count: count }))
57914                 .call(tooltipBehavior)
57915                 .on('click', function() {
57916                     tooltipBehavior.hide(warning);
57917                     // open map data panel?
57918                     event.preventDefault();
57919                 });
57920         }
57921
57922         selection
57923             .classed('hide', !hiddenList.length);
57924     }
57925
57926
57927     return function(selection) {
57928         update(selection);
57929
57930         context.features().on('change.feature_info', function() {
57931             update(selection);
57932         });
57933     };
57934 }
57935
57936 function uiFullScreen(context) {
57937     var element = context.container().node(),
57938         keybinding = d3keybinding('full-screen');
57939         // button;
57940
57941
57942     function getFullScreenFn() {
57943         if (element.requestFullscreen) {
57944             return element.requestFullscreen;
57945         } else if (element.msRequestFullscreen) {
57946             return element.msRequestFullscreen;
57947         } else if (element.mozRequestFullScreen) {
57948             return element.mozRequestFullScreen;
57949         } else if (element.webkitRequestFullscreen) {
57950             return element.webkitRequestFullscreen;
57951         }
57952     }
57953
57954
57955     function getExitFullScreenFn() {
57956         if (document.exitFullscreen) {
57957             return document.exitFullscreen;
57958         } else if (document.msExitFullscreen) {
57959             return document.msExitFullscreen;
57960         } else if (document.mozCancelFullScreen) {
57961             return document.mozCancelFullScreen;
57962         } else if (document.webkitExitFullscreen) {
57963             return document.webkitExitFullscreen;
57964         }
57965     }
57966
57967
57968     function isFullScreen() {
57969         return document.fullscreenElement ||
57970             document.mozFullScreenElement ||
57971             document.webkitFullscreenElement ||
57972             document.msFullscreenElement;
57973     }
57974
57975
57976     function isSupported() {
57977         return !!getFullScreenFn();
57978     }
57979
57980
57981     function fullScreen() {
57982         event.preventDefault();
57983         if (!isFullScreen()) {
57984             // button.classed('active', true);
57985             getFullScreenFn().apply(element);
57986         } else {
57987             // button.classed('active', false);
57988             getExitFullScreenFn().apply(document);
57989         }
57990     }
57991
57992
57993     return function() { // selection) {
57994         if (!isSupported())
57995             return;
57996
57997         // button = selection.append('button')
57998         //     .attr('title', t('full_screen'))
57999         //     .attr('tabindex', -1)
58000         //     .on('click', fullScreen)
58001         //     .call(tooltip);
58002
58003         // button.append('span')
58004         //     .attr('class', 'icon full-screen');
58005
58006         var detected = utilDetect();
58007         var keys = detected.os === 'mac' ? [uiCmd('⌃⌘F'), 'f11'] : ['f11'];
58008         keybinding.on(keys, fullScreen);
58009
58010         d3_select(document)
58011             .call(keybinding);
58012     };
58013 }
58014
58015 function uiLoading(context) {
58016     var _modalSelection = d3_select(null);
58017     var _message = '';
58018     var _blocking = false;
58019
58020
58021     var loading = function(selection) {
58022         _modalSelection = uiModal(selection, _blocking);
58023
58024         var loadertext = _modalSelection.select('.content')
58025             .classed('loading-modal', true)
58026             .append('div')
58027             .attr('class', 'modal-section fillL');
58028
58029         loadertext
58030             .append('img')
58031             .attr('class', 'loader')
58032             .attr('src', context.imagePath('loader-white.gif'));
58033
58034         loadertext
58035             .append('h3')
58036             .text(_message);
58037
58038         _modalSelection.select('button.close')
58039             .attr('class', 'hide');
58040
58041         return loading;
58042     };
58043
58044
58045     loading.message = function(_) {
58046         if (!arguments.length) return _message;
58047         _message = _;
58048         return loading;
58049     };
58050
58051
58052     loading.blocking = function(_) {
58053         if (!arguments.length) return _blocking;
58054         _blocking = _;
58055         return loading;
58056     };
58057
58058
58059     loading.close = function() {
58060         _modalSelection.remove();
58061     };
58062
58063
58064     return loading;
58065 }
58066
58067 function uiGeolocate(context) {
58068     var geoOptions = { enableHighAccuracy: false, timeout: 6000 /* 6sec */ },
58069         locating = uiLoading(context).message(t('geolocate.locating')).blocking(true),
58070         timeoutId;
58071
58072
58073     function click() {
58074         if (context.inIntro()) return;
58075         context.enter(modeBrowse(context));
58076         context.container().call(locating);
58077         navigator.geolocation.getCurrentPosition(success, error, geoOptions);
58078
58079         // This timeout ensures that we still call finish() even if
58080         // the user declines to share their location in Firefox
58081         timeoutId = setTimeout(finish, 10000 /* 10sec */ );
58082     }
58083
58084
58085     function success(position) {
58086         var map = context.map(),
58087             extent = geoExtent([position.coords.longitude, position.coords.latitude])
58088                 .padByMeters(position.coords.accuracy);
58089
58090         map.centerZoom(extent.center(), Math.min(20, map.extentZoom(extent)));
58091         finish();
58092     }
58093
58094
58095     function error() {
58096         finish();
58097     }
58098
58099
58100     function finish() {
58101         locating.close();  // unblock ui
58102         if (timeoutId) { clearTimeout(timeoutId); }
58103         timeoutId = undefined;
58104     }
58105
58106
58107     return function(selection) {
58108         if (!navigator.geolocation) return;
58109
58110         selection
58111             .append('button')
58112             .attr('tabindex', -1)
58113             .attr('title', t('geolocate.title'))
58114             .on('click', click)
58115             .call(svgIcon('#icon-geolocate', 'light'))
58116             .call(tooltip()
58117                 .placement((textDirection === 'rtl') ? 'right' : 'left'));
58118     };
58119 }
58120
58121 function uiPanelBackground(context) {
58122     var background = context.background();
58123     var currSourceName = null;
58124     var metadata = {};
58125     var metadataKeys = [
58126         'zoom', 'vintage', 'source', 'description', 'resolution', 'accuracy'
58127     ];
58128
58129     var debouncedRedraw = debounce(redraw, 250);
58130
58131     function redraw(selection) {
58132         var source = background.baseLayerSource(),
58133             isDG = (source.id.match(/^DigitalGlobe/i) !== null);
58134
58135         if (currSourceName !== source.name()) {
58136             currSourceName = source.name();
58137             metadata = {};
58138         }
58139
58140         selection.html('');
58141
58142         var list = selection
58143             .append('ul')
58144             .attr('class', 'background-info');
58145
58146         list
58147             .append('li')
58148             .text(currSourceName);
58149
58150         metadataKeys.forEach(function(k) {
58151             // DigitalGlobe vintage is available in raster layers for now.
58152             if (isDG && k === 'vintage') return;
58153
58154             list
58155                 .append('li')
58156                 .attr('class', 'background-info-list-' + k)
58157                 .classed('hide', !metadata[k])
58158                 .text(t('info_panels.background.' + k) + ':')
58159                 .append('span')
58160                 .attr('class', 'background-info-span-' + k)
58161                 .text(metadata[k]);
58162         });
58163
58164         debouncedGetMetadata(selection);
58165
58166         var toggleTiles = context.getDebug('tile') ? 'hide_tiles' : 'show_tiles';
58167
58168         selection
58169             .append('a')
58170             .text(t('info_panels.background.' + toggleTiles))
58171             .attr('href', '#')
58172             .attr('class', 'button button-toggle-tiles')
58173             .on('click', function() {
58174                 event.preventDefault();
58175                 context.setDebug('tile', !context.getDebug('tile'));
58176                 selection.call(redraw);
58177             });
58178
58179         if (isDG) {
58180             var key = source.id + '-vintage';
58181             var sourceVintage = context.background().findSource(key);
58182             var showsVintage = context.background().showsLayer(sourceVintage);
58183             var toggleVintage = showsVintage ? 'hide_vintage' : 'show_vintage';
58184             selection
58185                 .append('a')
58186                 .text(t('info_panels.background.' + toggleVintage))
58187                 .attr('href', '#')
58188                 .attr('class', 'button button-toggle-vintage')
58189                 .on('click', function() {
58190                     event.preventDefault();
58191                     context.background().toggleOverlayLayer(sourceVintage);
58192                     selection.call(redraw);
58193                 });
58194         }
58195
58196         // disable if necessary
58197         ['DigitalGlobe-Premium', 'DigitalGlobe-Standard'].forEach(function(layerId) {
58198             if (source.id !== layerId) {
58199                 var key = layerId + '-vintage';
58200                 var sourceVintage = context.background().findSource(key);
58201                 if (context.background().showsLayer(sourceVintage)) {
58202                     context.background().toggleOverlayLayer(sourceVintage);
58203                 }
58204             }
58205         });
58206     }
58207
58208
58209     var debouncedGetMetadata = debounce(getMetadata, 250);
58210
58211     function getMetadata(selection) {
58212         var tile = d3_select('.layer-background img.tile-center');   // tile near viewport center
58213         if (tile.empty()) return;
58214
58215         var sourceName = currSourceName,
58216             d = tile.datum(),
58217             zoom = (d && d.length >= 3 && d[2]) || Math.floor(context.map().zoom()),
58218             center = context.map().center();
58219
58220         // update zoom
58221         metadata.zoom = String(zoom);
58222         selection.selectAll('.background-info-list-zoom')
58223             .classed('hide', false)
58224             .selectAll('.background-info-span-zoom')
58225             .text(metadata.zoom);
58226
58227         if (!d || !d.length >= 3) return;
58228
58229         background.baseLayerSource().getMetadata(center, d, function(err, result) {
58230             if (err || currSourceName !== sourceName) return;
58231
58232             // update vintage
58233             var vintage = result.vintage;
58234             metadata.vintage = (vintage && vintage.range) || t('info_panels.background.unknown');
58235             selection.selectAll('.background-info-list-vintage')
58236                 .classed('hide', false)
58237                 .selectAll('.background-info-span-vintage')
58238                 .text(metadata.vintage);
58239
58240             // update other metdata
58241             without(metadataKeys, 'zoom', 'vintage')
58242                 .forEach(function(k) {
58243                     var val = result[k];
58244                     metadata[k] = val;
58245                     selection.selectAll('.background-info-list-' + k)
58246                         .classed('hide', !val)
58247                         .selectAll('.background-info-span-' + k)
58248                         .text(val);
58249                 });
58250         });
58251     }
58252
58253
58254     var panel = function(selection) {
58255         selection.call(redraw);
58256
58257         context.map()
58258             .on('drawn.info-background', function() {
58259                 selection.call(debouncedRedraw);
58260             })
58261             .on('move.info-background', function() {
58262                 selection.call(debouncedGetMetadata);
58263             });
58264
58265     };
58266
58267     panel.off = function() {
58268         context.map()
58269             .on('drawn.info-background', null)
58270             .on('move.info-background', null);
58271     };
58272
58273     panel.id = 'background';
58274     panel.title = t('info_panels.background.title');
58275     panel.key = t('info_panels.background.key');
58276
58277
58278     return panel;
58279 }
58280
58281 function uiPanelHistory(context) {
58282     var osm;
58283
58284     function displayTimestamp(entity) {
58285         if (!entity.timestamp) return t('info_panels.history.unknown');
58286         var detected = utilDetect();
58287         var options = {
58288             day: 'numeric', month: 'short', year: 'numeric',
58289             hour: 'numeric', minute: 'numeric', second: 'numeric'
58290         };
58291         var d = new Date(entity.timestamp);
58292         if (isNaN(d.getTime())) return t('info_panels.history.unknown');
58293         return d.toLocaleString(detected.locale, options);
58294     }
58295
58296
58297     function displayUser(selection, entity) {
58298         if (!entity.user) {
58299             selection
58300                 .append('span')
58301                 .text(t('info_panels.history.unknown'));
58302             return;
58303         }
58304
58305         selection
58306             .append('span')
58307             .attr('class', 'user-name')
58308             .text(entity.user);
58309
58310         var links = selection
58311             .append('div')
58312             .attr('class', 'links');
58313
58314         if (osm) {
58315             links
58316                 .append('a')
58317                 .attr('class', 'user-osm-link')
58318                 .attr('href', osm.userURL(entity.user))
58319                 .attr('target', '_blank')
58320                 .attr('tabindex', -1)
58321                 .text('OSM');
58322         }
58323
58324         links
58325             .append('a')
58326             .attr('class', 'user-hdyc-link')
58327             .attr('href', 'https://hdyc.neis-one.org/?' + entity.user)
58328             .attr('target', '_blank')
58329             .attr('tabindex', -1)
58330             .text('HDYC');
58331     }
58332
58333
58334     function displayChangeset(selection, entity) {
58335         if (!entity.changeset) {
58336             selection
58337                 .append('span')
58338                 .text(t('info_panels.history.unknown'));
58339             return;
58340         }
58341
58342         selection
58343             .append('span')
58344             .attr('class', 'changeset-id')
58345             .text(entity.changeset);
58346
58347         var links = selection
58348             .append('div')
58349             .attr('class', 'links');
58350
58351         if (osm) {
58352             links
58353                 .append('a')
58354                 .attr('class', 'changeset-osm-link')
58355                 .attr('href', osm.changesetURL(entity.changeset))
58356                 .attr('target', '_blank')
58357                 .attr('tabindex', -1)
58358                 .text('OSM');
58359         }
58360
58361         links
58362             .append('a')
58363             .attr('class', 'changeset-osmcha-link')
58364             .attr('href', 'https://osmcha.mapbox.com/changesets/' + entity.changeset)
58365             .attr('target', '_blank')
58366             .attr('tabindex', -1)
58367             .text('OSMCha');
58368     }
58369
58370
58371     function redraw(selection) {
58372         var selected = filter(context.selectedIDs(), function(e) { return context.hasEntity(e); }),
58373             singular = selected.length === 1 ? selected[0] : null;
58374
58375         osm = context.connection();
58376
58377         selection.html('');
58378
58379         selection
58380             .append('h4')
58381             .attr('class', 'history-heading')
58382             .text(singular || t('info_panels.history.selected', { n: selected.length }));
58383
58384         if (!singular) return;
58385
58386         var entity = context.entity(singular);
58387
58388         var list = selection
58389             .append('ul');
58390
58391         list
58392             .append('li')
58393             .text(t('info_panels.history.version') + ':')
58394             .append('span')
58395             .text(entity.version);
58396
58397         list
58398             .append('li')
58399             .text(t('info_panels.history.last_edit') + ':')
58400             .append('span')
58401             .text(displayTimestamp(entity));
58402
58403         list
58404             .append('li')
58405             .text(t('info_panels.history.edited_by') + ':')
58406             .call(displayUser, entity);
58407
58408         list
58409             .append('li')
58410             .text(t('info_panels.history.changeset') + ':')
58411             .call(displayChangeset, entity);
58412
58413         if (osm) {
58414             selection
58415                 .append('a')
58416                 .attr('class', 'view-history-on-osm')
58417                 .attr('target', '_blank')
58418                 .attr('tabindex', -1)
58419                 .attr('href', osm.historyURL(entity))
58420                 .call(svgIcon('#icon-out-link', 'inline'))
58421                 .append('span')
58422                 .text(t('info_panels.history.link_text'));
58423         }
58424     }
58425
58426
58427     var panel = function(selection) {
58428         selection.call(redraw);
58429
58430         context.map()
58431             .on('drawn.info-history', function() {
58432                 selection.call(redraw);
58433             });
58434     };
58435
58436     panel.off = function() {
58437         context.map()
58438             .on('drawn.info-history', null);
58439     };
58440
58441     panel.id = 'history';
58442     panel.title = t('info_panels.history.title');
58443     panel.key = t('info_panels.history.key');
58444
58445
58446     return panel;
58447 }
58448
58449 var OSM_PRECISION = 7;
58450 var locale$2 = utilDetect().locale;
58451
58452 /**
58453  * Returns a localized representation of the given length measurement.
58454  *
58455  * @param {Number} m area in meters
58456  * @param {Boolean} isImperial true for U.S. customary units; false for metric
58457  */
58458 function displayLength(m, isImperial) {
58459         var d = m * (isImperial ? 3.28084 : 1),
58460                 unit;
58461
58462         if (isImperial) {
58463                 if (d >= 5280) {
58464                         d /= 5280;
58465                         unit = 'miles';
58466                 } else {
58467                         unit = 'feet';
58468                 }
58469         } else {
58470                 if (d >= 1000) {
58471                         d /= 1000;
58472                         unit = 'kilometers';
58473                 } else {
58474                         unit = 'meters';
58475                 }
58476         }
58477
58478         return t('units.' + unit, {
58479                 quantity: d.toLocaleString(locale$2, { maximumSignificantDigits: 4 })
58480         });
58481 }
58482
58483 /**
58484  * Returns a localized representation of the given area measurement.
58485  *
58486  * @param {Number} m2 area in square meters
58487  * @param {Boolean} isImperial true for U.S. customary units; false for metric
58488  */
58489 function displayArea(m2, isImperial) {
58490         var d = m2 * (isImperial ? 10.7639111056 : 1),
58491                 d1, d2, unit1, unit2, area;
58492
58493         if (isImperial) {
58494                 if (d >= 6969600) {     // > 0.25mi² show mi²
58495                         d1 = d / 27878400;
58496                         unit1 = 'square_miles';
58497                 } else {
58498                         d1 = d;
58499                         unit1 = 'square_feet';
58500                 }
58501
58502                 if (d > 4356 && d < 43560000) {   // 0.1 - 1000 acres
58503                         d2 = d / 43560;
58504                         unit2 = 'acres';
58505                 }
58506
58507         } else {
58508                 if (d >= 250000) {    // > 0.25km² show km²
58509                         d1 = d / 1000000;
58510                         unit1 = 'square_kilometers';
58511                 } else {
58512                         d1 = d;
58513                         unit1 = 'square_meters';
58514                 }
58515
58516                 if (d > 1000 && d < 10000000) {   // 0.1 - 1000 hectares
58517                         d2 = d / 10000;
58518                         unit2 = 'hectares';
58519                 }
58520         }
58521
58522         area = t('units.' + unit1, {
58523                 quantity: d1.toLocaleString(locale$2, { maximumSignificantDigits: 4 })
58524         });
58525
58526         if (d2) {
58527                 return t('units.area_pair', {
58528                         area1: area,
58529                         area2: t('units.' + unit2, {
58530                                 quantity: d2.toLocaleString(locale$2, { maximumSignificantDigits: 2 })
58531                         })
58532                 });
58533         } else {
58534                 return area;
58535         }
58536 }
58537
58538 function wrap(x, min, max) {
58539         var d = max - min;
58540         return ((x - min) % d + d) % d + min;
58541 }
58542
58543 function clamp(x, min, max) {
58544         return Math.max(min, Math.min(x, max));
58545 }
58546
58547 function displayCoordinate(deg, pos, neg) {
58548         var min = (Math.abs(deg) - Math.floor(Math.abs(deg))) * 60,
58549                 sec = (min - Math.floor(min)) * 60,
58550                 displayDegrees = t('units.arcdegrees', {
58551                         quantity: Math.floor(Math.abs(deg)).toLocaleString(locale$2)
58552                 }),
58553                 displayCoordinate;
58554
58555         if (Math.floor(sec) > 0) {
58556                 displayCoordinate = displayDegrees +
58557                         t('units.arcminutes', { quantity: Math.floor(min).toLocaleString(locale$2) }) +
58558                         t('units.arcseconds', { quantity: Math.round(sec).toLocaleString(locale$2) });
58559         } else if (Math.floor(min) > 0) {
58560                 displayCoordinate = displayDegrees +
58561                         t('units.arcminutes', { quantity: Math.round(min).toLocaleString(locale$2) });
58562         } else {
58563                 displayCoordinate = t('units.arcdegrees', {
58564                         quantity: Math.round(Math.abs(deg)).toLocaleString(locale$2)
58565                 });
58566         }
58567
58568         if (deg === 0) {
58569                 return displayCoordinate;
58570         } else {
58571                 return t('units.coordinate', {
58572                         coordinate: displayCoordinate,
58573                         direction: t('units.' + (deg > 0 ? pos : neg))
58574                 });
58575         }
58576 }
58577
58578 /**
58579  * Returns given coordinate pair in degree-minute-second format.
58580  *
58581  * @param {Array<Number>} coord longitude and latitude
58582  */
58583 function dmsCoordinatePair(coord) {
58584         return t('units.coordinate_pair', {
58585                 latitude: displayCoordinate(clamp(coord[1], -90, 90), 'north', 'south'),
58586                 longitude: displayCoordinate(wrap(coord[0], -180, 180), 'east', 'west')
58587         });
58588 }
58589
58590 /**
58591  * Returns the given coordinate pair in decimal format.
58592  *
58593  * @param {Array<Number>} coord longitude and latitude
58594  */
58595 function decimalCoordinatePair(coord) {
58596         return t('units.coordinate_pair', {
58597                 latitude: clamp(coord[1], -90, 90).toLocaleString(locale$2, { maximumFractionDigits: OSM_PRECISION }),
58598                 longitude: wrap(coord[0], -180, 180).toLocaleString(locale$2, { maximumFractionDigits: OSM_PRECISION })
58599         });
58600 }
58601
58602 function uiPanelLocation(context) {
58603     var currLocation = '';
58604
58605
58606     function redraw(selection) {
58607         selection.html('');
58608
58609         var list = selection
58610             .append('ul');
58611
58612         // Mouse coordinates
58613         var coord = context.map().mouseCoordinates();
58614         if (coord.some(isNaN)) {
58615             coord = context.map().center();
58616         }
58617
58618         list
58619             .append('li')
58620             .text(dmsCoordinatePair(coord))
58621             .append('li')
58622             .text(decimalCoordinatePair(coord));
58623
58624         // Location Info
58625         selection
58626             .append('div')
58627             .attr('class', 'location-info')
58628             .text(currLocation || ' ');
58629
58630         debouncedGetLocation(selection, coord);
58631     }
58632
58633
58634     var debouncedGetLocation = debounce(getLocation, 250);
58635     function getLocation(selection, coord) {
58636         if (!services.geocoder) {
58637             currLocation = t('info_panels.location.unknown_location');
58638             selection.selectAll('.location-info')
58639                 .text(currLocation);
58640         } else {
58641             services.geocoder.reverse(coord, function(err, result) {
58642                 currLocation = result ? result.display_name : t('info_panels.location.unknown_location');
58643                 selection.selectAll('.location-info')
58644                     .text(currLocation);
58645             });
58646         }
58647     }
58648
58649
58650     var panel = function(selection) {
58651         selection.call(redraw);
58652
58653         context.surface()
58654             .on('mousemove.info-location', function() {
58655                 selection.call(redraw);
58656             });
58657     };
58658
58659     panel.off = function() {
58660         context.surface()
58661             .on('mousemove.info-location', null);
58662     };
58663
58664     panel.id = 'location';
58665     panel.title = t('info_panels.location.title');
58666     panel.key = t('info_panels.location.key');
58667
58668
58669     return panel;
58670 }
58671
58672 function uiPanelMeasurement(context) {
58673     var locale = utilDetect().locale,
58674         isImperial = (locale.toLowerCase() === 'en-us');
58675
58676
58677     function radiansToMeters(r) {
58678         // using WGS84 authalic radius (6371007.1809 m)
58679         return r * 6371007.1809;
58680     }
58681
58682     function steradiansToSqmeters(r) {
58683         // http://gis.stackexchange.com/a/124857/40446
58684         return r / (4 * Math.PI) * 510065621724000;
58685     }
58686
58687
58688     function toLineString(feature) {
58689         if (feature.type === 'LineString') return feature;
58690
58691         var result = { type: 'LineString', coordinates: [] };
58692         if (feature.type === 'Polygon') {
58693             result.coordinates = feature.coordinates[0];
58694         } else if (feature.type === 'MultiPolygon') {
58695             result.coordinates = feature.coordinates[0][0];
58696         }
58697
58698         return result;
58699     }
58700
58701     function nodeCount(feature) {
58702       if (feature.type === 'LineString') return feature.coordinates.length;
58703
58704       if (feature.type === 'Polygon') {
58705           return feature.coordinates[0].length - 1;
58706       }
58707     }
58708
58709
58710     function redraw(selection) {
58711         var resolver = context.graph();
58712         var selected = filter(context.selectedIDs(), function(e) { return context.hasEntity(e); });
58713         var singular = selected.length === 1 ? selected[0] : null;
58714         var extent = geoExtent();
58715         var entity;
58716
58717         selection.html('');
58718
58719         selection
58720             .append('h4')
58721             .attr('class', 'measurement-heading')
58722             .text(singular || t('info_panels.measurement.selected', { n: selected.length.toLocaleString(locale) }));
58723
58724         if (!selected.length) return;
58725
58726         var center;
58727         for (var i = 0; i < selected.length; i++) {
58728             entity = context.entity(selected[i]);
58729             extent._extend(entity.extent(resolver));
58730         }
58731         center = extent.center();
58732
58733
58734         var list = selection
58735             .append('ul');
58736         var coordItem;
58737
58738         // multiple features, just display extent center..
58739         if (!singular) {
58740             coordItem = list
58741                 .append('li')
58742                 .text(t('info_panels.measurement.center') + ':');
58743             coordItem.append('span')
58744                 .text(dmsCoordinatePair(center));
58745             coordItem.append('span')
58746                 .text(decimalCoordinatePair(center));
58747             return;
58748         }
58749
58750         // single feature, display details..
58751         if (!entity) return;
58752         var geometry = entity.geometry(resolver);
58753
58754         if (geometry === 'line' || geometry === 'area') {
58755             var closed = (entity.type === 'relation') || (entity.isClosed() && !entity.isDegenerate()),
58756                 feature = entity.asGeoJSON(resolver),
58757                 length = radiansToMeters(d3_geoLength(toLineString(feature))),
58758                 lengthLabel = t('info_panels.measurement.' + (closed ? 'perimeter' : 'length')),
58759                 centroid = d3_geoCentroid(feature);
58760
58761             list
58762                 .append('li')
58763                 .text(t('info_panels.measurement.geometry') + ':')
58764                 .append('span')
58765                 .text(
58766                     closed ? t('info_panels.measurement.closed_' + geometry) : t('geometry.' + geometry)
58767                 );
58768
58769             if (entity.type !== 'relation') {
58770                 list
58771                     .append('li')
58772                     .text(t('info_panels.measurement.node_count') + ':')
58773                     .append('span')
58774                     .text(nodeCount(feature).toLocaleString(locale));
58775             }
58776
58777             if (closed) {
58778                 var area = steradiansToSqmeters(entity.area(resolver));
58779                 list
58780                     .append('li')
58781                     .text(t('info_panels.measurement.area') + ':')
58782                     .append('span')
58783                     .text(displayArea(area, isImperial));
58784             }
58785
58786
58787             list
58788                 .append('li')
58789                 .text(lengthLabel + ':')
58790                 .append('span')
58791                 .text(displayLength(length, isImperial));
58792
58793             coordItem = list
58794                 .append('li')
58795                 .text(t('info_panels.measurement.centroid') + ':');
58796             coordItem.append('span')
58797                 .text(dmsCoordinatePair(centroid));
58798             coordItem.append('span')
58799                 .text(decimalCoordinatePair(centroid));
58800
58801             var toggle  = isImperial ? 'imperial' : 'metric';
58802
58803             selection
58804                 .append('a')
58805                 .text(t('info_panels.measurement.' + toggle))
58806                 .attr('href', '#')
58807                 .attr('class', 'button button-toggle-units')
58808                 .on('click', function() {
58809                     event.preventDefault();
58810                     isImperial = !isImperial;
58811                     selection.call(redraw);
58812                 });
58813
58814         } else {
58815             var centerLabel = t('info_panels.measurement.' + (entity.type === 'node' ? 'location' : 'center'));
58816
58817             list
58818                 .append('li')
58819                 .text(t('info_panels.measurement.geometry') + ':')
58820                 .append('span')
58821                 .text(t('geometry.' + geometry));
58822
58823             coordItem = list
58824                 .append('li')
58825                 .text(centerLabel + ':');
58826             coordItem.append('span')
58827                 .text(dmsCoordinatePair(center));
58828             coordItem.append('span')
58829                 .text(decimalCoordinatePair(center));
58830         }
58831     }
58832
58833
58834     var panel = function(selection) {
58835         selection.call(redraw);
58836
58837         context.map()
58838             .on('drawn.info-measurement', function() {
58839                 selection.call(redraw);
58840             });
58841     };
58842
58843     panel.off = function() {
58844         context.map()
58845             .on('drawn.info-measurement', null);
58846     };
58847
58848     panel.id = 'measurement';
58849     panel.title = t('info_panels.measurement.title');
58850     panel.key = t('info_panels.measurement.key');
58851
58852
58853     return panel;
58854 }
58855
58856 var uiInfoPanels = {
58857     background: uiPanelBackground,
58858     history: uiPanelHistory,
58859     location: uiPanelLocation,
58860     measurement: uiPanelMeasurement,
58861 };
58862
58863 function uiInfo(context) {
58864     var ids = Object.keys(uiInfoPanels),
58865         wasActive = ['measurement'],
58866         panels = {},
58867         active = {};
58868
58869     // create panels
58870     ids.forEach(function(k) {
58871         if (!panels[k]) {
58872             panels[k] = uiInfoPanels[k](context);
58873             active[k] = false;
58874         }
58875     });
58876
58877
58878     function info(selection) {
58879
58880         function redraw() {
58881             var activeids = ids.filter(function(k) { return active[k]; }).sort();
58882
58883             var containers = infoPanels.selectAll('.panel-container')
58884                 .data(activeids, function(k) { return k; });
58885
58886             containers.exit()
58887                 .style('opacity', 1)
58888                 .transition()
58889                 .duration(200)
58890                 .style('opacity', 0)
58891                 .on('end', function(d) {
58892                     d3_select(this)
58893                         .call(panels[d].off)
58894                         .remove();
58895                 });
58896
58897             var enter = containers.enter()
58898                 .append('div')
58899                 .attr('class', function(d) { return 'fillD2 panel-container panel-container-' + d; });
58900
58901             enter
58902                 .style('opacity', 0)
58903                 .transition()
58904                 .duration(200)
58905                 .style('opacity', 1);
58906
58907             var title = enter
58908                 .append('div')
58909                 .attr('class', 'panel-title fillD2');
58910
58911             title
58912                 .append('h3')
58913                 .text(function(d) { return panels[d].title; });
58914
58915             title
58916                 .append('button')
58917                 .attr('class', 'close')
58918                 .on('click', function (d) { toggle(d); })
58919                 .call(svgIcon('#icon-close'));
58920
58921             enter
58922                 .append('div')
58923                 .attr('class', function(d) { return 'panel-content panel-content-' + d; });
58924
58925
58926             // redraw the panels
58927             infoPanels.selectAll('.panel-content')
58928                 .each(function(d) {
58929                     d3_select(this).call(panels[d]);
58930                 });
58931         }
58932
58933
58934         function toggle(which) {
58935             if (event) {
58936                 event.stopImmediatePropagation();
58937                 event.preventDefault();
58938             }
58939
58940             var activeids = ids.filter(function(k) { return active[k]; });
58941
58942             if (which) {  // toggle one
58943                 active[which] = !active[which];
58944                 if (activeids.length === 1 && activeids[0] === which) {  // none active anymore
58945                     wasActive = [which];
58946                 }
58947             } else {      // toggle all
58948                 if (activeids.length) {
58949                     wasActive = activeids;
58950                     activeids.forEach(function(k) { active[k] = false; });
58951                 } else {
58952                     wasActive.forEach(function(k) { active[k] = true; });
58953                 }
58954             }
58955
58956             redraw();
58957         }
58958
58959
58960         var infoPanels = selection.selectAll('.info-panels')
58961             .data([0]);
58962
58963         infoPanels = infoPanels.enter()
58964             .append('div')
58965             .attr('class', 'info-panels')
58966             .merge(infoPanels);
58967
58968         redraw();
58969
58970         var keybinding = d3keybinding('info')
58971             .on(uiCmd('⌘' + t('info_panels.key')), toggle);
58972
58973         ids.forEach(function(k) {
58974             var key = t('info_panels.' + k + '.key', { default: null });
58975             if (!key) return;
58976             keybinding
58977                 .on(uiCmd('⌘⇧' + key), function() { toggle(k); });
58978         });
58979
58980         d3_select(document)
58981             .call(keybinding);
58982     }
58983
58984     return info;
58985 }
58986
58987 function uiModes(context) {
58988     var modes = [
58989         modeAddPoint(context),
58990         modeAddLine(context),
58991         modeAddArea(context)
58992     ];
58993
58994
58995     function editable() {
58996         var mode = context.mode();
58997         return context.editable() && mode && mode.id !== 'save';
58998     }
58999
59000
59001     return function(selection) {
59002         var buttons = selection.selectAll('button.add-button')
59003             .data(modes);
59004
59005         buttons = buttons.enter()
59006             .append('button')
59007             .attr('tabindex', -1)
59008             .attr('class', function(mode) { return mode.id + ' add-button col4'; })
59009             .on('click.mode-buttons', function(mode) {
59010                 // When drawing, ignore accidental clicks on mode buttons - #4042
59011                 var currMode = context.mode().id;
59012                 if (currMode.match(/^draw/) !== null) return;
59013
59014                 if (mode.id === currMode) {
59015                     context.enter(modeBrowse(context));
59016                 } else {
59017                     context.enter(mode);
59018                 }
59019             })
59020             .call(tooltip()
59021                 .placement('bottom')
59022                 .html(true)
59023                 .title(function(mode) {
59024                     return uiTooltipHtml(mode.description, mode.key);
59025                 })
59026             );
59027
59028         buttons
59029             .each(function(d) {
59030                 d3_select(this)
59031                     .call(svgIcon('#icon-' + d.button, 'pre-text'));
59032             });
59033
59034         buttons
59035             .append('span')
59036             .attr('class', 'label')
59037             .text(function(mode) { return mode.title; });
59038
59039         context
59040             .on('enter.editor', function(entered) {
59041                 selection.selectAll('button.add-button')
59042                     .classed('active', function(mode) { return entered.button === mode.button; });
59043                 context.container()
59044                     .classed('mode-' + entered.id, true);
59045             });
59046
59047         context
59048             .on('exit.editor', function(exited) {
59049                 context.container()
59050                     .classed('mode-' + exited.id, false);
59051             });
59052
59053         var keybinding = d3keybinding('mode-buttons');
59054
59055         modes.forEach(function(mode) {
59056             keybinding.on(mode.key, function() {
59057                 if (editable()) {
59058                     if (mode.id === context.mode().id) {
59059                         context.enter(modeBrowse(context));
59060                     } else {
59061                         context.enter(mode);
59062                     }
59063                 }
59064             });
59065         });
59066
59067         d3_select(document)
59068             .call(keybinding);
59069
59070
59071         var debouncedUpdate = debounce(update, 500, { leading: true, trailing: true });
59072
59073         context.map()
59074             .on('move.modes', debouncedUpdate)
59075             .on('drawn.modes', debouncedUpdate);
59076
59077         context
59078             .on('enter.modes', update);
59079
59080
59081
59082         function update() {
59083             selection.selectAll('button.add-button')
59084                 .property('disabled', !editable());
59085         }
59086     };
59087 }
59088
59089 function uiNotice(context) {
59090
59091     return function(selection) {
59092         var div = selection
59093             .append('div')
59094             .attr('class', 'notice');
59095
59096         var button = div
59097             .append('button')
59098             .attr('class', 'zoom-to notice fillD')
59099             .on('click', function() {
59100                 context.map().zoomEase(context.minEditableZoom());
59101             })
59102             .on('wheel', function() {   // let wheel events pass through #4482
59103                 var e2 = new WheelEvent(event.type, event);
59104                 context.surface().node().dispatchEvent(e2);
59105             });
59106
59107         button
59108             .call(svgIcon('#icon-plus', 'pre-text'))
59109             .append('span')
59110             .attr('class', 'label')
59111             .text(t('zoom_in_edit'));
59112
59113
59114         function disableTooHigh() {
59115             var canEdit = context.map().zoom() >= context.minEditableZoom();
59116             div.style('display', canEdit ? 'none' : 'block');
59117         }
59118
59119         context.map()
59120             .on('move.notice', debounce(disableTooHigh, 500));
59121
59122         disableTooHigh();
59123     };
59124 }
59125
59126 function uiRestore(context) {
59127
59128     return function(selection) {
59129         if (!context.history().lock() || !context.history().restorableChanges())
59130             return;
59131
59132         var modalSelection = uiModal(selection, true);
59133
59134         modalSelection.select('.modal')
59135             .attr('class', 'modal fillL col6');
59136
59137         var introModal = modalSelection.select('.content');
59138
59139         introModal
59140             .attr('class','cf');
59141
59142         introModal
59143             .append('div')
59144             .attr('class', 'modal-section')
59145             .append('h3')
59146             .text(t('restore.heading'));
59147
59148         introModal
59149             .append('div')
59150             .attr('class','modal-section')
59151             .append('p')
59152             .text(t('restore.description'));
59153
59154         var buttonWrap = introModal
59155             .append('div')
59156             .attr('class', 'modal-actions cf');
59157
59158         var restore = buttonWrap
59159             .append('button')
59160             .attr('class', 'restore col6')
59161             .on('click', function() {
59162                 context.history().restore();
59163                 modalSelection.remove();
59164             });
59165
59166         restore
59167             .append('svg')
59168             .attr('class', 'logo logo-restore')
59169             .append('use')
59170             .attr('xlink:href', '#logo-restore');
59171
59172         restore
59173             .append('div')
59174             .text(t('restore.restore'));
59175
59176         var reset = buttonWrap
59177             .append('button')
59178             .attr('class', 'reset col6')
59179             .on('click', function() {
59180                 context.history().clearSaved();
59181                 modalSelection.remove();
59182             });
59183
59184         reset
59185             .append('svg')
59186             .attr('class', 'logo logo-reset')
59187             .append('use')
59188             .attr('xlink:href', '#logo-reset');
59189
59190         reset
59191             .append('div')
59192             .text(t('restore.reset'));
59193
59194         restore.node().focus();
59195     };
59196 }
59197
59198 function uiSave(context) {
59199     var history = context.history();
59200     var key = uiCmd('⌘S');
59201
59202
59203     function saving() {
59204         var mode = context.mode();
59205         return mode && mode.id === 'save';
59206     }
59207
59208
59209     function save() {
59210         event.preventDefault();
59211         if (!context.inIntro() && !saving() && history.hasChanges()) {
59212             context.enter(modeSave(context));
59213         }
59214     }
59215
59216
59217     function getBackground(numChanges) {
59218         var step;
59219         if (numChanges === 0) {
59220             return null;
59221         } else if (numChanges <= 50) {
59222             step = numChanges / 50;
59223             return d3_interpolateRgb('#fff', '#ff8')(step);  // white -> yellow
59224         } else {
59225             step = Math.min((numChanges - 50) / 50, 1.0);
59226             return d3_interpolateRgb('#ff8', '#f88')(step);  // yellow -> red
59227         }
59228     }
59229
59230
59231     return function(selection) {
59232         var numChanges = 0;
59233
59234         function updateCount() {
59235             var _ = history.difference().summary().length;
59236             if (_ === numChanges) return;
59237             numChanges = _;
59238
59239             tooltipBehavior
59240                 .title(uiTooltipHtml(
59241                     t(numChanges > 0 ? 'save.help' : 'save.no_changes'), key)
59242                 );
59243
59244             var background = getBackground(numChanges);
59245
59246             button
59247                 .classed('disabled', numChanges === 0)
59248                 .classed('has-count', numChanges > 0)
59249                 .style('background', background);
59250
59251             button.select('span.count')
59252                 .text(numChanges)
59253                 .style('background', background)
59254                 .style('border-color', background);
59255         }
59256
59257
59258         var tooltipBehavior = tooltip()
59259             .placement('bottom')
59260             .html(true)
59261             .title(uiTooltipHtml(t('save.no_changes'), key));
59262
59263         var button = selection
59264             .append('button')
59265             .attr('class', 'save col12 disabled')
59266             .attr('tabindex', -1)
59267             .on('click', save)
59268             .call(tooltipBehavior);
59269
59270         button
59271             .call(svgIcon('#icon-save', 'pre-text'))
59272             .append('span')
59273             .attr('class', 'label')
59274             .text(t('save.title'));
59275
59276         button
59277             .append('span')
59278             .attr('class', 'count')
59279             .text('0');
59280
59281         updateCount();
59282
59283
59284         var keybinding = d3keybinding('uiSave')
59285             .on(key, save, true);
59286
59287         d3_select(document)
59288             .call(keybinding);
59289
59290         context.history()
59291             .on('change.save', updateCount);
59292
59293         context
59294             .on('enter.save', function() {
59295                 button.property('disabled', saving());
59296                 if (saving()) button.call(tooltipBehavior.hide);
59297             });
59298     };
59299 }
59300
59301 function uiScale(context) {
59302     var projection = context.projection,
59303         isImperial = (utilDetect().locale.toLowerCase() === 'en-us'),
59304         maxLength = 180,
59305         tickHeight = 8;
59306
59307
59308     function scaleDefs(loc1, loc2) {
59309         var lat = (loc2[1] + loc1[1]) / 2,
59310             conversion = (isImperial ? 3.28084 : 1),
59311             dist = geoLonToMeters(loc2[0] - loc1[0], lat) * conversion,
59312             scale = { dist: 0, px: 0, text: '' },
59313             buckets, i, val, dLon;
59314
59315         if (isImperial) {
59316             buckets = [5280000, 528000, 52800, 5280, 500, 50, 5, 1];
59317         } else {
59318             buckets = [5000000, 500000, 50000, 5000, 500, 50, 5, 1];
59319         }
59320
59321         // determine a user-friendly endpoint for the scale
59322         for (i = 0; i < buckets.length; i++) {
59323             val = buckets[i];
59324             if (dist >= val) {
59325                 scale.dist = Math.floor(dist / val) * val;
59326                 break;
59327             } else {
59328                 scale.dist = +dist.toFixed(2);
59329             }
59330         }
59331
59332         dLon = geoMetersToLon(scale.dist / conversion, lat);
59333         scale.px = Math.round(projection([loc1[0] + dLon, loc1[1]])[0]);
59334
59335         scale.text = displayLength(scale.dist / conversion, isImperial);
59336
59337         return scale;
59338     }
59339
59340
59341     function update(selection) {
59342         // choose loc1, loc2 along bottom of viewport (near where the scale will be drawn)
59343         var dims = context.map().dimensions(),
59344             loc1 = projection.invert([0, dims[1]]),
59345             loc2 = projection.invert([maxLength, dims[1]]),
59346             scale = scaleDefs(loc1, loc2);
59347
59348         selection.select('#scale-path')
59349             .attr('d', 'M0.5,0.5v' + tickHeight + 'h' + scale.px + 'v-' + tickHeight);
59350
59351         selection.select('#scale-textgroup')
59352             .attr('transform', 'translate(' + (scale.px + 8) + ',' + tickHeight + ')');
59353
59354         selection.select('#scale-text')
59355             .text(scale.text);
59356     }
59357
59358
59359     return function(selection) {
59360         function switchUnits() {
59361             isImperial = !isImperial;
59362             selection.call(update);
59363         }
59364
59365         var scalegroup = selection.append('svg')
59366             .attr('id', 'scale')
59367             .on('click', switchUnits)
59368             .append('g')
59369             .attr('transform', 'translate(10,11)');
59370
59371         scalegroup
59372             .append('path')
59373             .attr('id', 'scale-path');
59374
59375         scalegroup
59376             .append('g')
59377             .attr('id', 'scale-textgroup')
59378             .append('text')
59379             .attr('id', 'scale-text');
59380
59381         selection.call(update);
59382
59383         context.map().on('move.scale', function() {
59384             update(selection);
59385         });
59386     };
59387 }
59388
59389 var pair_1 = pair$1;
59390 function search(x, dims, r) {
59391   if (!dims) dims = 'NSEW';
59392   if (typeof x !== 'string') return { val: null, regex: r };
59393
59394   r = r || /[\s\,]*([NSEW])?\s*([\-|\—|\―]?[0-9.]+)°?\s*(?:([0-9.]+)['’′‘]\s*)?(?:([0-9.]+)(?:''|"|”|″)\s*)?([NSEW])?/gi;
59395
59396   var m = r.exec(x);
59397   if (!m) return { val: null, regex: r };
59398
59399   var dim = m[1] || m[5];
59400   if (dim && dims.indexOf(dim) === -1) return { val: null, regex: r };
59401
59402   return {
59403     val: (((m[2]) ? parseFloat(m[2]) : 0) +
59404           ((m[3] ? parseFloat(m[3]) / 60 : 0)) +
59405           ((m[4] ? parseFloat(m[4]) / 3600 : 0))) *
59406           ((dim === 'S' || dim === 'W') ? -1 : 1),
59407     regex: r,
59408     raw: m[0],
59409     dim: dim
59410   };
59411 }
59412
59413 function pair$1(x, dims) {
59414   x = x.trim();
59415   var one = search(x, dims);
59416   if (one.val === null) return null;
59417   var two = search(x, dims, one.regex);
59418   if (two.val === null) return null;
59419   // null if one/two are not contiguous.
59420   if (one.raw + two.raw !== x) return null;
59421   if (one.dim) {
59422     return swapdim(one.val, two.val, one.dim);
59423   } else {
59424     return [one.val, two.val];
59425   }
59426 }
59427
59428 function swapdim(a, b, dim) {
59429   if (dim === 'N' || dim === 'S') return [a, b];
59430   if (dim === 'W' || dim === 'E') return [b, a];
59431 }
59432
59433 function uiFeatureList(context) {
59434     var keybinding = d3keybinding('uiFeatureList');
59435     var _geocodeResults;
59436
59437
59438     function featureList(selection) {
59439         var header = selection
59440             .append('div')
59441             .attr('class', 'header fillL cf');
59442
59443         header
59444             .append('h3')
59445             .text(t('inspector.feature_list'));
59446
59447         var searchWrap = selection
59448             .append('div')
59449             .attr('class', 'search-header');
59450
59451         var search = searchWrap
59452             .append('input')
59453             .attr('placeholder', t('inspector.search'))
59454             .attr('type', 'search')
59455             .call(utilNoAuto)
59456             .on('keypress', keypress)
59457             .on('keydown', keydown)
59458             .on('input', inputevent);
59459
59460         searchWrap
59461             .call(svgIcon('#icon-search', 'pre-text'));
59462
59463         var listWrap = selection
59464             .append('div')
59465             .attr('class', 'inspector-body');
59466
59467         var list = listWrap
59468             .append('div')
59469             .attr('class', 'feature-list cf');
59470
59471         context
59472             .on('exit.feature-list', clearSearch);
59473         context.map()
59474             .on('drawn.feature-list', mapDrawn);
59475
59476         keybinding
59477             .on(uiCmd('⌘F'), focusSearch);
59478
59479         d3_select(document)
59480             .call(keybinding);
59481
59482
59483         function focusSearch() {
59484             var mode = context.mode() && context.mode().id;
59485             if (mode !== 'browse') return;
59486
59487             event.preventDefault();
59488             search.node().focus();
59489         }
59490
59491
59492         function keydown() {
59493             if (event.keyCode === 27) {  // escape
59494                 search.node().blur();
59495             }
59496         }
59497
59498
59499         function keypress() {
59500             var q = search.property('value'),
59501                 items = list.selectAll('.feature-list-item');
59502             if (event.keyCode === 13 && q.length && items.size()) {  // return
59503                 click(items.datum());
59504             }
59505         }
59506
59507
59508         function inputevent() {
59509             _geocodeResults = undefined;
59510             drawList();
59511         }
59512
59513
59514         function clearSearch() {
59515             search.property('value', '');
59516             drawList();
59517         }
59518
59519
59520         function mapDrawn(e) {
59521             if (e.full) {
59522                 drawList();
59523             }
59524         }
59525
59526
59527         function features() {
59528             var entities = {};
59529             var result = [];
59530             var graph = context.graph();
59531             var q = search.property('value').toLowerCase();
59532
59533             if (!q) return result;
59534
59535             var idMatch = q.match(/^([nwr])([0-9]+)$/);
59536
59537             if (idMatch) {
59538                 result.push({
59539                     id: idMatch[0],
59540                     geometry: idMatch[1] === 'n' ? 'point' : idMatch[1] === 'w' ? 'line' : 'relation',
59541                     type: idMatch[1] === 'n' ? t('inspector.node') : idMatch[1] === 'w' ? t('inspector.way') : t('inspector.relation'),
59542                     name: idMatch[2]
59543                 });
59544             }
59545
59546             var locationMatch = pair_1(q.toUpperCase()) || q.match(/^(-?\d+\.?\d*)\s+(-?\d+\.?\d*)$/);
59547
59548             if (locationMatch) {
59549                 var loc = [parseFloat(locationMatch[0]), parseFloat(locationMatch[1])];
59550                 result.push({
59551                     id: -1,
59552                     geometry: 'point',
59553                     type: t('inspector.location'),
59554                     name: dmsCoordinatePair([loc[1], loc[0]]),
59555                     location: loc
59556                 });
59557             }
59558
59559             function addEntity(entity) {
59560                 if (entity.id in entities || result.length > 200)
59561                     return;
59562
59563                 entities[entity.id] = true;
59564
59565                 var name = utilDisplayName(entity) || '';
59566                 if (name.toLowerCase().indexOf(q) >= 0) {
59567                     var matched = context.presets().match(entity, graph);
59568                     var type = (matched && matched.name()) || utilDisplayType(entity.id);
59569
59570                     result.push({
59571                         id: entity.id,
59572                         entity: entity,
59573                         geometry: context.geometry(entity.id),
59574                         type: type,
59575                         name: name
59576                     });
59577                 }
59578
59579                 graph.parentRelations(entity).forEach(function(parent) {
59580                     addEntity(parent);
59581                 });
59582             }
59583
59584             var visible = context.surface().selectAll('.point, .line, .area').nodes();
59585             for (var i = 0; i < visible.length && result.length <= 200; i++) {
59586                 var datum = visible[i].__data__;
59587                 var entity = datum && datum.properties && datum.properties.entity;
59588                 if (entity) { addEntity(entity); }
59589             }
59590
59591             (_geocodeResults || []).forEach(function(d) {
59592                 if (d.osm_type && d.osm_id) {    // some results may be missing these - #1890
59593
59594                     // Make a temporary osmEntity so we can preset match
59595                     // and better localize the search result - #4725
59596                     var id = osmEntity.id.fromOSM(d.osm_type, d.osm_id);
59597                     var tags = {};
59598                     tags[d.class] = d.type;
59599
59600                     var attrs = { id: id, type: d.osm_type, tags: tags };
59601                     if (d.osm_type === 'way') {   // for ways, add some fake closed nodes
59602                         attrs.nodes = ['a','a'];  // so that geometry area is possible
59603                     }
59604
59605                     var tempEntity = osmEntity(attrs);
59606                     var tempGraph = coreGraph([tempEntity]);
59607                     var matched = context.presets().match(tempEntity, tempGraph);
59608                     var type = (matched && matched.name()) || utilDisplayType(id);
59609
59610                     result.push({
59611                         id: tempEntity.id,
59612                         geometry: tempEntity.geometry(tempGraph),
59613                         type: type,
59614                         name: d.display_name,
59615                         extent: new geoExtent(
59616                             [parseFloat(d.boundingbox[3]), parseFloat(d.boundingbox[0])],
59617                             [parseFloat(d.boundingbox[2]), parseFloat(d.boundingbox[1])])
59618                     });
59619                 }
59620             });
59621
59622             return result;
59623         }
59624
59625
59626         function drawList() {
59627             var value = search.property('value');
59628             var results = features();
59629
59630             list.classed('filtered', value.length);
59631
59632             var noResultsWorldwide = _geocodeResults && _geocodeResults.length === 0;
59633
59634             var resultsIndicator = list.selectAll('.no-results-item')
59635                 .data([0])
59636                 .enter()
59637                 .append('button')
59638                 .property('disabled', true)
59639                 .attr('class', 'no-results-item')
59640                 .call(svgIcon('#icon-alert', 'pre-text'));
59641
59642             resultsIndicator.append('span')
59643                 .attr('class', 'entity-name');
59644
59645             list.selectAll('.no-results-item .entity-name')
59646                 .text(noResultsWorldwide ? t('geocoder.no_results_worldwide') : t('geocoder.no_results_visible'));
59647
59648             if (services.geocoder) {
59649               list.selectAll('.geocode-item')
59650                   .data([0])
59651                   .enter()
59652                   .append('button')
59653                   .attr('class', 'geocode-item')
59654                   .on('click', geocoderSearch)
59655                   .append('div')
59656                   .attr('class', 'label')
59657                   .append('span')
59658                   .attr('class', 'entity-name')
59659                   .text(t('geocoder.search'));
59660             }
59661
59662             list.selectAll('.no-results-item')
59663                 .style('display', (value.length && !results.length) ? 'block' : 'none');
59664
59665             list.selectAll('.geocode-item')
59666                 .style('display', (value && _geocodeResults === undefined) ? 'block' : 'none');
59667
59668             list.selectAll('.feature-list-item')
59669                 .data([-1])
59670                 .remove();
59671
59672             var items = list.selectAll('.feature-list-item')
59673                 .data(results, function(d) { return d.id; });
59674
59675             var enter = items.enter()
59676                 .insert('button', '.geocode-item')
59677                 .attr('class', 'feature-list-item')
59678                 .on('mouseover', mouseover)
59679                 .on('mouseout', mouseout)
59680                 .on('click', click);
59681
59682             var label = enter
59683                 .append('div')
59684                 .attr('class', 'label');
59685
59686             label
59687                 .each(function(d) {
59688                     d3_select(this)
59689                         .call(svgIcon('#icon-' + d.geometry, 'pre-text'));
59690                 });
59691
59692             label
59693                 .append('span')
59694                 .attr('class', 'entity-type')
59695                 .text(function(d) { return d.type; });
59696
59697             label
59698                 .append('span')
59699                 .attr('class', 'entity-name')
59700                 .text(function(d) { return d.name; });
59701
59702             enter
59703                 .style('opacity', 0)
59704                 .transition()
59705                 .style('opacity', 1);
59706
59707             items.order();
59708
59709             items.exit()
59710                 .remove();
59711         }
59712
59713
59714         function mouseover(d) {
59715             if (d.id === -1) return;
59716
59717             context.surface().selectAll(utilEntityOrMemberSelector([d.id], context.graph()))
59718                 .classed('hover', true);
59719         }
59720
59721
59722         function mouseout() {
59723             context.surface().selectAll('.hover')
59724                 .classed('hover', false);
59725         }
59726
59727
59728         function click(d) {
59729             event.preventDefault();
59730             if (d.location) {
59731                 context.map().centerZoom([d.location[1], d.location[0]], 20);
59732             }
59733             else if (d.entity) {
59734                 if (d.entity.type === 'node') {
59735                     context.map().center(d.entity.loc);
59736                 } else if (d.entity.type === 'way') {
59737                     var center = context.projection(context.map().center());
59738                     var edge = geoChooseEdge(context.childNodes(d.entity), center, context.projection);
59739                     context.map().center(edge.loc);
59740                 }
59741                 context.enter(modeSelect(context, [d.entity.id]));
59742             } else {
59743                 context.zoomToEntity(d.id);
59744             }
59745         }
59746
59747
59748         function geocoderSearch() {
59749             services.geocoder.search(search.property('value'), function (err, resp) {
59750                 _geocodeResults = resp || [];
59751                 drawList();
59752             });
59753         }
59754     }
59755
59756
59757     return featureList;
59758 }
59759
59760 function uiPresetIcon() {
59761     var preset, geometry;
59762
59763
59764     function presetIcon(selection) {
59765         selection.each(render);
59766     }
59767
59768
59769     function getIcon(p, geom) {
59770         if (p.icon)
59771             return p.icon;
59772         else if (geom === 'line')
59773             return 'other-line';
59774         else if (geom === 'vertex')
59775             return p.isFallback() ? '' : 'poi-vertex';
59776         else
59777             return 'marker-stroked';
59778     }
59779
59780
59781     function render() {
59782         var selection = d3_select(this),
59783             p = preset.apply(this, arguments),
59784             geom = geometry.apply(this, arguments),
59785             picon = getIcon(p, geom),
59786             isPoi = picon.match(/^poi-/) !== null,
59787             isMaki = dataFeatureIcons.indexOf(picon) !== -1,
59788             isFramed = (geom === 'area' || geom === 'verex');
59789
59790
59791         function tag_classes(p) {
59792             var s = '';
59793             for (var i in p.tags) {
59794                 s += ' tag-' + i;
59795                 if (p.tags[i] !== '*') {
59796                     s += ' tag-' + i + '-' + p.tags[i];
59797                 }
59798             }
59799             return s;
59800         }
59801
59802
59803         var fill = selection.selectAll('.preset-icon-fill')
59804             .data([0]);
59805
59806         fill = fill.enter()
59807             .append('div')
59808             .merge(fill);
59809
59810         fill
59811             .attr('class', function() {
59812                 return 'preset-icon-fill preset-icon-fill-' + geom + tag_classes(p);
59813             });
59814
59815
59816         var areaFrame = selection.selectAll('.preset-icon-frame')
59817             .data((geom === 'area') ? [0] : []);
59818
59819         areaFrame.exit()
59820             .remove();
59821
59822         areaFrame = areaFrame.enter()
59823             .append('div')
59824             .attr('class', 'preset-icon-frame')
59825             .call(svgIcon('#preset-icon-frame'));
59826
59827
59828         var icon = selection.selectAll('.preset-icon')
59829             .data([0]);
59830
59831         icon = icon.enter()
59832             .append('div')
59833             .attr('class', 'preset-icon')
59834             .call(svgIcon(''))
59835             .merge(icon);
59836
59837         icon
59838             .attr('class', 'preset-icon preset-icon-' +
59839                 ((isMaki || isPoi) ? (isFramed ? '24' : '28') : (isFramed ? '44' : '60'))
59840             );
59841
59842         icon.selectAll('svg')
59843             .attr('class', function() {
59844                 return 'icon ' + picon + (isMaki || isPoi ? '' : tag_classes(p));
59845             });
59846
59847         icon.selectAll('use')
59848             .attr('href', '#' + picon + (isMaki ? '-15' : ''));
59849     }
59850
59851
59852     presetIcon.preset = function(_) {
59853         if (!arguments.length) return preset;
59854         preset = utilFunctor(_);
59855         return presetIcon;
59856     };
59857
59858
59859     presetIcon.geometry = function(_) {
59860         if (!arguments.length) return geometry;
59861         geometry = utilFunctor(_);
59862         return presetIcon;
59863     };
59864
59865     return presetIcon;
59866 }
59867
59868 function d3combobox() {
59869     var dispatch$$1 = dispatch('accept');
59870     var _container = d3_select(document.body);
59871     var _data = [];
59872     var _suggestions = [];
59873     var _minItems = 2;
59874     var _caseSensitive = false;
59875
59876     var _fetcher = function(val, cb) {
59877         cb(_data.filter(function(d) {
59878             return d.value
59879                 .toString()
59880                 .toLowerCase()
59881                 .indexOf(val.toLowerCase()) !== -1;
59882         }));
59883     };
59884
59885     var combobox = function(input, attachTo) {
59886         var idx = -1;
59887         var wrapper = _container
59888             .selectAll('div.combobox')
59889             .filter(function(d) { return d === input.node(); });
59890         var shown = !wrapper.empty();
59891
59892         input
59893             .classed('combobox-input', true)
59894             .on('focus.typeahead', focus)
59895             .on('blur.typeahead', blur)
59896             .on('keydown.typeahead', keydown)
59897             .on('keyup.typeahead', keyup)
59898             .on('input.typeahead', change)
59899             .each(function() {
59900                 var parent = this.parentNode;
59901                 var sibling = this.nextSibling;
59902
59903                 var caret = d3_select(parent).selectAll('.combobox-caret')
59904                     .filter(function(d) { return d === input.node(); })
59905                     .data([input.node()]);
59906
59907                 caret = caret.enter()
59908                     .insert('div', function() { return sibling; })
59909                     .attr('class', 'combobox-caret')
59910                     .merge(caret);
59911
59912                 caret
59913                     .on('mousedown', function () {
59914                         // prevent the form element from blurring. it blurs
59915                         // on mousedown
59916                         event.stopPropagation();
59917                         event.preventDefault();
59918                         if (!shown) {
59919                             input.node().focus();
59920                             fetch('', render);
59921                         } else {
59922                             hide();
59923                         }
59924                     });
59925             });
59926
59927         function focus() {
59928             fetch(value(), render);
59929         }
59930
59931         function blur() {
59932             window.setTimeout(hide, 150);
59933         }
59934
59935         function show() {
59936             if (!shown) {
59937                 wrapper = _container
59938                     .insert('div', ':first-child')
59939                     .datum(input.node())
59940                     .attr('class', 'combobox')
59941                     .style('position', 'absolute')
59942                     .style('display', 'block')
59943                     .style('left', '0px')
59944                     .on('mousedown', function () {
59945                         // prevent moving focus out of the text field
59946                         event.preventDefault();
59947                     });
59948
59949                 d3_select('body')
59950                     .on('scroll.combobox', render, true);
59951
59952                 shown = true;
59953             }
59954         }
59955
59956         function hide() {
59957             if (shown) {
59958                 idx = -1;
59959                 wrapper.remove();
59960
59961                 d3_select('body')
59962                     .on('scroll.combobox', null);
59963
59964                 shown = false;
59965             }
59966         }
59967
59968         function keydown() {
59969            switch (event.keyCode) {
59970                // backspace, delete
59971                case 8:
59972                case 46:
59973                    input.on('input.typeahead', function() {
59974                        idx = -1;
59975                        render();
59976                        var start = input.property('selectionStart');
59977                        input.node().setSelectionRange(start, start);
59978                        input.on('input.typeahead', change);
59979                    });
59980                    break;
59981                // tab
59982                case 9:
59983                    wrapper.selectAll('a.selected').each(function (d) {
59984                        dispatch$$1.call('accept', this, d);
59985                    });
59986                    hide();
59987                    break;
59988                // return
59989                case 13:
59990                    event.preventDefault();
59991                    break;
59992                // up arrow
59993                case 38:
59994                    nav(-1);
59995                    event.preventDefault();
59996                    break;
59997                // down arrow
59998                case 40:
59999                    nav(+1);
60000                    event.preventDefault();
60001                    break;
60002            }
60003            event.stopPropagation();
60004         }
60005
60006         function keyup() {
60007             switch (event.keyCode) {
60008                 // escape
60009                 case 27:
60010                     hide();
60011                     break;
60012                 // return
60013                 case 13:
60014                     wrapper.selectAll('a.selected').each(function (d) {
60015                        dispatch$$1.call('accept', this, d);
60016                     });
60017                     hide();
60018                     break;
60019             }
60020         }
60021
60022         function change() {
60023             fetch(value(), function() {
60024                 if (input.property('selectionEnd') === input.property('value').length) {
60025                     autocomplete();
60026                 }
60027                 render();
60028             });
60029         }
60030
60031         function nav(dir) {
60032             if (!_suggestions.length) return;
60033             idx = Math.max(Math.min(idx + dir, _suggestions.length - 1), 0);
60034             input.property('value', _suggestions[idx].value);
60035             render();
60036             ensureVisible();
60037         }
60038
60039         function value() {
60040             var value = input.property('value');
60041             var start = input.property('selectionStart');
60042             var end = input.property('selectionEnd');
60043
60044             if (start && end) {
60045                 value = value.substring(0, start);
60046             }
60047
60048             return value;
60049         }
60050
60051         function fetch(v, cb) {
60052             _fetcher.call(input, v, function(_) {
60053                 _suggestions = _;
60054                 cb();
60055             });
60056         }
60057
60058         function autocomplete() {
60059             var v = _caseSensitive ? value() : value().toLowerCase();
60060             idx = -1;
60061             if (!v) return;
60062
60063             var best = -1;
60064             var suggestion, compare;
60065
60066             for (var i = 0; i < _suggestions.length; i++) {
60067                 suggestion = _suggestions[i].value;
60068                 compare = _caseSensitive ? suggestion : suggestion.toLowerCase();
60069
60070                 // if search string matches suggestion exactly, pick it..
60071                 if (compare === v) {
60072                     best = i;
60073                     break;
60074
60075                 // otherwise lock in the first result that starts with the search string..
60076                 } else if (best === -1 && compare.indexOf(v) === 0) {
60077                     best = i;
60078                 }
60079             }
60080
60081             if (best !== -1) {
60082                 idx = best;
60083                 suggestion = _suggestions[best].value;
60084                 input.property('value', suggestion);
60085                 input.node().setSelectionRange(v.length, suggestion.length);
60086             }
60087         }
60088
60089         function render() {
60090             if (_suggestions.length >= _minItems && document.activeElement === input.node()) {
60091                 show();
60092             } else {
60093                 hide();
60094                 return;
60095             }
60096
60097             var options = wrapper
60098                 .selectAll('a.combobox-option')
60099                 .data(_suggestions, function(d) { return d.value; });
60100
60101             options.exit()
60102                 .remove();
60103
60104             options.enter()
60105                 .append('a')
60106                 .attr('class', 'combobox-option')
60107                 .text(function(d) { return d.value; })
60108                 .merge(options)
60109                 .attr('title', function(d) { return d.title; })
60110                 .classed('selected', function(d, i) { return i === idx; })
60111                 .on('mouseover', select$$1)
60112                 .on('click', accept)
60113                 .order();
60114
60115
60116             var node = attachTo ? attachTo.node() : input.node();
60117             var rect = node.getBoundingClientRect();
60118
60119             wrapper
60120                 .style('left', rect.left + 'px')
60121                 .style('width', rect.width + 'px')
60122                 .style('top', rect.height + rect.top + 'px');
60123         }
60124
60125         function select$$1(d, i) {
60126             idx = i;
60127             render();
60128         }
60129
60130         function ensureVisible() {
60131             var node = wrapper.selectAll('a.selected').node();
60132             if (node) node.scrollIntoView();
60133         }
60134
60135         function accept(d) {
60136             if (!shown) return;
60137             input.property('value', d.value);
60138             utilTriggerEvent(input, 'change');
60139             dispatch$$1.call('accept', this, d);
60140             hide();
60141         }
60142     };
60143
60144     combobox.fetcher = function(_) {
60145         if (!arguments.length) return _fetcher;
60146         _fetcher = _;
60147         return combobox;
60148     };
60149
60150     combobox.data = function(_) {
60151         if (!arguments.length) return _data;
60152         _data = _;
60153         return combobox;
60154     };
60155
60156     combobox.minItems = function(_) {
60157         if (!arguments.length) return _minItems;
60158         _minItems = _;
60159         return combobox;
60160     };
60161
60162     combobox.caseSensitive = function(_) {
60163         if (!arguments.length) return _caseSensitive;
60164         _caseSensitive = _;
60165         return combobox;
60166     };
60167
60168     combobox.container = function(_) {
60169         if (!arguments.length) return _container;
60170         _container = _;
60171         return combobox;
60172     };
60173
60174     return utilRebind(combobox, dispatch$$1, 'on');
60175 }
60176
60177
60178 d3combobox.off = function(input) {
60179     input
60180         .on('focus.typeahead', null)
60181         .on('blur.typeahead', null)
60182         .on('keydown.typeahead', null)
60183         .on('keyup.typeahead', null)
60184         .on('input.typeahead', null)
60185         .each(function() {
60186             d3_select(this.parentNode).selectAll('.combobox-caret')
60187                 .filter(function(d) { return d === input.node(); })
60188                 .on('mousedown', null);
60189         });
60190
60191     d3_select('body')
60192         .on('scroll.combobox', null);
60193 };
60194
60195 function uiRawMemberEditor(context) {
60196     var taginfo = services.taginfo,
60197         _entityID;
60198
60199
60200     function selectMember(d) {
60201         event.preventDefault();
60202         context.enter(modeSelect(context, [d.id]));
60203     }
60204
60205
60206     function changeRole(d) {
60207         var role = d3_select(this).property('value');
60208         var member = { id: d.id, type: d.type, role: role };
60209         context.perform(
60210             actionChangeMember(d.relation.id, member, d.index),
60211             t('operations.change_role.annotation')
60212         );
60213     }
60214
60215
60216     function deleteMember(d) {
60217         context.perform(
60218             actionDeleteMember(d.relation.id, d.index),
60219             t('operations.delete_member.annotation')
60220         );
60221
60222         if (!context.hasEntity(d.relation.id)) {
60223             context.enter(modeBrowse(context));
60224         }
60225     }
60226
60227
60228     function rawMemberEditor(selection) {
60229         var entity = context.entity(_entityID),
60230             memberships = [];
60231
60232         entity.members.slice(0, 1000).forEach(function(member, index) {
60233             memberships.push({
60234                 index: index,
60235                 id: member.id,
60236                 type: member.type,
60237                 role: member.role,
60238                 relation: entity,
60239                 member: context.hasEntity(member.id)
60240             });
60241         });
60242
60243         var gt = entity.members.length > 1000 ? '>' : '';
60244         selection.call(uiDisclosure(context, 'raw_member_editor', true)
60245             .title(t('inspector.all_members') + ' (' + gt + memberships.length + ')')
60246             .expanded(true)
60247             .updatePreference(false)
60248             .on('toggled', function(expanded) {
60249                 if (expanded) { selection.node().parentNode.scrollTop += 200; }
60250             })
60251             .content(content)
60252         );
60253
60254
60255         function content(wrap) {
60256             var list = wrap.selectAll('.member-list')
60257                 .data([0]);
60258
60259             list = list.enter()
60260                 .append('ul')
60261                 .attr('class', 'member-list')
60262                 .merge(list);
60263
60264
60265             var items = list.selectAll('li')
60266                 .data(memberships, function(d) {
60267                     return osmEntity.key(d.relation) + ',' + d.index + ',' +
60268                         (d.member ? osmEntity.key(d.member) : 'incomplete');
60269                 });
60270
60271             items.exit()
60272                 .each(unbind)
60273                 .remove();
60274
60275             var enter = items.enter()
60276                 .append('li')
60277                 .attr('class', 'member-row form-field')
60278                 .classed('member-incomplete', function(d) { return !d.member; });
60279
60280             enter
60281                 .each(function(d) {
60282                     if (d.member) {
60283                         var label = d3_select(this).append('label')
60284                             .attr('class', 'form-label')
60285                             .append('a')
60286                             .attr('href', '#')
60287                             .on('click', selectMember);
60288
60289                         label.append('span')
60290                             .attr('class', 'member-entity-type')
60291                             .text(function(d) {
60292                                 var matched = context.presets().match(d.member, context.graph());
60293                                 return (matched && matched.name()) || utilDisplayType(d.member.id);
60294                             });
60295
60296                         label.append('span')
60297                             .attr('class', 'member-entity-name')
60298                             .text(function(d) { return utilDisplayName(d.member); });
60299
60300                     } else {
60301                         d3_select(this).append('label')
60302                             .attr('class', 'form-label')
60303                             .text(t('inspector.incomplete', { id: d.id }));
60304                     }
60305                 });
60306
60307             enter
60308                 .append('input')
60309                 .attr('class', 'member-role')
60310                 .property('type', 'text')
60311                 .attr('maxlength', 255)
60312                 .attr('placeholder', t('inspector.role'))
60313                 .call(utilNoAuto)
60314                 .property('value', function(d) { return d.role; })
60315                 .on('change', changeRole);
60316
60317             enter
60318                 .append('button')
60319                 .attr('tabindex', -1)
60320                 .attr('class', 'remove button-input-action member-delete minor')
60321                 .on('click', deleteMember)
60322                 .call(svgIcon('#operation-delete'));
60323
60324             if (taginfo) {
60325                 enter.each(bindTypeahead);
60326             }
60327
60328
60329             function bindTypeahead(d) {
60330                 var row = d3_select(this),
60331                     role = row.selectAll('input.member-role');
60332
60333                 function sort(value, data) {
60334                     var sameletter = [],
60335                         other = [];
60336                     for (var i = 0; i < data.length; i++) {
60337                         if (data[i].value.substring(0, value.length) === value) {
60338                             sameletter.push(data[i]);
60339                         } else {
60340                             other.push(data[i]);
60341                         }
60342                     }
60343                     return sameletter.concat(other);
60344                 }
60345
60346                 role.call(d3combobox()
60347                     .container(context.container())
60348                     .fetcher(function(role, callback) {
60349                         var rtype = entity.tags.type;
60350                         taginfo.roles({
60351                             debounce: true,
60352                             rtype: rtype || '',
60353                             geometry: context.geometry(d.member.id),
60354                             query: role
60355                         }, function(err, data) {
60356                             if (!err) callback(sort(role, data));
60357                         });
60358                     }));
60359             }
60360
60361
60362             function unbind() {
60363                 var row = d3_select(this);
60364
60365                 row.selectAll('input.member-role')
60366                     .call(d3combobox.off);
60367             }
60368         }
60369     }
60370
60371
60372     rawMemberEditor.entityID = function(_) {
60373         if (!arguments.length) return _entityID;
60374         _entityID = _;
60375         return rawMemberEditor;
60376     };
60377
60378
60379     return rawMemberEditor;
60380 }
60381
60382 function uiRawMembershipEditor(context) {
60383     var taginfo = services.taginfo,
60384         _entityID,
60385         _showBlank;
60386
60387
60388     function selectRelation(d) {
60389         event.preventDefault();
60390         context.enter(modeSelect(context, [d.relation.id]));
60391     }
60392
60393
60394     function changeRole(d) {
60395         var role = d3_select(this).property('value');
60396         context.perform(
60397             actionChangeMember(d.relation.id, assignIn({}, d.member, { role: role }), d.index),
60398             t('operations.change_role.annotation')
60399         );
60400     }
60401
60402
60403     function addMembership(d, role) {
60404         _showBlank = false;
60405
60406         var member = { id: _entityID, type: context.entity(_entityID).type, role: role };
60407
60408         if (d.relation) {
60409             context.perform(
60410                 actionAddMember(d.relation.id, member),
60411                 t('operations.add_member.annotation')
60412             );
60413
60414         } else {
60415             var relation = osmRelation();
60416             context.perform(
60417                 actionAddEntity(relation),
60418                 actionAddMember(relation.id, member),
60419                 t('operations.add.annotation.relation')
60420             );
60421
60422             context.enter(modeSelect(context, [relation.id]));
60423         }
60424     }
60425
60426
60427     function deleteMembership(d) {
60428         context.perform(
60429             actionDeleteMember(d.relation.id, d.index),
60430             t('operations.delete_member.annotation')
60431         );
60432     }
60433
60434
60435     function relations(q) {
60436         var newRelation = { relation: null, value: t('inspector.new_relation') };
60437         var result = [];
60438         var graph = context.graph();
60439
60440         context.intersects(context.extent()).forEach(function(entity) {
60441             if (entity.type !== 'relation' || entity.id === _entityID)
60442                 return;
60443
60444             var matched = context.presets().match(entity, graph),
60445                 presetName = (matched && matched.name()) || t('inspector.relation'),
60446                 entityName = utilDisplayName(entity) || '';
60447
60448             var value = presetName + ' ' + entityName;
60449             if (q && value.toLowerCase().indexOf(q.toLowerCase()) === -1)
60450                 return;
60451
60452             result.push({ relation: entity, value: value });
60453         });
60454
60455         result.sort(function(a, b) {
60456             return osmRelation.creationOrder(a.relation, b.relation);
60457         });
60458
60459         // Dedupe identical names by appending relation id - see #2891
60460         var dupeGroups = filter(
60461             groupBy(result, 'value'),
60462             function(v) { return v.length > 1; }
60463         );
60464
60465         dupeGroups.forEach(function(group) {
60466             group.forEach(function(obj) {
60467                 obj.value += ' ' + obj.relation.id;
60468             });
60469         });
60470
60471         forEach(result, function(obj) {
60472             obj.title = obj.value;
60473         });
60474
60475         result.unshift(newRelation);
60476         return result;
60477     }
60478
60479
60480     function rawMembershipEditor(selection) {
60481         var entity = context.entity(_entityID),
60482             parents = context.graph().parentRelations(entity),
60483             memberships = [];
60484
60485         parents.slice(0, 1000).forEach(function(relation) {
60486             relation.members.forEach(function(member, index) {
60487                 if (member.id === entity.id) {
60488                     memberships.push({ relation: relation, member: member, index: index });
60489                 }
60490             });
60491         });
60492
60493         var gt = parents.length > 1000 ? '>' : '';
60494         selection.call(uiDisclosure(context, 'raw_membership_editor', true)
60495             .title(t('inspector.all_relations') + ' (' + gt + memberships.length + ')')
60496             .expanded(true)
60497             .updatePreference(false)
60498             .on('toggled', function(expanded) {
60499                 if (expanded) { selection.node().parentNode.scrollTop += 200; }
60500             })
60501             .content(content)
60502         );
60503
60504
60505         function content(wrap) {
60506             var list = wrap.selectAll('.member-list')
60507                 .data([0]);
60508
60509             list = list.enter()
60510                 .append('ul')
60511                 .attr('class', 'member-list')
60512                 .merge(list);
60513
60514
60515             var items = list.selectAll('li.member-row-normal')
60516                 .data(memberships, function(d) {
60517                     return osmEntity.key(d.relation) + ',' + d.index;
60518                 });
60519
60520             items.exit()
60521                 .each(unbind)
60522                 .remove();
60523
60524             var enter = items.enter()
60525                 .append('li')
60526                 .attr('class', 'member-row member-row-normal form-field');
60527
60528             var label = enter
60529                 .append('label')
60530                 .attr('class', 'form-label')
60531                 .append('a')
60532                 .attr('href', '#')
60533                 .on('click', selectRelation);
60534
60535             label
60536                 .append('span')
60537                 .attr('class', 'member-entity-type')
60538                 .text(function(d) {
60539                     var matched = context.presets().match(d.relation, context.graph());
60540                     return (matched && matched.name()) || t('inspector.relation');
60541                 });
60542
60543             label
60544                 .append('span')
60545                 .attr('class', 'member-entity-name')
60546                 .text(function(d) { return utilDisplayName(d.relation); });
60547
60548             enter
60549                 .append('input')
60550                 .attr('class', 'member-role')
60551                 .property('type', 'text')
60552                 .attr('maxlength', 255)
60553                 .attr('placeholder', t('inspector.role'))
60554                 .call(utilNoAuto)
60555                 .property('value', function(d) { return d.member.role; })
60556                 .on('change', changeRole);
60557
60558             enter
60559                 .append('button')
60560                 .attr('tabindex', -1)
60561                 .attr('class', 'remove button-input-action member-delete minor')
60562                 .on('click', deleteMembership)
60563                 .call(svgIcon('#operation-delete'));
60564
60565             if (taginfo) {
60566                 enter.each(bindTypeahead);
60567             }
60568
60569
60570             var newrow = list.selectAll('.member-row-new')
60571                 .data(_showBlank ? [0] : []);
60572
60573             newrow.exit()
60574                 .remove();
60575
60576             enter = newrow.enter()
60577                 .append('li')
60578                 .attr('class', 'member-row member-row-new form-field');
60579
60580             enter
60581                 .append('input')
60582                 .attr('type', 'text')
60583                 .attr('class', 'member-entity-input')
60584                 .call(utilNoAuto);
60585
60586             enter
60587                 .append('input')
60588                 .attr('class', 'member-role')
60589                 .property('type', 'text')
60590                 .attr('maxlength', 255)
60591                 .attr('placeholder', t('inspector.role'))
60592                 .call(utilNoAuto)
60593                 .on('change', changeRole);
60594
60595             enter
60596                 .append('button')
60597                 .attr('tabindex', -1)
60598                 .attr('class', 'remove button-input-action member-delete minor')
60599                 .on('click', deleteMembership)
60600                 .call(svgIcon('#operation-delete'));
60601
60602             newrow = newrow
60603                 .merge(enter);
60604
60605             newrow.selectAll('.member-entity-input')
60606                 .call(d3combobox()
60607                     .container(context.container())
60608                     .minItems(1)
60609                     .fetcher(function(value, callback) { callback(relations(value)); })
60610                     .on('accept', onAccept)
60611                 );
60612
60613
60614             var addrel = wrap.selectAll('.add-relation')
60615                 .data([0]);
60616
60617             addrel = addrel.enter()
60618                 .append('button')
60619                 .attr('class', 'add-relation')
60620                 .merge(addrel);
60621
60622             addrel
60623                 .call(svgIcon('#icon-plus', 'light'))
60624                 .on('click', function() {
60625                     _showBlank = true;
60626                     content(wrap);
60627                     list.selectAll('.member-entity-input').node().focus();
60628                 });
60629
60630
60631             function onAccept(d) {
60632                 var role = list.selectAll('.member-row-new .member-role').property('value');
60633                 addMembership(d, role);
60634             }
60635
60636
60637             function bindTypeahead(d) {
60638                 var row = d3_select(this),
60639                     role = row.selectAll('input.member-role');
60640
60641                 function sort(value, data) {
60642                     var sameletter = [],
60643                         other = [];
60644                     for (var i = 0; i < data.length; i++) {
60645                         if (data[i].value.substring(0, value.length) === value) {
60646                             sameletter.push(data[i]);
60647                         } else {
60648                             other.push(data[i]);
60649                         }
60650                     }
60651                     return sameletter.concat(other);
60652                 }
60653
60654                 role.call(d3combobox()
60655                     .container(context.container())
60656                     .fetcher(function(role, callback) {
60657                         var rtype = d.relation.tags.type;
60658                         taginfo.roles({
60659                             debounce: true,
60660                             rtype: rtype || '',
60661                             geometry: context.geometry(_entityID),
60662                             query: role
60663                         }, function(err, data) {
60664                             if (!err) callback(sort(role, data));
60665                         });
60666                     }));
60667             }
60668
60669
60670             function unbind() {
60671                 var row = d3_select(this);
60672
60673                 row.selectAll('input.member-role')
60674                     .call(d3combobox.off);
60675             }
60676         }
60677     }
60678
60679
60680     rawMembershipEditor.entityID = function(_) {
60681         if (!arguments.length) return _entityID;
60682         _entityID = _;
60683         return rawMembershipEditor;
60684     };
60685
60686
60687     return rawMembershipEditor;
60688 }
60689
60690 function uiTagReference(tag) {
60691     var taginfo = services.taginfo,
60692         tagReference = {},
60693         button = d3_select(null),
60694         body = d3_select(null),
60695         loaded,
60696         showing;
60697
60698
60699     function findLocal(data) {
60700         var locale = utilDetect().locale.toLowerCase(),
60701             localized;
60702
60703         if (locale !== 'pt-br') {  // see #3776, prefer 'pt' over 'pt-br'
60704             localized = find$1(data, function(d) {
60705                 return d.lang.toLowerCase() === locale;
60706             });
60707             if (localized) return localized;
60708         }
60709
60710         // try the non-regional version of a language, like
60711         // 'en' if the language is 'en-US'
60712         if (locale.indexOf('-') !== -1) {
60713             var first = locale.split('-')[0];
60714             localized = find$1(data, function(d) {
60715                 return d.lang.toLowerCase() === first;
60716             });
60717             if (localized) return localized;
60718         }
60719
60720         // finally fall back to english
60721         return find$1(data, function(d) {
60722             return d.lang.toLowerCase() === 'en';
60723         });
60724     }
60725
60726
60727     function load(param) {
60728         if (!taginfo) return;
60729
60730         button
60731             .classed('tag-reference-loading', true);
60732
60733         taginfo.docs(param, function show(err, data) {
60734             var docs;
60735             if (!err && data) {
60736                 docs = findLocal(data);
60737             }
60738
60739             body.html('');
60740
60741             if (!docs || !docs.title) {
60742                 if (param.hasOwnProperty('value')) {
60743                     load(omit(param, 'value'));   // retry with key only
60744                 } else {
60745                     body
60746                         .append('p')
60747                         .attr('class', 'tag-reference-description')
60748                         .text(t('inspector.no_documentation_key'));
60749                     done();
60750                 }
60751                 return;
60752             }
60753
60754             if (docs.image && docs.image.thumb_url_prefix) {
60755                 body
60756                     .append('img')
60757                     .attr('class', 'tag-reference-wiki-image')
60758                     .attr('src', docs.image.thumb_url_prefix + '100' + docs.image.thumb_url_suffix)
60759                     .on('load', function() { done(); })
60760                     .on('error', function() { d3_select(this).remove(); done(); });
60761             } else {
60762                 done();
60763             }
60764
60765             body
60766                 .append('p')
60767                 .attr('class', 'tag-reference-description')
60768                 .text(docs.description || t('inspector.documentation_redirect'));
60769
60770             body
60771                 .append('a')
60772                 .attr('class', 'tag-reference-link')
60773                 .attr('target', '_blank')
60774                 .attr('tabindex', -1)
60775                 .attr('href', 'https://wiki.openstreetmap.org/wiki/' + docs.title)
60776                 .call(svgIcon('#icon-out-link', 'inline'))
60777                 .append('span')
60778                 .text(t('inspector.reference'));
60779
60780             // Add link to info about "good changeset comments" - #2923
60781             if (param.key === 'comment') {
60782                 body
60783                     .append('a')
60784                     .attr('class', 'tag-reference-comment-link')
60785                     .attr('target', '_blank')
60786                     .attr('tabindex', -1)
60787                     .call(svgIcon('#icon-out-link', 'inline'))
60788                     .attr('href', t('commit.about_changeset_comments_link'))
60789                     .append('span')
60790                     .text(t('commit.about_changeset_comments'));
60791             }
60792         });
60793     }
60794
60795
60796     function done() {
60797         loaded = true;
60798
60799         button
60800             .classed('tag-reference-loading', false);
60801
60802         body
60803             .classed('expanded', true)
60804             .transition()
60805             .duration(200)
60806             .style('max-height', '200px')
60807             .style('opacity', '1');
60808
60809         showing = true;
60810     }
60811
60812
60813     function hide() {
60814         body
60815             .transition()
60816             .duration(200)
60817             .style('max-height', '0px')
60818             .style('opacity', '0')
60819             .on('end', function () {
60820                 body.classed('expanded', false);
60821             });
60822
60823         showing = false;
60824     }
60825
60826
60827     tagReference.button = function(selection) {
60828         button = selection.selectAll('.tag-reference-button')
60829             .data([0]);
60830
60831         button = button.enter()
60832             .append('button')
60833             .attr('class', 'tag-reference-button')
60834             .attr('tabindex', -1)
60835             .call(svgIcon('#icon-inspect'))
60836             .merge(button);
60837
60838         button
60839             .on('click', function () {
60840                 event.stopPropagation();
60841                 event.preventDefault();
60842                 if (showing) {
60843                     hide();
60844                 } else if (loaded) {
60845                     done();
60846                 } else {
60847                     load(tag);
60848                 }
60849             });
60850     };
60851
60852
60853     tagReference.body = function(selection) {
60854
60855         var tagid = tag.rtype || (tag.key + '-' + tag.value);
60856
60857         body = selection.selectAll('.tag-reference-body')
60858             .data([tagid], function(d) { return d; });
60859
60860         body.exit()
60861             .remove();
60862
60863         body = body.enter()
60864             .append('div')
60865             .attr('class', 'tag-reference-body cf')
60866             .style('max-height', '0')
60867             .style('opacity', '0')
60868             .merge(body);
60869
60870         if (showing === false) {
60871             hide();
60872         }
60873     };
60874
60875
60876     tagReference.showing = function(_) {
60877         if (!arguments.length) return showing;
60878         showing = _;
60879         return tagReference;
60880     };
60881
60882
60883     return tagReference;
60884 }
60885
60886 function uiRawTagEditor(context) {
60887     var taginfo = services.taginfo,
60888         dispatch$$1 = dispatch('change'),
60889         _readOnlyTags = [],
60890         _showBlank = false,
60891         _updatePreference = true,
60892         _expanded = false,
60893         _newRow,
60894         _state,
60895         _preset,
60896         _tags,
60897         _entityID;
60898
60899
60900     function rawTagEditor(selection) {
60901         var count = Object.keys(_tags).filter(function(d) { return d; }).length;
60902
60903         var disclosure = uiDisclosure(context, 'raw_tag_editor', false)
60904             .title(t('inspector.all_tags') + ' (' + count + ')')
60905             .on('toggled', toggled)
60906             .updatePreference(_updatePreference)
60907             .content(content);
60908
60909         // Sometimes we want to force the raw_tag_editor to be opened/closed..
60910         // When undefined, uiDisclosure will use the user's stored preference.
60911         if (_expanded !== undefined) {
60912             disclosure.expanded(_expanded);
60913         }
60914
60915         selection.call(disclosure);
60916
60917         function toggled(expanded) {
60918             _expanded = expanded;
60919             if (expanded) {
60920                 selection.node().parentNode.scrollTop += 200;
60921             }
60922         }
60923     }
60924
60925
60926     function content(wrap) {
60927         var entries = map$4(_tags, function(v, k) {
60928             return { key: k, value: v };
60929         });
60930
60931         if (!entries.length || _showBlank) {
60932             _showBlank = false;
60933             entries.push({key: '', value: ''});
60934             _newRow = '';
60935         }
60936
60937         var list = wrap.selectAll('.tag-list')
60938             .data([0]);
60939
60940         list = list.enter()
60941             .append('ul')
60942             .attr('class', 'tag-list')
60943             .merge(list);
60944
60945         var newTag = wrap.selectAll('.add-tag')
60946             .data([0]);
60947
60948         newTag.enter()
60949             .append('button')
60950             .attr('class', 'add-tag')
60951             .on('click', addTag)
60952             .call(svgIcon('#icon-plus', 'light'));
60953
60954
60955         var items = list.selectAll('.tag-row')
60956             .data(entries, function(d) { return d.key; });
60957
60958         items.exit()
60959             .each(unbind)
60960             .remove();
60961
60962         // Enter
60963
60964         var enter = items.enter()
60965             .append('li')
60966             .attr('class', 'tag-row cf')
60967             .classed('readonly', isReadOnly);
60968
60969         enter
60970             .append('div')
60971             .attr('class', 'key-wrap')
60972             .append('input')
60973             .property('type', 'text')
60974             .attr('class', 'key')
60975             .attr('maxlength', 255)
60976             .call(utilNoAuto)
60977             .on('blur', keyChange)
60978             .on('change', keyChange);
60979
60980         enter
60981             .append('div')
60982             .attr('class', 'input-wrap-position')
60983             .append('input')
60984             .property('type', 'text')
60985             .attr('class', 'value')
60986             .attr('maxlength', 255)
60987             .call(utilNoAuto)
60988             .on('blur', valueChange)
60989             .on('change', valueChange)
60990             .on('keydown.push-more', pushMore);
60991
60992         enter
60993             .append('button')
60994             .attr('tabindex', -1)
60995             .attr('class', 'remove minor')
60996             .call(svgIcon('#operation-delete'));
60997
60998
60999         // Update
61000
61001         items = items
61002             .merge(enter)
61003             .sort(function(a, b) {
61004                 return (a.key === _newRow && b.key !== _newRow) ? 1
61005                     : (a.key !== _newRow && b.key === _newRow) ? -1
61006                     : d3_ascending(a.key, b.key);
61007             });
61008
61009         items
61010             .each(function(tag) {
61011                 var row = d3_select(this),
61012                     key = row.select('input.key'),      // propagate bound data to child
61013                     value = row.select('input.value');  // propagate bound data to child
61014
61015                 if (_entityID && taginfo) {
61016                     bindTypeahead(key, value);
61017                 }
61018
61019                 var isRelation = (_entityID && context.entity(_entityID).type === 'relation'),
61020                     reference;
61021
61022                 if (isRelation && tag.key === 'type') {
61023                     reference = uiTagReference({ rtype: tag.value }, context);
61024                 } else {
61025                     reference = uiTagReference({ key: tag.key, value: tag.value }, context);
61026                 }
61027
61028                 if (_state === 'hover') {
61029                     reference.showing(false);
61030                 }
61031
61032                 row
61033                     .call(reference.button)
61034                     .call(reference.body);
61035             });
61036
61037         items.selectAll('input.key')
61038             .attr('title', function(d) { return d.key; })
61039             .call(utilGetSetValue, function(d) { return d.key; })
61040             .property('disabled', isReadOnly);
61041
61042         items.selectAll('input.value')
61043             .attr('title', function(d) { return d.value; })
61044             .call(utilGetSetValue, function(d) { return d.value; })
61045             .property('disabled', isReadOnly);
61046
61047         items.selectAll('button.remove')
61048             .on('click', removeTag);
61049
61050
61051
61052         function isReadOnly(d) {
61053             for (var i = 0; i < _readOnlyTags.length; i++) {
61054                 if (d.key.match(_readOnlyTags[i]) !== null) {
61055                     return true;
61056                 }
61057             }
61058             return false;
61059         }
61060
61061
61062         function pushMore() {
61063             if (event.keyCode === 9 && !event.shiftKey &&
61064                 list.selectAll('li:last-child input.value').node() === this) {
61065                 addTag();
61066             }
61067         }
61068
61069
61070         function bindTypeahead(key, value) {
61071             if (isReadOnly({ key: key })) return;
61072             var geometry = context.geometry(_entityID);
61073
61074             key.call(d3combobox()
61075                 .container(context.container())
61076                 .fetcher(function(value, callback) {
61077                     taginfo.keys({
61078                         debounce: true,
61079                         geometry: geometry,
61080                         query: value
61081                     }, function(err, data) {
61082                         if (!err) callback(sort(value, data));
61083                     });
61084                 }));
61085
61086             value.call(d3combobox()
61087                 .container(context.container())
61088                 .fetcher(function(value, callback) {
61089                     taginfo.values({
61090                         debounce: true,
61091                         key: utilGetSetValue(key),
61092                         geometry: geometry,
61093                         query: value
61094                     }, function(err, data) {
61095                         if (!err) callback(sort(value, data));
61096                     });
61097                 }));
61098
61099
61100             function sort(value, data) {
61101                 var sameletter = [],
61102                     other = [];
61103                 for (var i = 0; i < data.length; i++) {
61104                     if (data[i].value.substring(0, value.length) === value) {
61105                         sameletter.push(data[i]);
61106                     } else {
61107                         other.push(data[i]);
61108                     }
61109                 }
61110                 return sameletter.concat(other);
61111             }
61112         }
61113
61114
61115         function unbind() {
61116             var row = d3_select(this);
61117
61118             row.selectAll('input.key')
61119                 .call(d3combobox.off);
61120
61121             row.selectAll('input.value')
61122                 .call(d3combobox.off);
61123         }
61124
61125
61126         function keyChange(d) {
61127             var kOld = d.key,
61128                 kNew = this.value.trim(),
61129                 tag = {};
61130
61131
61132             if (isReadOnly({ key: kNew })) {
61133                 this.value = kOld;
61134                 return;
61135             }
61136
61137             if (kNew && kNew !== kOld) {
61138                 var match = kNew.match(/^(.*?)(?:_(\d+))?$/),
61139                     base = match[1],
61140                     suffix = +(match[2] || 1);
61141                 while (_tags[kNew]) {  // rename key if already in use
61142                     kNew = base + '_' + suffix++;
61143                 }
61144             }
61145             tag[kOld] = undefined;
61146             tag[kNew] = d.value;
61147
61148             d.key = kNew; // Maintain DOM identity through the subsequent update.
61149
61150             if (_newRow === kOld) {  // see if this row is still a new row
61151                 _newRow = ((d.value === '' || kNew === '') ? kNew : undefined);
61152             }
61153
61154             this.value = kNew;
61155             dispatch$$1.call('change', this, tag);
61156         }
61157
61158
61159         function valueChange(d) {
61160             if (isReadOnly(d)) return;
61161             var tag = {};
61162             tag[d.key] = this.value;
61163
61164             if (_newRow === d.key && d.key !== '' && d.value !== '') {   // not a new row anymore
61165                 _newRow = undefined;
61166             }
61167
61168             dispatch$$1.call('change', this, tag);
61169         }
61170
61171
61172         function removeTag(d) {
61173             if (isReadOnly(d)) return;
61174             var tag = {};
61175             tag[d.key] = undefined;
61176             dispatch$$1.call('change', this, tag);
61177             d3_select(this.parentNode).remove();
61178         }
61179
61180
61181         function addTag() {
61182             // Wrapped in a setTimeout in case it's being called from a blur
61183             // handler. Without the setTimeout, the call to `content` would
61184             // wipe out the pending value change.
61185             setTimeout(function() {
61186                 _showBlank = true;
61187                 content(wrap);
61188                 list.selectAll('li:last-child input.key').node().focus();
61189             }, 0);
61190         }
61191     }
61192
61193
61194     rawTagEditor.state = function(_) {
61195         if (!arguments.length) return _state;
61196         _state = _;
61197         return rawTagEditor;
61198     };
61199
61200
61201     rawTagEditor.preset = function(_) {
61202         if (!arguments.length) return _preset;
61203         _preset = _;
61204         if (_preset.isFallback()) {
61205             _expanded = true;
61206             _updatePreference = false;
61207         } else {
61208             _expanded = undefined;
61209             _updatePreference = true;
61210         }
61211         return rawTagEditor;
61212     };
61213
61214
61215     rawTagEditor.tags = function(_) {
61216         if (!arguments.length) return _tags;
61217         _tags = _;
61218         return rawTagEditor;
61219     };
61220
61221
61222     rawTagEditor.entityID = function(_) {
61223         if (!arguments.length) return _entityID;
61224         _entityID = _;
61225         return rawTagEditor;
61226     };
61227
61228
61229     rawTagEditor.expanded = function(_) {
61230         if (!arguments.length) return _expanded;
61231         _expanded = _;
61232         _updatePreference = false;
61233         return rawTagEditor;
61234     };
61235
61236
61237     rawTagEditor.readOnlyTags = function(_) {
61238         if (!arguments.length) return _readOnlyTags;
61239         _readOnlyTags = _;
61240         return rawTagEditor;
61241     };
61242
61243
61244     return utilRebind(rawTagEditor, dispatch$$1, 'on');
61245 }
61246
61247 function uiFieldCheck(field, context) {
61248     var dispatch$$1 = dispatch('change');
61249     var options = field.strings && field.strings.options;
61250     var values = [];
61251     var texts = [];
61252
61253     var input = d3_select(null);
61254     var text = d3_select(null);
61255     var label = d3_select(null);
61256     var reverser = d3_select(null);
61257
61258     var _impliedYes;
61259     var _entityID;
61260     var _value;
61261
61262
61263     if (options) {
61264         for (var k in options) {
61265             values.push(k === 'undefined' ? undefined : k);
61266             texts.push(field.t('options.' + k, { 'default': options[k] }));
61267         }
61268     } else {
61269         values = [undefined, 'yes'];
61270         texts = [t('inspector.unknown'), t('inspector.check.yes')];
61271         if (field.type !== 'defaultCheck') {
61272             values.push('no');
61273             texts.push(t('inspector.check.no'));
61274         }
61275     }
61276
61277
61278     // Checks tags to see whether an undefined value is "Assumed to be Yes"
61279     function checkImpliedYes() {
61280         _impliedYes = (field.id === 'oneway_yes');
61281
61282         // hack: pretend `oneway` field is a `oneway_yes` field
61283         // where implied oneway tag exists (e.g. `junction=roundabout`) #2220, #1841
61284         if (field.id === 'oneway') {
61285             var entity = context.entity(_entityID);
61286             for (var key in entity.tags) {
61287                 if (key in osmOneWayTags && (entity.tags[key] in osmOneWayTags[key])) {
61288                     _impliedYes = true;
61289                     texts[0] = t('presets.fields.oneway_yes.options.undefined');
61290                     break;
61291                 }
61292             }
61293         }
61294     }
61295
61296
61297     function reverserHidden() {
61298         if (!d3_select('div.inspector-hover').empty()) return true;
61299         return !(_value === 'yes' || (_impliedYes && !_value));
61300     }
61301
61302
61303     function reverserSetText(selection) {
61304         var entity = context.hasEntity(_entityID);
61305         if (reverserHidden() || !entity) return selection;
61306
61307         var first = entity.first();
61308         var last = entity.isClosed() ? entity.nodes[entity.nodes.length - 2] : entity.last();
61309         var pseudoDirection = first < last;
61310         var icon = pseudoDirection ? '#icon-forward' : '#icon-backward';
61311
61312         selection.selectAll('.reverser-span')
61313             .text(t('inspector.check.reverser'))
61314             .call(svgIcon(icon, 'inline'));
61315
61316         return selection;
61317     }
61318
61319
61320     var check = function(selection) {
61321         checkImpliedYes();
61322         selection.classed('checkselect', 'true');
61323
61324         label = selection.selectAll('.preset-input-wrap')
61325             .data([0]);
61326
61327         var enter = label.enter()
61328             .append('label')
61329             .attr('class', 'preset-input-wrap');
61330
61331         enter
61332             .append('input')
61333             .property('indeterminate', field.type !== 'defaultCheck')
61334             .attr('type', 'checkbox')
61335             .attr('id', 'preset-input-' + field.id);
61336
61337         enter
61338             .append('span')
61339             .text(texts[0])
61340             .attr('class', 'value');
61341
61342         if (field.type === 'onewayCheck') {
61343             enter
61344                 .append('a')
61345                 .attr('id', 'preset-input-' + field.id + '-reverser')
61346                 .attr('class', 'reverser button' + (reverserHidden() ? ' hide' : ''))
61347                 .attr('href', '#')
61348                 .append('span')
61349                 .attr('class', 'reverser-span');
61350         }
61351
61352         label = label.merge(enter);
61353         input = label.selectAll('input');
61354         text = label.selectAll('span.value');
61355
61356         input
61357             .on('click', function() {
61358                 var t$$1 = {};
61359                 t$$1[field.key] = values[(values.indexOf(_value) + 1) % values.length];
61360                 dispatch$$1.call('change', this, t$$1);
61361                 event.stopPropagation();
61362             });
61363
61364         if (field.type === 'onewayCheck') {
61365             reverser = label.selectAll('.reverser');
61366
61367             reverser
61368                 .call(reverserSetText)
61369                 .on('click', function() {
61370                     event.preventDefault();
61371                     event.stopPropagation();
61372                     context.perform(
61373                         actionReverse(_entityID),
61374                         t('operations.reverse.annotation')
61375                     );
61376                     d3_select(this)
61377                         .call(reverserSetText);
61378                 });
61379         }
61380     };
61381
61382
61383     check.entity = function(_) {
61384         if (!arguments.length) return context.hasEntity(_entityID);
61385         _entityID = _.id;
61386         return check;
61387     };
61388
61389
61390     check.tags = function(tags) {
61391
61392         function isChecked(val) {
61393             return val !== 'no' && val !== '' && val !== undefined && val !== null;
61394         }
61395
61396         function textFor(val) {
61397             if (val === '') val = undefined;
61398             var index = values.indexOf(val);
61399             return (index !== -1 ? texts[index] : ('"' + val + '"'));
61400         }
61401
61402         checkImpliedYes();
61403         _value = tags[field.key] && tags[field.key].toLowerCase();
61404
61405         if (field.type === 'onewayCheck' && (_value === '1' || _value === '-1')) {
61406             _value = 'yes';
61407         }
61408
61409         input
61410             .property('indeterminate', field.type !== 'defaultCheck' && !_value)
61411             .property('checked', isChecked(_value));
61412
61413         text
61414             .text(textFor(_value));
61415
61416         label
61417             .classed('set', !!_value);
61418
61419         if (field.type === 'onewayCheck') {
61420             reverser
61421                 .classed('hide', reverserHidden())
61422                 .call(reverserSetText);
61423         }
61424     };
61425
61426
61427     check.focus = function() {
61428         input.node().focus();
61429     };
61430
61431     return utilRebind(check, dispatch$$1, 'on');
61432 }
61433
61434 /** Used for built-in method references. */
61435 var arrayProto$1 = Array.prototype;
61436
61437 /** Built-in value references. */
61438 var splice$1 = arrayProto$1.splice;
61439
61440 /**
61441  * The base implementation of `_.pullAt` without support for individual
61442  * indexes or capturing the removed elements.
61443  *
61444  * @private
61445  * @param {Array} array The array to modify.
61446  * @param {number[]} indexes The indexes of elements to remove.
61447  * @returns {Array} Returns `array`.
61448  */
61449 function basePullAt(array, indexes) {
61450   var length = array ? indexes.length : 0,
61451       lastIndex = length - 1;
61452
61453   while (length--) {
61454     var index = indexes[length];
61455     if (length == lastIndex || index !== previous) {
61456       var previous = index;
61457       if (isIndex(index)) {
61458         splice$1.call(array, index, 1);
61459       } else {
61460         baseUnset(array, index);
61461       }
61462     }
61463   }
61464   return array;
61465 }
61466
61467 /**
61468  * Removes all elements from `array` that `predicate` returns truthy for
61469  * and returns an array of the removed elements. The predicate is invoked
61470  * with three arguments: (value, index, array).
61471  *
61472  * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
61473  * to pull elements from an array by value.
61474  *
61475  * @static
61476  * @memberOf _
61477  * @since 2.0.0
61478  * @category Array
61479  * @param {Array} array The array to modify.
61480  * @param {Function} [predicate=_.identity] The function invoked per iteration.
61481  * @returns {Array} Returns the new array of removed elements.
61482  * @example
61483  *
61484  * var array = [1, 2, 3, 4];
61485  * var evens = _.remove(array, function(n) {
61486  *   return n % 2 == 0;
61487  * });
61488  *
61489  * console.log(array);
61490  * // => [1, 3]
61491  *
61492  * console.log(evens);
61493  * // => [2, 4]
61494  */
61495 function remove$8(array, predicate) {
61496   var result = [];
61497   if (!(array && array.length)) {
61498     return result;
61499   }
61500   var index = -1,
61501       indexes = [],
61502       length = array.length;
61503
61504   predicate = baseIteratee(predicate, 3);
61505   while (++index < length) {
61506     var value = array[index];
61507     if (predicate(value, index, array)) {
61508       result.push(value);
61509       indexes.push(index);
61510     }
61511   }
61512   basePullAt(array, indexes);
61513   return result;
61514 }
61515
61516 function uiFieldCombo(field, context) {
61517     var dispatch$$1 = dispatch('change'),
61518         nominatim = services.geocoder,
61519         taginfo = services.taginfo,
61520         isMulti = (field.type === 'multiCombo'),
61521         isNetwork = (field.type === 'networkCombo'),
61522         isSemi = (field.type === 'semiCombo'),
61523         optstrings = field.strings && field.strings.options,
61524         optarray = field.options,
61525         snake_case = (field.snake_case || (field.snake_case === undefined)),
61526         caseSensitive = field.caseSensitive,
61527         combobox = d3combobox()
61528             .container(context.container())
61529             .caseSensitive(caseSensitive)
61530             .minItems(isMulti || isSemi ? 1 : 2),
61531         comboData = [],
61532         multiData = [],
61533         container,
61534         input,
61535         entity,
61536         country;
61537
61538     // ensure multiCombo field.key ends with a ':'
61539     if (isMulti && field.key.match(/:$/) === null) {
61540         field.key += ':';
61541     }
61542
61543
61544     function snake(s) {
61545         return s.replace(/\s+/g, '_');
61546     }
61547
61548     function unsnake(s) {
61549         return s.replace(/_+/g, ' ');
61550     }
61551
61552     function clean(s) {
61553         return s.split(';')
61554             .map(function(s) { return s.trim(); })
61555             .join(';');
61556     }
61557
61558
61559     // returns the tag value for a display value
61560     // (for multiCombo, dval should be the key suffix, not the entire key)
61561     function tagValue(dval) {
61562         dval = clean(dval || '');
61563
61564         if (optstrings) {
61565             var match = find$1(comboData, function(o) {
61566                 return o.key && clean(o.value) === dval;
61567             });
61568             if (match) {
61569                 return match.key;
61570             }
61571         }
61572
61573         if (field.type === 'typeCombo' && !dval) {
61574             return 'yes';
61575         }
61576
61577         return (snake_case ? snake(dval) : dval) || undefined;
61578     }
61579
61580
61581     // returns the display value for a tag value
61582     // (for multiCombo, tval should be the key suffix, not the entire key)
61583     function displayValue(tval) {
61584         tval = tval || '';
61585
61586         if (optstrings) {
61587             var match = find$1(comboData, function(o) { return o.key === tval && o.value; });
61588             if (match) {
61589                 return match.value;
61590             }
61591         }
61592
61593         if (field.type === 'typeCombo' && tval.toLowerCase() === 'yes') {
61594             return '';
61595         }
61596
61597         return snake_case ? unsnake(tval) : tval;
61598     }
61599
61600
61601     function objectDifference(a, b) {
61602         return reject(a, function(d1) {
61603             return some(b, function(d2) { return d1.value === d2.value; });
61604         });
61605     }
61606
61607
61608     function initCombo(selection, attachTo) {
61609         if (optstrings) {
61610             selection.attr('readonly', 'readonly');
61611             selection.call(combobox, attachTo);
61612             setStaticValues(setPlaceholder);
61613
61614         } else if (optarray) {
61615             selection.call(combobox, attachTo);
61616             setStaticValues(setPlaceholder);
61617
61618         } else if (taginfo) {
61619             selection.call(combobox.fetcher(setTaginfoValues), attachTo);
61620             setTaginfoValues('', setPlaceholder);
61621         }
61622     }
61623
61624
61625     function setStaticValues(callback) {
61626         if (!(optstrings || optarray)) return;
61627
61628         if (optstrings) {
61629             comboData = Object.keys(optstrings).map(function(k) {
61630                 var v = field.t('options.' + k, { 'default': optstrings[k] });
61631                 return {
61632                     key: k,
61633                     value: v,
61634                     title: v
61635                 };
61636             });
61637
61638         } else if (optarray) {
61639             comboData = optarray.map(function(k) {
61640                 var v = snake_case ? unsnake(k) : k;
61641                 return {
61642                     key: k,
61643                     value: v,
61644                     title: v
61645                 };
61646             });
61647         }
61648
61649         combobox.data(objectDifference(comboData, multiData));
61650         if (callback) callback(comboData);
61651     }
61652
61653
61654     function setTaginfoValues(q, callback) {
61655         var fn = isMulti ? 'multikeys' : 'values';
61656         var query = (isMulti ? field.key : '') + q;
61657         var hasCountryPrefix = isNetwork && country && country.indexOf(q.toLowerCase()) === 0;
61658         if (hasCountryPrefix) {
61659             query = country + ':';
61660         }
61661
61662         var params = {
61663             debounce: (q !== ''),
61664             key: field.key,
61665             query: query
61666         };
61667
61668         if (entity) {
61669             params.geometry = context.geometry(entity.id);
61670         }
61671
61672         taginfo[fn](params, function(err, data) {
61673             if (err) return;
61674             if (hasCountryPrefix) {
61675                 data = filter(data, function(d) {
61676                     return d.value.toLowerCase().indexOf(country + ':') === 0;
61677                 });
61678             }
61679
61680             comboData = map$4(data, function(d) {
61681                 var k = d.value;
61682                 if (isMulti) k = k.replace(field.key, '');
61683                 var v = snake_case ? unsnake(k) : k;
61684                 return {
61685                     key: k,
61686                     value: v,
61687                     title: isMulti ? v : d.title
61688                 };
61689             });
61690
61691             comboData = objectDifference(comboData, multiData);
61692             if (callback) callback(comboData);
61693         });
61694     }
61695
61696
61697     function setPlaceholder(d) {
61698         var ph;
61699
61700         if (isMulti || isSemi) {
61701             ph = field.placeholder() || t('inspector.add');
61702         } else {
61703             var vals = map$4(d, 'value').filter(function(s) { return s.length < 20; }),
61704                 placeholders = vals.length > 1 ? vals : map$4(d, 'key');
61705             ph = field.placeholder() || placeholders.slice(0, 3).join(', ');
61706         }
61707
61708         if (ph.match(/(…|\.\.\.)$/) === null) {
61709             ph += '…';
61710         }
61711
61712         container.selectAll('input')
61713             .attr('placeholder', ph);
61714     }
61715
61716
61717     function change() {
61718         var val = tagValue(utilGetSetValue(input)),
61719             t$$1 = {};
61720
61721         if (isMulti || isSemi) {
61722             if (!val) return;
61723             container.classed('active', false);
61724             utilGetSetValue(input, '');
61725             if (isMulti) {
61726                 field.keys.push(field.key + val);
61727                 t$$1[field.key + val] = 'yes';
61728             } else if (isSemi) {
61729                 var arr = multiData.map(function(d) { return d.key; });
61730                 arr.push(val);
61731                 t$$1[field.key] = compact(uniq(arr)).join(';');
61732             }
61733             window.setTimeout(function() { input.node().focus(); }, 10);
61734
61735         } else {
61736             t$$1[field.key] = val;
61737         }
61738
61739         dispatch$$1.call('change', this, t$$1);
61740     }
61741
61742
61743     function removeMultikey(d) {
61744         event.stopPropagation();
61745         var t$$1 = {};
61746         if (isMulti) {
61747             t$$1[d.key] = undefined;
61748         } else if (isSemi) {
61749             remove$8(multiData, function(md) { return md.key === d.key; });
61750             var arr = multiData.map(function(md) { return md.key; });
61751             arr = compact(uniq(arr));
61752             t$$1[field.key] = arr.length ? arr.join(';') : undefined;
61753         }
61754         dispatch$$1.call('change', this, t$$1);
61755     }
61756
61757
61758     function combo(selection) {
61759         if (isMulti || isSemi) {
61760             container = selection.selectAll('ul').data([0]);
61761
61762             container = container.enter()
61763                 .append('ul')
61764                 .attr('class', 'form-field-multicombo')
61765                 .on('click', function() {
61766                     window.setTimeout(function() { input.node().focus(); }, 10);
61767                 })
61768                 .merge(container);
61769
61770         } else {
61771             container = selection;
61772         }
61773
61774         input = container.selectAll('input')
61775             .data([0]);
61776
61777         input = input.enter()
61778             .append('input')
61779             .attr('type', 'text')
61780             .attr('id', 'preset-input-' + field.id)
61781             .call(utilNoAuto)
61782             .call(initCombo, selection)
61783             .merge(input);
61784
61785         if (isNetwork && nominatim && entity) {
61786             var center = entity.extent(context.graph()).center();
61787             nominatim.countryCode(center, function (err, code) {
61788                 country = code;
61789             });
61790         }
61791
61792         input
61793             .on('change', change)
61794             .on('blur', change);
61795
61796         if (isMulti || isSemi) {
61797             combobox
61798                 .on('accept', function() {
61799                     input.node().blur();
61800                     input.node().focus();
61801                 });
61802
61803             input
61804                 .on('focus', function() { container.classed('active', true); });
61805         }
61806     }
61807
61808
61809     combo.tags = function(tags) {
61810         if (isMulti || isSemi) {
61811             multiData = [];
61812
61813             if (isMulti) {
61814                 // Build multiData array containing keys already set..
61815                 Object.keys(tags).forEach(function(key) {
61816                     if (key.indexOf(field.key) !== 0 || tags[key].toLowerCase() !== 'yes') return;
61817
61818                     var suffix = key.substring(field.key.length);
61819                     multiData.push({
61820                         key: key,
61821                         value: displayValue(suffix)
61822                     });
61823                 });
61824
61825                 // Set keys for form-field modified (needed for undo and reset buttons)..
61826                 field.keys = map$4(multiData, 'key');
61827
61828             } else if (isSemi) {
61829                 var arr = compact(uniq((tags[field.key] || '').split(';')));
61830                 multiData = arr.map(function(key) {
61831                     return {
61832                         key: key,
61833                         value: displayValue(key)
61834                     };
61835                 });
61836             }
61837
61838             // Exclude existing multikeys from combo options..
61839             var available = objectDifference(comboData, multiData);
61840             combobox.data(available);
61841
61842             // Hide 'Add' button if this field uses fixed set of
61843             // translateable optstrings and they're all currently used..
61844             container.selectAll('.combobox-input, .combobox-caret')
61845                 .classed('hide', optstrings && !available.length);
61846
61847
61848             // Render chips
61849             var chips = container.selectAll('.chips')
61850                 .data(multiData);
61851
61852             chips.exit()
61853                 .remove();
61854
61855             var enter = chips.enter()
61856                 .insert('li', 'input')
61857                 .attr('class', 'chips');
61858
61859             enter.append('span');
61860             enter.append('a');
61861
61862             chips = chips.merge(enter);
61863
61864             chips.select('span')
61865                 .text(function(d) { return d.value; });
61866
61867             chips.select('a')
61868                 .on('click', removeMultikey)
61869                 .attr('class', 'remove')
61870                 .text('×');
61871
61872         } else {
61873             utilGetSetValue(input, displayValue(tags[field.key]));
61874         }
61875     };
61876
61877
61878     combo.focus = function() {
61879         input.node().focus();
61880     };
61881
61882
61883     combo.entity = function(_) {
61884         if (!arguments.length) return entity;
61885         entity = _;
61886         return combo;
61887     };
61888
61889
61890     return utilRebind(combo, dispatch$$1, 'on');
61891 }
61892
61893 function uiFieldText(field, context) {
61894     var dispatch$$1 = dispatch('change'),
61895         nominatim = services.geocoder,
61896         input,
61897         entity;
61898
61899
61900     function i(selection) {
61901         var fieldId = 'preset-input-' + field.id;
61902
61903         input = selection.selectAll('input')
61904             .data([0]);
61905
61906         input = input.enter()
61907             .append('input')
61908             .attr('type', field.type)
61909             .attr('id', fieldId)
61910             .attr('placeholder', field.placeholder() || t('inspector.unknown'))
61911             .call(utilNoAuto)
61912             .merge(input);
61913
61914         input
61915             .on('input', change(true))
61916             .on('blur', change())
61917             .on('change', change());
61918
61919         if (field.type === 'tel' && nominatim && entity) {
61920             var center = entity.extent(context.graph()).center();
61921             nominatim.countryCode(center, function (err, countryCode) {
61922                 if (err || !dataPhoneFormats[countryCode]) return;
61923                 selection.selectAll('#' + fieldId)
61924                     .attr('placeholder', dataPhoneFormats[countryCode]);
61925             });
61926
61927         } else if (field.type === 'number') {
61928             var rtl = (textDirection === 'rtl');
61929
61930             input.attr('type', 'text');
61931
61932             var spinControl = selection.selectAll('.spin-control')
61933                 .data([0]);
61934
61935             var enter = spinControl.enter()
61936                 .append('div')
61937                 .attr('class', 'spin-control');
61938
61939             enter
61940                 .append('button')
61941                 .datum(rtl ? 1 : -1)
61942                 .attr('class', rtl ? 'increment' : 'decrement')
61943                 .attr('tabindex', -1);
61944
61945             enter
61946                 .append('button')
61947                 .datum(rtl ? -1 : 1)
61948                 .attr('class', rtl ? 'decrement' : 'increment')
61949                 .attr('tabindex', -1);
61950
61951             spinControl = spinControl
61952                 .merge(enter);
61953
61954             spinControl.selectAll('button')
61955                 .on('click', function(d) {
61956                     event.preventDefault();
61957                     var num = parseInt(input.node().value || 0, 10);
61958                     if (!isNaN(num)) input.node().value = num + d;
61959                     change()();
61960                 });
61961         }
61962     }
61963
61964
61965     function change(onInput) {
61966         return function() {
61967             var t$$1 = {};
61968             t$$1[field.key] = utilGetSetValue(input) || undefined;
61969             dispatch$$1.call('change', this, t$$1, onInput);
61970         };
61971     }
61972
61973
61974     i.entity = function(_) {
61975         if (!arguments.length) return entity;
61976         entity = _;
61977         return i;
61978     };
61979
61980
61981     i.tags = function(tags) {
61982         utilGetSetValue(input, tags[field.key] || '');
61983     };
61984
61985
61986     i.focus = function() {
61987         var node = input.node();
61988         if (node) node.focus();
61989     };
61990
61991     return utilRebind(i, dispatch$$1, 'on');
61992 }
61993
61994 function uiFieldAccess(field, context) {
61995     var dispatch$$1 = dispatch('change'),
61996         items;
61997
61998     function access(selection) {
61999         var wrap = selection.selectAll('.preset-input-wrap')
62000             .data([0]);
62001
62002         wrap = wrap.enter()
62003             .append('div')
62004             .attr('class', 'cf preset-input-wrap')
62005             .append('ul')
62006             .merge(wrap);
62007
62008         var list = wrap.selectAll('ul')
62009             .data([0]);
62010
62011         list = list.enter()
62012             .append('ul')
62013             .merge(list);
62014
62015
62016         items = list.selectAll('li')
62017             .data(field.keys);
62018
62019         // Enter
62020         var enter = items.enter()
62021             .append('li')
62022             .attr('class', function(d) { return 'cf preset-access-' + d; });
62023
62024         enter
62025             .append('span')
62026             .attr('class', 'col6 label preset-label-access')
62027             .attr('for', function(d) { return 'preset-input-access-' + d; })
62028             .text(function(d) { return field.t('types.' + d); });
62029
62030         enter
62031             .append('div')
62032             .attr('class', 'col6 preset-input-access-wrap')
62033             .append('input')
62034             .attr('type', 'text')
62035             .attr('class', 'preset-input-access')
62036             .attr('id', function(d) { return 'preset-input-access-' + d; })
62037             .call(utilNoAuto)
62038             .each(function(d) {
62039                 d3_select(this)
62040                     .call(d3combobox()
62041                         .container(context.container())
62042                         .data(access.options(d))
62043                     );
62044             });
62045
62046
62047         // Update
62048         items = items.merge(enter);
62049
62050         wrap.selectAll('.preset-input-access')
62051             .on('change', change)
62052             .on('blur', change);
62053     }
62054
62055
62056     function change(d) {
62057         var tag = {};
62058         tag[d] = utilGetSetValue(d3_select(this)) || undefined;
62059         dispatch$$1.call('change', this, tag);
62060     }
62061
62062
62063     access.options = function(type) {
62064         var options = ['no', 'permissive', 'private', 'destination'];
62065
62066         if (type !== 'access') {
62067             options.unshift('yes');
62068             options.push('designated');
62069
62070             if (type === 'bicycle') {
62071                 options.push('dismount');
62072             }
62073         }
62074
62075         return options.map(function(option) {
62076             return {
62077                 title: field.t('options.' + option + '.description'),
62078                 value: option
62079             };
62080         });
62081     };
62082
62083
62084     var placeholders = {
62085         footway: {
62086             foot: 'designated',
62087             motor_vehicle: 'no'
62088         },
62089         steps: {
62090             foot: 'yes',
62091             motor_vehicle: 'no',
62092             bicycle: 'no',
62093             horse: 'no'
62094         },
62095         pedestrian: {
62096             foot: 'yes',
62097             motor_vehicle: 'no'
62098         },
62099         cycleway: {
62100             motor_vehicle: 'no',
62101             bicycle: 'designated'
62102         },
62103         bridleway: {
62104             motor_vehicle: 'no',
62105             horse: 'designated'
62106         },
62107         path: {
62108             foot: 'yes',
62109             motor_vehicle: 'no',
62110             bicycle: 'yes',
62111             horse: 'yes'
62112         },
62113         motorway: {
62114             foot: 'no',
62115             motor_vehicle: 'yes',
62116             bicycle: 'no',
62117             horse: 'no'
62118         },
62119         trunk: {
62120             motor_vehicle: 'yes'
62121         },
62122         primary: {
62123             foot: 'yes',
62124             motor_vehicle: 'yes',
62125             bicycle: 'yes',
62126             horse: 'yes'
62127         },
62128         secondary: {
62129             foot: 'yes',
62130             motor_vehicle: 'yes',
62131             bicycle: 'yes',
62132             horse: 'yes'
62133         },
62134         tertiary: {
62135             foot: 'yes',
62136             motor_vehicle: 'yes',
62137             bicycle: 'yes',
62138             horse: 'yes'
62139         },
62140         residential: {
62141             foot: 'yes',
62142             motor_vehicle: 'yes',
62143             bicycle: 'yes',
62144             horse: 'yes'
62145         },
62146         unclassified: {
62147             foot: 'yes',
62148             motor_vehicle: 'yes',
62149             bicycle: 'yes',
62150             horse: 'yes'
62151         },
62152         service: {
62153             foot: 'yes',
62154             motor_vehicle: 'yes',
62155             bicycle: 'yes',
62156             horse: 'yes'
62157         },
62158         motorway_link: {
62159             foot: 'no',
62160             motor_vehicle: 'yes',
62161             bicycle: 'no',
62162             horse: 'no'
62163         },
62164         trunk_link: {
62165             motor_vehicle: 'yes'
62166         },
62167         primary_link: {
62168             foot: 'yes',
62169             motor_vehicle: 'yes',
62170             bicycle: 'yes',
62171             horse: 'yes'
62172         },
62173         secondary_link: {
62174             foot: 'yes',
62175             motor_vehicle: 'yes',
62176             bicycle: 'yes',
62177             horse: 'yes'
62178         },
62179         tertiary_link: {
62180             foot: 'yes',
62181             motor_vehicle: 'yes',
62182             bicycle: 'yes',
62183             horse: 'yes'
62184         }
62185     };
62186
62187
62188     access.tags = function(tags) {
62189         utilGetSetValue(items.selectAll('.preset-input-access'),
62190             function(d) { return tags[d] || ''; })
62191             .attr('placeholder', function() {
62192                 return tags.access ? tags.access : field.placeholder();
62193             });
62194
62195         items.selectAll('#preset-input-access-access')
62196             .attr('placeholder', 'yes');
62197
62198         forEach(placeholders[tags.highway], function(v, k) {
62199             items.selectAll('#preset-input-access-' + k)
62200                 .attr('placeholder', function() { return (tags.access || v); });
62201         });
62202     };
62203
62204
62205     access.focus = function() {
62206         items.selectAll('.preset-input-access')
62207             .node().focus();
62208     };
62209
62210
62211     return utilRebind(access, dispatch$$1, 'on');
62212 }
62213
62214 function uiFieldAddress(field, context) {
62215     var dispatch$$1 = dispatch('init', 'change'),
62216         nominatim = services.geocoder,
62217         wrap = d3_select(null),
62218         isInitialized = false,
62219         entity;
62220
62221     function getNearStreets() {
62222         var extent = entity.extent(context.graph()),
62223             l = extent.center(),
62224             box = geoExtent(l).padByMeters(200);
62225
62226         var streets = context.intersects(box)
62227             .filter(isAddressable)
62228             .map(function(d) {
62229                 var loc = context.projection([
62230                     (extent[0][0] + extent[1][0]) / 2,
62231                     (extent[0][1] + extent[1][1]) / 2]),
62232                     choice = geoChooseEdge(context.childNodes(d), loc, context.projection);
62233                 return {
62234                     title: d.tags.name,
62235                     value: d.tags.name,
62236                     dist: choice.distance
62237                 };
62238             })
62239             .sort(function(a, b) {
62240                 return a.dist - b.dist;
62241             });
62242
62243         return uniqBy(streets, 'value');
62244
62245         function isAddressable(d) {
62246             return d.tags.highway && d.tags.name && d.type === 'way';
62247         }
62248     }
62249
62250
62251     function getNearCities() {
62252         var extent = entity.extent(context.graph()),
62253             l = extent.center(),
62254             box = geoExtent(l).padByMeters(200);
62255
62256         var cities = context.intersects(box)
62257             .filter(isAddressable)
62258             .map(function(d) {
62259                 return {
62260                     title: d.tags['addr:city'] || d.tags.name,
62261                     value: d.tags['addr:city'] || d.tags.name,
62262                     dist: geoSphericalDistance(d.extent(context.graph()).center(), l)
62263                 };
62264             })
62265             .sort(function(a, b) {
62266                 return a.dist - b.dist;
62267             });
62268
62269         return uniqBy(cities, 'value');
62270
62271
62272         function isAddressable(d) {
62273             if (d.tags.name &&
62274                 (d.tags.admin_level === '8' || d.tags.border_type === 'city'))
62275                 return true;
62276
62277             if (d.tags.place && d.tags.name && (
62278                     d.tags.place === 'city' ||
62279                     d.tags.place === 'town' ||
62280                     d.tags.place === 'village'))
62281                 return true;
62282
62283             if (d.tags['addr:city']) return true;
62284
62285             return false;
62286         }
62287     }
62288
62289     function getNearValues(key) {
62290         var extent = entity.extent(context.graph()),
62291             l = extent.center(),
62292             box = geoExtent(l).padByMeters(200);
62293
62294         var results = context.intersects(box)
62295             .filter(function hasTag(d) {
62296                 return d.tags[key];
62297             })
62298             .map(function(d) {
62299                 return {
62300                     title: d.tags[key],
62301                     value: d.tags[key],
62302                     dist: geoSphericalDistance(d.extent(context.graph()).center(), l)
62303                 };
62304             })
62305             .sort(function(a, b) {
62306                 return a.dist - b.dist;
62307             });
62308
62309         return uniqBy(results, 'value');
62310     }
62311
62312
62313     function initCallback(err, countryCode) {
62314         if (err) return;
62315
62316         var addressFormat = find$1(dataAddressFormats, function (a) {
62317             return a && a.countryCodes && includes(a.countryCodes, countryCode.toLowerCase());
62318         }) || dataAddressFormats[0];
62319
62320         var widths = addressFormat.widths || {
62321             housenumber: 1/3, street: 2/3,
62322             city: 2/3, state: 1/4, postcode: 1/3
62323         };
62324
62325         function row(r) {
62326             // Normalize widths.
62327             var total = reduce(r, function(sum, field) {
62328                 return sum + (widths[field] || 0.5);
62329             }, 0);
62330
62331             return r.map(function (field) {
62332                 return {
62333                     id: field,
62334                     width: (widths[field] || 0.5) / total
62335                 };
62336             });
62337         }
62338
62339         wrap.selectAll('div.addr-row')
62340             .data(addressFormat.format)
62341             .enter()
62342             .append('div')
62343             .attr('class', 'addr-row')
62344             .selectAll('input')
62345             .data(row)
62346             .enter()
62347             .append('input')
62348             .property('type', 'text')
62349             .attr('placeholder', function (d) {
62350                 var localkey = d.id + '!' + countryCode.toLowerCase(),
62351                     tkey = field.strings.placeholders[localkey] ? localkey : d.id;
62352                 return field.t('placeholders.' + tkey);
62353             })
62354             .attr('class', function (d) { return 'addr-' + d.id; })
62355             .call(utilNoAuto)
62356             .style('width', function (d) { return d.width * 100 + '%'; });
62357
62358         // Update
62359
62360         // setup dropdowns for common address tags
62361         var dropdowns = addressFormat.dropdowns || [
62362             'city', 'county', 'country', 'district', 'hamlet',
62363             'neighbourhood', 'place', 'postcode', 'province',
62364             'quarter', 'state', 'street', 'subdistrict', 'suburb'
62365         ];
62366
62367         // If fields exist for any of these tags, create dropdowns to pick nearby values..
62368         dropdowns.forEach(function(tag) {
62369             var nearValues = (tag === 'street') ? getNearStreets
62370                     : (tag === 'city') ? getNearCities
62371                     : getNearValues;
62372
62373             wrap.selectAll('input.addr-' + tag)
62374                 .call(d3combobox()
62375                     .container(context.container())
62376                     .minItems(1)
62377                     .fetcher(function(value, callback) {
62378                         callback(nearValues('addr:' + tag));
62379                     })
62380                 );
62381         });
62382
62383         wrap.selectAll('input')
62384             .on('blur', change())
62385             .on('change', change());
62386
62387         wrap.selectAll('input:not(.combobox-input)')
62388             .on('input', change(true));
62389
62390         dispatch$$1.call('init');
62391         isInitialized = true;
62392     }
62393
62394
62395     function address(selection) {
62396         isInitialized = false;
62397
62398         wrap = selection.selectAll('.preset-input-wrap')
62399             .data([0]);
62400
62401         wrap = wrap.enter()
62402             .append('div')
62403             .attr('class', 'preset-input-wrap')
62404             .merge(wrap);
62405
62406         if (nominatim && entity) {
62407             var center = entity.extent(context.graph()).center();
62408             nominatim.countryCode(center, initCallback);
62409         }
62410     }
62411
62412
62413     function change(onInput) {
62414         return function() {
62415             var tags = {};
62416
62417             wrap.selectAll('input')
62418                 .each(function (field) {
62419                     tags['addr:' + field.id] = this.value || undefined;
62420                 });
62421
62422             dispatch$$1.call('change', this, tags, onInput);
62423         };
62424     }
62425
62426
62427     function updateTags(tags) {
62428         utilGetSetValue(wrap.selectAll('input'), function (field) {
62429             return tags['addr:' + field.id] || '';
62430         });
62431     }
62432
62433
62434     address.entity = function(_) {
62435         if (!arguments.length) return entity;
62436         entity = _;
62437         return address;
62438     };
62439
62440
62441     address.tags = function(tags) {
62442         if (isInitialized) {
62443             updateTags(tags);
62444         } else {
62445             dispatch$$1.on('init', function () {
62446                 dispatch$$1.on('init', null);
62447                 updateTags(tags);
62448             });
62449         }
62450     };
62451
62452
62453     address.focus = function() {
62454         var node = wrap.selectAll('input').node();
62455         if (node) node.focus();
62456     };
62457
62458
62459     return utilRebind(address, dispatch$$1, 'on');
62460 }
62461
62462 function uiFieldCycleway(field, context) {
62463     var dispatch$$1 = dispatch('change'),
62464         items = d3_select(null);
62465
62466
62467     function cycleway(selection) {
62468
62469         function stripcolon(s) {
62470             return s.replace(':', '');
62471         }
62472
62473
62474         var wrap = selection.selectAll('.preset-input-wrap')
62475             .data([0]);
62476
62477         wrap = wrap.enter()
62478             .append('div')
62479             .attr('class', 'cf preset-input-wrap')
62480             .merge(wrap);
62481
62482
62483         var div = wrap.selectAll('ul')
62484             .data([0]);
62485
62486         div = div.enter()
62487             .append('ul')
62488             .merge(div);
62489
62490
62491         items = div.selectAll('li')
62492             .data(field.keys);
62493
62494         var enter = items.enter()
62495             .append('li')
62496             .attr('class', function(d) { return 'cf preset-cycleway-' + stripcolon(d); });
62497
62498         enter
62499             .append('span')
62500             .attr('class', 'col6 label preset-label-cycleway')
62501             .attr('for', function(d) { return 'preset-input-cycleway-' + stripcolon(d); })
62502             .text(function(d) { return field.t('types.' + d); });
62503
62504         enter
62505             .append('div')
62506             .attr('class', 'col6 preset-input-cycleway-wrap')
62507             .append('input')
62508             .attr('type', 'text')
62509             .attr('class', function(d) { return 'preset-input-cycleway preset-input-' + stripcolon(d); })
62510             .call(utilNoAuto)
62511             .each(function(d) {
62512                 d3_select(this)
62513                     .call(d3combobox()
62514                         .container(context.container())
62515                         .data(cycleway.options(d))
62516                     );
62517             });
62518
62519
62520         // Update
62521         wrap.selectAll('.preset-input-cycleway')
62522             .on('change', change)
62523             .on('blur', change);
62524     }
62525
62526
62527     function change() {
62528         var left = utilGetSetValue(d3_select('.preset-input-cyclewayleft')),
62529             right = utilGetSetValue(d3_select('.preset-input-cyclewayright')),
62530             tag = {};
62531
62532         if (left === 'none' || left === '') { left = undefined; }
62533         if (right === 'none' || right === '') { right = undefined; }
62534
62535         // Always set both left and right as changing one can affect the other
62536         tag = {
62537             cycleway: undefined,
62538             'cycleway:left': left,
62539             'cycleway:right': right
62540         };
62541
62542         // If the left and right tags match, use the cycleway tag to tag both
62543         // sides the same way
62544         if (left === right) {
62545             tag = {
62546                 cycleway: left,
62547                 'cycleway:left': undefined,
62548                 'cycleway:right': undefined
62549             };
62550         }
62551
62552         dispatch$$1.call('change', this, tag);
62553     }
62554
62555
62556     cycleway.options = function() {
62557         return keys$1(field.strings.options).map(function(option) {
62558             return {
62559                 title: field.t('options.' + option + '.description'),
62560                 value: option
62561             };
62562         });
62563     };
62564
62565
62566     cycleway.tags = function(tags) {
62567         utilGetSetValue(items.selectAll('.preset-input-cycleway'), function(d) {
62568                 // If cycleway is set, always return that
62569                 if (tags.cycleway) {
62570                     return tags.cycleway;
62571                 }
62572                 return tags[d] || '';
62573             })
62574             .attr('placeholder', field.placeholder());
62575     };
62576
62577
62578     cycleway.focus = function() {
62579         items.selectAll('.preset-input-cycleway')
62580             .node().focus();
62581     };
62582
62583
62584     return utilRebind(cycleway, dispatch$$1, 'on');
62585 }
62586
62587 function uiFieldLanes(field, context) {
62588     var dispatch$$1 = dispatch('change'),
62589         LANE_WIDTH = 40,
62590         LANE_HEIGHT = 200,
62591         wayID,
62592         lanesData;
62593
62594     function lanes(selection) {
62595         lanesData = context.entity(wayID).lanes();
62596
62597         if (!d3_select('.inspector-wrap.inspector-hidden').empty() || !selection.node().parentNode) {
62598             selection.call(lanes.off);
62599             return;
62600         }
62601
62602         var wrap = selection.selectAll('.preset-input-wrap')
62603             .data([0]);
62604
62605         wrap = wrap.enter()
62606             .append('div')
62607             .attr('class', 'preset-input-wrap')
62608             .merge(wrap);
62609
62610         var surface =  wrap.selectAll('.surface')
62611             .data([0]);
62612
62613         var d = utilGetDimensions(wrap);
62614         var freeSpace = d[0] - lanesData.lanes.length * LANE_WIDTH * 1.5 + LANE_WIDTH * 0.5;
62615
62616         surface = surface.enter()
62617             .append('svg')
62618             .attr('width', d[0])
62619             .attr('height', 300)
62620             .attr('class', 'surface')
62621             .merge(surface);
62622
62623
62624         var lanesSelection = surface.selectAll('.lanes')
62625             .data([0]);
62626
62627         lanesSelection = lanesSelection.enter()
62628             .append('g')
62629             .attr('class', 'lanes')
62630             .merge(lanesSelection);
62631
62632         lanesSelection
62633             .attr('transform', function () {
62634                 return 'translate(' + (freeSpace / 2) + ', 0)';
62635             });
62636
62637
62638         var lane = lanesSelection.selectAll('.lane')
62639            .data(lanesData.lanes);
62640
62641         lane.exit()
62642             .remove();
62643
62644         var enter = lane.enter()
62645             .append('g')
62646             .attr('class', 'lane');
62647
62648         enter
62649             .append('g')
62650             .append('rect')
62651             .attr('y', 50)
62652             .attr('width', LANE_WIDTH)
62653             .attr('height', LANE_HEIGHT);
62654
62655         enter
62656             .append('g')
62657             .attr('class', 'forward')
62658             .append('text')
62659             .attr('y', 40)
62660             .attr('x', 14)
62661             .text('▲');
62662
62663         enter
62664             .append('g')
62665             .attr('class', 'bothways')
62666             .append('text')
62667             .attr('y', 40)
62668             .attr('x', 14)
62669             .text('▲▼');
62670
62671         enter
62672             .append('g')
62673             .attr('class', 'backward')
62674             .append('text')
62675             .attr('y', 40)
62676             .attr('x', 14)
62677             .text('▼');
62678
62679
62680         lane = lane
62681             .merge(enter);
62682
62683         lane
62684             .attr('transform', function(d) {
62685                 return 'translate(' + (LANE_WIDTH * d.index * 1.5) + ', 0)';
62686             });
62687
62688         lane.select('.forward')
62689             .style('visibility', function(d) {
62690                 return d.direction === 'forward' ? 'visible' : 'hidden';
62691             });
62692
62693         lane.select('.bothways')
62694             .style('visibility', function(d) {
62695                 return d.direction === 'bothways' ? 'visible' : 'hidden';
62696             });
62697
62698         lane.select('.backward')
62699             .style('visibility', function(d) {
62700                 return d.direction === 'backward' ? 'visible' : 'hidden';
62701             });
62702     }
62703
62704
62705     lanes.entity = function(_) {
62706         if (!wayID || wayID !== _.id) {
62707             wayID = _.id;
62708         }
62709     };
62710
62711     lanes.tags = function() {};
62712     lanes.focus = function() {};
62713     lanes.off = function() {};
62714
62715     return utilRebind(lanes, dispatch$$1, 'on');
62716 }
62717
62718 function uiFieldLocalized(field, context) {
62719     var dispatch$$1 = dispatch('change', 'input'),
62720         wikipedia = services.wikipedia,
62721         input = d3_select(null),
62722         localizedInputs = d3_select(null),
62723         wikiTitles,
62724         entity;
62725
62726
62727     function localized(selection) {
62728         input = selection.selectAll('.localized-main')
62729             .data([0]);
62730
62731         input = input.enter()
62732             .append('input')
62733             .attr('type', 'text')
62734             .attr('id', 'preset-input-' + field.id)
62735             .attr('class', 'localized-main')
62736             .attr('placeholder', field.placeholder())
62737             .call(utilNoAuto)
62738             .merge(input);
62739
62740         if (field.id === 'name') {
62741             var preset = context.presets().match(entity, context.graph());
62742             input
62743                 .call(d3combobox()
62744                     .container(context.container())
62745                     .fetcher(utilSuggestNames(preset, dataSuggestions))
62746                 );
62747         }
62748
62749         input
62750             .on('input', change(true))
62751             .on('blur', change())
62752             .on('change', change());
62753
62754
62755         var translateButton = selection.selectAll('.localized-add')
62756             .data([0]);
62757
62758         translateButton = translateButton.enter()
62759             .append('button')
62760             .attr('class', 'button-input-action localized-add minor')
62761             .attr('tabindex', -1)
62762             .call(svgIcon('#icon-plus'))
62763             .call(tooltip()
62764                 .title(t('translate.translate'))
62765                 .placement('left'))
62766             .merge(translateButton);
62767
62768         translateButton
62769             .on('click', addNew);
62770
62771
62772         localizedInputs = selection.selectAll('.localized-wrap')
62773             .data([0]);
62774
62775         localizedInputs = localizedInputs.enter().append('div')
62776             .attr('class', 'localized-wrap')
62777             .merge(localizedInputs);
62778     }
62779
62780
62781     function addNew() {
62782         event.preventDefault();
62783         var data$$1 = localizedInputs.selectAll('div.entry').data();
62784         var defaultLang = utilDetect().locale.toLowerCase().split('-')[0];
62785         var langExists = find$1(data$$1, function(datum) { return datum.lang === defaultLang;});
62786         var isLangEn = defaultLang.indexOf('en') > -1;
62787         if (isLangEn || langExists) {
62788             defaultLang = '';
62789         }
62790         data$$1.push({ lang: defaultLang, value: '' });
62791         localizedInputs.call(render, data$$1);
62792     }
62793
62794
62795     function change(onInput) {
62796         return function() {
62797             var t$$1 = {};
62798             t$$1[field.key] = utilGetSetValue(d3_select(this)) || undefined;
62799             dispatch$$1.call('change', this, t$$1, onInput);
62800         };
62801     }
62802
62803
62804     function key(lang) {
62805         return field.key + ':' + lang;
62806     }
62807
62808
62809     function changeLang(d) {
62810         var lang = utilGetSetValue(d3_select(this)),
62811             t$$1 = {},
62812             language = find$1(wikipedia$2, function(d) {
62813                 return d[0].toLowerCase() === lang.toLowerCase() ||
62814                     d[1].toLowerCase() === lang.toLowerCase();
62815             });
62816
62817         if (language) lang = language[2];
62818
62819         if (d.lang && d.lang !== lang) {
62820             t$$1[key(d.lang)] = undefined;
62821         }
62822
62823         var value = utilGetSetValue(d3_select(this.parentNode)
62824             .selectAll('.localized-value'));
62825
62826         if (lang && value) {
62827             t$$1[key(lang)] = value;
62828         } else if (lang && wikiTitles && wikiTitles[d.lang]) {
62829             t$$1[key(lang)] = wikiTitles[d.lang];
62830         }
62831
62832         d.lang = lang;
62833         dispatch$$1.call('change', this, t$$1);
62834     }
62835
62836
62837     function changeValue(d) {
62838         if (!d.lang) return;
62839         var t$$1 = {};
62840         t$$1[key(d.lang)] = utilGetSetValue(d3_select(this)) || undefined;
62841         dispatch$$1.call('change', this, t$$1);
62842     }
62843
62844
62845     function fetcher(value, cb) {
62846         var v = value.toLowerCase();
62847
62848         cb(wikipedia$2.filter(function(d) {
62849             return d[0].toLowerCase().indexOf(v) >= 0 ||
62850             d[1].toLowerCase().indexOf(v) >= 0 ||
62851             d[2].toLowerCase().indexOf(v) >= 0;
62852         }).map(function(d) {
62853             return { value: d[1] };
62854         }));
62855     }
62856
62857
62858     function render(selection, data$$1) {
62859         var wraps = selection.selectAll('div.entry').
62860             data(data$$1, function(d) { return d.lang; });
62861
62862         wraps.exit()
62863             .transition()
62864             .duration(200)
62865             .style('max-height','0px')
62866             .style('opacity', '0')
62867             .style('top','-10px')
62868             .remove();
62869
62870         var innerWrap = wraps.enter()
62871             .insert('div', ':first-child');
62872
62873         innerWrap.attr('class', 'entry')
62874             .each(function() {
62875                 var wrap = d3_select(this);
62876                 var langcombo = d3combobox()
62877                     .container(context.container())
62878                     .fetcher(fetcher)
62879                     .minItems(0);
62880
62881                 var label = wrap
62882                     .append('label')
62883                     .attr('class','form-label')
62884                     .text(t('translate.localized_translation_label'))
62885                     .attr('for','localized-lang');
62886
62887                 label
62888                     .append('button')
62889                     .attr('class', 'minor remove')
62890                     .on('click', function(d){
62891                         event.preventDefault();
62892                         var t$$1 = {};
62893                         t$$1[key(d.lang)] = undefined;
62894                         dispatch$$1.call('change', this, t$$1);
62895                         d3_select(this.parentNode.parentNode)
62896                             .style('top','0')
62897                             .style('max-height','240px')
62898                             .transition()
62899                             .style('opacity', '0')
62900                             .style('max-height','0px')
62901                             .remove();
62902                     })
62903                     .call(svgIcon('#operation-delete'));
62904
62905                 wrap
62906                     .append('input')
62907                     .attr('class', 'localized-lang')
62908                     .attr('type', 'text')
62909                     .attr('placeholder',t('translate.localized_translation_language'))
62910                     .on('blur', changeLang)
62911                     .on('change', changeLang)
62912                     .call(langcombo);
62913
62914                 wrap
62915                     .append('input')
62916                     .on('blur', changeValue)
62917                     .on('change', changeValue)
62918                     .attr('type', 'text')
62919                     .attr('placeholder', t('translate.localized_translation_name'))
62920                     .attr('class', 'localized-value');
62921             });
62922
62923         innerWrap
62924             .style('margin-top', '0px')
62925             .style('max-height', '0px')
62926             .style('opacity', '0')
62927             .transition()
62928             .duration(200)
62929             .style('margin-top', '10px')
62930             .style('max-height', '240px')
62931             .style('opacity', '1')
62932             .on('end', function() {
62933                 d3_select(this)
62934                     .style('max-height', '')
62935                     .style('overflow', 'visible');
62936             });
62937
62938
62939         var entry = selection.selectAll('.entry');
62940
62941         utilGetSetValue(entry.select('.localized-lang'), function(d) {
62942                 var lang = find$1(wikipedia$2, function(lang) { return lang[2] === d.lang; });
62943                 return lang ? lang[1] : d.lang;
62944             });
62945
62946         utilGetSetValue(entry.select('.localized-value'),
62947             function(d) { return d.value; });
62948     }
62949
62950
62951     localized.tags = function(tags) {
62952         // Fetch translations from wikipedia
62953         if (tags.wikipedia && !wikiTitles) {
62954             wikiTitles = {};
62955             var wm = tags.wikipedia.match(/([^:]+):(.+)/);
62956             if (wm && wm[0] && wm[1]) {
62957                 wikipedia.translations(wm[1], wm[2], function(d) {
62958                     wikiTitles = d;
62959                 });
62960             }
62961         }
62962
62963         utilGetSetValue(input, tags[field.key] || '');
62964
62965         var postfixed = [], k, m;
62966         for (k in tags) {
62967             m = k.match(/^(.*):([a-zA-Z_-]+)$/);
62968             if (m && m[1] === field.key && m[2]) {
62969                 postfixed.push({ lang: m[2], value: tags[k] });
62970             }
62971         }
62972
62973         localizedInputs.call(render, postfixed.reverse());
62974     };
62975
62976
62977     localized.focus = function() {
62978         input.node().focus();
62979     };
62980
62981
62982     localized.entity = function(_) {
62983         if (!arguments.length) return entity;
62984         entity = _;
62985         return localized;
62986     };
62987
62988     return utilRebind(localized, dispatch$$1, 'on');
62989 }
62990
62991 function uiFieldMaxspeed(field, context) {
62992     var dispatch$$1 = dispatch('change'),
62993         entity,
62994         isImperial,
62995         unitInput = d3_select(null),
62996         input = d3_select(null),
62997         combobox;
62998
62999     var metricValues = [20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120],
63000         imperialValues = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80];
63001
63002
63003     function maxspeed(selection) {
63004         combobox = d3combobox()
63005             .container(context.container());
63006
63007         var unitCombobox = d3combobox()
63008             .container(context.container())
63009             .data(['km/h', 'mph'].map(comboValues));
63010
63011         input = selection.selectAll('#preset-input-' + field.id)
63012             .data([0]);
63013
63014         input = input.enter()
63015             .append('input')
63016             .attr('type', 'text')
63017             .attr('id', 'preset-input-' + field.id)
63018             .attr('placeholder', field.placeholder())
63019             .call(utilNoAuto)
63020             .call(combobox)
63021             .merge(input);
63022
63023         input
63024             .on('change', change)
63025             .on('blur', change);
63026
63027         var childNodes = context.graph().childNodes(context.entity(entity.id)),
63028             loc = childNodes[~~(childNodes.length/2)].loc;
63029
63030         isImperial = some(dataImperial.features, function(f) {
63031             return some(f.geometry.coordinates, function(d) {
63032                 return geoPointInPolygon(loc, d);
63033             });
63034         });
63035
63036         unitInput = selection.selectAll('input.maxspeed-unit')
63037             .data([0]);
63038
63039         unitInput = unitInput.enter()
63040             .append('input')
63041             .attr('type', 'text')
63042             .attr('class', 'maxspeed-unit')
63043             .call(unitCombobox)
63044             .merge(unitInput);
63045
63046         unitInput
63047             .on('blur', changeUnits)
63048             .on('change', changeUnits);
63049
63050
63051         function changeUnits() {
63052             isImperial = utilGetSetValue(unitInput) === 'mph';
63053             utilGetSetValue(unitInput, isImperial ? 'mph' : 'km/h');
63054             setSuggestions();
63055             change();
63056         }
63057     }
63058
63059
63060     function setSuggestions() {
63061         combobox.data((isImperial ? imperialValues : metricValues).map(comboValues));
63062         utilGetSetValue(unitInput, isImperial ? 'mph' : 'km/h');
63063     }
63064
63065
63066     function comboValues(d) {
63067         return {
63068             value: d.toString(),
63069             title: d.toString()
63070         };
63071     }
63072
63073
63074     function change() {
63075         var tag = {},
63076             value = utilGetSetValue(input);
63077
63078         if (!value) {
63079             tag[field.key] = undefined;
63080         } else if (isNaN(value) || !isImperial) {
63081             tag[field.key] = value;
63082         } else {
63083             tag[field.key] = value + ' mph';
63084         }
63085
63086         dispatch$$1.call('change', this, tag);
63087     }
63088
63089
63090     maxspeed.tags = function(tags) {
63091         var value = tags[field.key];
63092
63093         if (value && value.indexOf('mph') >= 0) {
63094             value = parseInt(value, 10);
63095             isImperial = true;
63096         } else if (value) {
63097             isImperial = false;
63098         }
63099
63100         setSuggestions();
63101         utilGetSetValue(input, value || '');
63102     };
63103
63104
63105     maxspeed.focus = function() {
63106         input.node().focus();
63107     };
63108
63109
63110     maxspeed.entity = function(_) {
63111         entity = _;
63112     };
63113
63114
63115     return utilRebind(maxspeed, dispatch$$1, 'on');
63116 }
63117
63118 /**
63119  * This function is like `baseIndexOf` except that it accepts a comparator.
63120  *
63121  * @private
63122  * @param {Array} array The array to inspect.
63123  * @param {*} value The value to search for.
63124  * @param {number} fromIndex The index to search from.
63125  * @param {Function} comparator The comparator invoked per element.
63126  * @returns {number} Returns the index of the matched value, else `-1`.
63127  */
63128 function baseIndexOfWith(array, value, fromIndex, comparator) {
63129   var index = fromIndex - 1,
63130       length = array.length;
63131
63132   while (++index < length) {
63133     if (comparator(array[index], value)) {
63134       return index;
63135     }
63136   }
63137   return -1;
63138 }
63139
63140 /** Used for built-in method references. */
63141 var arrayProto$2 = Array.prototype;
63142
63143 /** Built-in value references. */
63144 var splice$2 = arrayProto$2.splice;
63145
63146 /**
63147  * The base implementation of `_.pullAllBy` without support for iteratee
63148  * shorthands.
63149  *
63150  * @private
63151  * @param {Array} array The array to modify.
63152  * @param {Array} values The values to remove.
63153  * @param {Function} [iteratee] The iteratee invoked per element.
63154  * @param {Function} [comparator] The comparator invoked per element.
63155  * @returns {Array} Returns `array`.
63156  */
63157 function basePullAll(array, values, iteratee, comparator) {
63158   var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
63159       index = -1,
63160       length = values.length,
63161       seen = array;
63162
63163   if (array === values) {
63164     values = copyArray(values);
63165   }
63166   if (iteratee) {
63167     seen = arrayMap(array, baseUnary(iteratee));
63168   }
63169   while (++index < length) {
63170     var fromIndex = 0,
63171         value = values[index],
63172         computed = iteratee ? iteratee(value) : value;
63173
63174     while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
63175       if (seen !== array) {
63176         splice$2.call(seen, fromIndex, 1);
63177       }
63178       splice$2.call(array, fromIndex, 1);
63179     }
63180   }
63181   return array;
63182 }
63183
63184 /**
63185  * This method is like `_.pull` except that it accepts an array of values to remove.
63186  *
63187  * **Note:** Unlike `_.difference`, this method mutates `array`.
63188  *
63189  * @static
63190  * @memberOf _
63191  * @since 4.0.0
63192  * @category Array
63193  * @param {Array} array The array to modify.
63194  * @param {Array} values The values to remove.
63195  * @returns {Array} Returns `array`.
63196  * @example
63197  *
63198  * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
63199  *
63200  * _.pullAll(array, ['a', 'c']);
63201  * console.log(array);
63202  * // => ['b', 'b']
63203  */
63204 function pullAll(array, values) {
63205   return (array && array.length && values && values.length)
63206     ? basePullAll(array, values)
63207     : array;
63208 }
63209
63210 /**
63211  * Removes all given values from `array` using
63212  * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
63213  * for equality comparisons.
63214  *
63215  * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
63216  * to remove elements from an array by predicate.
63217  *
63218  * @static
63219  * @memberOf _
63220  * @since 2.0.0
63221  * @category Array
63222  * @param {Array} array The array to modify.
63223  * @param {...*} [values] The values to remove.
63224  * @returns {Array} Returns `array`.
63225  * @example
63226  *
63227  * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
63228  *
63229  * _.pull(array, 'a', 'c');
63230  * console.log(array);
63231  * // => ['b', 'b']
63232  */
63233 var pull = baseRest(pullAll);
63234
63235 function uiFieldRadio(field, context) {
63236     var dispatch$$1 = dispatch('change'),
63237         placeholder = d3_select(null),
63238         wrap = d3_select(null),
63239         labels = d3_select(null),
63240         radios = d3_select(null),
63241         radioData = clone(field.options || field.keys),
63242         typeField,
63243         layerField,
63244         oldType = {},
63245         entity;
63246
63247
63248     function selectedKey() {
63249         var node = wrap.selectAll('.toggle-list label.active input');
63250         return !node.empty() && node.datum();
63251     }
63252
63253
63254     function radio(selection) {
63255         selection.classed('preset-radio', true);
63256
63257         wrap = selection.selectAll('.preset-input-wrap')
63258             .data([0]);
63259
63260         var enter = wrap.enter()
63261             .append('div')
63262             .attr('class', 'preset-input-wrap toggle-list');
63263
63264         enter
63265             .append('span')
63266             .attr('class', 'placeholder');
63267
63268         wrap = wrap
63269             .merge(enter);
63270
63271
63272         placeholder = wrap.selectAll('.placeholder');
63273
63274         labels = wrap.selectAll('label')
63275             .data(radioData);
63276
63277         enter = labels.enter()
63278             .append('label');
63279
63280         enter
63281             .append('input')
63282             .attr('type', 'radio')
63283             .attr('name', field.id)
63284             .attr('value', function(d) { return field.t('options.' + d, { 'default': d }); })
63285             .attr('checked', false);
63286
63287         enter
63288             .append('span')
63289             .text(function(d) { return field.t('options.' + d, { 'default': d }); });
63290
63291         labels = labels
63292             .merge(enter);
63293
63294         radios = labels.selectAll('input')
63295             .on('change', changeRadio);
63296
63297     }
63298
63299
63300     function structureExtras(selection, tags) {
63301         var selected = selectedKey(),
63302             type = context.presets().field(selected),
63303             layer = context.presets().field('layer'),
63304             showLayer = (selected === 'bridge' || selected === 'tunnel');
63305
63306
63307         var extrasWrap = selection.selectAll('.structure-extras-wrap')
63308             .data(selected ? [0] : []);
63309
63310         extrasWrap.exit()
63311             .remove();
63312
63313         extrasWrap = extrasWrap.enter()
63314             .append('div')
63315             .attr('class', 'structure-extras-wrap')
63316             .merge(extrasWrap);
63317
63318         var list = extrasWrap.selectAll('ul')
63319             .data([0]);
63320
63321         list = list.enter()
63322             .append('ul')
63323             .merge(list);
63324
63325
63326         // Type
63327         if (type) {
63328             if (!typeField || typeField.id !== selected) {
63329                 typeField = uiField(context, type, entity, { wrap: false })
63330                     .on('change', changeType);
63331             }
63332             typeField.tags(tags);
63333         } else {
63334             typeField = null;
63335         }
63336
63337         var typeItem = list.selectAll('.structure-type-item')
63338             .data(typeField ? [typeField] : [], function(d) { return d.id; });
63339
63340         // Exit
63341         typeItem.exit()
63342             .remove();
63343
63344         // Enter
63345         var typeEnter = typeItem.enter()
63346             .insert('li', ':first-child')
63347             .attr('class', 'cf structure-type-item');
63348
63349         typeEnter
63350             .append('span')
63351             .attr('class', 'col6 label structure-label-type')
63352             .attr('for', 'preset-input-' + selected)
63353             .text(t('inspector.radio.structure.type'));
63354
63355         typeEnter
63356             .append('div')
63357             .attr('class', 'col6 structure-input-type-wrap');
63358
63359         // Update
63360         typeItem = typeItem
63361             .merge(typeEnter);
63362
63363         if (typeField) {
63364             typeItem.selectAll('.structure-input-type-wrap')
63365                 .call(typeField.render);
63366         }
63367
63368
63369         // Layer
63370         if (layer && showLayer) {
63371             if (!layerField) {
63372                 layerField = uiField(context, layer, entity, { wrap: false })
63373                     .on('change', changeLayer);
63374             }
63375             layerField.tags(tags);
63376             field.keys = union(field.keys, ['layer']);
63377         } else {
63378             layerField = null;
63379             pull(field.keys, 'layer');
63380         }
63381
63382         var layerItem = list.selectAll('.structure-layer-item')
63383             .data(layerField ? [layerField] : []);
63384
63385         // Exit
63386         layerItem.exit()
63387             .remove();
63388
63389         // Enter
63390         var layerEnter = layerItem.enter()
63391             .append('li')
63392             .attr('class', 'cf structure-layer-item');
63393
63394         layerEnter
63395             .append('span')
63396             .attr('class', 'col6 label structure-label-layer')
63397             .attr('for', 'preset-input-layer')
63398             .text(t('inspector.radio.structure.layer'));
63399
63400         layerEnter
63401             .append('div')
63402             .attr('class', 'col6 structure-input-layer-wrap');
63403
63404         // Update
63405         layerItem = layerItem
63406             .merge(layerEnter);
63407
63408         if (layerField) {
63409             layerItem.selectAll('.structure-input-layer-wrap')
63410                 .call(layerField.render);
63411         }
63412     }
63413
63414
63415     function changeType(t$$1, onInput) {
63416         var key = selectedKey();
63417         if (!key) return;
63418
63419         var val = t$$1[key];
63420         if (val !== 'no') {
63421             oldType[key] = val;
63422         }
63423
63424         if (field.type === 'structureRadio') {
63425             // remove layer if it should not be set
63426             if (val === 'no' ||
63427                 (key !== 'bridge' && key !== 'tunnel') ||
63428                 (key === 'tunnel' && val === 'building_passage')) {
63429                 t$$1.layer = undefined;
63430             }
63431             // add layer if it should be set
63432             if (t$$1.layer === undefined) {
63433                 if (key === 'bridge' && val !== 'no') {
63434                     t$$1.layer = '1';
63435                 }
63436                 if (key === 'tunnel' && val !== 'no' && val !== 'building_passage') {
63437                     t$$1.layer = '-1';
63438                 }
63439             }
63440          }
63441
63442         dispatch$$1.call('change', this, t$$1, onInput);
63443     }
63444
63445
63446     function changeLayer(t$$1, onInput) {
63447         if (t$$1.layer === '0') {
63448             t$$1.layer = undefined;
63449         }
63450         dispatch$$1.call('change', this, t$$1, onInput);
63451     }
63452
63453
63454     function changeRadio() {
63455         var t$$1 = {},
63456             activeKey;
63457
63458         if (field.key) {
63459             t$$1[field.key] = undefined;
63460         }
63461
63462         radios.each(function(d) {
63463             var active = d3_select(this).property('checked');
63464             if (active) activeKey = d;
63465
63466             if (field.key) {
63467                 if (active) t$$1[field.key] = d;
63468             } else {
63469                 var val = oldType[activeKey] || 'yes';
63470                 t$$1[d] = active ? val : undefined;
63471             }
63472         });
63473
63474         if (field.type === 'structureRadio') {
63475             if (activeKey === 'bridge') {
63476                 t$$1.layer = '1';
63477             } else if (activeKey === 'tunnel' && t$$1.tunnel !== 'building_passage') {
63478                 t$$1.layer = '-1';
63479             } else {
63480                 t$$1.layer = undefined;
63481             }
63482         }
63483
63484         dispatch$$1.call('change', this, t$$1);
63485     }
63486
63487
63488     radio.tags = function(tags) {
63489         function checked(d) {
63490             if (field.key) {
63491                 return tags[field.key] === d;
63492             } else {
63493                 return !!(tags[d] && tags[d].toLowerCase() !== 'no');
63494             }
63495         }
63496
63497         labels.classed('active', checked);
63498         radios.property('checked', checked);
63499
63500         var selection = radios.filter(function() { return this.checked; });
63501
63502         if (selection.empty()) {
63503             placeholder.text(t('inspector.none'));
63504         } else {
63505             placeholder.text(selection.attr('value'));
63506             oldType[selection.datum()] = tags[selection.datum()];
63507         }
63508
63509         if (field.type === 'structureRadio') {
63510             // For waterways without a tunnel tag, set 'culvert' as
63511             // the oldType to default to if the user picks 'tunnel'
63512             if (!!tags.waterway && !oldType.tunnel) {
63513                 oldType.tunnel = 'culvert';
63514             }
63515
63516             wrap.call(structureExtras, tags);
63517         }
63518     };
63519
63520
63521     radio.focus = function() {
63522         radios.node().focus();
63523     };
63524
63525
63526     radio.entity = function(_) {
63527         if (!arguments.length) return entity;
63528         entity = _;
63529         oldType = {};
63530         return radio;
63531     };
63532
63533
63534     return utilRebind(radio, dispatch$$1, 'on');
63535 }
63536
63537 function uiFieldRestrictions(field, context) {
63538     var dispatch$$1 = dispatch('change');
63539     var breathe = behaviorBreathe(context);
63540     var hover = behaviorHover(context);
63541     var initialized = false;
63542     var vertexID;
63543     var fromNodeID;
63544
63545
63546     function restrictions(selection) {
63547         // if form field is hidden or has detached from dom, clean up.
63548         if (!d3_select('.inspector-wrap.inspector-hidden').empty() || !selection.node().parentNode) {
63549             selection.call(restrictions.off);
63550             return;
63551         }
63552
63553         var wrap = selection.selectAll('.preset-input-wrap')
63554             .data([0]);
63555
63556         var enter = wrap.enter()
63557             .append('div')
63558             .attr('class', 'preset-input-wrap');
63559
63560         enter
63561             .append('div')
63562             .attr('class', 'restriction-help');
63563
63564
63565         var intersection = osmIntersection(context.graph(), vertexID);
63566         var graph = intersection.graph;
63567         var vertex = graph.entity(vertexID);
63568         var filter = utilFunctor(true);
63569         var projection = geoRawMercator();
63570
63571         var d = utilGetDimensions(wrap.merge(enter));
63572         var c = [d[0] / 2, d[1] / 2];
63573         var z = 24;
63574
63575         projection
63576             .scale(geoZoomToScale(z));
63577
63578         var s = projection(vertex.loc);
63579
63580         projection
63581             .translate([c[0] - s[0], c[1] - s[1]])
63582             .clipExtent([[0, 0], d]);
63583
63584         var extent = geoExtent(projection.invert([0, d[1]]), projection.invert([d[0], 0]));
63585
63586         var drawLayers = svgLayers(projection, context).only('osm').dimensions(d);
63587         var drawVertices = svgVertices(projection, context);
63588         var drawLines = svgLines(projection, context);
63589         var drawTurns = svgTurns(projection, context);
63590
63591         enter
63592             .call(drawLayers);
63593
63594         wrap = wrap
63595             .merge(enter);
63596
63597         var surface = wrap.selectAll('.surface');
63598
63599         if (!enter.empty()) {
63600             initialized = true;
63601             surface
63602                 .call(breathe)
63603                 .call(hover);
63604         }
63605
63606         surface
63607             .call(utilSetDimensions, d)
63608             .call(drawVertices, graph, [vertex], filter, extent, true)
63609             .call(drawLines, graph, intersection.ways, filter)
63610             .call(drawTurns, graph, intersection.turns(fromNodeID));
63611
63612         surface
63613             .on('click.restrictions', click)
63614             .on('mouseover.restrictions', mouseover)
63615             .on('mouseout.restrictions', mouseout);
63616
63617         surface
63618             .selectAll('.selected')
63619             .classed('selected', false);
63620
63621         if (fromNodeID) {
63622             surface
63623                 .selectAll('.' + intersection.highways[fromNodeID].id)
63624                 .classed('selected', true);
63625         }
63626
63627         mouseout();
63628
63629         context.history()
63630             .on('change.restrictions', render);
63631
63632         d3_select(window)
63633             .on('resize.restrictions', function() {
63634                 utilSetDimensions(wrap, null);
63635                 render();
63636             });
63637
63638
63639         function click() {
63640             surface
63641                 .call(breathe.off)
63642                 .call(breathe);
63643
63644             var datum = event.target.__data__;
63645             var entity = datum && datum.properties && datum.properties.entity;
63646             if (entity) datum = entity;
63647
63648             if (datum instanceof osmEntity) {
63649                 fromNodeID = intersection.adjacentNodeId(datum.id);
63650                 render();
63651
63652             } else if (datum instanceof osmTurn) {
63653                 if (datum.restriction) {
63654                     context.perform(
63655                         actionUnrestrictTurn(datum, projection),
63656                         t('operations.restriction.annotation.delete')
63657                     );
63658                 } else {
63659                     context.perform(
63660                         actionRestrictTurn(datum, projection),
63661                         t('operations.restriction.annotation.create')
63662                     );
63663                 }
63664             }
63665         }
63666
63667
63668         function mouseover() {
63669             var datum = event.target.__data__;
63670             if (datum instanceof osmTurn) {
63671                 var graph = context.graph();
63672                 var presets = context.presets();
63673                 var preset;
63674
63675                 if (datum.restriction) {
63676                     preset = presets.match(graph.entity(datum.restriction), graph);
63677                 } else {
63678                     preset = presets.item('type/restriction/' +
63679                         osmInferRestriction(
63680                             graph,
63681                             datum.from,
63682                             datum.via,
63683                             datum.to,
63684                             projection
63685                         )
63686                     );
63687                 }
63688
63689                 wrap.selectAll('.restriction-help')
63690                     .text(t('operations.restriction.help.' +
63691                         (datum.restriction ? 'toggle_off' : 'toggle_on'),
63692                         { restriction: preset.name() })
63693                     );
63694             }
63695         }
63696
63697
63698         function mouseout() {
63699             wrap.selectAll('.restriction-help')
63700                 .text(t('operations.restriction.help.' +
63701                     (fromNodeID ? 'toggle' : 'select'))
63702                 );
63703         }
63704
63705
63706         function render() {
63707             if (context.hasEntity(vertexID)) {
63708                 restrictions(selection);
63709             }
63710         }
63711     }
63712
63713
63714     restrictions.entity = function(_) {
63715         if (!vertexID || vertexID !== _.id) {
63716             fromNodeID = null;
63717             vertexID = _.id;
63718         }
63719     };
63720
63721
63722     restrictions.tags = function() {};
63723     restrictions.focus = function() {};
63724
63725
63726     restrictions.off = function(selection) {
63727         if (!initialized) return;
63728
63729         selection.selectAll('.surface')
63730             .call(hover.off)
63731             .call(breathe.off)
63732             .on('click.restrictions', null)
63733             .on('mouseover.restrictions', null)
63734             .on('mouseout.restrictions', null);
63735
63736         context.history()
63737             .on('change.restrictions', null);
63738
63739         d3_select(window)
63740             .on('resize.restrictions', null);
63741     };
63742
63743
63744     return utilRebind(restrictions, dispatch$$1, 'on');
63745 }
63746
63747 function uiFieldTextarea(field) {
63748     var dispatch$$1 = dispatch('change'),
63749         input = d3_select(null);
63750
63751
63752     function textarea(selection) {
63753         input = selection.selectAll('textarea')
63754             .data([0]);
63755
63756         input = input.enter()
63757             .append('textarea')
63758             .attr('id', 'preset-input-' + field.id)
63759             .attr('placeholder', field.placeholder() || t('inspector.unknown'))
63760             .attr('maxlength', 255)
63761             .call(utilNoAuto)
63762             .on('input', change(true))
63763             .on('blur', change())
63764             .on('change', change())
63765             .merge(input);
63766     }
63767
63768
63769     function change(onInput) {
63770         return function() {
63771             var t$$1 = {};
63772             t$$1[field.key] = utilGetSetValue(input) || undefined;
63773             dispatch$$1.call('change', this, t$$1, onInput);
63774         };
63775     }
63776
63777
63778     textarea.tags = function(tags) {
63779         utilGetSetValue(input, tags[field.key] || '');
63780     };
63781
63782
63783     textarea.focus = function() {
63784         input.node().focus();
63785     };
63786
63787
63788     return utilRebind(textarea, dispatch$$1, 'on');
63789 }
63790
63791 function uiFieldWikipedia(field, context) {
63792     var dispatch$$1 = dispatch('change'),
63793         wikipedia = services.wikipedia,
63794         wikidata = services.wikidata,
63795         link = d3_select(null),
63796         lang = d3_select(null),
63797         title = d3_select(null),
63798         wikiURL = '',
63799         entity;
63800
63801
63802     function wiki(selection) {
63803         var langcombo = d3combobox()
63804             .container(context.container())
63805             .fetcher(function(value, cb) {
63806                 var v = value.toLowerCase();
63807
63808                 cb(wikipedia$2.filter(function(d) {
63809                     return d[0].toLowerCase().indexOf(v) >= 0 ||
63810                         d[1].toLowerCase().indexOf(v) >= 0 ||
63811                         d[2].toLowerCase().indexOf(v) >= 0;
63812                 }).map(function(d) {
63813                     return { value: d[1] };
63814                 }));
63815             });
63816
63817         var titlecombo = d3combobox()
63818             .container(context.container())
63819             .fetcher(function(value, cb) {
63820                 if (!value) {
63821                     value = context.entity(entity.id).tags.name || '';
63822                 }
63823
63824                 var searchfn = value.length > 7 ? wikipedia.search : wikipedia.suggestions;
63825                 searchfn(language()[2], value, function(query, data$$1) {
63826                     cb(data$$1.map(function(d) {
63827                         return { value: d };
63828                     }));
63829                 });
63830             });
63831
63832
63833         lang = selection.selectAll('input.wiki-lang')
63834             .data([0]);
63835
63836         lang = lang.enter()
63837             .append('input')
63838             .attr('type', 'text')
63839             .attr('class', 'wiki-lang')
63840             .attr('placeholder', t('translate.localized_translation_language'))
63841             .call(utilNoAuto)
63842             .merge(lang);
63843
63844         utilGetSetValue(lang, language()[1]);
63845
63846         lang
63847             .call(langcombo)
63848             .on('blur', changeLang)
63849             .on('change', changeLang);
63850
63851
63852         title = selection.selectAll('input.wiki-title')
63853             .data([0]);
63854
63855         title = title.enter()
63856             .append('input')
63857             .attr('type', 'text')
63858             .attr('class', 'wiki-title')
63859             .attr('id', 'preset-input-' + field.id)
63860             .call(utilNoAuto)
63861             .merge(title);
63862
63863         title
63864             .call(titlecombo)
63865             .on('blur', blur)
63866             .on('change', change);
63867
63868
63869         link = selection.selectAll('.wiki-link')
63870             .data([0]);
63871
63872         link = link.enter()
63873             .append('button')
63874             .attr('class', 'button-input-action wiki-link minor')
63875             .attr('tabindex', -1)
63876             .call(svgIcon('#icon-out-link'))
63877             .merge(link);
63878
63879         link
63880             .on('click', function() {
63881                 event.preventDefault();
63882                 if (wikiURL) window.open(wikiURL, '_blank');
63883             });
63884     }
63885
63886
63887     function language() {
63888         var value = utilGetSetValue(lang).toLowerCase();
63889         var locale = utilDetect().locale.toLowerCase();
63890         var localeLanguage;
63891         return find$1(wikipedia$2, function(d) {
63892             if (d[2] === locale) localeLanguage = d;
63893             return d[0].toLowerCase() === value ||
63894                 d[1].toLowerCase() === value ||
63895                 d[2] === value;
63896         }) || localeLanguage || ['English', 'English', 'en'];
63897     }
63898
63899
63900     function changeLang() {
63901         utilGetSetValue(lang, language()[1]);
63902         change(true);
63903     }
63904
63905
63906     function blur() {
63907         change(true);
63908     }
63909
63910
63911     function change(skipWikidata) {
63912         var value = utilGetSetValue(title),
63913             m = value.match(/https?:\/\/([-a-z]+)\.wikipedia\.org\/(?:wiki|\1-[-a-z]+)\/([^#]+)(?:#(.+))?/),
63914             l = m && find$1(wikipedia$2, function(d) { return m[1] === d[2]; }),
63915             syncTags = {};
63916
63917         if (l) {
63918             // Normalize title http://www.mediawiki.org/wiki/API:Query#Title_normalization
63919             value = decodeURIComponent(m[2]).replace(/_/g, ' ');
63920             if (m[3]) {
63921                 var anchor;
63922                 try {
63923                     // Best-effort `anchordecode:` implementation
63924                     anchor = decodeURIComponent(m[3].replace(/\.([0-9A-F]{2})/g, '%$1'));
63925                 } catch (e) {
63926                     anchor = decodeURIComponent(m[3]);
63927                 }
63928                 value += '#' + anchor.replace(/_/g, ' ');
63929             }
63930             value = value.slice(0, 1).toUpperCase() + value.slice(1);
63931             utilGetSetValue(lang, l[1]);
63932             utilGetSetValue(title, value);
63933         }
63934
63935         if (value) {
63936             syncTags.wikipedia = language()[2] + ':' + value;
63937         } else {
63938             syncTags.wikipedia = undefined;
63939             syncTags.wikidata = undefined;
63940         }
63941
63942         dispatch$$1.call('change', this, syncTags);
63943
63944
63945         if (skipWikidata || !value || !language()[2]) return;
63946
63947         // attempt asynchronous update of wikidata tag..
63948         var initGraph = context.graph(),
63949             initEntityId = entity.id;
63950
63951         wikidata.itemsByTitle(language()[2], value, function(title, data$$1) {
63952             // If graph has changed, we can't apply this update.
63953             if (context.graph() !== initGraph) return;
63954
63955             if (!data$$1 || !Object.keys(data$$1).length) return;
63956
63957             var qids = Object.keys(data$$1);
63958             var value = qids && find$1(qids, function(id) { return id.match(/^Q\d+$/); });
63959             var currTags = clone(context.entity(initEntityId).tags);
63960
63961             currTags.wikidata = value;
63962
63963             // Coalesce the update of wikidata tag into the previous tag change
63964             context.overwrite(
63965                 actionChangeTags(initEntityId, currTags),
63966                 context.history().undoAnnotation()
63967             );
63968
63969             // do not dispatch.call('change') here, because entity_editor
63970             // changeTags() is not intended to be called asynchronously
63971         });
63972     }
63973
63974
63975     wiki.tags = function(tags) {
63976         var value = tags[field.key] || '',
63977             m = value.match(/([^:]+):([^#]+)(?:#(.+))?/),
63978             l = m && find$1(wikipedia$2, function(d) { return m[1] === d[2]; }),
63979             anchor = m && m[3];
63980
63981         // value in correct format
63982         if (l) {
63983             utilGetSetValue(lang, l[1]);
63984             utilGetSetValue(title, m[2] + (anchor ? ('#' + anchor) : ''));
63985             if (anchor) {
63986                 try {
63987                     // Best-effort `anchorencode:` implementation
63988                     anchor = encodeURIComponent(anchor.replace(/ /g, '_')).replace(/%/g, '.');
63989                 } catch (e) {
63990                     anchor = anchor.replace(/ /g, '_');
63991                 }
63992             }
63993             wikiURL = 'https://' + m[1] + '.wikipedia.org/wiki/' +
63994                 m[2].replace(/ /g, '_') + (anchor ? ('#' + anchor) : '');
63995
63996         // unrecognized value format
63997         } else {
63998             utilGetSetValue(title, value);
63999             if (value && value !== '') {
64000                 utilGetSetValue(lang, '');
64001                 wikiURL = 'https://en.wikipedia.org/wiki/Special:Search?search=' + value;
64002             } else {
64003                 wikiURL = '';
64004             }
64005         }
64006     };
64007
64008
64009     wiki.entity = function(_) {
64010         if (!arguments.length) return entity;
64011         entity = _;
64012         return wiki;
64013     };
64014
64015
64016     wiki.focus = function() {
64017         title.node().focus();
64018     };
64019
64020
64021     return utilRebind(wiki, dispatch$$1, 'on');
64022 }
64023
64024 var uiFields = {
64025     access: uiFieldAccess,
64026     address: uiFieldAddress,
64027     check: uiFieldCheck,
64028     combo: uiFieldCombo,
64029     cycleway: uiFieldCycleway,
64030     defaultCheck: uiFieldCheck,
64031     email: uiFieldText,
64032     lanes: uiFieldLanes,
64033     localized: uiFieldLocalized,
64034     maxspeed: uiFieldMaxspeed,
64035     multiCombo: uiFieldCombo,
64036     networkCombo: uiFieldCombo,
64037     number: uiFieldText,
64038     onewayCheck: uiFieldCheck,
64039     radio: uiFieldRadio,
64040     restrictions: uiFieldRestrictions,
64041     semiCombo: uiFieldCombo,
64042     structureRadio: uiFieldRadio,
64043     tel: uiFieldText,
64044     text: uiFieldText,
64045     textarea: uiFieldTextarea,
64046     typeCombo: uiFieldCombo,
64047     url: uiFieldText,
64048     wikipedia: uiFieldWikipedia
64049 };
64050
64051 function uiField(context, presetField, entity, options) {
64052     options = assignIn({
64053         show: true,
64054         wrap: true,
64055         remove: true,
64056         revert: true,
64057         info: true
64058     }, options);
64059
64060     var dispatch$$1 = dispatch('change'),
64061         field = clone(presetField),
64062         show = options.show,
64063         state = '',
64064         tags = {};
64065
64066
64067     field.impl = uiFields[field.type](field, context)
64068         .on('change', function(t$$1, onInput) {
64069             dispatch$$1.call('change', field, t$$1, onInput);
64070         });
64071
64072     if (entity && field.impl.entity) {
64073         field.impl.entity(entity);
64074     }
64075
64076     field.keys = field.keys || [field.key];
64077
64078
64079     function isModified() {
64080         if (!entity) return false;
64081         var original = context.graph().base().entities[entity.id];
64082         return some(field.keys, function(key) {
64083             return original ? tags[key] !== original.tags[key] : tags[key];
64084         });
64085     }
64086
64087
64088     function isPresent() {
64089         return some(field.keys, function(key) {
64090             return tags[key];
64091         });
64092     }
64093
64094
64095     function revert(d) {
64096         event.stopPropagation();
64097         event.preventDefault();
64098         if (!entity) return false;
64099
64100         var original = context.graph().base().entities[entity.id],
64101             t$$1 = {};
64102         d.keys.forEach(function(key) {
64103             t$$1[key] = original ? original.tags[key] : undefined;
64104         });
64105
64106         dispatch$$1.call('change', d, t$$1);
64107     }
64108
64109
64110     function remove(d) {
64111         event.stopPropagation();
64112         event.preventDefault();
64113
64114         var t$$1 = {};
64115         d.keys.forEach(function(key) {
64116             t$$1[key] = undefined;
64117         });
64118
64119         dispatch$$1.call('change', d, t$$1);
64120     }
64121
64122
64123     field.render = function(selection) {
64124         var container = selection.selectAll('.form-field')
64125             .data([field]);
64126
64127         // Enter
64128         var enter = container.enter()
64129             .append('div')
64130             .attr('class', function(d) { return 'form-field form-field-' + d.id; })
64131             .classed('nowrap', !options.wrap);
64132
64133         if (options.wrap) {
64134             var label = enter
64135                 .append('label')
64136                 .attr('class', 'form-label')
64137                 .attr('for', function(d) { return 'preset-input-' + d.id; })
64138                 .text(function(d) { return d.label(); });
64139
64140             var wrap = label
64141                 .append('div')
64142                 .attr('class', 'form-label-button-wrap');
64143
64144             if (options.remove) {
64145                 wrap
64146                     .append('button')
64147                     .attr('class', 'remove-icon')
64148                     .attr('tabindex', -1)
64149                     .call(svgIcon('#operation-delete'));
64150             }
64151
64152             if (options.revert) {
64153                 wrap
64154                     .append('button')
64155                     .attr('class', 'modified-icon')
64156                     .attr('tabindex', -1)
64157                     .call(
64158                         (textDirection === 'rtl') ? svgIcon('#icon-redo') : svgIcon('#icon-undo')
64159                     );
64160             }
64161         }
64162
64163
64164         // Update
64165         container = container
64166             .merge(enter);
64167
64168         container.selectAll('.form-label-button-wrap .remove-icon')
64169             .on('click', remove);
64170
64171         container.selectAll('.form-label-button-wrap .modified-icon')
64172             .on('click', revert);
64173
64174         container
64175             .classed('modified', isModified())
64176             .classed('present', isPresent())
64177             .each(function(d) {
64178                 if (options.wrap && options.info) {
64179                     var referenceKey = d.key;
64180                     if (d.type === 'multiCombo') {   // lookup key without the trailing ':'
64181                         referenceKey = referenceKey.replace(/:$/, '');
64182                     }
64183                     var reference = uiTagReference(d.reference || { key: referenceKey }, context);
64184
64185                     if (state === 'hover') {
64186                         reference.showing(false);
64187                     }
64188                 }
64189
64190                 d3_select(this)
64191                     .call(d.impl);
64192
64193                 if (options.wrap && options.info) {
64194                     d3_select(this)
64195                         .call(reference.body)
64196                         .select('.form-label-button-wrap')
64197                         .call(reference.button);
64198                 }
64199
64200                 d.impl.tags(tags);
64201             });
64202     };
64203
64204
64205     field.state = function(_) {
64206         if (!arguments.length) return state;
64207         state = _;
64208         return field;
64209     };
64210
64211
64212     field.tags = function(_) {
64213         if (!arguments.length) return tags;
64214         tags = _;
64215         return field;
64216     };
64217
64218
64219     field.show = function() {
64220         show = true;
64221         if (field.default && field.key && tags[field.key] !== field.default) {
64222             var t$$1 = {};
64223             t$$1[field.key] = field.default;
64224             dispatch$$1.call('change', this, t$$1);
64225         }
64226     };
64227
64228
64229     field.isShown = function() {
64230         return show || some(field.keys, function(key) { return !!tags[key]; });
64231     };
64232
64233
64234     field.focus = function() {
64235         field.impl.focus();
64236     };
64237
64238
64239     return utilRebind(field, dispatch$$1, 'on');
64240 }
64241
64242 function uiFormFields(context) {
64243     var fieldsArr;
64244
64245
64246     function formFields(selection, klass) {
64247         render(selection, klass);
64248     }
64249
64250
64251     function render(selection, klass) {
64252
64253         var shown = fieldsArr.filter(function(field) { return field.isShown(); }),
64254             notShown = fieldsArr.filter(function(field) { return !field.isShown(); });
64255
64256         var container = selection.selectAll('.form-fields-container')
64257             .data([0]);
64258
64259         container = container.enter()
64260             .append('div')
64261             .attr('class', 'form-fields-container ' + (klass || ''))
64262             .merge(container);
64263
64264
64265         var fields = container.selectAll('.wrap-form-field')
64266             .data(shown, function(d) { return d.id; });
64267
64268         fields.exit()
64269             .remove();
64270
64271         // Enter
64272         var enter = fields.enter()
64273             .append('div')
64274             .attr('class', function(d) { return 'wrap-form-field wrap-form-field-' + d.id; });
64275
64276         // Update
64277         fields = fields
64278             .merge(enter);
64279
64280         fields
64281             .order()
64282             .each(function(d) {
64283                 d3_select(this)
64284                     .call(d.render);
64285             });
64286
64287
64288         notShown = notShown.map(function(field) {
64289             return {
64290                 title: field.label(),
64291                 value: field.label(),
64292                 field: field
64293             };
64294         });
64295
64296
64297         var more = selection.selectAll('.more-fields')
64298             .data((notShown.length > 0) ? [0] : []);
64299
64300         more.exit()
64301             .remove();
64302
64303         more = more.enter()
64304             .append('div')
64305             .attr('class', 'more-fields')
64306             .append('label')
64307             .text(t('inspector.add_fields'))
64308             .merge(more);
64309
64310
64311         var input = more.selectAll('.value')
64312             .data([0]);
64313
64314         input.exit()
64315             .remove();
64316
64317         input = input.enter()
64318             .append('input')
64319             .attr('class', 'value')
64320             .attr('type', 'text')
64321             .call(utilNoAuto)
64322             .merge(input);
64323
64324         input
64325             .call(utilGetSetValue, '')
64326             .attr('placeholder', function() {
64327                 var placeholder = [];
64328                 for (var field in notShown) {
64329                     placeholder.push(notShown[field].title);
64330                 }
64331                 return placeholder.slice(0,3).join(', ') + ((placeholder.length > 3) ? '…' : '');
64332             })
64333             .call(d3combobox()
64334                 .container(context.container())
64335                 .data(notShown)
64336                 .minItems(1)
64337                 .on('accept', function (d) {
64338                     var field = d.field;
64339                     field.show();
64340                     render(selection);
64341                     if (field.type !== 'semiCombo' && field.type !== 'multiCombo') {
64342                         field.focus();
64343                     }
64344                 })
64345             );
64346     }
64347
64348
64349     formFields.fieldsArr = function(_) {
64350         if (!arguments.length) return fieldsArr;
64351         fieldsArr = _;
64352         return formFields;
64353     };
64354
64355
64356     return formFields;
64357 }
64358
64359 function uiPresetEditor(context) {
64360     var dispatch$$1 = dispatch('change'),
64361         formFields = uiFormFields(context),
64362         state,
64363         fieldsArr,
64364         preset,
64365         tags,
64366         entityId;
64367
64368
64369     function presetEditor(selection) {
64370         selection.call(uiDisclosure(context, 'preset_fields', true)
64371             .title(t('inspector.all_fields'))
64372             .content(render)
64373         );
64374     }
64375
64376
64377     function render(selection) {
64378         if (!fieldsArr) {
64379             var entity = context.entity(entityId),
64380                 geometry = context.geometry(entityId),
64381                 presets = context.presets();
64382
64383             fieldsArr = [];
64384
64385             preset.fields.forEach(function(field) {
64386                 if (field.matchGeometry(geometry)) {
64387                     fieldsArr.push(
64388                         uiField(context, field, entity)
64389                     );
64390                 }
64391             });
64392
64393             if (entity.isHighwayIntersection(context.graph()) && presets.field('restrictions')) {
64394                 fieldsArr.push(
64395                     uiField(context, presets.field('restrictions'), entity)
64396                 );
64397             }
64398
64399             presets.universal().forEach(function(field) {
64400                 if (preset.fields.indexOf(field) === -1) {
64401                     fieldsArr.push(
64402                         uiField(context, field, entity, { show: false })
64403                     );
64404                 }
64405             });
64406
64407             fieldsArr.forEach(function(field) {
64408                 field
64409                     .on('change', function(t$$1, onInput) {
64410                         dispatch$$1.call('change', field, t$$1, onInput);
64411                     });
64412             });
64413         }
64414
64415         fieldsArr.forEach(function(field) {
64416             field
64417                 .state(state)
64418                 .tags(tags);
64419         });
64420
64421
64422         selection
64423             .call(formFields.fieldsArr(fieldsArr), 'inspector-inner fillL3');
64424
64425
64426         selection.selectAll('.wrap-form-field input')
64427             .on('keydown', function() {
64428                 // if user presses enter, and combobox is not active, accept edits..
64429                 if (event.keyCode === 13 && d3_select('.combobox').empty()) {
64430                     context.enter(modeBrowse(context));
64431                 }
64432             });
64433     }
64434
64435
64436     presetEditor.preset = function(_) {
64437         if (!arguments.length) return preset;
64438         if (preset && preset.id === _.id) return presetEditor;
64439         preset = _;
64440         fieldsArr = null;
64441         return presetEditor;
64442     };
64443
64444
64445     presetEditor.state = function(_) {
64446         if (!arguments.length) return state;
64447         state = _;
64448         return presetEditor;
64449     };
64450
64451
64452     presetEditor.tags = function(_) {
64453         if (!arguments.length) return tags;
64454         tags = _;
64455         // Don't reset fieldsArr here.
64456         return presetEditor;
64457     };
64458
64459
64460     presetEditor.entityID = function(_) {
64461         if (!arguments.length) return entityId;
64462         if (entityId === _) return presetEditor;
64463         entityId = _;
64464         fieldsArr = null;
64465         return presetEditor;
64466     };
64467
64468
64469     return utilRebind(presetEditor, dispatch$$1, 'on');
64470 }
64471
64472 function uiEntityEditor(context) {
64473     var dispatch$$1 = dispatch('choose'),
64474         state = 'select',
64475         coalesceChanges = false,
64476         modified = false,
64477         base,
64478         entityId,
64479         activePreset,
64480         reference;
64481
64482     var presetEditor = uiPresetEditor(context)
64483         .on('change', changeTags);
64484     var rawTagEditor = uiRawTagEditor(context)
64485         .on('change', changeTags);
64486
64487
64488     function entityEditor(selection) {
64489         var entity = context.entity(entityId),
64490             tags = clone(entity.tags);
64491
64492         // Header
64493         var header = selection.selectAll('.header')
64494             .data([0]);
64495
64496         // Enter
64497         var enter = header.enter()
64498             .append('div')
64499             .attr('class', 'header fillL cf');
64500
64501         enter
64502             .append('button')
64503             .attr('class', 'fl preset-reset preset-choose')
64504             .call(svgIcon((textDirection === 'rtl') ? '#icon-forward' : '#icon-backward'));
64505
64506         enter
64507             .append('button')
64508             .attr('class', 'fr preset-close')
64509             .on('click', function() { context.enter(modeBrowse(context)); })
64510             .call(svgIcon(modified ? '#icon-apply' : '#icon-close'));
64511
64512         enter
64513             .append('h3')
64514             .text(t('inspector.edit'));
64515
64516         // Update
64517         header = header
64518             .merge(enter);
64519
64520         header.selectAll('.preset-reset')
64521             .on('click', function() {
64522                 dispatch$$1.call('choose', this, activePreset);
64523             });
64524
64525
64526         // Body
64527         var body = selection.selectAll('.inspector-body')
64528             .data([0]);
64529
64530         // Enter
64531         enter = body.enter()
64532             .append('div')
64533             .attr('class', 'inspector-body');
64534
64535         enter
64536             .append('div')
64537             .attr('class', 'preset-list-item inspector-inner')
64538             .append('div')
64539             .attr('class', 'preset-list-button-wrap')
64540             .append('button')
64541             .attr('class', 'preset-list-button preset-reset')
64542             .call(tooltip().title(t('inspector.back_tooltip')).placement('bottom'))
64543             .append('div')
64544             .attr('class', 'label');
64545
64546         enter
64547             .append('div')
64548             .attr('class', 'inspector-border preset-editor');
64549
64550         enter
64551             .append('div')
64552             .attr('class', 'inspector-border raw-tag-editor inspector-inner');
64553
64554         enter
64555             .append('div')
64556             .attr('class', 'inspector-border raw-member-editor inspector-inner');
64557
64558         enter
64559             .append('div')
64560             .attr('class', 'raw-membership-editor inspector-inner');
64561
64562         enter
64563             .append('input')
64564             .attr('type', 'text')
64565             .attr('class', 'key-trap');
64566
64567
64568         // Update
64569         body = body
64570             .merge(enter);
64571
64572         body.selectAll('.preset-list-button-wrap')
64573             .call(reference.button);
64574
64575         body.selectAll('.preset-list-item')
64576             .call(reference.body);
64577
64578         body.selectAll('.preset-reset')
64579             .on('click', function() {
64580                 dispatch$$1.call('choose', this, activePreset);
64581             });
64582
64583         body.select('.preset-list-item button')
64584             .call(uiPresetIcon()
64585                 .geometry(context.geometry(entityId))
64586                 .preset(activePreset)
64587             );
64588
64589         body.select('.preset-list-item .label')
64590             .text(activePreset.name());
64591
64592         body.select('.preset-editor')
64593             .call(presetEditor
64594                 .preset(activePreset)
64595                 .entityID(entityId)
64596                 .tags(tags)
64597                 .state(state)
64598             );
64599
64600         body.select('.raw-tag-editor')
64601             .call(rawTagEditor
64602                 .preset(activePreset)
64603                 .entityID(entityId)
64604                 .tags(tags)
64605                 .state(state)
64606             );
64607
64608         if (entity.type === 'relation') {
64609             body.select('.raw-member-editor')
64610                 .style('display', 'block')
64611                 .call(uiRawMemberEditor(context)
64612                     .entityID(entityId)
64613                 );
64614         } else {
64615             body.select('.raw-member-editor')
64616                 .style('display', 'none');
64617         }
64618
64619         body.select('.raw-membership-editor')
64620             .call(uiRawMembershipEditor(context)
64621                 .entityID(entityId)
64622             );
64623
64624         body.select('.key-trap')
64625             .on('keydown.key-trap', function() {
64626                 // On tabbing, send focus back to the first field on the inspector-body
64627                 // (probably the `name` field) #4159
64628                 if (event.keyCode === 9 && !event.shiftKey) {
64629                     event.preventDefault();
64630                     body.select('input').node().focus();
64631                 }
64632             });
64633
64634         context.history()
64635             .on('change.entity-editor', historyChanged);
64636
64637
64638         function historyChanged() {
64639             if (state === 'hide') return;
64640
64641             var entity = context.hasEntity(entityId);
64642             var graph = context.graph();
64643             if (!entity) return;
64644
64645             var match = context.presets().match(entity, graph);
64646             var activePreset = entityEditor.preset();
64647             var weakPreset = activePreset && isEmpty(activePreset.addTags);
64648
64649             // A "weak" preset doesn't set any tags. (e.g. "Address")
64650             // Don't replace a weak preset with a fallback preset (e.g. "Point")
64651             if (!(weakPreset && match.isFallback())) {
64652                 entityEditor.preset(match);
64653             }
64654             entityEditor.modified(base !== graph);
64655             entityEditor(selection);
64656         }
64657     }
64658
64659
64660     function clean(o) {
64661
64662         function cleanVal(k, v) {
64663             function keepSpaces(k) {
64664                 return k.match(/_hours|_times/) !== null;
64665             }
64666
64667             var blacklist = ['description', 'note', 'fixme'];
64668             if (some(blacklist, function(s) { return k.indexOf(s) !== -1; })) return v;
64669
64670             var cleaned = v.split(';')
64671                 .map(function(s) { return s.trim(); })
64672                 .join(keepSpaces(k) ? '; ' : ';');
64673
64674             // The code below is not intended to validate websites and emails.
64675             // It is only intended to prevent obvious copy-paste errors. (#2323)
64676             // clean website- and email-like tags
64677             if (k.indexOf('website') !== -1 ||
64678                 k.indexOf('email') !== -1 ||
64679                 cleaned.indexOf('http') === 0) {
64680                 cleaned = cleaned
64681                     .replace(/[\u200B-\u200F\uFEFF]/g, '');  // strip LRM and other zero width chars
64682
64683             }
64684
64685             return cleaned;
64686         }
64687
64688         var out = {}, k, v;
64689         for (k in o) {
64690             if (k && (v = o[k]) !== undefined) {
64691                 out[k] = cleanVal(k, v);
64692             }
64693         }
64694         return out;
64695     }
64696
64697
64698     // Tag changes that fire on input can all get coalesced into a single
64699     // history operation when the user leaves the field.  #2342
64700     function changeTags(changed, onInput) {
64701         var entity = context.entity(entityId),
64702             annotation = t('operations.change_tags.annotation'),
64703             tags = clone(entity.tags);
64704
64705         forEach(changed, function(v, k) {
64706             if (v !== undefined || tags.hasOwnProperty(k)) {
64707                 tags[k] = v;
64708             }
64709         });
64710
64711         if (!onInput) {
64712             tags = clean(tags);
64713         }
64714
64715         if (!isEqual(entity.tags, tags)) {
64716             if (coalesceChanges) {
64717                 context.overwrite(actionChangeTags(entityId, tags), annotation);
64718             } else {
64719                 context.perform(actionChangeTags(entityId, tags), annotation);
64720                 coalesceChanges = !!onInput;
64721             }
64722         }
64723     }
64724
64725
64726     entityEditor.modified = function(_) {
64727         if (!arguments.length) return modified;
64728         modified = _;
64729         d3_selectAll('button.preset-close use')
64730             .attr('xlink:href', (modified ? '#icon-apply' : '#icon-close'));
64731     };
64732
64733
64734     entityEditor.state = function(_) {
64735         if (!arguments.length) return state;
64736         state = _;
64737         return entityEditor;
64738     };
64739
64740
64741     entityEditor.entityID = function(_) {
64742         if (!arguments.length) return entityId;
64743         entityId = _;
64744         base = context.graph();
64745         entityEditor.preset(context.presets().match(context.entity(entityId), base));
64746         entityEditor.modified(false);
64747         coalesceChanges = false;
64748         return entityEditor;
64749     };
64750
64751
64752     entityEditor.preset = function(_) {
64753         if (!arguments.length) return activePreset;
64754         if (_ !== activePreset) {
64755             activePreset = _;
64756             reference = uiTagReference(activePreset.reference(context.geometry(entityId)), context)
64757                 .showing(false);
64758         }
64759         return entityEditor;
64760     };
64761
64762
64763     return utilRebind(entityEditor, dispatch$$1, 'on');
64764 }
64765
64766 function uiPresetList(context) {
64767     var dispatch$$1 = dispatch('choose'),
64768         id,
64769         currentPreset,
64770         autofocus = false;
64771
64772
64773     function presetList(selection) {
64774         var entity = context.entity(id),
64775             geometry = context.geometry(id);
64776
64777         // Treat entities on addr:interpolation lines as points, not vertices (#3241)
64778         if (geometry === 'vertex' && entity.isOnAddressLine(context.graph())) {
64779             geometry = 'point';
64780         }
64781
64782         var presets = context.presets().matchGeometry(geometry);
64783
64784         selection.html('');
64785
64786         var messagewrap = selection
64787             .append('div')
64788             .attr('class', 'header fillL cf');
64789
64790         var message = messagewrap
64791             .append('h3')
64792             .text(t('inspector.choose'));
64793
64794         if (context.entity(id).isUsed(context.graph())) {
64795             messagewrap
64796                 .append('button')
64797                 .attr('class', 'preset-choose')
64798                 .on('click', function() { dispatch$$1.call('choose', this, currentPreset); })
64799                 .call(svgIcon((textDirection === 'rtl') ? '#icon-backward' : '#icon-forward'));
64800         } else {
64801             messagewrap
64802                 .append('button')
64803                 .attr('class', 'close')
64804                 .on('click', function() {
64805                     context.enter(modeBrowse(context));
64806                 })
64807                 .call(svgIcon('#icon-close'));
64808         }
64809
64810         function keydown() {
64811             // hack to let delete shortcut work when search is autofocused
64812             if (search.property('value').length === 0 &&
64813                 (event.keyCode === d3keybinding.keyCodes['⌫'] ||
64814                  event.keyCode === d3keybinding.keyCodes['⌦'])) {
64815                 event.preventDefault();
64816                 event.stopPropagation();
64817                 operationDelete([id], context)();
64818             } else if (search.property('value').length === 0 &&
64819                 (event.ctrlKey || event.metaKey) &&
64820                 event.keyCode === d3keybinding.keyCodes.z) {
64821                 event.preventDefault();
64822                 event.stopPropagation();
64823                 context.undo();
64824             } else if (!event.ctrlKey && !event.metaKey) {
64825                 d3_select(this).on('keydown', null);
64826             }
64827         }
64828
64829         function keypress() {
64830             // enter
64831             var value = search.property('value');
64832             if (event.keyCode === 13 && value.length) {
64833                 list.selectAll('.preset-list-item:first-child').datum().choose();
64834             }
64835         }
64836
64837         function inputevent() {
64838             var value = search.property('value');
64839             list.classed('filtered', value.length);
64840             if (value.length) {
64841                 var results = presets.search(value, geometry);
64842                 message.text(t('inspector.results', {
64843                     n: results.collection.length,
64844                     search: value
64845                 }));
64846                 list.call(drawList, results);
64847             } else {
64848                 list.call(drawList, context.presets().defaults(geometry, 36));
64849                 message.text(t('inspector.choose'));
64850             }
64851         }
64852
64853         var searchWrap = selection
64854             .append('div')
64855             .attr('class', 'search-header');
64856
64857         var search = searchWrap
64858             .append('input')
64859             .attr('class', 'preset-search-input')
64860             .attr('placeholder', t('inspector.search'))
64861             .attr('type', 'search')
64862             .call(utilNoAuto)
64863             .on('keydown', keydown)
64864             .on('keypress', keypress)
64865             .on('input', inputevent);
64866
64867         searchWrap
64868             .call(svgIcon('#icon-search', 'pre-text'));
64869
64870         if (autofocus) {
64871             search.node().focus();
64872         }
64873
64874         var listWrap = selection
64875             .append('div')
64876             .attr('class', 'inspector-body');
64877
64878         var list = listWrap
64879             .append('div')
64880             .attr('class', 'preset-list fillL cf')
64881             .call(drawList, context.presets().defaults(geometry, 36));
64882     }
64883
64884
64885     function drawList(list, presets) {
64886         var collection = presets.collection.map(function(preset) {
64887             return preset.members ? CategoryItem(preset) : PresetItem(preset);
64888         });
64889
64890         var items = list.selectAll('.preset-list-item')
64891             .data(collection, function(d) { return d.preset.id; });
64892
64893         items.order();
64894
64895         items.exit()
64896             .remove();
64897
64898         items.enter()
64899             .append('div')
64900             .attr('class', function(item) { return 'preset-list-item preset-' + item.preset.id.replace('/', '-'); })
64901             .classed('current', function(item) { return item.preset === currentPreset; })
64902             .each(function(item) { d3_select(this).call(item); })
64903             .style('opacity', 0)
64904             .transition()
64905             .style('opacity', 1);
64906     }
64907
64908
64909     function CategoryItem(preset) {
64910         var box, sublist, shown = false;
64911
64912         function item(selection) {
64913             var wrap = selection.append('div')
64914                 .attr('class', 'preset-list-button-wrap category col12');
64915
64916             var button = wrap
64917                 .append('button')
64918                 .attr('class', 'preset-list-button')
64919                 .classed('expanded', false)
64920                 .call(uiPresetIcon()
64921                     .geometry(context.geometry(id))
64922                     .preset(preset))
64923                 .on('click', function() {
64924                     var isExpanded = d3_select(this).classed('expanded');
64925                     var iconName = isExpanded ?
64926                         (textDirection === 'rtl' ? '#icon-backward' : '#icon-forward') : '#icon-down';
64927                     d3_select(this)
64928                         .classed('expanded', !isExpanded);
64929                     d3_select(this).selectAll('div.label svg.icon use')
64930                         .attr('href', iconName);
64931                     item.choose();
64932                 });
64933
64934             var label = button
64935                 .append('div')
64936                 .attr('class', 'label');
64937
64938             label
64939                 .call(svgIcon((textDirection === 'rtl' ? '#icon-backward' : '#icon-forward'), 'inline'))
64940                 .append('span')
64941                 .html(function() { return preset.name() + '&hellip;'; });
64942
64943             box = selection.append('div')
64944                 .attr('class', 'subgrid col12')
64945                 .style('max-height', '0px')
64946                 .style('opacity', 0);
64947
64948             box.append('div')
64949                 .attr('class', 'arrow');
64950
64951             sublist = box.append('div')
64952                 .attr('class', 'preset-list fillL3 cf fl');
64953         }
64954
64955
64956         item.choose = function() {
64957             if (!box || !sublist) return;
64958
64959             if (shown) {
64960                 shown = false;
64961                 box.transition()
64962                     .duration(200)
64963                     .style('opacity', '0')
64964                     .style('max-height', '0px')
64965                     .style('padding-bottom', '0px');
64966             } else {
64967                 shown = true;
64968                 sublist.call(drawList, preset.members);
64969                 box.transition()
64970                     .duration(200)
64971                     .style('opacity', '1')
64972                     .style('max-height', 200 + preset.members.collection.length * 190 + 'px')
64973                     .style('padding-bottom', '20px');
64974             }
64975         };
64976
64977         item.preset = preset;
64978
64979         return item;
64980     }
64981
64982
64983     function PresetItem(preset) {
64984         function item(selection) {
64985             var wrap = selection.append('div')
64986                 .attr('class', 'preset-list-button-wrap col12');
64987
64988             wrap.append('button')
64989                 .attr('class', 'preset-list-button')
64990                 .call(uiPresetIcon()
64991                     .geometry(context.geometry(id))
64992                     .preset(preset))
64993                 .on('click', item.choose)
64994                 .append('div')
64995                 .attr('class', 'label')
64996                 .text(preset.name());
64997
64998             wrap.call(item.reference.button);
64999             selection.call(item.reference.body);
65000         }
65001
65002         item.choose = function() {
65003             context.presets().choose(preset);
65004
65005             context.perform(
65006                 actionChangePreset(id, currentPreset, preset),
65007                 t('operations.change_tags.annotation')
65008             );
65009
65010             dispatch$$1.call('choose', this, preset);
65011         };
65012
65013         item.help = function() {
65014             event.stopPropagation();
65015             item.reference.toggle();
65016         };
65017
65018         item.preset = preset;
65019         item.reference = uiTagReference(preset.reference(context.geometry(id)), context);
65020
65021         return item;
65022     }
65023
65024
65025     presetList.autofocus = function(_) {
65026         if (!arguments.length) return autofocus;
65027         autofocus = _;
65028         return presetList;
65029     };
65030
65031
65032     presetList.entityID = function(_) {
65033         if (!arguments.length) return id;
65034         id = _;
65035         presetList.preset(context.presets().match(context.entity(id), context.graph()));
65036         return presetList;
65037     };
65038
65039
65040     presetList.preset = function(_) {
65041         if (!arguments.length) return currentPreset;
65042         currentPreset = _;
65043         return presetList;
65044     };
65045
65046
65047     return utilRebind(presetList, dispatch$$1, 'on');
65048 }
65049
65050 function uiViewOnOSM(context) {
65051     var id;
65052
65053     function viewOnOSM(selection) {
65054         var entity = context.entity(id);
65055
65056         selection.style('display', entity.isNew() ? 'none' : null);
65057
65058         var link = selection.selectAll('.view-on-osm')
65059             .data([0]);
65060
65061         var enter = link.enter()
65062             .append('a')
65063             .attr('class', 'view-on-osm')
65064             .attr('target', '_blank')
65065             .call(svgIcon('#icon-out-link', 'inline'));
65066
65067         enter
65068             .append('span')
65069             .text(t('inspector.view_on_osm'));
65070
65071         link
65072             .merge(enter)
65073             .attr('href', context.connection().entityURL(entity));
65074     }
65075
65076
65077     viewOnOSM.entityID = function(_) {
65078         if (!arguments.length) return id;
65079         id = _;
65080         return viewOnOSM;
65081     };
65082
65083     return viewOnOSM;
65084 }
65085
65086 function uiInspector(context) {
65087     var presetList = uiPresetList(context),
65088         entityEditor = uiEntityEditor(context),
65089         state = 'select',
65090         entityID,
65091         newFeature = false;
65092
65093
65094     function inspector(selection) {
65095         presetList
65096             .entityID(entityID)
65097             .autofocus(newFeature)
65098             .on('choose', setPreset);
65099
65100         entityEditor
65101             .state(state)
65102             .entityID(entityID)
65103             .on('choose', showList);
65104
65105         var wrap = selection.selectAll('.panewrap')
65106             .data([0]);
65107
65108         var enter = wrap.enter()
65109             .append('div')
65110             .attr('class', 'panewrap');
65111
65112         enter
65113             .append('div')
65114             .attr('class', 'preset-list-pane pane');
65115
65116         enter
65117             .append('div')
65118             .attr('class', 'entity-editor-pane pane');
65119
65120         wrap = wrap.merge(enter);
65121         var presetPane = wrap.selectAll('.preset-list-pane');
65122         var editorPane = wrap.selectAll('.entity-editor-pane');
65123
65124         var graph = context.graph(),
65125             entity = context.entity(entityID),
65126             showEditor = state === 'hover' ||
65127                 entity.isUsed(graph) ||
65128                 entity.isHighwayIntersection(graph);
65129
65130         if (showEditor) {
65131             wrap.style('right', '0%');
65132             editorPane.call(entityEditor);
65133         } else {
65134             wrap.style('right', '-100%');
65135             presetPane.call(presetList);
65136         }
65137
65138         var footer = selection.selectAll('.footer')
65139             .data([0]);
65140
65141         footer = footer.enter()
65142             .append('div')
65143             .attr('class', 'footer')
65144             .merge(footer);
65145
65146         footer
65147             .call(uiViewOnOSM(context).entityID(entityID));
65148
65149
65150         function showList(preset) {
65151             wrap.transition()
65152                 .styleTween('right', function() { return d3_interpolate('0%', '-100%'); });
65153
65154             presetPane
65155                 .call(presetList.preset(preset).autofocus(true));
65156         }
65157
65158
65159         function setPreset(preset) {
65160             wrap.transition()
65161                 .styleTween('right', function() { return d3_interpolate('-100%', '0%'); });
65162
65163             editorPane
65164                 .call(entityEditor.preset(preset));
65165         }
65166     }
65167
65168
65169     inspector.state = function(_) {
65170         if (!arguments.length) return state;
65171         state = _;
65172         entityEditor.state(state);
65173         return inspector;
65174     };
65175
65176
65177     inspector.entityID = function(_) {
65178         if (!arguments.length) return entityID;
65179         entityID = _;
65180         return inspector;
65181     };
65182
65183
65184     inspector.newFeature = function(_) {
65185         if (!arguments.length) return newFeature;
65186         newFeature = _;
65187         return inspector;
65188     };
65189
65190
65191     return inspector;
65192 }
65193
65194 function uiSidebar(context) {
65195     var inspector = uiInspector(context),
65196         current;
65197
65198
65199     function sidebar(selection) {
65200         var featureListWrap = selection
65201             .append('div')
65202             .attr('class', 'feature-list-pane')
65203             .call(uiFeatureList(context));
65204
65205
65206         var inspectorWrap = selection
65207             .append('div')
65208             .attr('class', 'inspector-hidden inspector-wrap fr');
65209
65210
65211         function hover(id) {
65212             if (!current && context.hasEntity(id)) {
65213                 featureListWrap
65214                     .classed('inspector-hidden', true);
65215
65216                 inspectorWrap
65217                     .classed('inspector-hidden', false)
65218                     .classed('inspector-hover', true);
65219
65220                 if (inspector.entityID() !== id || inspector.state() !== 'hover') {
65221                     inspector
65222                         .state('hover')
65223                         .entityID(id);
65224
65225                     inspectorWrap
65226                         .call(inspector);
65227                 }
65228
65229             } else if (!current) {
65230                 featureListWrap
65231                     .classed('inspector-hidden', false);
65232                 inspectorWrap
65233                     .classed('inspector-hidden', true);
65234                 inspector
65235                     .state('hide');
65236             }
65237         }
65238
65239
65240         sidebar.hover = throttle(hover, 200);
65241
65242
65243         sidebar.select = function(id, newFeature) {
65244             if (!current && id) {
65245                 featureListWrap
65246                     .classed('inspector-hidden', true);
65247
65248                 inspectorWrap
65249                     .classed('inspector-hidden', false)
65250                     .classed('inspector-hover', false);
65251
65252                 if (inspector.entityID() !== id || inspector.state() !== 'select') {
65253                     inspector
65254                         .state('select')
65255                         .entityID(id)
65256                         .newFeature(newFeature);
65257
65258                     inspectorWrap
65259                         .call(inspector);
65260                 }
65261
65262             } else if (!current) {
65263                 featureListWrap
65264                     .classed('inspector-hidden', false);
65265                 inspectorWrap
65266                     .classed('inspector-hidden', true);
65267                 inspector
65268                     .state('hide');
65269             }
65270         };
65271
65272
65273         sidebar.show = function(component) {
65274             featureListWrap
65275                 .classed('inspector-hidden', true);
65276             inspectorWrap
65277                 .classed('inspector-hidden', true);
65278
65279             if (current) current.remove();
65280             current = selection
65281                 .append('div')
65282                 .attr('class', 'sidebar-component')
65283                 .call(component);
65284         };
65285
65286
65287         sidebar.hide = function() {
65288             featureListWrap
65289                 .classed('inspector-hidden', false);
65290             inspectorWrap
65291                 .classed('inspector-hidden', true);
65292
65293             if (current) current.remove();
65294             current = null;
65295         };
65296     }
65297
65298
65299     sidebar.hover = function() {};
65300     sidebar.hover.cancel = function() {};
65301     sidebar.select = function() {};
65302     sidebar.show = function() {};
65303     sidebar.hide = function() {};
65304
65305     return sidebar;
65306 }
65307
65308 function uiSpinner(context) {
65309     var osm = context.connection();
65310
65311
65312     return function(selection) {
65313         var img = selection
65314             .append('img')
65315             .attr('src', context.imagePath('loader-black.gif'))
65316             .style('opacity', 0);
65317
65318         if (osm) {
65319             osm
65320                 .on('loading.spinner', function() {
65321                     img.transition()
65322                         .style('opacity', 1);
65323                 })
65324                 .on('loaded.spinner', function() {
65325                     img.transition()
65326                         .style('opacity', 0);
65327                 });
65328         }
65329     };
65330 }
65331
65332 function uiSplash(context) {
65333
65334     return function(selection) {
65335         if (context.storage('sawSplash'))
65336              return;
65337
65338         context.storage('sawSplash', true);
65339
65340         var modalSelection = uiModal(selection);
65341
65342         modalSelection.select('.modal')
65343             .attr('class', 'modal-splash modal col6');
65344
65345         var introModal = modalSelection.select('.content')
65346             .append('div')
65347             .attr('class', 'fillL');
65348
65349         introModal
65350             .append('div')
65351             .attr('class','modal-section cf')
65352             .append('h3').text(t('splash.welcome'));
65353
65354         introModal
65355             .append('div')
65356             .attr('class','modal-section')
65357             .append('p')
65358             .html(t('splash.text', {
65359                 version: context.version,
65360                 website: '<a href="http://ideditor.com/">ideditor.com</a>',
65361                 github: '<a href="https://github.com/openstreetmap/iD">github.com</a>'
65362             }));
65363
65364         var buttonWrap = introModal
65365             .append('div')
65366             .attr('class', 'modal-actions cf');
65367
65368         var walkthrough = buttonWrap
65369             .append('button')
65370             .attr('class', 'walkthrough col6')
65371             .on('click', function() {
65372                 context.container().call(uiIntro(context));
65373                 modalSelection.close();
65374             });
65375
65376         walkthrough
65377             .append('svg')
65378             .attr('class', 'logo logo-walkthrough')
65379             .append('use')
65380             .attr('xlink:href', '#logo-walkthrough');
65381
65382         walkthrough
65383             .append('div')
65384             .text(t('splash.walkthrough'));
65385
65386         var startEditing = buttonWrap
65387             .append('button')
65388             .attr('class', 'start-editing col6')
65389             .on('click', modalSelection.close);
65390
65391         startEditing
65392             .append('svg')
65393             .attr('class', 'logo logo-features')
65394             .append('use')
65395             .attr('xlink:href', '#logo-features');
65396
65397         startEditing
65398             .append('div')
65399             .text(t('splash.start'));
65400
65401
65402         modalSelection.select('button.close')
65403             .attr('class','hide');
65404
65405     };
65406 }
65407
65408 function uiStatus(context) {
65409     var osm = context.connection();
65410
65411
65412     return function(selection) {
65413         if (!osm) return;
65414
65415         function update() {
65416             osm.status(function(err, apiStatus) {
65417                 selection.html('');
65418
65419                 if (err) {
65420                     if (apiStatus === 'connectionSwitched') {
65421                         // if the connection was just switched, we can't rely on
65422                         // the status (we're getting the status of the previous api)
65423                         return;
65424
65425                     } else if (apiStatus === 'rateLimited') {
65426                         selection
65427                             .text(t('status.rateLimit'))
65428                             .append('a')
65429                             .attr('class', 'api-status-login')
65430                             .attr('target', '_blank')
65431                             .call(svgIcon('#icon-out-link', 'inline'))
65432                             .append('span')
65433                             .text(t('login'))
65434                             .on('click.login', function() {
65435                                 event.preventDefault();
65436                                 osm.authenticate();
65437                             });
65438                     } else {
65439                         // eslint-disable-next-line no-warning-comments
65440                         // TODO: nice messages for different error types
65441                         selection.text(t('status.error'));
65442                     }
65443
65444                 } else if (apiStatus === 'readonly') {
65445                     selection.text(t('status.readonly'));
65446                 } else if (apiStatus === 'offline') {
65447                     selection.text(t('status.offline'));
65448                 }
65449
65450                 selection.attr('class', 'api-status ' + (err ? 'error' : apiStatus));
65451             });
65452         }
65453
65454         osm.on('change', function() { update(selection); });
65455
65456         window.setInterval(update, 90000);
65457         update(selection);
65458     };
65459 }
65460
65461 function uiUndoRedo(context) {
65462     var commands = [{
65463         id: 'undo',
65464         cmd: uiCmd('⌘Z'),
65465         action: function() { if (editable()) context.undo(); },
65466         annotation: function() { return context.history().undoAnnotation(); }
65467     }, {
65468         id: 'redo',
65469         cmd: uiCmd('⌘⇧Z'),
65470         action: function() { if (editable()) context.redo(); },
65471         annotation: function() { return context.history().redoAnnotation(); }
65472     }];
65473
65474
65475     function editable() {
65476         var mode = context.mode();
65477         return context.editable() && mode && mode.id !== 'save';
65478     }
65479
65480
65481     return function(selection) {
65482         var tooltipBehavior = tooltip()
65483             .placement('bottom')
65484             .html(true)
65485             .title(function (d) {
65486                 return uiTooltipHtml(d.annotation() ?
65487                     t(d.id + '.tooltip', {action: d.annotation()}) :
65488                     t(d.id + '.nothing'), d.cmd);
65489             });
65490
65491         var buttons = selection.selectAll('button')
65492             .data(commands)
65493             .enter()
65494             .append('button')
65495             .attr('class', function(d) { return 'col6 disabled ' + d.id + '-button'; })
65496             .on('click', function(d) { return d.action(); })
65497             .call(tooltipBehavior);
65498
65499         buttons.each(function(d) {
65500             var iconName = d.id;
65501             if (textDirection === 'rtl') {
65502                 if (iconName === 'undo') {
65503                     iconName = 'redo';
65504                 } else if (iconName === 'redo') {
65505                     iconName = 'undo';
65506                 }
65507             }
65508             d3_select(this)
65509                 .call(svgIcon('#icon-' + iconName));
65510         });
65511
65512         var keybinding = d3keybinding('undo')
65513             .on(commands[0].cmd, function() { event.preventDefault(); commands[0].action(); })
65514             .on(commands[1].cmd, function() { event.preventDefault(); commands[1].action(); });
65515
65516         d3_select(document)
65517             .call(keybinding);
65518
65519
65520         var debouncedUpdate = debounce(update, 500, { leading: true, trailing: true });
65521
65522         context.map()
65523             .on('move.undo_redo', debouncedUpdate)
65524             .on('drawn.undo_redo', debouncedUpdate);
65525
65526         context.history()
65527             .on('change.undo_redo', update);
65528
65529         context
65530             .on('enter.undo_redo', update);
65531
65532
65533         function update() {
65534             buttons
65535                 .property('disabled', !editable())
65536                 .classed('disabled', function(d) { return !d.annotation(); })
65537                 .each(function() {
65538                     var selection = d3_select(this);
65539                     if (selection.property('tooltipVisible')) {
65540                         selection.call(tooltipBehavior.show);
65541                     }
65542                 });
65543         }
65544     };
65545 }
65546
65547 // these are module variables so they are preserved through a ui.restart()
65548 var sawVersion = null;
65549 var isNewVersion = false;
65550 var isNewUser = false;
65551
65552
65553 function uiVersion(context) {
65554
65555     var currVersion = context.version,
65556         matchedVersion = currVersion.match(/\d\.\d\.\d.*/);
65557
65558     if (sawVersion === null && matchedVersion !== null) {
65559         isNewVersion = (context.storage('sawVersion') !== currVersion);
65560         isNewUser = !context.storage('sawSplash');
65561         context.storage('sawVersion', currVersion);
65562         sawVersion = currVersion;
65563     }
65564
65565     return function(selection) {
65566         selection
65567             .append('a')
65568             .attr('target', '_blank')
65569             .attr('tabindex', -1)
65570             .attr('href', 'https://github.com/openstreetmap/iD')
65571             .text(currVersion);
65572
65573         // only show new version indicator to users that have used iD before
65574         if (isNewVersion && !isNewUser) {
65575             selection
65576                 .append('div')
65577                 .attr('class', 'badge')
65578                 .append('a')
65579                 .attr('target', '_blank')
65580                 .attr('tabindex', -1)
65581                 .attr('href', 'https://github.com/openstreetmap/iD/blob/master/CHANGELOG.md#whats-new')
65582                 .call(svgIcon('#gift-11'))
65583                 .call(tooltip()
65584                     .title(t('version.whats_new', { version: currVersion }))
65585                     .placement('top')
65586                 );
65587         }
65588     };
65589 }
65590
65591 function uiZoom(context) {
65592     var zooms = [{
65593         id: 'zoom-in',
65594         icon: 'plus',
65595         title: t('zoom.in'),
65596         action: context.zoomIn,
65597         key: '+'
65598     }, {
65599         id: 'zoom-out',
65600         icon: 'minus',
65601         title: t('zoom.out'),
65602         action: context.zoomOut,
65603         key: '-'
65604     }];
65605
65606
65607     function zoomIn() {
65608         event.preventDefault();
65609         context.zoomIn();
65610     }
65611
65612
65613     function zoomOut() {
65614         event.preventDefault();
65615         context.zoomOut();
65616     }
65617
65618
65619     function zoomInFurther() {
65620         event.preventDefault();
65621         context.zoomInFurther();
65622     }
65623
65624
65625     function zoomOutFurther() {
65626         event.preventDefault();
65627         context.zoomOutFurther();
65628     }
65629
65630
65631     return function(selection) {
65632         var button = selection.selectAll('button')
65633             .data(zooms)
65634             .enter()
65635             .append('button')
65636             .attr('tabindex', -1)
65637             .attr('class', function(d) { return d.id; })
65638             .on('click.editor', function(d) { d.action(); })
65639             .call(tooltip()
65640                 .placement((textDirection === 'rtl') ? 'right' : 'left')
65641                 .html(true)
65642                 .title(function(d) {
65643                     return uiTooltipHtml(d.title, d.key);
65644                 })
65645             );
65646
65647         button.each(function(d) {
65648             d3_select(this)
65649                 .call(svgIcon('#icon-' + d.icon, 'light'));
65650         });
65651
65652         var keybinding = d3keybinding('zoom');
65653
65654         ['plus', 'ffplus', '=', 'ffequals'].forEach(function(key) {
65655             keybinding.on([key], zoomIn);
65656             keybinding.on([uiCmd('⌘' + key)], zoomInFurther);
65657         });
65658
65659         ['_', '-', 'ffminus', 'dash'].forEach(function(key) {
65660             keybinding.on([key], zoomOut);
65661             keybinding.on([uiCmd('⌘' + key)], zoomOutFurther);
65662         });
65663
65664         d3_select(document)
65665             .call(keybinding);
65666     };
65667 }
65668
65669 function uiInit(context) {
65670     var uiInitCounter = 0;
65671
65672
65673     function render(container) {
65674         container
65675             .attr('dir', textDirection);
65676
65677         var map = context.map();
65678
65679         var hash = behaviorHash(context);
65680         hash();
65681
65682         if (!hash.hadHash) {
65683             map.centerZoom([0, 0], 2);
65684         }
65685
65686         container
65687             .append('svg')
65688             .attr('id', 'defs')
65689             .call(svgDefs(context));
65690
65691         container
65692             .append('div')
65693             .attr('id', 'sidebar')
65694             .attr('class', 'col4')
65695             .call(ui.sidebar);
65696
65697         var content = container
65698             .append('div')
65699             .attr('id', 'content')
65700             .attr('class', 'active');
65701
65702         var bar = content
65703             .append('div')
65704             .attr('id', 'bar')
65705             .attr('class', 'fillD');
65706
65707         content
65708             .append('div')
65709             .attr('id', 'map')
65710             .attr('dir', 'ltr')
65711             .call(map);
65712
65713         content
65714             .call(uiMapInMap(context))
65715             .call(uiInfo(context))
65716             .call(uiNotice(context));
65717
65718         bar
65719             .append('div')
65720             .attr('class', 'spacer col4');
65721
65722         var limiter = bar.append('div')
65723             .attr('class', 'limiter');
65724
65725         limiter
65726             .append('div')
65727             .attr('class', 'button-wrap joined col3')
65728             .call(uiModes(context), limiter);
65729
65730         limiter
65731             .append('div')
65732             .attr('class', 'button-wrap joined col1')
65733             .call(uiUndoRedo(context));
65734
65735         limiter
65736             .append('div')
65737             .attr('class', 'button-wrap col1')
65738             .call(uiSave(context));
65739
65740         bar
65741             .append('div')
65742             .attr('class', 'full-screen')
65743             .call(uiFullScreen(context));
65744
65745         bar
65746             .append('div')
65747             .attr('class', 'spinner')
65748             .call(uiSpinner(context));
65749
65750
65751         var controls = bar
65752             .append('div')
65753             .attr('class', 'map-controls');
65754
65755         controls
65756             .append('div')
65757             .attr('class', 'map-control zoombuttons')
65758             .call(uiZoom(context));
65759
65760         controls
65761             .append('div')
65762             .attr('class', 'map-control geolocate-control')
65763             .call(uiGeolocate(context));
65764
65765         controls
65766             .append('div')
65767             .attr('class', 'map-control background-control')
65768             .call(uiBackground(context));
65769
65770         controls
65771             .append('div')
65772             .attr('class', 'map-control map-data-control')
65773             .call(uiMapData(context));
65774
65775         controls
65776             .append('div')
65777             .attr('class', 'map-control help-control')
65778             .call(uiHelp(context));
65779
65780
65781         var about = content
65782             .append('div')
65783             .attr('id', 'about');
65784
65785         about
65786             .append('div')
65787             .attr('id', 'attrib')
65788             .attr('dir', 'ltr')
65789             .call(uiAttribution(context));
65790
65791         about
65792             .append('div')
65793             .attr('class', 'api-status')
65794             .call(uiStatus(context));
65795
65796
65797         var footer = about
65798             .append('div')
65799             .attr('id', 'footer')
65800             .attr('class', 'fillD');
65801
65802         footer
65803             .append('div')
65804             .attr('id', 'flash-wrap')
65805             .attr('class', 'footer-hide');
65806
65807         var footerWrap = footer
65808             .append('div')
65809             .attr('id', 'footer-wrap')
65810             .attr('class', 'footer-show');
65811
65812         footerWrap
65813             .append('div')
65814             .attr('id', 'scale-block')
65815             .call(uiScale(context));
65816
65817         var aboutList = footerWrap
65818             .append('div')
65819             .attr('id', 'info-block')
65820             .append('ul')
65821             .attr('id', 'about-list');
65822
65823         if (!context.embed()) {
65824             aboutList
65825                 .call(uiAccount(context));
65826         }
65827
65828         aboutList
65829             .append('li')
65830             .attr('class', 'version')
65831             .call(uiVersion(context));
65832
65833         var issueLinks = aboutList
65834             .append('li');
65835
65836         issueLinks
65837             .append('a')
65838             .attr('target', '_blank')
65839             .attr('tabindex', -1)
65840             .attr('href', 'https://github.com/openstreetmap/iD/issues')
65841             .call(svgIcon('#icon-bug', 'light'))
65842             .call(tooltip().title(t('report_a_bug')).placement('top'));
65843
65844         issueLinks
65845             .append('a')
65846             .attr('target', '_blank')
65847             .attr('tabindex', -1)
65848             .attr('href', 'https://github.com/openstreetmap/iD/blob/master/CONTRIBUTING.md#translating')
65849             .call(svgIcon('#icon-translate', 'light'))
65850             .call(tooltip().title(t('help_translate')).placement('top'));
65851
65852         aboutList
65853             .append('li')
65854             .attr('class', 'feature-warning')
65855             .attr('tabindex', -1)
65856             .call(uiFeatureInfo(context));
65857
65858         aboutList
65859             .append('li')
65860             .attr('class', 'user-list')
65861             .attr('tabindex', -1)
65862             .call(uiContributors(context));
65863
65864
65865         var photoviewer = content
65866             .append('div')
65867             .attr('id', 'photoviewer')
65868             .classed('al', true)       // 'al'=left,  'ar'=right
65869             .classed('hide', true);
65870
65871         photoviewer
65872             .append('button')
65873             .attr('class', 'thumb-hide')
65874             .on('click', function () {
65875                 if (services.mapillary) { services.mapillary.hideViewer(); }
65876                 if (services.openstreetcam) { services.openstreetcam.hideViewer(); }
65877             })
65878             .append('div')
65879             .call(svgIcon('#icon-close'));
65880
65881
65882         window.onbeforeunload = function() {
65883             return context.save();
65884         };
65885
65886         window.onunload = function() {
65887             context.history().unlock();
65888         };
65889
65890         var mapDimensions = map.dimensions();
65891
65892
65893         function onResize() {
65894             mapDimensions = utilGetDimensions(content, true);
65895             map.dimensions(mapDimensions);
65896         }
65897
65898         d3_select(window)
65899             .on('resize.editor', onResize);
65900
65901         onResize();
65902
65903         function pan(d) {
65904             return function() {
65905                 event.preventDefault();
65906                 context.pan(d, 100);
65907             };
65908         }
65909
65910
65911         // pan amount
65912         var pa = 80;
65913
65914         var keybinding = d3keybinding('main')
65915             .on('⌫', function() { event.preventDefault(); })
65916             .on('←', pan([pa, 0]))
65917             .on('↑', pan([0, pa]))
65918             .on('→', pan([-pa, 0]))
65919             .on('↓', pan([0, -pa]))
65920             .on(['⇧←', uiCmd('⌘←')], pan([mapDimensions[0], 0]))
65921             .on(['⇧↑', uiCmd('⌘↑')], pan([0, mapDimensions[1]]))
65922             .on(['⇧→', uiCmd('⌘→')], pan([-mapDimensions[0], 0]))
65923             .on(['⇧↓', uiCmd('⌘↓')], pan([0, -mapDimensions[1]]));
65924
65925         d3_select(document)
65926             .call(keybinding);
65927
65928         context.enter(modeBrowse(context));
65929
65930         if (!uiInitCounter++) {
65931             if (!hash.startWalkthrough) {
65932                 context.container()
65933                     .call(uiSplash(context))
65934                     .call(uiRestore(context));
65935             }
65936
65937             context.container()
65938                 .call(uiShortcuts(context));
65939         }
65940
65941         var osm = context.connection(),
65942             auth = uiLoading(context).message(t('loading_auth')).blocking(true);
65943
65944         if (osm && auth) {
65945             osm
65946                 .on('authLoading.ui', function() {
65947                     context.container()
65948                         .call(auth);
65949                 })
65950                 .on('authDone.ui', function() {
65951                     auth.close();
65952                 });
65953         }
65954
65955         uiInitCounter++;
65956
65957         if (hash.startWalkthrough) {
65958             hash.startWalkthrough = false;
65959             context.container().call(uiIntro(context));
65960         }
65961     }
65962
65963
65964     var renderCallback;
65965
65966     function ui(node, callback) {
65967         renderCallback = callback;
65968         var container = d3_select(node);
65969         context.container(container);
65970         context.loadLocale(function(err) {
65971             if (!err) {
65972                 render(container);
65973             }
65974             if (callback) {
65975                 callback(err);
65976             }
65977         });
65978     }
65979
65980
65981     ui.restart = function(arg) {
65982         context.locale(arg);
65983         context.loadLocale(function(err) {
65984             if (!err) {
65985                 context.container().selectAll('*').remove();
65986                 render(context.container());
65987                 if (renderCallback) renderCallback();
65988             }
65989         });
65990     };
65991
65992
65993     ui.sidebar = uiSidebar(context);
65994
65995     return ui;
65996 }
65997
65998 function uiChangesetEditor(context) {
65999     var dispatch$$1 = dispatch('change'),
66000         formFields = uiFormFields(context),
66001         fieldsArr,
66002         tags,
66003         changesetId;
66004
66005
66006
66007     function changesetEditor(selection) {
66008         render(selection);
66009     }
66010
66011
66012     function render(selection) {
66013         var initial = false;
66014
66015         if (!fieldsArr) {
66016             initial = true;
66017             var presets = context.presets();
66018
66019             fieldsArr = [
66020                 uiField(context, presets.field('comment'), null, { show: true, revert: false }),
66021                 uiField(context, presets.field('source'), null, { show: false, revert: false }),
66022                 uiField(context, presets.field('hashtags'), null, { show: false, revert: false }),
66023             ];
66024
66025             fieldsArr.forEach(function(field) {
66026                 field
66027                     .on('change', function(t$$1, onInput) {
66028                         dispatch$$1.call('change', field, t$$1, onInput);
66029                     });
66030             });
66031         }
66032
66033         fieldsArr.forEach(function(field) {
66034             field
66035                 .tags(tags);
66036         });
66037
66038
66039         selection
66040             .call(formFields.fieldsArr(fieldsArr));
66041
66042
66043         if (initial) {
66044             var commentField = selection.select('#preset-input-comment'),
66045                 commentNode = commentField.node();
66046
66047             if (commentNode) {
66048                 commentNode.focus();
66049                 commentNode.select();
66050             }
66051
66052             // trigger a 'blur' event so that comment field can be cleaned
66053             // and checked for hashtags, even if retrieved from localstorage
66054             utilTriggerEvent(commentField, 'blur');
66055
66056             var osm = context.connection();
66057             if (osm) {
66058                 osm.userChangesets(function (err, changesets) {
66059                     if (err) return;
66060
66061                     var comments = changesets.map(function(changeset) {
66062                         return {
66063                             title: changeset.tags.comment,
66064                             value: changeset.tags.comment
66065                         };
66066                     });
66067
66068                     commentField
66069                         .call(d3combobox()
66070                             .container(context.container())
66071                             .caseSensitive(true)
66072                             .data(uniqBy(comments, 'title'))
66073                         );
66074                 });
66075             }
66076         }
66077
66078         // Add warning if comment mentions Google
66079         var hasGoogle = tags.comment.match(/google/i);
66080         var commentWarning = selection.select('.form-field-comment').selectAll('.comment-warning')
66081             .data(hasGoogle ? [0] : []);
66082
66083         commentWarning.exit()
66084             .transition()
66085             .duration(200)
66086             .style('opacity', 0)
66087             .remove();
66088
66089         var commentEnter = commentWarning.enter()
66090             .insert('div', '.tag-reference-body')
66091             .attr('class', 'field-warning comment-warning')
66092             .style('opacity', 0);
66093
66094         commentEnter
66095             .append('a')
66096             .attr('target', '_blank')
66097             .attr('tabindex', -1)
66098             .call(svgIcon('#icon-alert', 'inline'))
66099             .attr('href', t('commit.google_warning_link'))
66100             .append('span')
66101             .text(t('commit.google_warning'));
66102
66103         commentEnter
66104             .transition()
66105             .duration(200)
66106             .style('opacity', 1);
66107     }
66108
66109
66110     changesetEditor.tags = function(_) {
66111         if (!arguments.length) return tags;
66112         tags = _;
66113         // Don't reset fieldsArr here.
66114         return changesetEditor;
66115     };
66116
66117
66118     changesetEditor.changesetID = function(_) {
66119         if (!arguments.length) return changesetId;
66120         if (changesetId === _) return changesetEditor;
66121         changesetId = _;
66122         fieldsArr = null;
66123         return changesetEditor;
66124     };
66125
66126
66127     return utilRebind(changesetEditor, dispatch$$1, 'on');
66128 }
66129
66130 /**
66131  * This method is like `_.union` except that it accepts `iteratee` which is
66132  * invoked for each element of each `arrays` to generate the criterion by
66133  * which uniqueness is computed. Result values are chosen from the first
66134  * array in which the value occurs. The iteratee is invoked with one argument:
66135  * (value).
66136  *
66137  * @static
66138  * @memberOf _
66139  * @since 4.0.0
66140  * @category Array
66141  * @param {...Array} [arrays] The arrays to inspect.
66142  * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
66143  * @returns {Array} Returns the new array of combined values.
66144  * @example
66145  *
66146  * _.unionBy([2.1], [1.2, 2.3], Math.floor);
66147  * // => [2.1, 1.2]
66148  *
66149  * // The `_.property` iteratee shorthand.
66150  * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
66151  * // => [{ 'x': 1 }, { 'x': 2 }]
66152  */
66153 var unionBy = baseRest(function(arrays) {
66154   var iteratee = last(arrays);
66155   if (isArrayLikeObject(iteratee)) {
66156     iteratee = undefined;
66157   }
66158   return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), baseIteratee(iteratee, 2));
66159 });
66160
66161 function uiCommitChanges(context) {
66162     var _entityID;
66163     var detected = utilDetect();
66164
66165
66166     function commitChanges(selection) {
66167
66168         var history = context.history(),
66169             summary = history.difference().summary();
66170
66171         var container = selection.selectAll('.modal-section.commit-section')
66172             .data([0]);
66173
66174         var containerEnter = container.enter()
66175             .append('div')
66176             .attr('class', 'commit-section modal-section fillL2');
66177
66178         containerEnter
66179             .append('h3')
66180             .text(t('commit.changes', { count: summary.length }));
66181
66182         containerEnter
66183             .append('ul')
66184             .attr('class', 'changeset-list');
66185
66186         container = containerEnter
66187             .merge(container);
66188
66189
66190         var items = container.select('ul').selectAll('li')
66191             .data(summary);
66192
66193         var itemsEnter = items.enter()
66194             .append('li')
66195             .attr('class', 'change-item');
66196
66197         itemsEnter
66198             .each(function(d) {
66199                 d3_select(this)
66200                     .call(svgIcon('#icon-' + d.entity.geometry(d.graph), 'pre-text ' + d.changeType));
66201             });
66202
66203         itemsEnter
66204             .append('span')
66205             .attr('class', 'change-type')
66206             .text(function(d) { return t('commit.' + d.changeType) + ' '; });
66207
66208         itemsEnter
66209             .append('strong')
66210             .attr('class', 'entity-type')
66211             .text(function(d) {
66212                 var matched = context.presets().match(d.entity, d.graph);
66213                 return (matched && matched.name()) || utilDisplayType(d.entity.id);
66214             });
66215
66216         itemsEnter
66217             .append('span')
66218             .attr('class', 'entity-name')
66219             .text(function(d) {
66220                 var name = utilDisplayName(d.entity) || '',
66221                     string = '';
66222                 if (name !== '') {
66223                     string += ':';
66224                 }
66225                 return string += ' ' + name;
66226             });
66227
66228         itemsEnter
66229             .style('opacity', 0)
66230             .transition()
66231             .style('opacity', 1);
66232
66233         items = itemsEnter
66234             .merge(items);
66235
66236         items
66237             .on('mouseover', mouseover)
66238             .on('mouseout', mouseout)
66239             .on('click', click);
66240
66241
66242         // Download changeset link
66243         var changeset = new osmChangeset().update({ id: undefined }),
66244             changes = history.changes(actionDiscardTags(history.difference()));
66245
66246         delete changeset.id;  // Export without chnageset_id
66247
66248         var data = JXON.stringify(changeset.osmChangeJXON(changes)),
66249             blob = new Blob([data], {type: 'text/xml;charset=utf-8;'}),
66250             fileName = 'changes.osc';
66251
66252         var linkEnter = container.selectAll('.download-changes')
66253             .data([0])
66254             .enter()
66255             .append('a')
66256             .attr('class', 'download-changes');
66257
66258         if (detected.download) {      // All except IE11 and Edge
66259             linkEnter                 // download the data as a file
66260                 .attr('href', window.URL.createObjectURL(blob))
66261                 .attr('download', fileName);
66262
66263         } else {                      // IE11 and Edge
66264             linkEnter                 // open data uri in a new tab
66265                 .attr('target', '_blank')
66266                 .on('click.download', function() {
66267                     navigator.msSaveBlob(blob, fileName);
66268                 });
66269         }
66270
66271         linkEnter
66272             .call(svgIcon('#icon-load', 'inline'))
66273             .append('span')
66274             .text(t('commit.download_changes'));
66275
66276
66277         function mouseover(d) {
66278             if (d.entity) {
66279                 context.surface().selectAll(
66280                     utilEntityOrMemberSelector([d.entity.id], context.graph())
66281                 ).classed('hover', true);
66282             }
66283         }
66284
66285
66286         function mouseout() {
66287             context.surface().selectAll('.hover')
66288                 .classed('hover', false);
66289         }
66290
66291
66292         function click(change) {
66293             if (change.changeType === 'deleted') {
66294                 _entityID = null;
66295             } else {
66296                 var entity = change.entity;
66297                 _entityID = change.entity.id;
66298                 context.map().zoomTo(entity);
66299                 context.surface().selectAll(utilEntityOrMemberSelector([_entityID], context.graph()))
66300                     .classed('hover', true);
66301             }
66302         }
66303     }
66304
66305
66306     commitChanges.entityID = function(_) {
66307         if (!arguments.length) return _entityID;
66308         _entityID = _;
66309         return commitChanges;
66310     };
66311
66312
66313
66314     return commitChanges;
66315 }
66316
66317 function uiCommitWarnings(context) {
66318
66319     function commitWarnings(selection) {
66320
66321         var changes = context.history().changes();
66322         var warnings = context.history().validate(changes);
66323
66324         var container = selection.selectAll('.warning-section')
66325             .data(warnings.length ? [0] : []);
66326
66327         container.exit()
66328             .remove();
66329
66330         var containerEnter = container.enter()
66331             .append('div')
66332             .attr('class', 'modal-section warning-section fillL2');
66333
66334         containerEnter
66335             .append('h3')
66336             .text(t('commit.warnings'));
66337
66338         containerEnter
66339             .append('ul')
66340             .attr('class', 'changeset-list');
66341
66342         container = containerEnter
66343             .merge(container);
66344
66345
66346         var items = container.select('ul').selectAll('li')
66347             .data(warnings);
66348
66349         items.exit()
66350             .remove();
66351
66352         var itemsEnter = items.enter()
66353             .append('li')
66354             .attr('class', 'warning-item');
66355
66356         itemsEnter
66357             .call(svgIcon('#icon-alert', 'pre-text'));
66358
66359         itemsEnter
66360             .append('strong')
66361             .text(function(d) { return d.message; });
66362
66363         itemsEnter.filter(function(d) { return d.tooltip; })
66364             .call(tooltip()
66365                 .title(function(d) { return d.tooltip; })
66366                 .placement('top')
66367             );
66368
66369         items = itemsEnter
66370             .merge(items);
66371
66372         items
66373             .on('mouseover', mouseover)
66374             .on('mouseout', mouseout)
66375             .on('click', warningClick);
66376
66377
66378         function mouseover(d) {
66379             if (d.entity) {
66380                 context.surface().selectAll(
66381                     utilEntityOrMemberSelector([d.entity.id], context.graph())
66382                 ).classed('hover', true);
66383             }
66384         }
66385
66386
66387         function mouseout() {
66388             context.surface().selectAll('.hover')
66389                 .classed('hover', false);
66390         }
66391
66392
66393         function warningClick(d) {
66394             if (d.entity) {
66395                 context.map().zoomTo(d.entity);
66396                 context.enter(modeSelect(context, [d.entity.id]));
66397             }
66398         }
66399
66400     }
66401
66402
66403     return commitWarnings;
66404 }
66405
66406 var _changeset$1;
66407 var readOnlyTags = [
66408     /^_changesets_count$/,
66409     /^created_by$/,
66410     /^ideditor:/,
66411     /^imagery_used$/,
66412     /^host$/,
66413     /^locale$/
66414 ];
66415
66416 // treat most punctuation (except -, _, +, &) as hashtag delimiters - #4398
66417 // from https://stackoverflow.com/a/25575009
66418 var hashtagRegex = /(#[^\u2000-\u206F\u2E00-\u2E7F\s\\'!"#$%()*,.\/:;<=>?@\[\]^`{|}~]+)/g;
66419
66420
66421 function uiCommit(context) {
66422     var dispatch$$1 = dispatch('cancel', 'save');
66423     var _userDetails;
66424     var _selection;
66425
66426     var changesetEditor = uiChangesetEditor(context)
66427         .on('change', changeTags);
66428     var rawTagEditor = uiRawTagEditor(context)
66429         .on('change', changeTags);
66430     var commitChanges = uiCommitChanges(context);
66431     var commitWarnings = uiCommitWarnings(context);
66432
66433
66434     function commit(selection) {
66435         _selection = selection;
66436
66437         var osm = context.connection();
66438         if (!osm) return;
66439
66440         // expire stored comment and hashtags after cutoff datetime - #3947
66441         var commentDate = +context.storage('commentDate') || 0;
66442         var currDate = Date.now();
66443         var cutoff = 2 * 86400 * 1000;   // 2 days
66444         if (commentDate > currDate || currDate - commentDate > cutoff) {
66445             context.storage('comment', null);
66446             context.storage('hashtags', null);
66447         }
66448
66449         var tags;
66450         if (!_changeset$1) {
66451             var detected = utilDetect();
66452             tags = {
66453                 comment: context.storage('comment') || '',
66454                 created_by: ('iD ' + context.version).substr(0, 255),
66455                 host: detected.host.substr(0, 255),
66456                 locale: detected.locale.substr(0, 255)
66457             };
66458
66459             // call findHashtags initially - this will remove stored
66460             // hashtags if any hashtags are found in the comment - #4304
66461             findHashtags(tags, true);
66462
66463             var hashtags = context.storage('hashtags');
66464             if (hashtags) {
66465                 tags.hashtags = hashtags;
66466             }
66467
66468             _changeset$1 = new osmChangeset({ tags: tags });
66469         }
66470
66471         tags = clone(_changeset$1.tags);
66472         tags.imagery_used = context.history().imageryUsed().join(';').substr(0, 255);
66473         _changeset$1 = _changeset$1.update({ tags: tags });
66474
66475         var header = selection.selectAll('.header')
66476             .data([0]);
66477
66478         header.enter()
66479             .append('div')
66480             .attr('class', 'header fillL')
66481             .append('h3')
66482             .text(t('commit.title'));
66483
66484         var body = selection.selectAll('.body')
66485             .data([0]);
66486
66487         body = body.enter()
66488             .append('div')
66489             .attr('class', 'body')
66490             .merge(body);
66491
66492
66493         // Changeset Section
66494         var changesetSection = body.selectAll('.changeset-editor')
66495             .data([0]);
66496
66497         changesetSection = changesetSection.enter()
66498             .append('div')
66499             .attr('class', 'modal-section changeset-editor')
66500             .merge(changesetSection);
66501
66502         changesetSection
66503             .call(changesetEditor
66504                 .changesetID(_changeset$1.id)
66505                 .tags(tags)
66506             );
66507
66508
66509         // Warnings
66510         body.call(commitWarnings);
66511
66512
66513         // Upload Explanation
66514         var saveSection = body.selectAll('.save-section')
66515             .data([0]);
66516
66517         saveSection = saveSection.enter()
66518             .append('div')
66519             .attr('class','modal-section save-section fillL cf')
66520             .merge(saveSection);
66521
66522         var prose = saveSection.selectAll('.commit-info')
66523             .data([0]);
66524
66525         prose = prose.enter()
66526             .append('p')
66527             .attr('class', 'commit-info')
66528             .text(t('commit.upload_explanation'))
66529             .merge(prose);
66530
66531         osm.userDetails(function(err, user) {
66532             if (err) return;
66533
66534             var userLink = d3_select(document.createElement('div'));
66535
66536             _userDetails = user;
66537
66538             if (user.image_url) {
66539                 userLink
66540                     .append('img')
66541                     .attr('src', user.image_url)
66542                     .attr('class', 'icon pre-text user-icon');
66543             }
66544
66545             userLink
66546                 .append('a')
66547                 .attr('class','user-info')
66548                 .text(user.display_name)
66549                 .attr('href', osm.userURL(user.display_name))
66550                 .attr('tabindex', -1)
66551                 .attr('target', '_blank');
66552
66553             prose
66554                 .html(t('commit.upload_explanation_with_user', { user: userLink.html() }));
66555         });
66556
66557
66558         // Request Review
66559         var requestReview = saveSection.selectAll('.request-review')
66560             .data([0]);
66561
66562         // Enter
66563         var requestReviewEnter = requestReview.enter()
66564             .append('div')
66565             .attr('class', 'request-review');
66566
66567         var labelEnter = requestReviewEnter
66568             .append('label')
66569             .attr('for', 'commit-input-request-review');
66570
66571         labelEnter
66572             .append('input')
66573             .attr('type', 'checkbox')
66574             .attr('id', 'commit-input-request-review');
66575
66576         labelEnter
66577             .append('span')
66578             .text(t('commit.request_review'));
66579
66580         // Update
66581         requestReview = requestReview
66582             .merge(requestReviewEnter);
66583
66584         var requestReviewInput = requestReview.selectAll('input')
66585             .property('checked', isReviewRequested(_changeset$1.tags))
66586             .on('change', toggleRequestReview);
66587
66588
66589         // Buttons
66590         var buttonSection = saveSection.selectAll('.buttons')
66591             .data([0]);
66592
66593         // enter
66594         var buttonEnter = buttonSection.enter()
66595             .append('div')
66596             .attr('class', 'buttons fillL cf');
66597
66598         buttonEnter
66599             .append('button')
66600             .attr('class', 'secondary-action col5 button cancel-button')
66601             .append('span')
66602             .attr('class', 'label')
66603             .text(t('commit.cancel'));
66604
66605         buttonEnter
66606             .append('button')
66607             .attr('class', 'action col5 button save-button')
66608             .append('span')
66609             .attr('class', 'label')
66610             .text(t('commit.save'));
66611
66612         // update
66613         buttonSection = buttonSection
66614             .merge(buttonEnter);
66615
66616         buttonSection.selectAll('.cancel-button')
66617             .on('click.cancel', function() {
66618                 var selectedID = commitChanges.entityID();
66619                 dispatch$$1.call('cancel', this, selectedID);
66620             });
66621
66622         buttonSection.selectAll('.save-button')
66623             .attr('disabled', function() {
66624                 var n = d3_select('#preset-input-comment').node();
66625                 return (n && n.value.length) ? null : true;
66626             })
66627             .on('click.save', function() {
66628                 this.blur();    // avoid keeping focus on the button - #4641
66629                 dispatch$$1.call('save', this, _changeset$1);
66630             });
66631
66632
66633         // Raw Tag Editor
66634         var tagSection = body.selectAll('.tag-section.raw-tag-editor')
66635             .data([0]);
66636
66637         tagSection = tagSection.enter()
66638             .append('div')
66639             .attr('class', 'modal-section tag-section raw-tag-editor')
66640             .merge(tagSection);
66641
66642         var expanded = !tagSection.selectAll('a.hide-toggle.expanded').empty();
66643         tagSection
66644             .call(rawTagEditor
66645                 .expanded(expanded)
66646                 .readOnlyTags(readOnlyTags)
66647                 .tags(clone(_changeset$1.tags))
66648             );
66649
66650
66651         // Change summary
66652         body.call(commitChanges);
66653
66654
66655         function toggleRequestReview() {
66656             var rr = requestReviewInput.property('checked');
66657             updateChangeset({ review_requested: (rr ? 'yes' : undefined) });
66658
66659             var expanded = !tagSection.selectAll('a.hide-toggle.expanded').empty();
66660             tagSection
66661                 .call(rawTagEditor
66662                     .expanded(expanded)
66663                     .readOnlyTags(readOnlyTags)
66664                     .tags(clone(_changeset$1.tags))
66665                 );
66666         }
66667     }
66668
66669
66670     function changeTags(changed, onInput) {
66671         if (changed.hasOwnProperty('comment')) {
66672             if (changed.comment === undefined) {
66673                 changed.comment = '';
66674             }
66675             if (!onInput) {
66676                 context.storage('comment', changed.comment);
66677                 context.storage('commentDate', Date.now());
66678             }
66679         }
66680
66681         updateChangeset(changed, onInput);
66682
66683         if (_selection) {
66684             _selection.call(commit);
66685         }
66686     }
66687
66688
66689     function findHashtags(tags, commentOnly) {
66690         var inComment = commentTags();
66691         var inHashTags = hashTags();
66692
66693         if (inComment !== null) {                    // when hashtags are detected in comment...
66694             context.storage('hashtags', null);       // always remove stored hashtags - #4304
66695             if (commentOnly) { inHashTags = null; }  // optionally override hashtags field
66696         }
66697         return unionBy(inComment, inHashTags, function (s) {
66698             return s.toLowerCase();
66699         });
66700
66701         // Extract hashtags from `comment`
66702         function commentTags() {
66703             return tags.comment
66704                 .replace(/http\S*/g, '')  // drop anything that looks like a URL - #4289
66705                 .match(hashtagRegex);
66706         }
66707
66708         // Extract and clean hashtags from `hashtags`
66709         function hashTags() {
66710             var t$$1 = tags.hashtags || '';
66711             return t$$1
66712                 .split(/[,;\s]+/)
66713                 .map(function (s) {
66714                     if (s[0] !== '#') { s = '#' + s; }    // prepend '#'
66715                     var matched = s.match(hashtagRegex);
66716                     return matched && matched[0];
66717                 }).filter(Boolean);                       // exclude falsey
66718         }
66719     }
66720
66721
66722     function isReviewRequested(tags) {
66723         var rr = tags.review_requested;
66724         if (rr === undefined) return false;
66725         rr = rr.trim().toLowerCase();
66726         return !(rr === '' || rr === 'no');
66727     }
66728
66729
66730     function updateChangeset(changed, onInput) {
66731         var tags = clone(_changeset$1.tags);
66732
66733         forEach(changed, function(v, k) {
66734             k = k.trim().substr(0, 255);
66735             if (readOnlyTags.indexOf(k) !== -1) return;
66736
66737             if (k !== '' && v !== undefined) {
66738                 if (onInput) {
66739                     tags[k] = v;
66740                 } else {
66741                     tags[k] = v.trim().substr(0, 255);
66742                 }
66743             } else {
66744                 delete tags[k];
66745             }
66746         });
66747
66748         if (!onInput) {
66749             // when changing the comment, override hashtags with any found in comment.
66750             var commentOnly = changed.hasOwnProperty('comment') && (changed.comment !== '');
66751             var arr = findHashtags(tags, commentOnly);
66752             if (arr.length) {
66753                 tags.hashtags = arr.join(';').substr(0, 255);
66754                 context.storage('hashtags', tags.hashtags);
66755             } else {
66756                 delete tags.hashtags;
66757                 context.storage('hashtags', null);
66758             }
66759         }
66760
66761         // always update userdetails, just in case user reauthenticates as someone else
66762         if (_userDetails && _userDetails.changesets_count !== undefined) {
66763             var changesetsCount = parseInt(_userDetails.changesets_count, 10) + 1;  // #4283
66764             tags.changesets_count = String(changesetsCount);
66765
66766             // first 100 edits - new user
66767             if (changesetsCount <= 100) {
66768                 var s;
66769                 s = context.storage('walkthrough_completed');
66770                 if (s) {
66771                     tags['ideditor:walkthrough_completed'] = s;
66772                 }
66773
66774                 s = context.storage('walkthrough_progress');
66775                 if (s) {
66776                     tags['ideditor:walkthrough_progress'] = s;
66777                 }
66778
66779                 s = context.storage('walkthrough_started');
66780                 if (s) {
66781                     tags['ideditor:walkthrough_started'] = s;
66782                 }
66783             }
66784         } else {
66785             delete tags.changesets_count;
66786         }
66787
66788         if (!isEqual(_changeset$1.tags, tags)) {
66789             _changeset$1 = _changeset$1.update({ tags: tags });
66790         }
66791     }
66792
66793
66794     commit.reset = function() {
66795         _changeset$1 = null;
66796     };
66797
66798
66799     return utilRebind(commit, dispatch$$1, 'on');
66800 }
66801
66802 function uiConfirm(selection) {
66803     var modalSelection = uiModal(selection);
66804
66805     modalSelection.select('.modal')
66806         .classed('modal-alert', true);
66807
66808     var section = modalSelection.select('.content');
66809
66810     section.append('div')
66811         .attr('class', 'modal-section header');
66812
66813     section.append('div')
66814         .attr('class', 'modal-section message-text');
66815
66816     var buttons = section.append('div')
66817         .attr('class', 'modal-section buttons cf');
66818
66819
66820     modalSelection.okButton = function() {
66821         buttons
66822             .append('button')
66823             .attr('class', 'action col4')
66824             .on('click.confirm', function() {
66825                 modalSelection.remove();
66826             })
66827             .text(t('confirm.okay'))
66828             .node()
66829             .focus();
66830
66831         return modalSelection;
66832     };
66833
66834
66835     return modalSelection;
66836 }
66837
66838 function uiConflicts(context) {
66839     var dispatch$$1 = dispatch('cancel', 'save');
66840     var keybinding = d3keybinding('conflicts');
66841     var _origChanges;
66842     var _conflictList;
66843
66844
66845     function keybindingOn() {
66846         d3_select(document)
66847             .call(keybinding.on('⎋', cancel, true));
66848     }
66849
66850     function keybindingOff() {
66851         d3_select(document)
66852             .call(keybinding.off);
66853     }
66854
66855     function tryAgain() {
66856         keybindingOff();
66857         dispatch$$1.call('save');
66858     }
66859
66860     function cancel() {
66861         keybindingOff();
66862         dispatch$$1.call('cancel');
66863     }
66864
66865
66866     function conflicts(selection) {
66867         keybindingOn();
66868
66869         var headerEnter = selection.selectAll('.header')
66870             .data([0])
66871             .enter()
66872             .append('div')
66873             .attr('class', 'header fillL');
66874
66875         headerEnter
66876             .append('button')
66877             .attr('class', 'fr')
66878             .on('click', cancel)
66879             .call(svgIcon('#icon-close'));
66880
66881         headerEnter
66882             .append('h3')
66883             .text(t('save.conflict.header'));
66884
66885         var bodyEnter = selection.selectAll('.body')
66886             .data([0])
66887             .enter()
66888             .append('div')
66889             .attr('class', 'body fillL');
66890
66891         var conflictsHelpEnter = bodyEnter
66892             .append('div')
66893             .attr('class', 'conflicts-help')
66894             .text(t('save.conflict.help'));
66895
66896
66897         // Download changes link
66898         var detected = utilDetect();
66899         var changeset = new osmChangeset();
66900
66901         delete changeset.id;  // Export without changeset_id
66902
66903         var data = JXON.stringify(changeset.osmChangeJXON(_origChanges));
66904         var blob = new Blob([data], { type: 'text/xml;charset=utf-8;' });
66905         var fileName = 'changes.osc';
66906
66907         var linkEnter = conflictsHelpEnter.selectAll('.download-changes')
66908             .append('a')
66909             .attr('class', 'download-changes');
66910
66911         if (detected.download) {      // All except IE11 and Edge
66912             linkEnter                 // download the data as a file
66913                 .attr('href', window.URL.createObjectURL(blob))
66914                 .attr('download', fileName);
66915
66916         } else {                      // IE11 and Edge
66917             linkEnter                 // open data uri in a new tab
66918                 .attr('target', '_blank')
66919                 .on('click.download', function() {
66920                     navigator.msSaveBlob(blob, fileName);
66921                 });
66922         }
66923
66924         linkEnter
66925             .call(svgIcon('#icon-load', 'inline'))
66926             .append('span')
66927             .text(t('save.conflict.download_changes'));
66928
66929
66930         bodyEnter
66931             .append('div')
66932             .attr('class', 'conflict-container fillL3')
66933             .call(showConflict, 0);
66934
66935         bodyEnter
66936             .append('div')
66937             .attr('class', 'conflicts-done')
66938             .attr('opacity', 0)
66939             .style('display', 'none')
66940             .text(t('save.conflict.done'));
66941
66942         var buttonsEnter = bodyEnter
66943             .append('div')
66944             .attr('class','buttons col12 joined conflicts-buttons');
66945
66946         buttonsEnter
66947             .append('button')
66948             .attr('disabled', _conflictList.length > 1)
66949             .attr('class', 'action conflicts-button col6')
66950             .text(t('save.title'))
66951             .on('click.try_again', tryAgain);
66952
66953         buttonsEnter
66954             .append('button')
66955             .attr('class', 'secondary-action conflicts-button col6')
66956             .text(t('confirm.cancel'))
66957             .on('click.cancel', cancel);
66958     }
66959
66960
66961     function showConflict(selection, index) {
66962         index = utilWrap(index, _conflictList.length);
66963
66964         var parent = d3_select(selection.node().parentNode);
66965
66966         // enable save button if this is the last conflict being reviewed..
66967         if (index === _conflictList.length - 1) {
66968             window.setTimeout(function() {
66969                 parent.select('.conflicts-button')
66970                     .attr('disabled', null);
66971
66972                 parent.select('.conflicts-done')
66973                     .transition()
66974                     .attr('opacity', 1)
66975                     .style('display', 'block');
66976             }, 250);
66977         }
66978
66979         var conflict = selection
66980             .selectAll('.conflict')
66981             .data([_conflictList[index]]);
66982
66983         conflict.exit()
66984             .remove();
66985
66986         var conflictEnter = conflict.enter()
66987             .append('div')
66988             .attr('class', 'conflict');
66989
66990         conflictEnter
66991             .append('h4')
66992             .attr('class', 'conflict-count')
66993             .text(t('save.conflict.count', { num: index + 1, total: _conflictList.length }));
66994
66995         conflictEnter
66996             .append('a')
66997             .attr('class', 'conflict-description')
66998             .attr('href', '#')
66999             .text(function(d) { return d.name; })
67000             .on('click', function(d) {
67001                 event.preventDefault();
67002                 zoomToEntity(d.id);
67003             });
67004
67005         var details = conflictEnter
67006             .append('div')
67007             .attr('class', 'conflict-detail-container');
67008
67009         details
67010             .append('ul')
67011             .attr('class', 'conflict-detail-list')
67012             .selectAll('li')
67013             .data(function(d) { return d.details || []; })
67014             .enter()
67015             .append('li')
67016             .attr('class', 'conflict-detail-item')
67017             .html(function(d) { return d; });
67018
67019         details
67020             .append('div')
67021             .attr('class', 'conflict-choices')
67022             .call(addChoices);
67023
67024         details
67025             .append('div')
67026             .attr('class', 'conflict-nav-buttons joined cf')
67027             .selectAll('button')
67028             .data(['previous', 'next'])
67029             .enter()
67030             .append('button')
67031             .text(function(d) { return t('save.conflict.' + d); })
67032             .attr('class', 'conflict-nav-button action col6')
67033             .attr('disabled', function(d, i) {
67034                 return (i === 0 && index === 0) ||
67035                     (i === 1 && index === _conflictList.length - 1) || null;
67036             })
67037             .on('click', function(d, i) {
67038                 event.preventDefault();
67039
67040                 var container = parent.selectAll('.conflict-container');
67041                 var sign = (i === 0 ? -1 : 1);
67042
67043                 container
67044                     .selectAll('.conflict')
67045                     .remove();
67046
67047                 container
67048                     .call(showConflict, index + sign);
67049             });
67050
67051     }
67052
67053
67054     function addChoices(selection) {
67055         var choices = selection
67056             .append('ul')
67057             .attr('class', 'layer-list')
67058             .selectAll('li')
67059             .data(function(d) { return d.choices || []; });
67060
67061         // enter
67062         var choicesEnter = choices.enter()
67063             .append('li')
67064             .attr('class', 'layer');
67065
67066         var labelEnter = choicesEnter
67067             .append('label');
67068
67069         labelEnter
67070             .append('input')
67071             .attr('type', 'radio')
67072             .attr('name', function(d) { return d.id; })
67073             .on('change', function(d, i) {
67074                 var ul = this.parentNode.parentNode.parentNode;
67075                 ul.__data__.chosen = i;
67076                 choose(ul, d);
67077             });
67078
67079         labelEnter
67080             .append('span')
67081             .text(function(d) { return d.text; });
67082
67083         // update
67084         choicesEnter
67085             .merge(choices)
67086             .each(function(d, i) {
67087                 var ul = this.parentNode;
67088                 if (ul.__data__.chosen === i) {
67089                     choose(ul, d);
67090                 }
67091             });
67092     }
67093
67094
67095     function choose(ul, datum) {
67096         if (event) event.preventDefault();
67097
67098         d3_select(ul)
67099             .selectAll('li')
67100             .classed('active', function(d) { return d === datum; })
67101             .selectAll('input')
67102             .property('checked', function(d) { return d === datum; });
67103
67104         var extent = geoExtent();
67105         var entity;
67106
67107         entity = context.graph().hasEntity(datum.id);
67108         if (entity) extent._extend(entity.extent(context.graph()));
67109
67110         datum.action();
67111
67112         entity = context.graph().hasEntity(datum.id);
67113         if (entity) extent._extend(entity.extent(context.graph()));
67114
67115         zoomToEntity(datum.id, extent);
67116     }
67117
67118
67119     function zoomToEntity(id, extent) {
67120         context.surface().selectAll('.hover')
67121             .classed('hover', false);
67122
67123         var entity = context.graph().hasEntity(id);
67124         if (entity) {
67125             if (extent) {
67126                 context.map().trimmedExtent(extent);
67127             } else {
67128                 context.map().zoomTo(entity);
67129             }
67130             context.surface().selectAll(utilEntityOrMemberSelector([entity.id], context.graph()))
67131                 .classed('hover', true);
67132         }
67133     }
67134
67135
67136     // The conflict list should be an array of objects like:
67137     // {
67138     //     id: id,
67139     //     name: entityName(local),
67140     //     details: merge.conflicts(),
67141     //     chosen: 1,
67142     //     choices: [
67143     //         choice(id, keepMine, forceLocal),
67144     //         choice(id, keepTheirs, forceRemote)
67145     //     ]
67146     // }
67147     conflicts.conflictList = function(_) {
67148         if (!arguments.length) return _conflictList;
67149         _conflictList = _;
67150         return conflicts;
67151     };
67152
67153
67154     conflicts.origChanges = function(_) {
67155         if (!arguments.length) return _origChanges;
67156         _origChanges = _;
67157         return conflicts;
67158     };
67159
67160
67161     return utilRebind(conflicts, dispatch$$1, 'on');
67162 }
67163
67164 function uiEditMenu(context, operations) {
67165     var menu,
67166         center = [0, 0],
67167         offset = [0, 0],
67168         tooltip;
67169
67170     var p = 8,               // top padding
67171         m = 4,               // top margin
67172         h = 15,              // height of icon
67173         vpBottomMargin = 45, // viewport bottom margin
67174         vpSideMargin = 35,   // viewport side margin
67175         buttonWidth = 44,
67176         buttonHeight = (2 * p + h),
67177         menuWidth = buttonWidth,
67178         menuHeight = (2 * m) + operations.length * buttonHeight,
67179         menuSideMargin = 10,
67180         tooltipWidth = 200,
67181         tooltipHeight = 200;  // a reasonable guess, real height depends on tooltip contents
67182
67183
67184     var editMenu = function (selection) {
67185         if (!operations.length) return;
67186
67187         selection.node().parentNode.focus();
67188
67189         var isRTL = textDirection === 'rtl',
67190             viewport = context.surfaceRect();
67191
67192         if (!isRTL && (center[0] + menuSideMargin + menuWidth) > (viewport.width - vpSideMargin)) {
67193             // menu is going left-to-right and near right viewport edge, go left instead
67194             isRTL = true;
67195         } else if (isRTL && (center[0] - menuSideMargin - menuWidth) < vpSideMargin) {
67196             // menu is going right-to-left and near left viewport edge, go right instead
67197             isRTL = false;
67198         }
67199
67200         offset[0] = (isRTL ? -1 * (menuSideMargin + menuWidth) : menuSideMargin);
67201
67202         if (center[1] + menuHeight > (viewport.height - vpBottomMargin)) {
67203             // menu is near bottom viewport edge, shift upwards
67204             offset[1] = -1 * (center[1] + menuHeight - viewport.height + vpBottomMargin);
67205         }
67206
67207         var origin = [ center[0] + offset[0], center[1] + offset[1] ];
67208
67209         menu = selection
67210             .append('g')
67211             .attr('class', 'edit-menu')
67212             .attr('transform', 'translate(' + origin + ')')
67213             .attr('opacity', 0);
67214
67215         menu
67216             .transition()
67217             .attr('opacity', 1);
67218
67219         menu
67220             .append('rect')
67221             .attr('class', 'edit-menu-background')
67222             .attr('x', 4)
67223             .attr('rx', 4)
67224             .attr('ry', 4)
67225             .attr('width', menuWidth)
67226             .attr('height', menuHeight)
67227             .attr('stroke-linecap', 'round');
67228
67229
67230         var button = menu.selectAll('.edit-menu-item')
67231             .data(operations)
67232             .enter()
67233             .append('g')
67234             .attr('class', function (d) { return 'edit-menu-item edit-menu-item-' + d.id; })
67235             .classed('disabled', function (d) { return d.disabled(); })
67236             .attr('transform', function (d, i) {
67237                 return 'translate(' + geoVecFloor([
67238                     0,
67239                     m + i * buttonHeight
67240                 ]).join(',') + ')';
67241             });
67242
67243         button
67244             .append('rect')
67245             .attr('x', 4)
67246             .attr('width', buttonWidth)
67247             .attr('height', buttonHeight)
67248             .on('click', click)
67249             .on('mousedown', mousedown)
67250             .on('mouseover', mouseover)
67251             .on('mouseout', mouseout);
67252
67253         button
67254             .append('use')
67255             .attr('width', '20')
67256             .attr('height', '20')
67257             .attr('transform', function () {
67258                 return 'translate(' + [2 * p, 5] + ')';
67259             })
67260             .attr('xlink:href', function (d) { return '#operation-' + d.id; });
67261
67262         tooltip = d3_select(document.body)
67263             .append('div')
67264             .attr('class', 'tooltip-inner edit-menu-tooltip');
67265
67266
67267         function click(operation) {
67268             event.stopPropagation();
67269             if (operation.disabled()) return;
67270             operation();
67271             editMenu.close();
67272         }
67273
67274         function mousedown() {
67275             event.stopPropagation();  // https://github.com/openstreetmap/iD/issues/1869
67276         }
67277
67278         function mouseover(d, i) {
67279             var tipX, tipY;
67280
67281             if (!isRTL) {
67282                 tipX = viewport.left + origin[0] + menuSideMargin + menuWidth;
67283             } else {
67284                 tipX = viewport.left + origin[0] - 4 - tooltipWidth;
67285             }
67286
67287             if (tipX + tooltipWidth > viewport.right) {
67288                 // tip is going left-to-right and near right viewport edge, go left instead
67289                 tipX = viewport.left + origin[0] - 4 - tooltipWidth;
67290             } else if (tipX < viewport.left) {
67291                 // tip is going right-to-left and near left viewport edge, go right instead
67292                 tipX = viewport.left + origin[0] + menuSideMargin + menuWidth;
67293             }
67294
67295             tipY = viewport.top + origin[1] + (i * buttonHeight);
67296             if (tipY + tooltipHeight > viewport.bottom) {
67297                 // tip is near bottom viewport edge, shift upwards
67298                 tipY -= tipY + tooltipHeight - viewport.bottom;
67299             }
67300
67301             tooltip
67302                 .style('left', tipX + 'px')
67303                 .style('top', tipY + 'px')
67304                 .style('display', 'block')
67305                 .html(uiTooltipHtml(d.tooltip(), d.keys[0], d.title));
67306         }
67307
67308         function mouseout() {
67309             tooltip.style('display', 'none');
67310         }
67311     };
67312
67313
67314     editMenu.close = function () {
67315         if (menu) {
67316             menu
67317                 .style('pointer-events', 'none')
67318                 .transition()
67319                 .attr('opacity', 0)
67320                 .remove();
67321         }
67322
67323         if (tooltip) {
67324             tooltip.remove();
67325         }
67326     };
67327
67328
67329     editMenu.center = function (_) {
67330         if (!arguments.length) return center;
67331         center = _;
67332         return editMenu;
67333     };
67334
67335
67336     return editMenu;
67337 }
67338
67339 var _flashTimer;
67340
67341
67342 function uiFlash() {
67343     var _duration = 2000;
67344     var _iconName = '#icon-no';
67345     var _iconClass = 'disabled';
67346     var _text = '';
67347     var _textClass;
67348
67349
67350     function flash() {
67351         if (_flashTimer) {
67352             _flashTimer.stop();
67353         }
67354
67355         d3_select('#footer-wrap')
67356             .attr('class', 'footer-hide');
67357         d3_select('#flash-wrap')
67358             .attr('class', 'footer-show');
67359
67360         var content = d3_select('#flash-wrap').selectAll('.flash-content')
67361             .data([0]);
67362
67363         // Enter
67364         var contentEnter = content.enter()
67365             .append('div')
67366             .attr('class', 'flash-content');
67367
67368         var iconEnter = contentEnter
67369             .append('svg')
67370             .attr('class', 'flash-icon')
67371             .append('g')
67372             .attr('transform', 'translate(10,10)');
67373
67374         iconEnter
67375             .append('circle')
67376             .attr('r', 9);
67377
67378         iconEnter
67379             .append('use')
67380             .attr('transform', 'translate(-7,-7)')
67381             .attr('width', '14')
67382             .attr('height', '14');
67383
67384         contentEnter
67385             .append('div')
67386             .attr('class', 'flash-text');
67387
67388
67389         // Update
67390         content = content
67391             .merge(contentEnter);
67392
67393         content
67394             .selectAll('.flash-icon')
67395             .attr('class', 'flash-icon ' + (_iconClass || ''));
67396
67397         content
67398             .selectAll('.flash-icon use')
67399             .attr('xlink:href', _iconName);
67400
67401         content
67402             .selectAll('.flash-text')
67403             .attr('class', 'flash-text ' + (_textClass || ''))
67404             .text(_text);
67405
67406
67407         _flashTimer = d3_timeout(function() {
67408             _flashTimer = null;
67409             d3_select('#footer-wrap')
67410                 .attr('class', 'footer-show');
67411             d3_select('#flash-wrap')
67412                 .attr('class', 'footer-hide');
67413         }, _duration);
67414
67415         return content;
67416     }
67417
67418
67419     flash.duration = function(_) {
67420         if (!arguments.length) return _duration;
67421         _duration = _;
67422         return flash;
67423     };
67424
67425     flash.text = function(_) {
67426         if (!arguments.length) return _text;
67427         _text = _;
67428         return flash;
67429     };
67430
67431     flash.textClass = function(_) {
67432         if (!arguments.length) return _textClass;
67433         _textClass = _;
67434         return flash;
67435     };
67436
67437     flash.iconName = function(_) {
67438         if (!arguments.length) return _iconName;
67439         _iconName = _;
67440         return flash;
67441     };
67442
67443     flash.iconClass = function(_) {
67444         if (!arguments.length) return _iconClass;
67445         _iconClass = _;
67446         return flash;
67447     };
67448
67449     return flash;
67450 }
67451
67452 function uiLasso(context) {
67453     var group, polygon;
67454
67455     lasso.coordinates = [];
67456
67457     function lasso(selection) {
67458         context.container()
67459             .classed('lasso', true);
67460
67461         group = selection
67462             .append('g')
67463             .attr('class', 'lasso hide');
67464
67465         polygon = group
67466             .append('path')
67467             .attr('class', 'lasso-path');
67468
67469         group
67470             .call(uiToggle(true));
67471     }
67472
67473
67474     function draw() {
67475         if (polygon) {
67476             polygon.data([lasso.coordinates])
67477                 .attr('d', function(d) { return 'M' + d.join(' L') + ' Z'; });
67478         }
67479     }
67480
67481
67482     lasso.extent = function () {
67483         return lasso.coordinates.reduce(function(extent, point) {
67484             return extent.extend(geoExtent(point));
67485         }, geoExtent());
67486     };
67487
67488
67489     lasso.p = function(_) {
67490         if (!arguments.length) return lasso;
67491         lasso.coordinates.push(_);
67492         draw();
67493         return lasso;
67494     };
67495
67496
67497     lasso.close = function() {
67498         if (group) {
67499             group.call(uiToggle(false, function() {
67500                 d3_select(this).remove();
67501             }));
67502         }
67503         context.container().classed('lasso', false);
67504     };
67505
67506
67507     return lasso;
67508 }
67509
67510 function uiRadialMenu(context, operations) {
67511     var menu,
67512         center = [0, 0],
67513         tooltip;
67514
67515
67516     var radialMenu = function(selection) {
67517         if (!operations.length) return;
67518
67519         selection.node().parentNode.focus();
67520
67521         function click(operation) {
67522             event.stopPropagation();
67523             if (operation.disabled()) return;
67524             operation();
67525             radialMenu.close();
67526         }
67527
67528         menu = selection
67529             .append('g')
67530             .attr('class', 'radial-menu')
67531             .attr('transform', 'translate(' + center + ')')
67532             .attr('opacity', 0);
67533
67534         menu
67535             .transition()
67536             .attr('opacity', 1);
67537
67538         var r = 50,
67539             a = Math.PI / 4,
67540             a0 = -Math.PI / 4,
67541             a1 = a0 + (operations.length - 1) * a;
67542
67543         menu
67544             .append('path')
67545             .attr('class', 'radial-menu-background')
67546             .attr('d', 'M' + r * Math.sin(a0) + ',' +
67547                              r * Math.cos(a0) +
67548                       ' A' + r + ',' + r + ' 0 ' + (operations.length > 5 ? '1' : '0') + ',0 ' +
67549                              (r * Math.sin(a1) + 1e-3) + ',' +
67550                              (r * Math.cos(a1) + 1e-3)) // Force positive-length path (#1305)
67551             .attr('stroke-width', 50)
67552             .attr('stroke-linecap', 'round');
67553
67554         var button = menu.selectAll()
67555             .data(operations)
67556             .enter()
67557             .append('g')
67558             .attr('class', function(d) { return 'radial-menu-item radial-menu-item-' + d.id; })
67559             .classed('disabled', function(d) { return d.disabled(); })
67560             .attr('transform', function(d, i) {
67561                 return 'translate(' + geoVecFloor([
67562                         r * Math.sin(a0 + i * a),
67563                         r * Math.cos(a0 + i * a)]).join(',') + ')';
67564             });
67565
67566         button
67567             .append('circle')
67568             .attr('r', 15)
67569             .on('click', click)
67570             .on('mousedown', mousedown)
67571             .on('mouseover', mouseover)
67572             .on('mouseout', mouseout);
67573
67574         button
67575             .append('use')
67576             .attr('transform', 'translate(-10,-10)')
67577             .attr('width', '20')
67578             .attr('height', '20')
67579             .attr('xlink:href', function(d) { return '#operation-' + d.id; });
67580
67581         tooltip = d3_select(document.body)
67582             .append('div')
67583             .attr('class', 'tooltip-inner radial-menu-tooltip');
67584
67585         function mousedown() {
67586             event.stopPropagation(); // https://github.com/openstreetmap/iD/issues/1869
67587         }
67588
67589         function mouseover(d, i) {
67590             var rect = context.surfaceRect(),
67591                 angle = a0 + i * a,
67592                 top = rect.top + (r + 25) * Math.cos(angle) + center[1] + 'px',
67593                 left = rect.left + (r + 25) * Math.sin(angle) + center[0] + 'px',
67594                 bottom = rect.height - (r + 25) * Math.cos(angle) - center[1] + 'px',
67595                 right = rect.width - (r + 25) * Math.sin(angle) - center[0] + 'px';
67596
67597             tooltip
67598                 .style('top', null)
67599                 .style('left', null)
67600                 .style('bottom', null)
67601                 .style('right', null)
67602                 .style('display', 'block')
67603                 .html(uiTooltipHtml(d.tooltip(), d.keys[0]));
67604
67605             if (i === 0) {
67606                 tooltip
67607                     .style('right', right)
67608                     .style('top', top);
67609             } else if (i >= 4) {
67610                 tooltip
67611                     .style('left', left)
67612                     .style('bottom', bottom);
67613             } else {
67614                 tooltip
67615                     .style('left', left)
67616                     .style('top', top);
67617             }
67618         }
67619
67620         function mouseout() {
67621             tooltip.style('display', 'none');
67622         }
67623     };
67624
67625
67626     radialMenu.close = function() {
67627         if (menu) {
67628             menu
67629                 .style('pointer-events', 'none')
67630                 .transition()
67631                 .attr('opacity', 0)
67632                 .remove();
67633         }
67634
67635         if (tooltip) {
67636             tooltip.remove();
67637         }
67638     };
67639
67640
67641     radialMenu.center = function(_) {
67642         if (!arguments.length) return center;
67643         center = _;
67644         return radialMenu;
67645     };
67646
67647
67648     return radialMenu;
67649 }
67650
67651 function uiSelectionList(context, selectedIDs) {
67652
67653     function selectEntity(entity) {
67654         context.enter(modeSelect(context, [entity.id]));
67655     }
67656
67657
67658     function deselectEntity(entity) {
67659         event.stopPropagation();
67660         var index = selectedIDs.indexOf(entity.id);
67661         if (index > -1) {
67662             selectedIDs.splice(index, 1);
67663         }
67664         context.enter(modeSelect(context, selectedIDs));
67665     }
67666
67667
67668     function selectionList(selection) {
67669         selection.classed('selection-list-pane', true);
67670
67671         var header = selection
67672             .append('div')
67673             .attr('class', 'header fillL cf');
67674
67675         header
67676             .append('h3')
67677             .text(t('inspector.multiselect'));
67678
67679         var listWrap = selection
67680             .append('div')
67681             .attr('class', 'inspector-body');
67682
67683         var list = listWrap
67684             .append('div')
67685             .attr('class', 'feature-list cf');
67686
67687         context.history().on('change.selection-list', drawList);
67688         drawList();
67689
67690
67691         function drawList() {
67692             var entities = selectedIDs
67693                 .map(function(id) { return context.hasEntity(id); })
67694                 .filter(function(entity) { return entity; });
67695
67696             var items = list.selectAll('.feature-list-item')
67697                 .data(entities, osmEntity.key);
67698
67699             items.exit()
67700                 .remove();
67701
67702             // Enter
67703             var enter = items.enter()
67704                 .append('div')
67705                 .attr('class', 'feature-list-item')
67706                 .on('click', selectEntity);
67707
67708             var label = enter
67709                 .append('button')
67710                 .attr('class', 'label');
67711
67712             enter
67713                 .append('button')
67714                 .attr('class', 'close')
67715                 .on('click', deselectEntity)
67716                 .call(svgIcon('#icon-close'));
67717
67718             label
67719                 .append('span')
67720                 .attr('class', 'entity-geom-icon')
67721                 .call(svgIcon('', 'pre-text'));
67722
67723             label
67724                 .append('span')
67725                 .attr('class', 'entity-type');
67726
67727             label
67728                 .append('span')
67729                 .attr('class', 'entity-name');
67730
67731             // Update
67732             items = items.merge(enter);
67733
67734             items.selectAll('.entity-geom-icon use')
67735                 .attr('href', function() {
67736                     var entity = this.parentNode.parentNode.__data__;
67737                     return '#icon-' + context.geometry(entity.id);
67738                 });
67739
67740             items.selectAll('.entity-type')
67741                 .text(function(entity) { return context.presets().match(entity, context.graph()).name(); });
67742
67743             items.selectAll('.entity-name')
67744                 .text(function(entity) { return utilDisplayName(entity); });
67745         }
67746     }
67747
67748     return selectionList;
67749 }
67750
67751 function uiSourceSwitch(context) {
67752     var keys;
67753
67754
67755     function click() {
67756         event.preventDefault();
67757
67758         var osm = context.connection();
67759         if (!osm) return;
67760
67761         if (context.inIntro()) return;
67762
67763         if (context.history().hasChanges() &&
67764             !window.confirm(t('source_switch.lose_changes'))) return;
67765
67766         var isLive = d3_select(this)
67767             .classed('live');
67768
67769         isLive = !isLive;
67770         context.enter(modeBrowse(context));
67771         context.history().clearSaved();          // remove saved history
67772         context.flush();                         // remove stored data
67773
67774         d3_select(this)
67775             .text(isLive ? t('source_switch.live') : t('source_switch.dev'))
67776             .classed('live', isLive);
67777
67778         osm.switch(isLive ? keys[0] : keys[1]);  // switch connection (warning: dispatches 'change' event)
67779     }
67780
67781     var sourceSwitch = function(selection) {
67782         selection
67783             .append('a')
67784             .attr('href', '#')
67785             .text(t('source_switch.live'))
67786             .classed('live', true)
67787             .attr('tabindex', -1)
67788             .on('click', click);
67789     };
67790
67791
67792     sourceSwitch.keys = function(_) {
67793         if (!arguments.length) return keys;
67794         keys = _;
67795         return sourceSwitch;
67796     };
67797
67798
67799     return sourceSwitch;
67800 }
67801
67802 function uiSuccess(context) {
67803     var dispatch$$1 = dispatch('cancel'),
67804         changeset;
67805
67806
67807     function success(selection) {
67808         var header = selection
67809             .append('div')
67810             .attr('class', 'header fillL');
67811
67812         header
67813             .append('button')
67814             .attr('class', 'fr')
67815             .on('click', function() { dispatch$$1.call('cancel'); })
67816             .call(svgIcon('#icon-close'));
67817
67818         header
67819             .append('h3')
67820             .text(t('success.just_edited'));
67821
67822         var body = selection
67823             .append('div')
67824             .attr('class', 'body save-success fillL');
67825
67826         body
67827             .append('p')
67828             .html(t('success.help_html'));
67829
67830         body
67831             .append('a')
67832             .attr('class', 'details')
67833             .attr('target', '_blank')
67834             .attr('tabindex', -1)
67835             .call(svgIcon('#icon-out-link', 'inline'))
67836             .attr('href', t('success.help_link_url'))
67837             .append('span')
67838             .text(t('success.help_link_text'));
67839
67840         var osm = context.connection();
67841         if (!osm) return;
67842
67843         var changesetURL = osm.changesetURL(changeset.id);
67844
67845         var viewOnOsm = body
67846             .append('a')
67847             .attr('class', 'button col12 osm')
67848             .attr('target', '_blank')
67849             .attr('href', changesetURL);
67850
67851         viewOnOsm
67852             .append('svg')
67853             .attr('class', 'logo logo-osm')
67854             .append('use')
67855             .attr('xlink:href', '#logo-osm');
67856
67857         viewOnOsm
67858             .append('div')
67859             .text(t('success.view_on_osm'));
67860
67861         var message = (changeset.tags.comment || t('success.edited_osm')).substring(0, 130) +
67862             ' ' + changesetURL;
67863
67864         var sharing = [
67865             { key: 'facebook', value: 'https://facebook.com/sharer/sharer.php?u=' + encodeURIComponent(changesetURL) },
67866             { key: 'twitter', value: 'https://twitter.com/intent/tweet?source=webclient&text=' + encodeURIComponent(message) },
67867             { key: 'google', value: 'https://plus.google.com/share?url=' + encodeURIComponent(changesetURL) }
67868         ];
67869
67870         body.selectAll('.button.social')
67871             .data(sharing)
67872             .enter()
67873             .append('a')
67874             .attr('class', 'button social col4')
67875             .attr('target', '_blank')
67876             .attr('href', function(d) { return d.value; })
67877             .call(tooltip()
67878                 .title(function(d) { return t('success.' + d.key); })
67879                 .placement('bottom'))
67880             .each(function(d) { d3_select(this).call(svgIcon('#logo-' + d.key, 'social')); });
67881     }
67882
67883
67884     success.changeset = function(_) {
67885         if (!arguments.length) return changeset;
67886         changeset = _;
67887         return success;
67888     };
67889
67890
67891     return utilRebind(success, dispatch$$1, 'on');
67892 }
67893
67894 function coreHistory(context) {
67895     var imageryUsed = ['Bing'],
67896         dispatch$$1 = dispatch('change', 'undone', 'redone'),
67897         lock = utilSessionMutex('lock'),
67898         duration = 150,
67899         checkpoints = {},
67900         stack, index, tree;
67901
67902
67903     // internal _act, accepts list of actions and eased time
67904     function _act(actions, t) {
67905         actions = Array.prototype.slice.call(actions);
67906
67907         var annotation;
67908
67909         if (!isFunction(actions[actions.length - 1])) {
67910             annotation = actions.pop();
67911         }
67912
67913         stack[index].transform = context.projection.transform();
67914         stack[index].selectedIDs = context.selectedIDs();
67915
67916         var graph = stack[index].graph;
67917         for (var i = 0; i < actions.length; i++) {
67918             graph = actions[i](graph, t);
67919         }
67920
67921         return {
67922             graph: graph,
67923             annotation: annotation,
67924             imageryUsed: imageryUsed
67925         };
67926     }
67927
67928
67929     // internal _perform with eased time
67930     function _perform(args, t) {
67931         var previous = stack[index].graph;
67932         stack = stack.slice(0, index + 1);
67933         stack.push(_act(args, t));
67934         index++;
67935         return change(previous);
67936     }
67937
67938
67939     // internal _replace with eased time
67940     function _replace(args, t) {
67941         var previous = stack[index].graph;
67942         // assert(index == stack.length - 1)
67943         stack[index] = _act(args, t);
67944         return change(previous);
67945     }
67946
67947
67948     // internal _overwrite with eased time
67949     function _overwrite(args, t) {
67950         var previous = stack[index].graph;
67951         if (index > 0) {
67952             index--;
67953             stack.pop();
67954         }
67955         stack = stack.slice(0, index + 1);
67956         stack.push(_act(args, t));
67957         index++;
67958         return change(previous);
67959     }
67960
67961
67962     // determine diffrence and dispatch a change event
67963     function change(previous) {
67964         var difference$$1 = coreDifference(previous, history.graph());
67965         dispatch$$1.call('change', this, difference$$1);
67966         return difference$$1;
67967     }
67968
67969
67970     // iD uses namespaced keys so multiple installations do not conflict
67971     function getKey(n) {
67972         return 'iD_' + window.location.origin + '_' + n;
67973     }
67974
67975
67976     var history = {
67977
67978         graph: function() {
67979             return stack[index].graph;
67980         },
67981
67982
67983         base: function() {
67984             return stack[0].graph;
67985         },
67986
67987
67988         merge: function(entities, extent) {
67989             stack[0].graph.rebase(entities, map$4(stack, 'graph'), false);
67990             tree.rebase(entities, false);
67991
67992             dispatch$$1.call('change', this, undefined, extent);
67993         },
67994
67995
67996         perform: function() {
67997             // complete any transition already in progress
67998             d3_select(document).interrupt('history.perform');
67999
68000             var transitionable = false,
68001                 action0 = arguments[0];
68002
68003             if (arguments.length === 1 ||
68004                 arguments.length === 2 && !isFunction(arguments[1])) {
68005                 transitionable = !!action0.transitionable;
68006             }
68007
68008             if (transitionable) {
68009                 var origArguments = arguments;
68010                 d3_select(document)
68011                     .transition('history.perform')
68012                     .duration(duration)
68013                     .ease(linear$1)
68014                     .tween('history.tween', function() {
68015                         return function(t) {
68016                             if (t < 1) _overwrite([action0], t);
68017                         };
68018                     })
68019                     .on('start', function() {
68020                         _perform([action0], 0);
68021                     })
68022                     .on('end interrupt', function() {
68023                         _overwrite(origArguments, 1);
68024                     });
68025
68026             } else {
68027                 return _perform(arguments);
68028             }
68029         },
68030
68031
68032         replace: function() {
68033             d3_select(document).interrupt('history.perform');
68034             return _replace(arguments, 1);
68035         },
68036
68037
68038         // Same as calling pop and then perform
68039         overwrite: function() {
68040             d3_select(document).interrupt('history.perform');
68041             return _overwrite(arguments, 1);
68042         },
68043
68044
68045         pop: function(n) {
68046             d3_select(document).interrupt('history.perform');
68047
68048             var previous = stack[index].graph;
68049             if (isNaN(+n) || +n < 0) {
68050                 n = 1;
68051             }
68052             while (n-- > 0 && index > 0) {
68053                 index--;
68054                 stack.pop();
68055             }
68056             return change(previous);
68057         },
68058
68059
68060         // Back to the previous annotated state or index = 0.
68061         undo: function() {
68062             d3_select(document).interrupt('history.perform');
68063
68064             var previous = stack[index].graph;
68065             while (index > 0) {
68066                 index--;
68067                 if (stack[index].annotation) break;
68068             }
68069
68070             dispatch$$1.call('undone', this, stack[index]);
68071             return change(previous);
68072         },
68073
68074
68075         // Forward to the next annotated state.
68076         redo: function() {
68077             d3_select(document).interrupt('history.perform');
68078
68079             var previous = stack[index].graph;
68080             var tryIndex = index;
68081             while (tryIndex < stack.length - 1) {
68082                 tryIndex++;
68083                 if (stack[tryIndex].annotation) {
68084                     index = tryIndex;
68085                     dispatch$$1.call('redone', this, stack[index]);
68086                     break;
68087                 }
68088             }
68089
68090             return change(previous);
68091         },
68092
68093
68094         undoAnnotation: function() {
68095             var i = index;
68096             while (i >= 0) {
68097                 if (stack[i].annotation) return stack[i].annotation;
68098                 i--;
68099             }
68100         },
68101
68102
68103         redoAnnotation: function() {
68104             var i = index + 1;
68105             while (i <= stack.length - 1) {
68106                 if (stack[i].annotation) return stack[i].annotation;
68107                 i++;
68108             }
68109         },
68110
68111
68112         intersects: function(extent) {
68113             return tree.intersects(extent, stack[index].graph);
68114         },
68115
68116
68117         difference: function() {
68118             var base = stack[0].graph,
68119                 head = stack[index].graph;
68120             return coreDifference(base, head);
68121         },
68122
68123
68124         changes: function(action) {
68125             var base = stack[0].graph,
68126                 head = stack[index].graph;
68127
68128             if (action) {
68129                 head = action(head);
68130             }
68131
68132             var difference$$1 = coreDifference(base, head);
68133
68134             return {
68135                 modified: difference$$1.modified(),
68136                 created: difference$$1.created(),
68137                 deleted: difference$$1.deleted()
68138             };
68139         },
68140
68141
68142         validate: function(changes) {
68143             return flatten(
68144                 map$4(Validations, function(fn) { return fn()(changes, stack[index].graph); })
68145             );
68146         },
68147
68148
68149         hasChanges: function() {
68150             return this.difference().length() > 0;
68151         },
68152
68153
68154         imageryUsed: function(sources) {
68155             if (sources) {
68156                 imageryUsed = sources;
68157                 return history;
68158             } else {
68159                 var arr = map$4(stack.slice(1, index + 1), 'imageryUsed');
68160                 return without(uniq(flatten(arr)), 'Custom');
68161             }
68162         },
68163
68164
68165         // save the current history state
68166         checkpoint: function(key) {
68167             checkpoints[key] = {
68168                 stack: cloneDeep(stack),
68169                 index: index
68170             };
68171             return history;
68172         },
68173
68174
68175         // restore history state to a given checkpoint or reset completely
68176         reset: function(key) {
68177             if (key !== undefined && checkpoints.hasOwnProperty(key)) {
68178                 stack = cloneDeep(checkpoints[key].stack);
68179                 index = checkpoints[key].index;
68180             } else {
68181                 stack = [{graph: coreGraph()}];
68182                 index = 0;
68183                 tree = coreTree(stack[0].graph);
68184                 checkpoints = {};
68185             }
68186             dispatch$$1.call('change');
68187             return history;
68188         },
68189
68190
68191         toIntroGraph: function() {
68192             var nextId = { n: 0, r: 0, w: 0 },
68193                 permIds = {},
68194                 graph = this.graph(),
68195                 baseEntities = {};
68196
68197             // clone base entities..
68198             forEach(graph.base().entities, function(entity) {
68199                 var copy = cloneDeepWith(entity, customizer);
68200                 baseEntities[copy.id] = copy;
68201             });
68202
68203             // replace base entities with head entities..
68204             forEach(graph.entities, function(entity, id) {
68205                 if (entity) {
68206                     var copy = cloneDeepWith(entity, customizer);
68207                     baseEntities[copy.id] = copy;
68208                 } else {
68209                     delete baseEntities[id];
68210                 }
68211             });
68212
68213             // swap temporary for permanent ids..
68214             forEach(baseEntities, function(entity) {
68215                 if (Array.isArray(entity.nodes)) {
68216                     entity.nodes = entity.nodes.map(function(node) {
68217                         return permIds[node] || node;
68218                     });
68219                 }
68220                 if (Array.isArray(entity.members)) {
68221                     entity.members = entity.members.map(function(member) {
68222                         member.id = permIds[member.id] || member.id;
68223                         return member;
68224                     });
68225                 }
68226             });
68227
68228             return JSON.stringify({ dataIntroGraph: baseEntities });
68229
68230
68231             function customizer(src) {
68232                 var copy = omit(cloneDeep(src), ['type', 'user', 'v', 'version', 'visible']);
68233                 if (isEmpty(copy.tags)) {
68234                     delete copy.tags;
68235                 }
68236
68237                 if (Array.isArray(copy.loc)) {
68238                     copy.loc[0] = +copy.loc[0].toFixed(6);
68239                     copy.loc[1] = +copy.loc[1].toFixed(6);
68240                 }
68241
68242                 var match = src.id.match(/([nrw])-\d*/);  // temporary id
68243                 if (match !== null) {
68244                     var nrw = match[1], permId;
68245                     do { permId = nrw + (++nextId[nrw]); }
68246                     while (baseEntities.hasOwnProperty(permId));
68247
68248                     copy.id = permIds[src.id] = permId;
68249                 }
68250                 return copy;
68251             }
68252         },
68253
68254
68255         toJSON: function() {
68256             if (!this.hasChanges()) return;
68257
68258             var allEntities = {},
68259                 baseEntities = {},
68260                 base = stack[0];
68261
68262             var s = stack.map(function(i) {
68263                 var modified = [], deleted = [];
68264
68265                 forEach(i.graph.entities, function(entity, id) {
68266                     if (entity) {
68267                         var key = osmEntity.key(entity);
68268                         allEntities[key] = entity;
68269                         modified.push(key);
68270                     } else {
68271                         deleted.push(id);
68272                     }
68273
68274                     // make sure that the originals of changed or deleted entities get merged
68275                     // into the base of the stack after restoring the data from JSON.
68276                     if (id in base.graph.entities) {
68277                         baseEntities[id] = base.graph.entities[id];
68278                     }
68279                     // get originals of parent entities too
68280                     forEach(base.graph._parentWays[id], function(parentId) {
68281                         if (parentId in base.graph.entities) {
68282                             baseEntities[parentId] = base.graph.entities[parentId];
68283                         }
68284                     });
68285                 });
68286
68287                 var x = {};
68288
68289                 if (modified.length) x.modified = modified;
68290                 if (deleted.length) x.deleted = deleted;
68291                 if (i.imageryUsed) x.imageryUsed = i.imageryUsed;
68292                 if (i.annotation) x.annotation = i.annotation;
68293
68294                 return x;
68295             });
68296
68297             return JSON.stringify({
68298                 version: 3,
68299                 entities: values$1(allEntities),
68300                 baseEntities: values$1(baseEntities),
68301                 stack: s,
68302                 nextIDs: osmEntity.id.next,
68303                 index: index
68304             });
68305         },
68306
68307
68308         fromJSON: function(json, loadChildNodes) {
68309             var h = JSON.parse(json),
68310                 loadComplete = true;
68311
68312             osmEntity.id.next = h.nextIDs;
68313             index = h.index;
68314
68315             if (h.version === 2 || h.version === 3) {
68316                 var allEntities = {};
68317
68318                 h.entities.forEach(function(entity) {
68319                     allEntities[osmEntity.key(entity)] = osmEntity(entity);
68320                 });
68321
68322                 if (h.version === 3) {
68323                     // This merges originals for changed entities into the base of
68324                     // the stack even if the current stack doesn't have them (for
68325                     // example when iD has been restarted in a different region)
68326                     var baseEntities = h.baseEntities.map(function(d) { return osmEntity(d); });
68327                     stack[0].graph.rebase(baseEntities, map$4(stack, 'graph'), true);
68328                     tree.rebase(baseEntities, true);
68329
68330                     // When we restore a modified way, we also need to fetch any missing
68331                     // childnodes that would normally have been downloaded with it.. #2142
68332                     if (loadChildNodes) {
68333                         var osm = context.connection();
68334                         var nodes = flatten(uniq(map$4(filter(baseEntities, { type: 'way' }), 'nodes')));
68335                         var missing = reject(nodes, function(n) { return stack[0].graph.hasEntity(n); });
68336
68337                         if (!isEmpty(missing) && osm) {
68338                             loadComplete = false;
68339                             context.redrawEnable(false);
68340
68341                             var loading = uiLoading(context).blocking(true);
68342                             context.container().call(loading);
68343
68344                             var childNodesLoaded = function(err, result) {
68345                                 if (!err) {
68346                                     var visible = groupBy(result.data, 'visible');
68347                                     if (!isEmpty(visible.true)) {
68348                                         missing = difference(missing, map$4(visible.true, 'id'));
68349                                         stack[0].graph.rebase(visible.true, map$4(stack, 'graph'), true);
68350                                         tree.rebase(visible.true, true);
68351                                     }
68352
68353                                     // fetch older versions of nodes that were deleted..
68354                                     forEach(visible.false, function(entity) {
68355                                         osm.loadEntityVersion(entity.id, +entity.version - 1, childNodesLoaded);
68356                                     });
68357                                 }
68358
68359                                 if (err || isEmpty(missing)) {
68360                                     loading.close();
68361                                     context.redrawEnable(true);
68362                                     dispatch$$1.call('change');
68363                                 }
68364                             };
68365
68366                             osm.loadMultiple(missing, childNodesLoaded);
68367                         }
68368                     }
68369                 }
68370
68371                 stack = h.stack.map(function(d) {
68372                     var entities = {}, entity;
68373
68374                     if (d.modified) {
68375                         d.modified.forEach(function(key) {
68376                             entity = allEntities[key];
68377                             entities[entity.id] = entity;
68378                         });
68379                     }
68380
68381                     if (d.deleted) {
68382                         d.deleted.forEach(function(id) {
68383                             entities[id] = undefined;
68384                         });
68385                     }
68386
68387                     return {
68388                         graph: coreGraph(stack[0].graph).load(entities),
68389                         annotation: d.annotation,
68390                         imageryUsed: d.imageryUsed
68391                     };
68392                 });
68393
68394             } else { // original version
68395                 stack = h.stack.map(function(d) {
68396                     var entities = {};
68397
68398                     for (var i in d.entities) {
68399                         var entity = d.entities[i];
68400                         entities[i] = entity === 'undefined' ? undefined : osmEntity(entity);
68401                     }
68402
68403                     d.graph = coreGraph(stack[0].graph).load(entities);
68404                     return d;
68405                 });
68406             }
68407
68408             if (loadComplete) {
68409                 dispatch$$1.call('change');
68410             }
68411
68412             return history;
68413         },
68414
68415
68416         save: function() {
68417             if (lock.locked()) context.storage(getKey('saved_history'), history.toJSON() || null);
68418             return history;
68419         },
68420
68421
68422         clearSaved: function() {
68423             context.debouncedSave.cancel();
68424             if (lock.locked()) context.storage(getKey('saved_history'), null);
68425             return history;
68426         },
68427
68428
68429         lock: function() {
68430             return lock.lock();
68431         },
68432
68433
68434         unlock: function() {
68435             lock.unlock();
68436         },
68437
68438
68439         // is iD not open in another window and it detects that
68440         // there's a history stored in localStorage that's recoverable?
68441         restorableChanges: function() {
68442             return lock.locked() && !!context.storage(getKey('saved_history'));
68443         },
68444
68445
68446         // load history from a version stored in localStorage
68447         restore: function() {
68448             if (!lock.locked()) return;
68449
68450             var json = context.storage(getKey('saved_history'));
68451             if (json) history.fromJSON(json, true);
68452         },
68453
68454
68455         _getKey: getKey
68456
68457     };
68458
68459
68460     history.reset();
68461
68462     return utilRebind(history, dispatch$$1, 'on');
68463 }
68464
68465 /** Used to store function metadata. */
68466 var metaMap = WeakMap && new WeakMap;
68467
68468 /**
68469  * The base implementation of `setData` without support for hot loop shorting.
68470  *
68471  * @private
68472  * @param {Function} func The function to associate metadata with.
68473  * @param {*} data The metadata.
68474  * @returns {Function} Returns `func`.
68475  */
68476 var baseSetData = !metaMap ? identity$8 : function(func, data) {
68477   metaMap.set(func, data);
68478   return func;
68479 };
68480
68481 /**
68482  * Creates a function that produces an instance of `Ctor` regardless of
68483  * whether it was invoked as part of a `new` expression or by `call` or `apply`.
68484  *
68485  * @private
68486  * @param {Function} Ctor The constructor to wrap.
68487  * @returns {Function} Returns the new wrapped function.
68488  */
68489 function createCtor(Ctor) {
68490   return function() {
68491     // Use a `switch` statement to work with class constructors. See
68492     // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
68493     // for more details.
68494     var args = arguments;
68495     switch (args.length) {
68496       case 0: return new Ctor;
68497       case 1: return new Ctor(args[0]);
68498       case 2: return new Ctor(args[0], args[1]);
68499       case 3: return new Ctor(args[0], args[1], args[2]);
68500       case 4: return new Ctor(args[0], args[1], args[2], args[3]);
68501       case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
68502       case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
68503       case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
68504     }
68505     var thisBinding = baseCreate(Ctor.prototype),
68506         result = Ctor.apply(thisBinding, args);
68507
68508     // Mimic the constructor's `return` behavior.
68509     // See https://es5.github.io/#x13.2.2 for more details.
68510     return isObject(result) ? result : thisBinding;
68511   };
68512 }
68513
68514 /** Used to compose bitmasks for function metadata. */
68515 var WRAP_BIND_FLAG = 1;
68516
68517 /**
68518  * Creates a function that wraps `func` to invoke it with the optional `this`
68519  * binding of `thisArg`.
68520  *
68521  * @private
68522  * @param {Function} func The function to wrap.
68523  * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
68524  * @param {*} [thisArg] The `this` binding of `func`.
68525  * @returns {Function} Returns the new wrapped function.
68526  */
68527 function createBind(func, bitmask, thisArg) {
68528   var isBind = bitmask & WRAP_BIND_FLAG,
68529       Ctor = createCtor(func);
68530
68531   function wrapper() {
68532     var fn = (this && this !== root$2 && this instanceof wrapper) ? Ctor : func;
68533     return fn.apply(isBind ? thisArg : this, arguments);
68534   }
68535   return wrapper;
68536 }
68537
68538 /* Built-in method references for those with the same name as other `lodash` methods. */
68539 var nativeMax$5 = Math.max;
68540
68541 /**
68542  * Creates an array that is the composition of partially applied arguments,
68543  * placeholders, and provided arguments into a single array of arguments.
68544  *
68545  * @private
68546  * @param {Array} args The provided arguments.
68547  * @param {Array} partials The arguments to prepend to those provided.
68548  * @param {Array} holders The `partials` placeholder indexes.
68549  * @params {boolean} [isCurried] Specify composing for a curried function.
68550  * @returns {Array} Returns the new array of composed arguments.
68551  */
68552 function composeArgs(args, partials, holders, isCurried) {
68553   var argsIndex = -1,
68554       argsLength = args.length,
68555       holdersLength = holders.length,
68556       leftIndex = -1,
68557       leftLength = partials.length,
68558       rangeLength = nativeMax$5(argsLength - holdersLength, 0),
68559       result = Array(leftLength + rangeLength),
68560       isUncurried = !isCurried;
68561
68562   while (++leftIndex < leftLength) {
68563     result[leftIndex] = partials[leftIndex];
68564   }
68565   while (++argsIndex < holdersLength) {
68566     if (isUncurried || argsIndex < argsLength) {
68567       result[holders[argsIndex]] = args[argsIndex];
68568     }
68569   }
68570   while (rangeLength--) {
68571     result[leftIndex++] = args[argsIndex++];
68572   }
68573   return result;
68574 }
68575
68576 /* Built-in method references for those with the same name as other `lodash` methods. */
68577 var nativeMax$6 = Math.max;
68578
68579 /**
68580  * This function is like `composeArgs` except that the arguments composition
68581  * is tailored for `_.partialRight`.
68582  *
68583  * @private
68584  * @param {Array} args The provided arguments.
68585  * @param {Array} partials The arguments to append to those provided.
68586  * @param {Array} holders The `partials` placeholder indexes.
68587  * @params {boolean} [isCurried] Specify composing for a curried function.
68588  * @returns {Array} Returns the new array of composed arguments.
68589  */
68590 function composeArgsRight(args, partials, holders, isCurried) {
68591   var argsIndex = -1,
68592       argsLength = args.length,
68593       holdersIndex = -1,
68594       holdersLength = holders.length,
68595       rightIndex = -1,
68596       rightLength = partials.length,
68597       rangeLength = nativeMax$6(argsLength - holdersLength, 0),
68598       result = Array(rangeLength + rightLength),
68599       isUncurried = !isCurried;
68600
68601   while (++argsIndex < rangeLength) {
68602     result[argsIndex] = args[argsIndex];
68603   }
68604   var offset = argsIndex;
68605   while (++rightIndex < rightLength) {
68606     result[offset + rightIndex] = partials[rightIndex];
68607   }
68608   while (++holdersIndex < holdersLength) {
68609     if (isUncurried || argsIndex < argsLength) {
68610       result[offset + holders[holdersIndex]] = args[argsIndex++];
68611     }
68612   }
68613   return result;
68614 }
68615
68616 /**
68617  * Gets the number of `placeholder` occurrences in `array`.
68618  *
68619  * @private
68620  * @param {Array} array The array to inspect.
68621  * @param {*} placeholder The placeholder to search for.
68622  * @returns {number} Returns the placeholder count.
68623  */
68624 function countHolders(array, placeholder) {
68625   var length = array.length,
68626       result = 0;
68627
68628   while (length--) {
68629     if (array[length] === placeholder) {
68630       ++result;
68631     }
68632   }
68633   return result;
68634 }
68635
68636 /**
68637  * The function whose prototype chain sequence wrappers inherit from.
68638  *
68639  * @private
68640  */
68641 function baseLodash() {
68642   // No operation performed.
68643 }
68644
68645 /** Used as references for the maximum length and index of an array. */
68646 var MAX_ARRAY_LENGTH = 4294967295;
68647
68648 /**
68649  * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
68650  *
68651  * @private
68652  * @constructor
68653  * @param {*} value The value to wrap.
68654  */
68655 function LazyWrapper(value) {
68656   this.__wrapped__ = value;
68657   this.__actions__ = [];
68658   this.__dir__ = 1;
68659   this.__filtered__ = false;
68660   this.__iteratees__ = [];
68661   this.__takeCount__ = MAX_ARRAY_LENGTH;
68662   this.__views__ = [];
68663 }
68664
68665 // Ensure `LazyWrapper` is an instance of `baseLodash`.
68666 LazyWrapper.prototype = baseCreate(baseLodash.prototype);
68667 LazyWrapper.prototype.constructor = LazyWrapper;
68668
68669 /**
68670  * Gets metadata for `func`.
68671  *
68672  * @private
68673  * @param {Function} func The function to query.
68674  * @returns {*} Returns the metadata for `func`.
68675  */
68676 var getData = !metaMap ? noop$3 : function(func) {
68677   return metaMap.get(func);
68678 };
68679
68680 /** Used to lookup unminified function names. */
68681 var realNames = {};
68682
68683 /** Used for built-in method references. */
68684 var objectProto$19 = Object.prototype;
68685
68686 /** Used to check objects for own properties. */
68687 var hasOwnProperty$17 = objectProto$19.hasOwnProperty;
68688
68689 /**
68690  * Gets the name of `func`.
68691  *
68692  * @private
68693  * @param {Function} func The function to query.
68694  * @returns {string} Returns the function name.
68695  */
68696 function getFuncName(func) {
68697   var result = (func.name + ''),
68698       array = realNames[result],
68699       length = hasOwnProperty$17.call(realNames, result) ? array.length : 0;
68700
68701   while (length--) {
68702     var data = array[length],
68703         otherFunc = data.func;
68704     if (otherFunc == null || otherFunc == func) {
68705       return data.name;
68706     }
68707   }
68708   return result;
68709 }
68710
68711 /**
68712  * The base constructor for creating `lodash` wrapper objects.
68713  *
68714  * @private
68715  * @param {*} value The value to wrap.
68716  * @param {boolean} [chainAll] Enable explicit method chain sequences.
68717  */
68718 function LodashWrapper(value, chainAll) {
68719   this.__wrapped__ = value;
68720   this.__actions__ = [];
68721   this.__chain__ = !!chainAll;
68722   this.__index__ = 0;
68723   this.__values__ = undefined;
68724 }
68725
68726 LodashWrapper.prototype = baseCreate(baseLodash.prototype);
68727 LodashWrapper.prototype.constructor = LodashWrapper;
68728
68729 /**
68730  * Creates a clone of `wrapper`.
68731  *
68732  * @private
68733  * @param {Object} wrapper The wrapper to clone.
68734  * @returns {Object} Returns the cloned wrapper.
68735  */
68736 function wrapperClone(wrapper) {
68737   if (wrapper instanceof LazyWrapper) {
68738     return wrapper.clone();
68739   }
68740   var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
68741   result.__actions__ = copyArray(wrapper.__actions__);
68742   result.__index__  = wrapper.__index__;
68743   result.__values__ = wrapper.__values__;
68744   return result;
68745 }
68746
68747 /** Used for built-in method references. */
68748 var objectProto$20 = Object.prototype;
68749
68750 /** Used to check objects for own properties. */
68751 var hasOwnProperty$18 = objectProto$20.hasOwnProperty;
68752
68753 /**
68754  * Creates a `lodash` object which wraps `value` to enable implicit method
68755  * chain sequences. Methods that operate on and return arrays, collections,
68756  * and functions can be chained together. Methods that retrieve a single value
68757  * or may return a primitive value will automatically end the chain sequence
68758  * and return the unwrapped value. Otherwise, the value must be unwrapped
68759  * with `_#value`.
68760  *
68761  * Explicit chain sequences, which must be unwrapped with `_#value`, may be
68762  * enabled using `_.chain`.
68763  *
68764  * The execution of chained methods is lazy, that is, it's deferred until
68765  * `_#value` is implicitly or explicitly called.
68766  *
68767  * Lazy evaluation allows several methods to support shortcut fusion.
68768  * Shortcut fusion is an optimization to merge iteratee calls; this avoids
68769  * the creation of intermediate arrays and can greatly reduce the number of
68770  * iteratee executions. Sections of a chain sequence qualify for shortcut
68771  * fusion if the section is applied to an array and iteratees accept only
68772  * one argument. The heuristic for whether a section qualifies for shortcut
68773  * fusion is subject to change.
68774  *
68775  * Chaining is supported in custom builds as long as the `_#value` method is
68776  * directly or indirectly included in the build.
68777  *
68778  * In addition to lodash methods, wrappers have `Array` and `String` methods.
68779  *
68780  * The wrapper `Array` methods are:
68781  * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
68782  *
68783  * The wrapper `String` methods are:
68784  * `replace` and `split`
68785  *
68786  * The wrapper methods that support shortcut fusion are:
68787  * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
68788  * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
68789  * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
68790  *
68791  * The chainable wrapper methods are:
68792  * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
68793  * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
68794  * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
68795  * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
68796  * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
68797  * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
68798  * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
68799  * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
68800  * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
68801  * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
68802  * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
68803  * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
68804  * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
68805  * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
68806  * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
68807  * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
68808  * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
68809  * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
68810  * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
68811  * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
68812  * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
68813  * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
68814  * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
68815  * `zipObject`, `zipObjectDeep`, and `zipWith`
68816  *
68817  * The wrapper methods that are **not** chainable by default are:
68818  * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
68819  * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
68820  * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
68821  * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
68822  * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
68823  * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
68824  * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
68825  * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
68826  * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
68827  * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
68828  * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
68829  * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
68830  * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
68831  * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
68832  * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
68833  * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
68834  * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
68835  * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
68836  * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
68837  * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
68838  * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
68839  * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
68840  * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
68841  * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
68842  * `upperFirst`, `value`, and `words`
68843  *
68844  * @name _
68845  * @constructor
68846  * @category Seq
68847  * @param {*} value The value to wrap in a `lodash` instance.
68848  * @returns {Object} Returns the new `lodash` wrapper instance.
68849  * @example
68850  *
68851  * function square(n) {
68852  *   return n * n;
68853  * }
68854  *
68855  * var wrapped = _([1, 2, 3]);
68856  *
68857  * // Returns an unwrapped value.
68858  * wrapped.reduce(_.add);
68859  * // => 6
68860  *
68861  * // Returns a wrapped value.
68862  * var squares = wrapped.map(square);
68863  *
68864  * _.isArray(squares);
68865  * // => false
68866  *
68867  * _.isArray(squares.value());
68868  * // => true
68869  */
68870 function lodash(value) {
68871   if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
68872     if (value instanceof LodashWrapper) {
68873       return value;
68874     }
68875     if (hasOwnProperty$18.call(value, '__wrapped__')) {
68876       return wrapperClone(value);
68877     }
68878   }
68879   return new LodashWrapper(value);
68880 }
68881
68882 // Ensure wrappers are instances of `baseLodash`.
68883 lodash.prototype = baseLodash.prototype;
68884 lodash.prototype.constructor = lodash;
68885
68886 /**
68887  * Checks if `func` has a lazy counterpart.
68888  *
68889  * @private
68890  * @param {Function} func The function to check.
68891  * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
68892  *  else `false`.
68893  */
68894 function isLaziable(func) {
68895   var funcName = getFuncName(func),
68896       other = lodash[funcName];
68897
68898   if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
68899     return false;
68900   }
68901   if (func === other) {
68902     return true;
68903   }
68904   var data = getData(other);
68905   return !!data && func === data[0];
68906 }
68907
68908 /**
68909  * Sets metadata for `func`.
68910  *
68911  * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
68912  * period of time, it will trip its breaker and transition to an identity
68913  * function to avoid garbage collection pauses in V8. See
68914  * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
68915  * for more details.
68916  *
68917  * @private
68918  * @param {Function} func The function to associate metadata with.
68919  * @param {*} data The metadata.
68920  * @returns {Function} Returns `func`.
68921  */
68922 var setData = shortOut(baseSetData);
68923
68924 /** Used to match wrap detail comments. */
68925 var reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/;
68926 var reSplitDetails = /,? & /;
68927
68928 /**
68929  * Extracts wrapper details from the `source` body comment.
68930  *
68931  * @private
68932  * @param {string} source The source to inspect.
68933  * @returns {Array} Returns the wrapper details.
68934  */
68935 function getWrapDetails(source) {
68936   var match = source.match(reWrapDetails);
68937   return match ? match[1].split(reSplitDetails) : [];
68938 }
68939
68940 /** Used to match wrap detail comments. */
68941 var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/;
68942
68943 /**
68944  * Inserts wrapper `details` in a comment at the top of the `source` body.
68945  *
68946  * @private
68947  * @param {string} source The source to modify.
68948  * @returns {Array} details The details to insert.
68949  * @returns {string} Returns the modified source.
68950  */
68951 function insertWrapDetails(source, details) {
68952   var length = details.length;
68953   if (!length) {
68954     return source;
68955   }
68956   var lastIndex = length - 1;
68957   details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
68958   details = details.join(length > 2 ? ', ' : ' ');
68959   return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
68960 }
68961
68962 /** Used to compose bitmasks for function metadata. */
68963 var WRAP_BIND_FLAG$1 = 1;
68964 var WRAP_BIND_KEY_FLAG = 2;
68965 var WRAP_CURRY_FLAG = 8;
68966 var WRAP_CURRY_RIGHT_FLAG = 16;
68967 var WRAP_PARTIAL_FLAG = 32;
68968 var WRAP_PARTIAL_RIGHT_FLAG = 64;
68969 var WRAP_ARY_FLAG = 128;
68970 var WRAP_REARG_FLAG = 256;
68971 var WRAP_FLIP_FLAG = 512;
68972
68973 /** Used to associate wrap methods with their bit flags. */
68974 var wrapFlags = [
68975   ['ary', WRAP_ARY_FLAG],
68976   ['bind', WRAP_BIND_FLAG$1],
68977   ['bindKey', WRAP_BIND_KEY_FLAG],
68978   ['curry', WRAP_CURRY_FLAG],
68979   ['curryRight', WRAP_CURRY_RIGHT_FLAG],
68980   ['flip', WRAP_FLIP_FLAG],
68981   ['partial', WRAP_PARTIAL_FLAG],
68982   ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
68983   ['rearg', WRAP_REARG_FLAG]
68984 ];
68985
68986 /**
68987  * Updates wrapper `details` based on `bitmask` flags.
68988  *
68989  * @private
68990  * @returns {Array} details The details to modify.
68991  * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
68992  * @returns {Array} Returns `details`.
68993  */
68994 function updateWrapDetails(details, bitmask) {
68995   arrayEach(wrapFlags, function(pair) {
68996     var value = '_.' + pair[0];
68997     if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
68998       details.push(value);
68999     }
69000   });
69001   return details.sort();
69002 }
69003
69004 /**
69005  * Sets the `toString` method of `wrapper` to mimic the source of `reference`
69006  * with wrapper details in a comment at the top of the source body.
69007  *
69008  * @private
69009  * @param {Function} wrapper The function to modify.
69010  * @param {Function} reference The reference function.
69011  * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
69012  * @returns {Function} Returns `wrapper`.
69013  */
69014 function setWrapToString(wrapper, reference, bitmask) {
69015   var source = (reference + '');
69016   return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
69017 }
69018
69019 /** Used to compose bitmasks for function metadata. */
69020 var WRAP_BIND_FLAG$2 = 1;
69021 var WRAP_BIND_KEY_FLAG$1 = 2;
69022 var WRAP_CURRY_BOUND_FLAG = 4;
69023 var WRAP_CURRY_FLAG$1 = 8;
69024 var WRAP_PARTIAL_FLAG$1 = 32;
69025 var WRAP_PARTIAL_RIGHT_FLAG$1 = 64;
69026
69027 /**
69028  * Creates a function that wraps `func` to continue currying.
69029  *
69030  * @private
69031  * @param {Function} func The function to wrap.
69032  * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
69033  * @param {Function} wrapFunc The function to create the `func` wrapper.
69034  * @param {*} placeholder The placeholder value.
69035  * @param {*} [thisArg] The `this` binding of `func`.
69036  * @param {Array} [partials] The arguments to prepend to those provided to
69037  *  the new function.
69038  * @param {Array} [holders] The `partials` placeholder indexes.
69039  * @param {Array} [argPos] The argument positions of the new function.
69040  * @param {number} [ary] The arity cap of `func`.
69041  * @param {number} [arity] The arity of `func`.
69042  * @returns {Function} Returns the new wrapped function.
69043  */
69044 function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
69045   var isCurry = bitmask & WRAP_CURRY_FLAG$1,
69046       newHolders = isCurry ? holders : undefined,
69047       newHoldersRight = isCurry ? undefined : holders,
69048       newPartials = isCurry ? partials : undefined,
69049       newPartialsRight = isCurry ? undefined : partials;
69050
69051   bitmask |= (isCurry ? WRAP_PARTIAL_FLAG$1 : WRAP_PARTIAL_RIGHT_FLAG$1);
69052   bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG$1 : WRAP_PARTIAL_FLAG$1);
69053
69054   if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
69055     bitmask &= ~(WRAP_BIND_FLAG$2 | WRAP_BIND_KEY_FLAG$1);
69056   }
69057   var newData = [
69058     func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
69059     newHoldersRight, argPos, ary, arity
69060   ];
69061
69062   var result = wrapFunc.apply(undefined, newData);
69063   if (isLaziable(func)) {
69064     setData(result, newData);
69065   }
69066   result.placeholder = placeholder;
69067   return setWrapToString(result, func, bitmask);
69068 }
69069
69070 /**
69071  * Gets the argument placeholder value for `func`.
69072  *
69073  * @private
69074  * @param {Function} func The function to inspect.
69075  * @returns {*} Returns the placeholder value.
69076  */
69077 function getHolder(func) {
69078   var object = func;
69079   return object.placeholder;
69080 }
69081
69082 /* Built-in method references for those with the same name as other `lodash` methods. */
69083 var nativeMin$2 = Math.min;
69084
69085 /**
69086  * Reorder `array` according to the specified indexes where the element at
69087  * the first index is assigned as the first element, the element at
69088  * the second index is assigned as the second element, and so on.
69089  *
69090  * @private
69091  * @param {Array} array The array to reorder.
69092  * @param {Array} indexes The arranged array indexes.
69093  * @returns {Array} Returns `array`.
69094  */
69095 function reorder(array, indexes) {
69096   var arrLength = array.length,
69097       length = nativeMin$2(indexes.length, arrLength),
69098       oldArray = copyArray(array);
69099
69100   while (length--) {
69101     var index = indexes[length];
69102     array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
69103   }
69104   return array;
69105 }
69106
69107 /** Used as the internal argument placeholder. */
69108 var PLACEHOLDER = '__lodash_placeholder__';
69109
69110 /**
69111  * Replaces all `placeholder` elements in `array` with an internal placeholder
69112  * and returns an array of their indexes.
69113  *
69114  * @private
69115  * @param {Array} array The array to modify.
69116  * @param {*} placeholder The placeholder to replace.
69117  * @returns {Array} Returns the new array of placeholder indexes.
69118  */
69119 function replaceHolders(array, placeholder) {
69120   var index = -1,
69121       length = array.length,
69122       resIndex = 0,
69123       result = [];
69124
69125   while (++index < length) {
69126     var value = array[index];
69127     if (value === placeholder || value === PLACEHOLDER) {
69128       array[index] = PLACEHOLDER;
69129       result[resIndex++] = index;
69130     }
69131   }
69132   return result;
69133 }
69134
69135 /** Used to compose bitmasks for function metadata. */
69136 var WRAP_BIND_FLAG$3 = 1;
69137 var WRAP_BIND_KEY_FLAG$2 = 2;
69138 var WRAP_CURRY_FLAG$2 = 8;
69139 var WRAP_CURRY_RIGHT_FLAG$1 = 16;
69140 var WRAP_ARY_FLAG$1 = 128;
69141 var WRAP_FLIP_FLAG$1 = 512;
69142
69143 /**
69144  * Creates a function that wraps `func` to invoke it with optional `this`
69145  * binding of `thisArg`, partial application, and currying.
69146  *
69147  * @private
69148  * @param {Function|string} func The function or method name to wrap.
69149  * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
69150  * @param {*} [thisArg] The `this` binding of `func`.
69151  * @param {Array} [partials] The arguments to prepend to those provided to
69152  *  the new function.
69153  * @param {Array} [holders] The `partials` placeholder indexes.
69154  * @param {Array} [partialsRight] The arguments to append to those provided
69155  *  to the new function.
69156  * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
69157  * @param {Array} [argPos] The argument positions of the new function.
69158  * @param {number} [ary] The arity cap of `func`.
69159  * @param {number} [arity] The arity of `func`.
69160  * @returns {Function} Returns the new wrapped function.
69161  */
69162 function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
69163   var isAry = bitmask & WRAP_ARY_FLAG$1,
69164       isBind = bitmask & WRAP_BIND_FLAG$3,
69165       isBindKey = bitmask & WRAP_BIND_KEY_FLAG$2,
69166       isCurried = bitmask & (WRAP_CURRY_FLAG$2 | WRAP_CURRY_RIGHT_FLAG$1),
69167       isFlip = bitmask & WRAP_FLIP_FLAG$1,
69168       Ctor = isBindKey ? undefined : createCtor(func);
69169
69170   function wrapper() {
69171     var length = arguments.length,
69172         args = Array(length),
69173         index = length;
69174
69175     while (index--) {
69176       args[index] = arguments[index];
69177     }
69178     if (isCurried) {
69179       var placeholder = getHolder(wrapper),
69180           holdersCount = countHolders(args, placeholder);
69181     }
69182     if (partials) {
69183       args = composeArgs(args, partials, holders, isCurried);
69184     }
69185     if (partialsRight) {
69186       args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
69187     }
69188     length -= holdersCount;
69189     if (isCurried && length < arity) {
69190       var newHolders = replaceHolders(args, placeholder);
69191       return createRecurry(
69192         func, bitmask, createHybrid, wrapper.placeholder, thisArg,
69193         args, newHolders, argPos, ary, arity - length
69194       );
69195     }
69196     var thisBinding = isBind ? thisArg : this,
69197         fn = isBindKey ? thisBinding[func] : func;
69198
69199     length = args.length;
69200     if (argPos) {
69201       args = reorder(args, argPos);
69202     } else if (isFlip && length > 1) {
69203       args.reverse();
69204     }
69205     if (isAry && ary < length) {
69206       args.length = ary;
69207     }
69208     if (this && this !== root$2 && this instanceof wrapper) {
69209       fn = Ctor || createCtor(fn);
69210     }
69211     return fn.apply(thisBinding, args);
69212   }
69213   return wrapper;
69214 }
69215
69216 /**
69217  * Creates a function that wraps `func` to enable currying.
69218  *
69219  * @private
69220  * @param {Function} func The function to wrap.
69221  * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
69222  * @param {number} arity The arity of `func`.
69223  * @returns {Function} Returns the new wrapped function.
69224  */
69225 function createCurry(func, bitmask, arity) {
69226   var Ctor = createCtor(func);
69227
69228   function wrapper() {
69229     var length = arguments.length,
69230         args = Array(length),
69231         index = length,
69232         placeholder = getHolder(wrapper);
69233
69234     while (index--) {
69235       args[index] = arguments[index];
69236     }
69237     var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
69238       ? []
69239       : replaceHolders(args, placeholder);
69240
69241     length -= holders.length;
69242     if (length < arity) {
69243       return createRecurry(
69244         func, bitmask, createHybrid, wrapper.placeholder, undefined,
69245         args, holders, undefined, undefined, arity - length);
69246     }
69247     var fn = (this && this !== root$2 && this instanceof wrapper) ? Ctor : func;
69248     return apply(fn, this, args);
69249   }
69250   return wrapper;
69251 }
69252
69253 /** Used to compose bitmasks for function metadata. */
69254 var WRAP_BIND_FLAG$4 = 1;
69255
69256 /**
69257  * Creates a function that wraps `func` to invoke it with the `this` binding
69258  * of `thisArg` and `partials` prepended to the arguments it receives.
69259  *
69260  * @private
69261  * @param {Function} func The function to wrap.
69262  * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
69263  * @param {*} thisArg The `this` binding of `func`.
69264  * @param {Array} partials The arguments to prepend to those provided to
69265  *  the new function.
69266  * @returns {Function} Returns the new wrapped function.
69267  */
69268 function createPartial(func, bitmask, thisArg, partials) {
69269   var isBind = bitmask & WRAP_BIND_FLAG$4,
69270       Ctor = createCtor(func);
69271
69272   function wrapper() {
69273     var argsIndex = -1,
69274         argsLength = arguments.length,
69275         leftIndex = -1,
69276         leftLength = partials.length,
69277         args = Array(leftLength + argsLength),
69278         fn = (this && this !== root$2 && this instanceof wrapper) ? Ctor : func;
69279
69280     while (++leftIndex < leftLength) {
69281       args[leftIndex] = partials[leftIndex];
69282     }
69283     while (argsLength--) {
69284       args[leftIndex++] = arguments[++argsIndex];
69285     }
69286     return apply(fn, isBind ? thisArg : this, args);
69287   }
69288   return wrapper;
69289 }
69290
69291 /** Used as the internal argument placeholder. */
69292 var PLACEHOLDER$1 = '__lodash_placeholder__';
69293
69294 /** Used to compose bitmasks for function metadata. */
69295 var WRAP_BIND_FLAG$5 = 1;
69296 var WRAP_BIND_KEY_FLAG$3 = 2;
69297 var WRAP_CURRY_BOUND_FLAG$1 = 4;
69298 var WRAP_CURRY_FLAG$3 = 8;
69299 var WRAP_ARY_FLAG$2 = 128;
69300 var WRAP_REARG_FLAG$1 = 256;
69301
69302 /* Built-in method references for those with the same name as other `lodash` methods. */
69303 var nativeMin$3 = Math.min;
69304
69305 /**
69306  * Merges the function metadata of `source` into `data`.
69307  *
69308  * Merging metadata reduces the number of wrappers used to invoke a function.
69309  * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
69310  * may be applied regardless of execution order. Methods like `_.ary` and
69311  * `_.rearg` modify function arguments, making the order in which they are
69312  * executed important, preventing the merging of metadata. However, we make
69313  * an exception for a safe combined case where curried functions have `_.ary`
69314  * and or `_.rearg` applied.
69315  *
69316  * @private
69317  * @param {Array} data The destination metadata.
69318  * @param {Array} source The source metadata.
69319  * @returns {Array} Returns `data`.
69320  */
69321 function mergeData(data, source) {
69322   var bitmask = data[1],
69323       srcBitmask = source[1],
69324       newBitmask = bitmask | srcBitmask,
69325       isCommon = newBitmask < (WRAP_BIND_FLAG$5 | WRAP_BIND_KEY_FLAG$3 | WRAP_ARY_FLAG$2);
69326
69327   var isCombo =
69328     ((srcBitmask == WRAP_ARY_FLAG$2) && (bitmask == WRAP_CURRY_FLAG$3)) ||
69329     ((srcBitmask == WRAP_ARY_FLAG$2) && (bitmask == WRAP_REARG_FLAG$1) && (data[7].length <= source[8])) ||
69330     ((srcBitmask == (WRAP_ARY_FLAG$2 | WRAP_REARG_FLAG$1)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG$3));
69331
69332   // Exit early if metadata can't be merged.
69333   if (!(isCommon || isCombo)) {
69334     return data;
69335   }
69336   // Use source `thisArg` if available.
69337   if (srcBitmask & WRAP_BIND_FLAG$5) {
69338     data[2] = source[2];
69339     // Set when currying a bound function.
69340     newBitmask |= bitmask & WRAP_BIND_FLAG$5 ? 0 : WRAP_CURRY_BOUND_FLAG$1;
69341   }
69342   // Compose partial arguments.
69343   var value = source[3];
69344   if (value) {
69345     var partials = data[3];
69346     data[3] = partials ? composeArgs(partials, value, source[4]) : value;
69347     data[4] = partials ? replaceHolders(data[3], PLACEHOLDER$1) : source[4];
69348   }
69349   // Compose partial right arguments.
69350   value = source[5];
69351   if (value) {
69352     partials = data[5];
69353     data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
69354     data[6] = partials ? replaceHolders(data[5], PLACEHOLDER$1) : source[6];
69355   }
69356   // Use source `argPos` if available.
69357   value = source[7];
69358   if (value) {
69359     data[7] = value;
69360   }
69361   // Use source `ary` if it's smaller.
69362   if (srcBitmask & WRAP_ARY_FLAG$2) {
69363     data[8] = data[8] == null ? source[8] : nativeMin$3(data[8], source[8]);
69364   }
69365   // Use source `arity` if one is not provided.
69366   if (data[9] == null) {
69367     data[9] = source[9];
69368   }
69369   // Use source `func` and merge bitmasks.
69370   data[0] = source[0];
69371   data[1] = newBitmask;
69372
69373   return data;
69374 }
69375
69376 /** Error message constants. */
69377 var FUNC_ERROR_TEXT$4 = 'Expected a function';
69378
69379 /** Used to compose bitmasks for function metadata. */
69380 var WRAP_BIND_FLAG$6 = 1;
69381 var WRAP_BIND_KEY_FLAG$4 = 2;
69382 var WRAP_CURRY_FLAG$4 = 8;
69383 var WRAP_CURRY_RIGHT_FLAG$2 = 16;
69384 var WRAP_PARTIAL_FLAG$2 = 32;
69385 var WRAP_PARTIAL_RIGHT_FLAG$2 = 64;
69386
69387 /* Built-in method references for those with the same name as other `lodash` methods. */
69388 var nativeMax$7 = Math.max;
69389
69390 /**
69391  * Creates a function that either curries or invokes `func` with optional
69392  * `this` binding and partially applied arguments.
69393  *
69394  * @private
69395  * @param {Function|string} func The function or method name to wrap.
69396  * @param {number} bitmask The bitmask flags.
69397  *    1 - `_.bind`
69398  *    2 - `_.bindKey`
69399  *    4 - `_.curry` or `_.curryRight` of a bound function
69400  *    8 - `_.curry`
69401  *   16 - `_.curryRight`
69402  *   32 - `_.partial`
69403  *   64 - `_.partialRight`
69404  *  128 - `_.rearg`
69405  *  256 - `_.ary`
69406  *  512 - `_.flip`
69407  * @param {*} [thisArg] The `this` binding of `func`.
69408  * @param {Array} [partials] The arguments to be partially applied.
69409  * @param {Array} [holders] The `partials` placeholder indexes.
69410  * @param {Array} [argPos] The argument positions of the new function.
69411  * @param {number} [ary] The arity cap of `func`.
69412  * @param {number} [arity] The arity of `func`.
69413  * @returns {Function} Returns the new wrapped function.
69414  */
69415 function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
69416   var isBindKey = bitmask & WRAP_BIND_KEY_FLAG$4;
69417   if (!isBindKey && typeof func != 'function') {
69418     throw new TypeError(FUNC_ERROR_TEXT$4);
69419   }
69420   var length = partials ? partials.length : 0;
69421   if (!length) {
69422     bitmask &= ~(WRAP_PARTIAL_FLAG$2 | WRAP_PARTIAL_RIGHT_FLAG$2);
69423     partials = holders = undefined;
69424   }
69425   ary = ary === undefined ? ary : nativeMax$7(toInteger(ary), 0);
69426   arity = arity === undefined ? arity : toInteger(arity);
69427   length -= holders ? holders.length : 0;
69428
69429   if (bitmask & WRAP_PARTIAL_RIGHT_FLAG$2) {
69430     var partialsRight = partials,
69431         holdersRight = holders;
69432
69433     partials = holders = undefined;
69434   }
69435   var data = isBindKey ? undefined : getData(func);
69436
69437   var newData = [
69438     func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
69439     argPos, ary, arity
69440   ];
69441
69442   if (data) {
69443     mergeData(newData, data);
69444   }
69445   func = newData[0];
69446   bitmask = newData[1];
69447   thisArg = newData[2];
69448   partials = newData[3];
69449   holders = newData[4];
69450   arity = newData[9] = newData[9] === undefined
69451     ? (isBindKey ? 0 : func.length)
69452     : nativeMax$7(newData[9] - length, 0);
69453
69454   if (!arity && bitmask & (WRAP_CURRY_FLAG$4 | WRAP_CURRY_RIGHT_FLAG$2)) {
69455     bitmask &= ~(WRAP_CURRY_FLAG$4 | WRAP_CURRY_RIGHT_FLAG$2);
69456   }
69457   if (!bitmask || bitmask == WRAP_BIND_FLAG$6) {
69458     var result = createBind(func, bitmask, thisArg);
69459   } else if (bitmask == WRAP_CURRY_FLAG$4 || bitmask == WRAP_CURRY_RIGHT_FLAG$2) {
69460     result = createCurry(func, bitmask, arity);
69461   } else if ((bitmask == WRAP_PARTIAL_FLAG$2 || bitmask == (WRAP_BIND_FLAG$6 | WRAP_PARTIAL_FLAG$2)) && !holders.length) {
69462     result = createPartial(func, bitmask, thisArg, partials);
69463   } else {
69464     result = createHybrid.apply(undefined, newData);
69465   }
69466   var setter = data ? baseSetData : setData;
69467   return setWrapToString(setter(result, newData), func, bitmask);
69468 }
69469
69470 /** Used to compose bitmasks for function metadata. */
69471 var WRAP_BIND_FLAG$7 = 1;
69472 var WRAP_PARTIAL_FLAG$3 = 32;
69473
69474 /**
69475  * Creates a function that invokes `func` with the `this` binding of `thisArg`
69476  * and `partials` prepended to the arguments it receives.
69477  *
69478  * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
69479  * may be used as a placeholder for partially applied arguments.
69480  *
69481  * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
69482  * property of bound functions.
69483  *
69484  * @static
69485  * @memberOf _
69486  * @since 0.1.0
69487  * @category Function
69488  * @param {Function} func The function to bind.
69489  * @param {*} thisArg The `this` binding of `func`.
69490  * @param {...*} [partials] The arguments to be partially applied.
69491  * @returns {Function} Returns the new bound function.
69492  * @example
69493  *
69494  * function greet(greeting, punctuation) {
69495  *   return greeting + ' ' + this.user + punctuation;
69496  * }
69497  *
69498  * var object = { 'user': 'fred' };
69499  *
69500  * var bound = _.bind(greet, object, 'hi');
69501  * bound('!');
69502  * // => 'hi fred!'
69503  *
69504  * // Bound with placeholders.
69505  * var bound = _.bind(greet, object, _, '!');
69506  * bound('hi');
69507  * // => 'hi fred!'
69508  */
69509 var bind$2 = baseRest(function(func, thisArg, partials) {
69510   var bitmask = WRAP_BIND_FLAG$7;
69511   if (partials.length) {
69512     var holders = replaceHolders(partials, getHolder(bind$2));
69513     bitmask |= WRAP_PARTIAL_FLAG$3;
69514   }
69515   return createWrap(func, bitmask, thisArg, partials, holders);
69516 });
69517
69518 // Assign default placeholders.
69519 bind$2.placeholder = {};
69520
69521 function presetCollection(collection) {
69522     var maxSearchResults = 50,
69523         maxSuggestionResults = 10;
69524
69525     var presets = {
69526
69527         collection: collection,
69528
69529
69530         item: function(id) {
69531             return find$1(this.collection, function(d) {
69532                 return d.id === id;
69533             });
69534         },
69535
69536
69537         matchGeometry: function(geometry) {
69538             return presetCollection(this.collection.filter(function(d) {
69539                 return d.matchGeometry(geometry);
69540             }));
69541         },
69542
69543
69544         search: function(value, geometry) {
69545             if (!value) return this;
69546
69547             function leading(a) {
69548                 var index = a.indexOf(value);
69549                 return index === 0 || a[index - 1] === ' ';
69550             }
69551
69552             function suggestionName(name) {
69553                 var nameArray = name.split(' - ');
69554                 if (nameArray.length > 1) {
69555                     name = nameArray.slice(0, nameArray.length - 1).join(' - ');
69556                 }
69557                 return name.toLowerCase();
69558             }
69559
69560
69561             value = value.toLowerCase();
69562
69563             var searchable = filter(this.collection, function(a) {
69564                     return a.searchable !== false && a.suggestion !== true;
69565                 }),
69566                 suggestions = filter(this.collection, function(a) {
69567                     return a.suggestion === true;
69568                 });
69569
69570
69571             // matches value to preset.name
69572             var leading_name = filter(searchable, function(a) {
69573                     return leading(a.name().toLowerCase());
69574                 }).sort(function(a, b) {
69575                     var aCompare = a.name().toLowerCase(),
69576                         bCompare = b.name().toLowerCase(),
69577                         i;
69578
69579                     // priority if search string matches preset name exactly - #4325
69580                     if (value === aCompare) return -1;
69581                     if (value === bCompare) return 1;
69582
69583                     // priority for higher matchScore
69584                     i = b.originalScore - a.originalScore;
69585                     if (i !== 0) return i;
69586
69587                     // priority if search string appears earlier in preset name
69588                     i = aCompare.indexOf(value) - bCompare.indexOf(value);
69589                     if (i !== 0) return i;
69590
69591                     // priority for shorter preset names
69592                     return a.name().length - b.name().length;
69593                 });
69594
69595             // matches value to preset.terms values
69596             var leading_terms = filter(searchable, function(a) {
69597                     return some(a.terms() || [], leading);
69598                 });
69599
69600             // matches value to preset.tags values
69601             var leading_tag_values = filter(searchable, function(a) {
69602                     return some(without(values$1(a.tags || {}), '*'), leading);
69603                 });
69604
69605
69606             // finds close matches to value in preset.name
69607             var similar_name = searchable.map(function(a) {
69608                     return {
69609                         preset: a,
69610                         dist: utilEditDistance(value, a.name())
69611                     };
69612                 }).filter(function(a) {
69613                     return a.dist + Math.min(value.length - a.preset.name().length, 0) < 3;
69614                 }).sort(function(a, b) {
69615                     return a.dist - b.dist;
69616                 }).map(function(a) {
69617                     return a.preset;
69618                 });
69619
69620             // finds close matches to value in preset.terms
69621             var similar_terms = filter(searchable, function(a) {
69622                     return some(a.terms() || [], function(b) {
69623                         return utilEditDistance(value, b) + Math.min(value.length - b.length, 0) < 3;
69624                     });
69625                 });
69626
69627             var leading_suggestions = filter(suggestions, function(a) {
69628                     return leading(suggestionName(a.name()));
69629                 }).sort(function(a, b) {
69630                     a = suggestionName(a.name());
69631                     b = suggestionName(b.name());
69632                     var i = a.indexOf(value) - b.indexOf(value);
69633                     if (i === 0) return a.length - b.length;
69634                     else return i;
69635                 });
69636
69637             var similar_suggestions = suggestions.map(function(a) {
69638                     return {
69639                         preset: a,
69640                         dist: utilEditDistance(value, suggestionName(a.name()))
69641                     };
69642                 }).filter(function(a) {
69643                     return a.dist + Math.min(value.length - suggestionName(a.preset.name()).length, 0) < 1;
69644                 }).sort(function(a, b) {
69645                     return a.dist - b.dist;
69646                 }).map(function(a) {
69647                     return a.preset;
69648                 });
69649
69650             var other = presets.item(geometry);
69651
69652             var results = leading_name.concat(
69653                     leading_terms,
69654                     leading_tag_values,
69655                     leading_suggestions.slice(0, maxSuggestionResults + 5),
69656                     similar_name,
69657                     similar_terms,
69658                     similar_suggestions.slice(0, maxSuggestionResults)
69659                 ).slice(0, maxSearchResults - 1);
69660
69661             return presetCollection(uniq(results.concat(other)));
69662         }
69663     };
69664
69665
69666     return presets;
69667 }
69668
69669 function presetCategory(id, category, all) {
69670     category = clone(category);
69671
69672     category.id = id;
69673
69674
69675     category.members = presetCollection(category.members.map(function(id) {
69676         return all.item(id);
69677     }));
69678
69679
69680     category.matchGeometry = function(geometry) {
69681         return category.geometry.indexOf(geometry) >= 0;
69682     };
69683
69684
69685     category.matchScore = function() {
69686         return -1;
69687     };
69688
69689
69690     category.name = function() {
69691         return t('presets.categories.' + id + '.name', {'default': id});
69692     };
69693
69694
69695     category.terms = function() {
69696         return [];
69697     };
69698
69699
69700     return category;
69701 }
69702
69703 function presetField(id, field) {
69704     field = clone(field);
69705
69706     field.id = id;
69707
69708
69709     field.matchGeometry = function(geometry) {
69710         return !field.geometry || field.geometry === geometry;
69711     };
69712
69713
69714     field.t = function(scope, options) {
69715         return t('presets.fields.' + id + '.' + scope, options);
69716     };
69717
69718
69719     field.label = function() {
69720         return field.t('label', {'default': id});
69721     };
69722
69723
69724     var placeholder = field.placeholder;
69725     field.placeholder = function() {
69726         return field.t('placeholder', {'default': placeholder});
69727     };
69728
69729
69730     return field;
69731 }
69732
69733 function presetPreset(id, preset, fields) {
69734     preset = clone(preset);
69735
69736     preset.id = id;
69737     preset.fields = (preset.fields || []).map(getFields);
69738     preset.geometry = (preset.geometry || []);
69739
69740
69741     function getFields(f) {
69742         return fields[f];
69743     }
69744
69745
69746     preset.matchGeometry = function(geometry) {
69747         return preset.geometry.indexOf(geometry) >= 0;
69748     };
69749
69750
69751     preset.originalScore = preset.matchScore || 1;
69752
69753
69754     preset.matchScore = function(entity) {
69755         var tags = preset.tags,
69756             score = 0;
69757
69758         for (var t$$1 in tags) {
69759             if (entity.tags[t$$1] === tags[t$$1]) {
69760                 score += preset.originalScore;
69761             } else if (tags[t$$1] === '*' && t$$1 in entity.tags) {
69762                 score += preset.originalScore / 2;
69763             } else {
69764                 return -1;
69765             }
69766         }
69767
69768         return score;
69769     };
69770
69771
69772     preset.t = function(scope, options) {
69773         return t('presets.presets.' + id + '.' + scope, options);
69774     };
69775
69776
69777     var origName = preset.name || '';
69778     preset.name = function() {
69779         if (preset.suggestion) {
69780             id = id.split('/');
69781             id = id[0] + '/' + id[1];
69782             return origName + ' - ' + t('presets.presets.' + id + '.name');
69783         }
69784         return preset.t('name', { 'default': origName });
69785     };
69786
69787     var origTerms = (preset.terms || []).join();
69788     preset.terms = function() {
69789         return preset.t('terms', { 'default': origTerms }).toLowerCase().trim().split(/\s*,+\s*/);
69790     };
69791
69792
69793     preset.isFallback = function() {
69794         var tagCount = Object.keys(preset.tags).length;
69795         return tagCount === 0 || (tagCount === 1 && preset.tags.hasOwnProperty('area'));
69796     };
69797
69798
69799     var reference = preset.reference || {};
69800     preset.reference = function(geometry) {
69801         var key = reference.key || Object.keys(omit(preset.tags, 'name'))[0],
69802             value = reference.value || preset.tags[key];
69803
69804         if (geometry === 'relation' && key === 'type') {
69805             if (value in preset.tags) {
69806                 key = value;
69807                 value = preset.tags[key];
69808             } else {
69809                 return { rtype: value };
69810             }
69811         }
69812
69813         if (value === '*') {
69814             return { key: key };
69815         } else {
69816             return { key: key, value: value };
69817         }
69818     };
69819
69820
69821     var removeTags = preset.removeTags || preset.tags || {};
69822     preset.removeTags = function(tags, geometry) {
69823         tags = omit(tags, keys$1(removeTags));
69824
69825         for (var f in preset.fields) {
69826             var field = preset.fields[f];
69827             if (field.matchGeometry(geometry) && field.default === tags[field.key]) {
69828                 delete tags[field.key];
69829             }
69830         }
69831
69832         delete tags.area;
69833         return tags;
69834     };
69835
69836
69837     var applyTags = preset.addTags || preset.tags || {};
69838     preset.applyTags = function(tags, geometry) {
69839         var k;
69840
69841         tags = clone(tags);
69842
69843         for (k in applyTags) {
69844             if (applyTags[k] === '*') {
69845                 tags[k] = 'yes';
69846             } else {
69847                 tags[k] = applyTags[k];
69848             }
69849         }
69850
69851         // Add area=yes if necessary.
69852         // This is necessary if the geometry is already an area (e.g. user drew an area) AND any of:
69853         // 1. chosen preset could be either an area or a line (`barrier=city_wall`)
69854         // 2. chosen preset doesn't have a key in areaKeys (`railway=station`)
69855         if (!applyTags.hasOwnProperty('area')) {
69856             delete tags.area;
69857             if (geometry === 'area') {
69858                 var needsAreaTag = true;
69859                 if (preset.geometry.indexOf('line') === -1) {
69860                     for (k in applyTags) {
69861                         if (k in areaKeys) {
69862                             needsAreaTag = false;
69863                             break;
69864                         }
69865                     }
69866                 }
69867                 if (needsAreaTag) {
69868                     tags.area = 'yes';
69869                 }
69870             }
69871         }
69872
69873         for (var f in preset.fields) {
69874             var field = preset.fields[f];
69875             if (field.matchGeometry(geometry) && field.key && !tags[field.key] && field.default) {
69876                 tags[field.key] = field.default;
69877             }
69878         }
69879
69880         return tags;
69881     };
69882
69883
69884     return preset;
69885 }
69886
69887 function presetIndex() {
69888     // a presetCollection with methods for
69889     // loading new data and returning defaults
69890
69891     var all = presetCollection([]);
69892     var _defaults = { area: all, line: all, point: all, vertex: all, relation: all };
69893     var _fields = {};
69894     var _universal = [];
69895     var _recent = presetCollection([]);
69896
69897     // Index of presets by (geometry, tag key).
69898     var _index = {
69899         point: {},
69900         vertex: {},
69901         line: {},
69902         area: {},
69903         relation: {}
69904     };
69905
69906     all.match = function(entity, resolver) {
69907         var geometry = entity.geometry(resolver);
69908         var address;
69909
69910         // Treat entities on addr:interpolation lines as points, not vertices - #3241
69911         if (geometry === 'vertex' && entity.isOnAddressLine(resolver)) {
69912             geometry = 'point';
69913         }
69914
69915         var geometryMatches = _index[geometry];
69916         var best = -1;
69917         var match;
69918
69919         for (var k in entity.tags) {
69920             // If any part of an address is present,
69921             // allow fallback to "Address" preset - #4353
69922             if (k.match(/^addr:/) !== null && geometryMatches['addr:*']) {
69923                 address = geometryMatches['addr:*'][0];
69924             }
69925
69926             var keyMatches = geometryMatches[k];
69927             if (!keyMatches) continue;
69928
69929             for (var i = 0; i < keyMatches.length; i++) {
69930                 var score = keyMatches[i].matchScore(entity);
69931                 if (score > best) {
69932                     best = score;
69933                     match = keyMatches[i];
69934                 }
69935             }
69936         }
69937
69938         if (address && (!match || match.isFallback())) {
69939             match = address;
69940         }
69941
69942         return match || all.item(geometry);
69943     };
69944
69945
69946     // Because of the open nature of tagging, iD will never have a complete
69947     // list of tags used in OSM, so we want it to have logic like "assume
69948     // that a closed way with an amenity tag is an area, unless the amenity
69949     // is one of these specific types". This function computes a structure
69950     // that allows testing of such conditions, based on the presets designated
69951     // as as supporting (or not supporting) the area geometry.
69952     //
69953     // The returned object L is a whitelist/blacklist of tags. A closed way
69954     // with a tag (k, v) is considered to be an area if `k in L && !(v in L[k])`
69955     // (see `Way#isArea()`). In other words, the keys of L form the whitelist,
69956     // and the subkeys form the blacklist.
69957     all.areaKeys = function() {
69958         var areaKeys = {};
69959         var ignore = ['barrier', 'highway', 'footway', 'railway', 'type'];  // probably a line..
69960         var presets = reject(all.collection, 'suggestion');
69961
69962         // whitelist
69963         presets.forEach(function(d) {
69964             for (var key in d.tags) break;
69965             if (!key) return;
69966             if (ignore.indexOf(key) !== -1) return;
69967
69968             if (d.geometry.indexOf('area') !== -1) {    // probably an area..
69969                 areaKeys[key] = areaKeys[key] || {};
69970             }
69971         });
69972
69973         // blacklist
69974         presets.forEach(function(d) {
69975             for (var key in d.tags) break;
69976             if (!key) return;
69977             if (ignore.indexOf(key) !== -1) return;
69978
69979             var value = d.tags[key];
69980             if (key in areaKeys &&                      // probably an area...
69981                 d.geometry.indexOf('line') !== -1 &&    // but sometimes a line
69982                 value !== '*') {
69983                 areaKeys[key][value] = true;
69984             }
69985         });
69986
69987         return areaKeys;
69988     };
69989
69990
69991     all.init = function() {
69992         var d = data.presets;
69993
69994         all.collection = [];
69995         _recent.collection = [];
69996         _fields = {};
69997         _universal = [];
69998         _index = { point: {}, vertex: {}, line: {}, area: {}, relation: {} };
69999
70000         if (d.fields) {
70001             forEach(d.fields, function(d, id) {
70002                 _fields[id] = presetField(id, d);
70003                 if (d.universal) {
70004                     _universal.push(_fields[id]);
70005                 }
70006             });
70007         }
70008
70009         if (d.presets) {
70010             forEach(d.presets, function(d, id) {
70011                 all.collection.push(presetPreset(id, d, _fields));
70012             });
70013         }
70014
70015         if (d.categories) {
70016             forEach(d.categories, function(d, id) {
70017                 all.collection.push(presetCategory(id, d, all));
70018             });
70019         }
70020
70021         if (d.defaults) {
70022             var getItem = bind$2(all.item, all);
70023             _defaults = {
70024                 area: presetCollection(d.defaults.area.map(getItem)),
70025                 line: presetCollection(d.defaults.line.map(getItem)),
70026                 point: presetCollection(d.defaults.point.map(getItem)),
70027                 vertex: presetCollection(d.defaults.vertex.map(getItem)),
70028                 relation: presetCollection(d.defaults.relation.map(getItem))
70029             };
70030         }
70031
70032         for (var i = 0; i < all.collection.length; i++) {
70033             var preset = all.collection[i];
70034             var geometry = preset.geometry;
70035
70036             for (var j = 0; j < geometry.length; j++) {
70037                 var g = _index[geometry[j]];
70038                 for (var k in preset.tags) {
70039                     (g[k] = g[k] || []).push(preset);
70040                 }
70041             }
70042         }
70043
70044         return all;
70045     };
70046
70047     all.field = function(id) {
70048         return _fields[id];
70049     };
70050
70051     all.universal = function() {
70052         return _universal;
70053     };
70054
70055     all.defaults = function(geometry, n) {
70056         var rec = _recent.matchGeometry(geometry).collection.slice(0, 4);
70057         var def = uniq(rec.concat(_defaults[geometry].collection)).slice(0, n - 1);
70058         return presetCollection(uniq(rec.concat(def).concat(all.item(geometry))));
70059     };
70060
70061     all.choose = function(preset) {
70062         _recent = presetCollection(uniq([preset].concat(_recent.collection)));
70063         return all;
70064     };
70065
70066     return all;
70067 }
70068
70069 var areaKeys = {};
70070
70071 function setAreaKeys(value) {
70072     areaKeys = value;
70073 }
70074
70075
70076 function coreContext() {
70077     var context = {};
70078     context.version = '2.6.1';
70079
70080     // create a special translation that contains the keys in place of the strings
70081     var tkeys = cloneDeep(en);
70082     var parents = [];
70083
70084     function traverser(v, k, obj) {
70085         parents.push(k);
70086         if (isObject(v)) {
70087             forOwn(v, traverser);
70088         } else if (isString(v)) {
70089             obj[k] = parents.join('.');
70090         }
70091         parents.pop();
70092     }
70093
70094     forOwn(tkeys, traverser);
70095     addTranslation('_tkeys_', tkeys);
70096
70097     addTranslation('en', en);
70098     setLocale('en');
70099
70100     var dispatch$$1 = dispatch('enter', 'exit', 'change');
70101
70102     // https://github.com/openstreetmap/iD/issues/772
70103     // http://mathiasbynens.be/notes/localstorage-pattern#comment-9
70104     var storage;
70105     try { storage = localStorage; } catch (e) {}  // eslint-disable-line no-empty
70106     storage = storage || (function() {
70107         var s = {};
70108         return {
70109             getItem: function(k) { return s[k]; },
70110             setItem: function(k, v) { s[k] = v; },
70111             removeItem: function(k) { delete s[k]; }
70112         };
70113     })();
70114
70115     context.storage = function(k, v) {
70116         try {
70117             if (arguments.length === 1) return storage.getItem(k);
70118             else if (v === null) storage.removeItem(k);
70119             else storage.setItem(k, v);
70120         } catch (e) {
70121             // localstorage quota exceeded
70122             /* eslint-disable no-console */
70123             if (typeof console !== 'undefined') console.error('localStorage quota exceeded');
70124             /* eslint-enable no-console */
70125         }
70126     };
70127
70128
70129     /* Straight accessors. Avoid using these if you can. */
70130     var ui, connection, history;
70131     context.ui = function() { return ui; };
70132     context.connection = function() { return connection; };
70133     context.history = function() { return history; };
70134
70135
70136     /* Connection */
70137     context.preauth = function(options) {
70138         if (connection) {
70139             connection.switch(options);
70140         }
70141         return context;
70142     };
70143
70144     context.loadTiles = utilCallWhenIdle(function(projection, dimensions, callback) {
70145         var cid;
70146         function done(err, result) {
70147             if (connection.getConnectionId() !== cid) {
70148                 if (callback) callback({ message: 'Connection Switched', status: -1 });
70149                 return;
70150             }
70151             if (!err) history.merge(result.data, result.extent);
70152             if (callback) callback(err, result);
70153         }
70154         if (connection && context.editable()) {
70155             cid = connection.getConnectionId();
70156             connection.loadTiles(projection, dimensions, done);
70157         }
70158     });
70159
70160     context.loadEntity = function(entityId, callback) {
70161         var cid;
70162         function done(err, result) {
70163             if (connection.getConnectionId() !== cid) {
70164                 if (callback) callback({ message: 'Connection Switched', status: -1 });
70165                 return;
70166             }
70167             if (!err) history.merge(result.data, result.extent);
70168             if (callback) callback(err, result);
70169         }
70170         if (connection) {
70171             cid = connection.getConnectionId();
70172             connection.loadEntity(entityId, done);
70173         }
70174     };
70175
70176     context.zoomToEntity = function(entityId, zoomTo) {
70177         if (zoomTo !== false) {
70178             this.loadEntity(entityId, function(err, result) {
70179                 if (err) return;
70180                 var entity = find$1(result.data, function(e) { return e.id === entityId; });
70181                 if (entity) { map.zoomTo(entity); }
70182             });
70183         }
70184
70185         map.on('drawn.zoomToEntity', function() {
70186             if (!context.hasEntity(entityId)) return;
70187             map.on('drawn.zoomToEntity', null);
70188             context.on('enter.zoomToEntity', null);
70189             context.enter(modeSelect(context, [entityId]));
70190         });
70191
70192         context.on('enter.zoomToEntity', function() {
70193             if (mode.id !== 'browse') {
70194                 map.on('drawn.zoomToEntity', null);
70195                 context.on('enter.zoomToEntity', null);
70196             }
70197         });
70198     };
70199
70200     var minEditableZoom = 16;
70201     context.minEditableZoom = function(_) {
70202         if (!arguments.length) return minEditableZoom;
70203         minEditableZoom = _;
70204         if (connection) {
70205             connection.tileZoom(_);
70206         }
70207         return context;
70208     };
70209
70210
70211     /* History */
70212     var inIntro = false;
70213     context.inIntro = function(_) {
70214         if (!arguments.length) return inIntro;
70215         inIntro = _;
70216         return context;
70217     };
70218
70219     context.save = function() {
70220         // no history save, no message onbeforeunload
70221         if (inIntro || d3_select('.modal').size()) return;
70222
70223         var canSave;
70224         if (mode && mode.id === 'save') {
70225             canSave = false;
70226         } else {
70227             canSave = context.selectedIDs().every(function(id) {
70228                 var entity = context.hasEntity(id);
70229                 return entity && !entity.isDegenerate();
70230             });
70231         }
70232
70233         if (canSave) {
70234             history.save();
70235         }
70236         if (history.hasChanges()) {
70237             return t('save.unsaved_changes');
70238         }
70239     };
70240
70241
70242     /* Graph */
70243     context.hasEntity = function(id) {
70244         return history.graph().hasEntity(id);
70245     };
70246     context.entity = function(id) {
70247         return history.graph().entity(id);
70248     };
70249     context.childNodes = function(way) {
70250         return history.graph().childNodes(way);
70251     };
70252     context.geometry = function(id) {
70253         return context.entity(id).geometry(history.graph());
70254     };
70255
70256
70257     /* Modes */
70258     var mode;
70259     context.mode = function() {
70260         return mode;
70261     };
70262     context.enter = function(newMode) {
70263         if (mode) {
70264             mode.exit();
70265             dispatch$$1.call('exit', this, mode);
70266         }
70267
70268         mode = newMode;
70269         mode.enter();
70270         dispatch$$1.call('enter', this, mode);
70271     };
70272
70273     context.selectedIDs = function() {
70274         if (mode && mode.selectedIDs) {
70275             return mode.selectedIDs();
70276         } else {
70277             return [];
70278         }
70279     };
70280     context.activeID = function() {
70281         return mode && mode.activeID && mode.activeID();
70282     };
70283
70284
70285     /* Behaviors */
70286     context.install = function(behavior) {
70287         context.surface().call(behavior);
70288     };
70289     context.uninstall = function(behavior) {
70290         context.surface().call(behavior.off);
70291     };
70292
70293
70294     /* Copy/Paste */
70295     var copyIDs = [], copyGraph;
70296     context.copyGraph = function() { return copyGraph; };
70297     context.copyIDs = function(_) {
70298         if (!arguments.length) return copyIDs;
70299         copyIDs = _;
70300         copyGraph = history.graph();
70301         return context;
70302     };
70303
70304
70305     /* Background */
70306     var background;
70307     context.background = function() { return background; };
70308
70309
70310     /* Features */
70311     var features;
70312     context.features = function() { return features; };
70313     context.hasHiddenConnections = function(id) {
70314         var graph = history.graph(),
70315             entity = graph.entity(id);
70316         return features.hasHiddenConnections(entity, graph);
70317     };
70318
70319
70320     /* Presets */
70321     var presets;
70322     context.presets = function() { return presets; };
70323
70324
70325     /* Map */
70326     var map;
70327     context.map = function() { return map; };
70328     context.layers = function() { return map.layers; };
70329     context.surface = function() { return map.surface; };
70330     context.editable = function() { return map.editable(); };
70331     context.surfaceRect = function() {
70332         return map.surface.node().getBoundingClientRect();
70333     };
70334
70335
70336     /* Debug */
70337     var debugFlags = {
70338         tile: false,        // tile boundaries
70339         collision: false,   // label collision bounding boxes
70340         imagery: false,     // imagery bounding polygons
70341         imperial: false,    // imperial (not metric) bounding polygons
70342         driveLeft: false,   // driveLeft bounding polygons
70343         target: false       // touch targets
70344     };
70345     context.debugFlags = function() {
70346         return debugFlags;
70347     };
70348     context.setDebug = function(flag, val) {
70349         if (arguments.length === 1) val = true;
70350         debugFlags[flag] = val;
70351         dispatch$$1.call('change');
70352         return context;
70353     };
70354     context.getDebug = function(flag) {
70355         return flag && debugFlags[flag];
70356     };
70357
70358
70359     /* Container */
70360     var container = d3_select(document.body);
70361     context.container = function(_) {
70362         if (!arguments.length) return container;
70363         container = _;
70364         container.classed('id-container', true);
70365         return context;
70366     };
70367     var embed;
70368     context.embed = function(_) {
70369         if (!arguments.length) return embed;
70370         embed = _;
70371         return context;
70372     };
70373
70374
70375     /* Assets */
70376     var assetPath = '';
70377     context.assetPath = function(_) {
70378         if (!arguments.length) return assetPath;
70379         assetPath = _;
70380         return context;
70381     };
70382
70383     var assetMap = {};
70384     context.assetMap = function(_) {
70385         if (!arguments.length) return assetMap;
70386         assetMap = _;
70387         return context;
70388     };
70389
70390     context.asset = function(_) {
70391         var filename = assetPath + _;
70392         return assetMap[filename] || filename;
70393     };
70394
70395     context.imagePath = function(_) {
70396         return context.asset('img/' + _);
70397     };
70398
70399
70400     /* locales */
70401     // `locale` variable contains a "requested locale".
70402     // It won't become the `currentLocale` until after loadLocale() is called.
70403     var locale, localePath;
70404
70405     context.locale = function(loc, path) {
70406         if (!arguments.length) return currentLocale;
70407         locale = loc;
70408         localePath = path;
70409         return context;
70410     };
70411
70412     context.loadLocale = function(callback) {
70413         if (locale && locale !== 'en' && dataLocales.hasOwnProperty(locale)) {
70414             localePath = localePath || context.asset('locales/' + locale + '.json');
70415             d3_json(localePath, function(err, result) {
70416                 if (!err) {
70417                     addTranslation(locale, result[locale]);
70418                     setLocale(locale);
70419                     utilDetect(true);
70420                 }
70421                 if (callback) {
70422                     callback(err);
70423                 }
70424             });
70425         } else {
70426             if (locale) {
70427                 setLocale(locale);
70428                 utilDetect(true);
70429             }
70430             if (callback) {
70431                 callback();
70432             }
70433         }
70434     };
70435
70436
70437     /* reset (aka flush) */
70438     context.reset = context.flush = function() {
70439         context.debouncedSave.cancel();
70440         forEach(services, function(service) {
70441             if (service && typeof service.reset === 'function') {
70442                 service.reset(context);
70443             }
70444         });
70445         features.reset();
70446         history.reset();
70447         return context;
70448     };
70449
70450
70451     /* Init */
70452
70453     context.projection = geoRawMercator();
70454     context.curtainProjection = geoRawMercator();
70455
70456     locale = utilDetect().locale;
70457     if (locale && !dataLocales.hasOwnProperty(locale)) {
70458         locale = locale.split('-')[0];
70459     }
70460
70461     history = coreHistory(context);
70462     context.graph = history.graph;
70463     context.changes = history.changes;
70464     context.intersects = history.intersects;
70465
70466     // Debounce save, since it's a synchronous localStorage write,
70467     // and history changes can happen frequently (e.g. when dragging).
70468     context.debouncedSave = debounce(context.save, 350);
70469     function withDebouncedSave(fn) {
70470         return function() {
70471             var result = fn.apply(history, arguments);
70472             context.debouncedSave();
70473             return result;
70474         };
70475     }
70476
70477     context.perform = withDebouncedSave(history.perform);
70478     context.replace = withDebouncedSave(history.replace);
70479     context.pop = withDebouncedSave(history.pop);
70480     context.overwrite = withDebouncedSave(history.overwrite);
70481     context.undo = withDebouncedSave(history.undo);
70482     context.redo = withDebouncedSave(history.redo);
70483
70484     ui = uiInit(context);
70485
70486     connection = services.osm;
70487     background = rendererBackground(context);
70488     features = rendererFeatures(context);
70489     presets = presetIndex();
70490
70491     map = rendererMap(context);
70492     context.mouse = map.mouse;
70493     context.extent = map.extent;
70494     context.pan = map.pan;
70495     context.zoomIn = map.zoomIn;
70496     context.zoomOut = map.zoomOut;
70497     context.zoomInFurther = map.zoomInFurther;
70498     context.zoomOutFurther = map.zoomOutFurther;
70499     context.redrawEnable = map.redrawEnable;
70500
70501     forEach(services, function(service) {
70502         if (service && typeof service.init === 'function') {
70503             service.init(context);
70504         }
70505     });
70506
70507     background.init();
70508     features.init();
70509     presets.init();
70510     areaKeys = presets.areaKeys();
70511
70512
70513     return utilRebind(context, dispatch$$1, 'on');
70514 }
70515
70516 function osmWay() {
70517     if (!(this instanceof osmWay)) {
70518         return (new osmWay()).initialize(arguments);
70519     } else if (arguments.length) {
70520         this.initialize(arguments);
70521     }
70522 }
70523
70524
70525 osmEntity.way = osmWay;
70526
70527 osmWay.prototype = Object.create(osmEntity.prototype);
70528
70529
70530 assignIn(osmWay.prototype, {
70531     type: 'way',
70532     nodes: [],
70533
70534
70535     copy: function(resolver, copies) {
70536         if (copies[this.id])
70537             return copies[this.id];
70538
70539         var copy = osmEntity.prototype.copy.call(this, resolver, copies);
70540
70541         var nodes = this.nodes.map(function(id) {
70542             return resolver.entity(id).copy(resolver, copies).id;
70543         });
70544
70545         copy = copy.update({ nodes: nodes });
70546         copies[this.id] = copy;
70547
70548         return copy;
70549     },
70550
70551
70552     extent: function(resolver) {
70553         return resolver.transient(this, 'extent', function() {
70554             var extent = geoExtent();
70555             for (var i = 0; i < this.nodes.length; i++) {
70556                 var node = resolver.hasEntity(this.nodes[i]);
70557                 if (node) {
70558                     extent._extend(node.extent());
70559                 }
70560             }
70561             return extent;
70562         });
70563     },
70564
70565
70566     first: function() {
70567         return this.nodes[0];
70568     },
70569
70570
70571     last: function() {
70572         return this.nodes[this.nodes.length - 1];
70573     },
70574
70575
70576     contains: function(node) {
70577         return this.nodes.indexOf(node) >= 0;
70578     },
70579
70580
70581     affix: function(node) {
70582         if (this.nodes[0] === node) return 'prefix';
70583         if (this.nodes[this.nodes.length - 1] === node) return 'suffix';
70584     },
70585
70586
70587     layer: function() {
70588         // explicit layer tag, clamp between -10, 10..
70589         if (isFinite(this.tags.layer)) {
70590             return Math.max(-10, Math.min(+(this.tags.layer), 10));
70591         }
70592
70593         // implied layer tag..
70594         if (this.tags.covered === 'yes') return -1;
70595         if (this.tags.location === 'overground') return 1;
70596         if (this.tags.location === 'underground') return -1;
70597         if (this.tags.location === 'underwater') return -10;
70598
70599         if (this.tags.power === 'line') return 10;
70600         if (this.tags.power === 'minor_line') return 10;
70601         if (this.tags.aerialway) return 10;
70602         if (this.tags.bridge) return 1;
70603         if (this.tags.cutting) return -1;
70604         if (this.tags.tunnel) return -1;
70605         if (this.tags.waterway) return -1;
70606         if (this.tags.man_made === 'pipeline') return -10;
70607         if (this.tags.boundary) return -10;
70608         return 0;
70609     },
70610
70611
70612     isOneWay: function() {
70613         // explicit oneway tag..
70614         var values = {
70615             'yes': true,
70616             '1': true,
70617             '-1': true,
70618             'reversible': true,
70619             'alternating': true,
70620             'no': false,
70621             '0': false
70622         };
70623         if (values[this.tags.oneway] !== undefined) {
70624             return values[this.tags.oneway];
70625         }
70626
70627         // implied oneway tag..
70628         for (var key in this.tags) {
70629             if (key in osmOneWayTags && (this.tags[key] in osmOneWayTags[key]))
70630                 return true;
70631         }
70632         return false;
70633     },
70634
70635
70636     lanes: function() {
70637         return osmLanes(this);
70638     },
70639
70640
70641     isClosed: function() {
70642         return this.nodes.length > 1 && this.first() === this.last();
70643     },
70644
70645
70646     isConvex: function(resolver) {
70647         if (!this.isClosed() || this.isDegenerate()) return null;
70648
70649         var nodes = uniq(resolver.childNodes(this));
70650         var coords = map$4(nodes, 'loc');
70651         var curr = 0;
70652         var prev = 0;
70653
70654         for (var i = 0; i < coords.length; i++) {
70655             var o = coords[(i+1) % coords.length];
70656             var a = coords[i];
70657             var b = coords[(i+2) % coords.length];
70658             var res = geoVecCross(a, b, o);
70659
70660             curr = (res > 0) ? 1 : (res < 0) ? -1 : 0;
70661             if (curr === 0) {
70662                 continue;
70663             } else if (prev && curr !== prev) {
70664                 return false;
70665             }
70666             prev = curr;
70667         }
70668         return true;
70669     },
70670
70671
70672     isArea: function() {
70673         // `highway` and `railway` are typically linear features, but there
70674         // are a few exceptions that should be treated as areas, even in the
70675         // absence of a proper `area=yes` or `areaKeys` tag.. see #4194
70676         var lineKeys = {
70677             highway: {
70678                 rest_area: true,
70679                 services: true
70680             },
70681             railway: {
70682                 roundhouse: true,
70683                 station: true,
70684                 traverser: true,
70685                 turntable: true,
70686                 wash: true
70687             }
70688         };
70689
70690         if (this.tags.area === 'yes')
70691             return true;
70692         if (!this.isClosed() || this.tags.area === 'no')
70693             return false;
70694         for (var key in this.tags) {
70695             if (key in areaKeys && !(this.tags[key] in areaKeys[key])) {
70696                 return true;
70697             }
70698             if (key in lineKeys && this.tags[key] in lineKeys[key]) {
70699                 return true;
70700             }
70701         }
70702         return false;
70703     },
70704
70705
70706     isDegenerate: function() {
70707         return uniq(this.nodes).length < (this.isArea() ? 3 : 2);
70708     },
70709
70710
70711     areAdjacent: function(n1, n2) {
70712         for (var i = 0; i < this.nodes.length; i++) {
70713             if (this.nodes[i] === n1) {
70714                 if (this.nodes[i - 1] === n2) return true;
70715                 if (this.nodes[i + 1] === n2) return true;
70716             }
70717         }
70718         return false;
70719     },
70720
70721
70722     geometry: function(graph) {
70723         return graph.transient(this, 'geometry', function() {
70724             return this.isArea() ? 'area' : 'line';
70725         });
70726     },
70727
70728
70729     // If this way is not closed, append the beginning node to the end of the nodelist to close it.
70730     close: function() {
70731         if (this.isClosed() || !this.nodes.length) return this;
70732
70733         var nodes = this.nodes.slice();
70734         nodes = nodes.filter(noRepeatNodes);
70735         nodes.push(nodes[0]);
70736         return this.update({ nodes: nodes });
70737     },
70738
70739
70740     // If this way is closed, remove any connector nodes from the end of the nodelist to unclose it.
70741     unclose: function() {
70742         if (!this.isClosed()) return this;
70743
70744         var nodes = this.nodes.slice(),
70745             connector = this.first(),
70746             i = nodes.length - 1;
70747
70748         // remove trailing connectors..
70749         while (i > 0 && nodes.length > 1 && nodes[i] === connector) {
70750             nodes.splice(i, 1);
70751             i = nodes.length - 1;
70752         }
70753
70754         nodes = nodes.filter(noRepeatNodes);
70755         return this.update({ nodes: nodes });
70756     },
70757
70758
70759     // Adds a node (id) in front of the node which is currently at position index.
70760     // If index is undefined, the node will be added to the end of the way for linear ways,
70761     //   or just before the final connecting node for circular ways.
70762     // Consecutive duplicates are eliminated including existing ones.
70763     // Circularity is always preserved when adding a node.
70764     addNode: function(id, index) {
70765         var nodes = this.nodes.slice(),
70766             isClosed = this.isClosed(),
70767             max = isClosed ? nodes.length - 1 : nodes.length;
70768
70769         if (index === undefined) {
70770             index = max;
70771         }
70772
70773         if (index < 0 || index > max) {
70774             throw new RangeError('index ' + index + ' out of range 0..' + max);
70775         }
70776
70777         // If this is a closed way, remove all connector nodes except the first one
70778         // (there may be duplicates) and adjust index if necessary..
70779         if (isClosed) {
70780             var connector = this.first();
70781
70782             // leading connectors..
70783             var i = 1;
70784             while (i < nodes.length && nodes.length > 2 && nodes[i] === connector) {
70785                 nodes.splice(i, 1);
70786                 if (index > i) index--;
70787             }
70788
70789             // trailing connectors..
70790             i = nodes.length - 1;
70791             while (i > 0 && nodes.length > 1 && nodes[i] === connector) {
70792                 nodes.splice(i, 1);
70793                 if (index > i) index--;
70794                 i = nodes.length - 1;
70795             }
70796         }
70797
70798         nodes.splice(index, 0, id);
70799         nodes = nodes.filter(noRepeatNodes);
70800
70801         // If the way was closed before, append a connector node to keep it closed..
70802         if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
70803             nodes.push(nodes[0]);
70804         }
70805
70806         return this.update({ nodes: nodes });
70807     },
70808
70809
70810     // Replaces the node which is currently at position index with the given node (id).
70811     // Consecutive duplicates are eliminated including existing ones.
70812     // Circularity is preserved when updating a node.
70813     updateNode: function(id, index) {
70814         var nodes = this.nodes.slice(),
70815             isClosed = this.isClosed(),
70816             max = nodes.length - 1;
70817
70818         if (index === undefined || index < 0 || index > max) {
70819             throw new RangeError('index ' + index + ' out of range 0..' + max);
70820         }
70821
70822         // If this is a closed way, remove all connector nodes except the first one
70823         // (there may be duplicates) and adjust index if necessary..
70824         if (isClosed) {
70825             var connector = this.first();
70826
70827             // leading connectors..
70828             var i = 1;
70829             while (i < nodes.length && nodes.length > 2 && nodes[i] === connector) {
70830                 nodes.splice(i, 1);
70831                 if (index > i) index--;
70832             }
70833
70834             // trailing connectors..
70835             i = nodes.length - 1;
70836             while (i > 0 && nodes.length > 1 && nodes[i] === connector) {
70837                 nodes.splice(i, 1);
70838                 if (index === i) index = 0;  // update leading connector instead
70839                 i = nodes.length - 1;
70840             }
70841         }
70842
70843         nodes.splice(index, 1, id);
70844         nodes = nodes.filter(noRepeatNodes);
70845
70846         // If the way was closed before, append a connector node to keep it closed..
70847         if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
70848             nodes.push(nodes[0]);
70849         }
70850
70851         return this.update({nodes: nodes});
70852     },
70853
70854
70855     // Replaces each occurrence of node id needle with replacement.
70856     // Consecutive duplicates are eliminated including existing ones.
70857     // Circularity is preserved.
70858     replaceNode: function(needle, replacement) {
70859         var nodes = this.nodes.slice(),
70860             isClosed = this.isClosed();
70861
70862         for (var i = 0; i < nodes.length; i++) {
70863             if (nodes[i] === needle) {
70864                 nodes[i] = replacement;
70865             }
70866         }
70867
70868         nodes = nodes.filter(noRepeatNodes);
70869
70870         // If the way was closed before, append a connector node to keep it closed..
70871         if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
70872             nodes.push(nodes[0]);
70873         }
70874
70875         return this.update({nodes: nodes});
70876     },
70877
70878
70879     // Removes each occurrence of node id needle with replacement.
70880     // Consecutive duplicates are eliminated including existing ones.
70881     // Circularity is preserved.
70882     removeNode: function(id) {
70883         var nodes = this.nodes.slice(),
70884             isClosed = this.isClosed();
70885
70886         nodes = nodes
70887             .filter(function(node) { return node !== id; })
70888             .filter(noRepeatNodes);
70889
70890         // If the way was closed before, append a connector node to keep it closed..
70891         if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
70892             nodes.push(nodes[0]);
70893         }
70894
70895         return this.update({nodes: nodes});
70896     },
70897
70898
70899     asJXON: function(changeset_id) {
70900         var r = {
70901             way: {
70902                 '@id': this.osmId(),
70903                 '@version': this.version || 0,
70904                 nd: map$4(this.nodes, function(id) {
70905                     return { keyAttributes: { ref: osmEntity.id.toOSM(id) } };
70906                 }),
70907                 tag: map$4(this.tags, function(v, k) {
70908                     return { keyAttributes: { k: k, v: v } };
70909                 })
70910             }
70911         };
70912         if (changeset_id) {
70913             r.way['@changeset'] = changeset_id;
70914         }
70915         return r;
70916     },
70917
70918
70919     asGeoJSON: function(resolver) {
70920         return resolver.transient(this, 'GeoJSON', function() {
70921             var coordinates = map$4(resolver.childNodes(this), 'loc');
70922             if (this.isArea() && this.isClosed()) {
70923                 return {
70924                     type: 'Polygon',
70925                     coordinates: [coordinates]
70926                 };
70927             } else {
70928                 return {
70929                     type: 'LineString',
70930                     coordinates: coordinates
70931                 };
70932             }
70933         });
70934     },
70935
70936
70937     area: function(resolver) {
70938         return resolver.transient(this, 'area', function() {
70939             var nodes = resolver.childNodes(this);
70940
70941             var json = {
70942                 type: 'Polygon',
70943                 coordinates: [map$4(nodes, 'loc')]
70944             };
70945
70946             if (!this.isClosed() && nodes.length) {
70947                 json.coordinates[0].push(nodes[0].loc);
70948             }
70949
70950             var area = d3_geoArea(json);
70951
70952             // Heuristic for detecting counterclockwise winding order. Assumes
70953             // that OpenStreetMap polygons are not hemisphere-spanning.
70954             if (area > 2 * Math.PI) {
70955                 json.coordinates[0] = json.coordinates[0].reverse();
70956                 area = d3_geoArea(json);
70957             }
70958
70959             return isNaN(area) ? 0 : area;
70960         });
70961     }
70962 });
70963
70964
70965 // Filter function to eliminate consecutive duplicates.
70966 function noRepeatNodes(node, i, arr) {
70967     return i === 0 || node !== arr[i - 1];
70968 }
70969
70970 // For fixing up rendering of multipolygons with tags on the outer member.
70971 // https://github.com/openstreetmap/iD/issues/613
70972 function osmIsSimpleMultipolygonOuterMember(entity, graph) {
70973     if (entity.type !== 'way' || Object.keys(entity.tags).filter(osmIsInterestingTag).length === 0)
70974         return false;
70975
70976     var parents = graph.parentRelations(entity);
70977     if (parents.length !== 1)
70978         return false;
70979
70980     var parent = parents[0];
70981     if (!parent.isMultipolygon() || Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1)
70982         return false;
70983
70984     var members = parent.members, member;
70985     for (var i = 0; i < members.length; i++) {
70986         member = members[i];
70987         if (member.id === entity.id && member.role && member.role !== 'outer')
70988             return false; // Not outer member
70989         if (member.id !== entity.id && (!member.role || member.role === 'outer'))
70990             return false; // Not a simple multipolygon
70991     }
70992
70993     return parent;
70994 }
70995
70996
70997 function osmSimpleMultipolygonOuterMember(entity, graph) {
70998     if (entity.type !== 'way')
70999         return false;
71000
71001     var parents = graph.parentRelations(entity);
71002     if (parents.length !== 1)
71003         return false;
71004
71005     var parent = parents[0];
71006     if (!parent.isMultipolygon() || Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1)
71007         return false;
71008
71009     var members = parent.members, member, outerMember;
71010     for (var i = 0; i < members.length; i++) {
71011         member = members[i];
71012         if (!member.role || member.role === 'outer') {
71013             if (outerMember)
71014                 return false; // Not a simple multipolygon
71015             outerMember = member;
71016         }
71017     }
71018
71019     if (!outerMember)
71020         return false;
71021
71022     var outerEntity = graph.hasEntity(outerMember.id);
71023     if (!outerEntity || !Object.keys(outerEntity.tags).filter(osmIsInterestingTag).length)
71024         return false;
71025
71026     return outerEntity;
71027 }
71028
71029
71030 // Join `toJoin` array into sequences of connecting ways.
71031
71032 // Segments which share identical start/end nodes will, as much as possible,
71033 // be connected with each other.
71034 //
71035 // The return value is a nested array. Each constituent array contains elements
71036 // of `toJoin` which have been determined to connect.
71037 //
71038 // Each consitituent array also has a `nodes` property whose value is an
71039 // ordered array of member nodes, with appropriate order reversal and
71040 // start/end coordinate de-duplication.
71041 //
71042 // Members of `toJoin` must have, at minimum, `type` and `id` properties.
71043 // Thus either an array of `osmWay`s or a relation member array may be used.
71044 //
71045 // If an member is an `osmWay`, its tags and childnodes may be reversed via
71046 // `actionReverse` in the output.
71047 //
71048 // The returned sequences array also has an `actions` array property, containing
71049 // any reversal actions that should be applied to the graph, should the calling
71050 // code attempt to actually join the given ways.
71051 //
71052 // Incomplete members (those for which `graph.hasEntity(element.id)` returns
71053 // false) and non-way members are ignored.
71054 //
71055 function osmJoinWays(toJoin, graph) {
71056     function resolve(member) {
71057         return graph.childNodes(graph.entity(member.id));
71058     }
71059
71060     function reverse(item) {
71061         var action = actionReverse(item.id, { reverseOneway: true });
71062         sequences.actions.push(action);
71063         return (item instanceof osmWay) ? action(graph).entity(item.id) : item;
71064     }
71065
71066     // make a copy containing only the items to join
71067     toJoin = toJoin.filter(function(member) {
71068         return member.type === 'way' && graph.hasEntity(member.id);
71069     });
71070
71071
71072     var sequences = [];
71073     sequences.actions = [];
71074
71075     while (toJoin.length) {
71076         // start a new sequence
71077         var item = toJoin.shift();
71078         var currWays = [item];
71079         var currNodes = resolve(item).slice();
71080         var doneSequence = false;
71081
71082         // add to it
71083         while (toJoin.length && !doneSequence) {
71084             var start = currNodes[0];
71085             var end = currNodes[currNodes.length - 1];
71086             var fn = null;
71087             var nodes = null;
71088             var i;
71089
71090             // Find the next way/member to join.
71091             for (i = 0; i < toJoin.length; i++) {
71092                 item = toJoin[i];
71093                 nodes = resolve(item);
71094
71095                 // Strongly prefer to generate a forward path that preserves the order
71096                 // of the members array. For multipolygons and most relations, member
71097                 // order does not matter - but for routes, it does. If we started this
71098                 // sequence backwards (i.e. next member way attaches to the start node
71099                 // and not the end node), reverse the initial way before continuing.
71100                 if (currWays.length === 1 && nodes[0] !== end && nodes[nodes.length - 1] !== end &&
71101                     (nodes[nodes.length - 1] === start || nodes[0] === start)
71102                 ) {
71103                     currWays[0] = reverse(currWays[0]);
71104                     currNodes.reverse();
71105                     start = currNodes[0];
71106                     end = currNodes[currNodes.length - 1];
71107                 }
71108
71109                 if (nodes[0] === end) {
71110                     fn = currNodes.push;               // join to end
71111                     nodes = nodes.slice(1);
71112                     break;
71113                 } else if (nodes[nodes.length - 1] === end) {
71114                     fn = currNodes.push;               // join to end
71115                     nodes = nodes.slice(0, -1).reverse();
71116                     item = reverse(item);
71117                     break;
71118                 } else if (nodes[nodes.length - 1] === start) {
71119                     fn = currNodes.unshift;            // join to beginning
71120                     nodes = nodes.slice(0, -1);
71121                     break;
71122                 } else if (nodes[0] === start) {
71123                     fn = currNodes.unshift;            // join to beginning
71124                     nodes = nodes.slice(1).reverse();
71125                     item = reverse(item);
71126                     break;
71127                 } else {
71128                     fn = nodes = null;
71129                 }
71130             }
71131
71132             if (!nodes) {     // couldn't find a joinable way/member
71133                 doneSequence = true;
71134                 break;
71135             }
71136
71137             fn.apply(currWays, [item]);
71138             fn.apply(currNodes, nodes);
71139
71140             toJoin.splice(i, 1);
71141         }
71142
71143         currWays.nodes = currNodes;
71144         sequences.push(currWays);
71145     }
71146
71147     return sequences;
71148 }
71149
71150 function osmRelation() {
71151     if (!(this instanceof osmRelation)) {
71152         return (new osmRelation()).initialize(arguments);
71153     } else if (arguments.length) {
71154         this.initialize(arguments);
71155     }
71156 }
71157
71158
71159 osmEntity.relation = osmRelation;
71160
71161 osmRelation.prototype = Object.create(osmEntity.prototype);
71162
71163
71164 osmRelation.creationOrder = function(a, b) {
71165     var aId = parseInt(osmEntity.id.toOSM(a.id), 10);
71166     var bId = parseInt(osmEntity.id.toOSM(b.id), 10);
71167
71168     if (aId < 0 || bId < 0) return aId - bId;
71169     return bId - aId;
71170 };
71171
71172
71173 assignIn(osmRelation.prototype, {
71174     type: 'relation',
71175     members: [],
71176
71177
71178     copy: function(resolver, copies) {
71179         if (copies[this.id])
71180             return copies[this.id];
71181
71182         var copy = osmEntity.prototype.copy.call(this, resolver, copies);
71183
71184         var members = this.members.map(function(member) {
71185             return assignIn({}, member, { id: resolver.entity(member.id).copy(resolver, copies).id });
71186         });
71187
71188         copy = copy.update({members: members});
71189         copies[this.id] = copy;
71190
71191         return copy;
71192     },
71193
71194
71195     extent: function(resolver, memo) {
71196         return resolver.transient(this, 'extent', function() {
71197             if (memo && memo[this.id]) return geoExtent();
71198             memo = memo || {};
71199             memo[this.id] = true;
71200
71201             var extent = geoExtent();
71202             for (var i = 0; i < this.members.length; i++) {
71203                 var member = resolver.hasEntity(this.members[i].id);
71204                 if (member) {
71205                     extent._extend(member.extent(resolver, memo));
71206                 }
71207             }
71208             return extent;
71209         });
71210     },
71211
71212
71213     geometry: function(graph) {
71214         return graph.transient(this, 'geometry', function() {
71215             return this.isMultipolygon() ? 'area' : 'relation';
71216         });
71217     },
71218
71219
71220     isDegenerate: function() {
71221         return this.members.length === 0;
71222     },
71223
71224
71225     // Return an array of members, each extended with an 'index' property whose value
71226     // is the member index.
71227     indexedMembers: function() {
71228         var result = new Array(this.members.length);
71229         for (var i = 0; i < this.members.length; i++) {
71230             result[i] = assignIn({}, this.members[i], {index: i});
71231         }
71232         return result;
71233     },
71234
71235
71236     // Return the first member with the given role. A copy of the member object
71237     // is returned, extended with an 'index' property whose value is the member index.
71238     memberByRole: function(role) {
71239         for (var i = 0; i < this.members.length; i++) {
71240             if (this.members[i].role === role) {
71241                 return assignIn({}, this.members[i], {index: i});
71242             }
71243         }
71244     },
71245
71246
71247     // Return the first member with the given id. A copy of the member object
71248     // is returned, extended with an 'index' property whose value is the member index.
71249     memberById: function(id) {
71250         for (var i = 0; i < this.members.length; i++) {
71251             if (this.members[i].id === id) {
71252                 return assignIn({}, this.members[i], {index: i});
71253             }
71254         }
71255     },
71256
71257
71258     // Return the first member with the given id and role. A copy of the member object
71259     // is returned, extended with an 'index' property whose value is the member index.
71260     memberByIdAndRole: function(id, role) {
71261         for (var i = 0; i < this.members.length; i++) {
71262             if (this.members[i].id === id && this.members[i].role === role) {
71263                 return assignIn({}, this.members[i], {index: i});
71264             }
71265         }
71266     },
71267
71268
71269     addMember: function(member, index) {
71270         var members = this.members.slice();
71271         members.splice(index === undefined ? members.length : index, 0, member);
71272         return this.update({members: members});
71273     },
71274
71275
71276     updateMember: function(member, index) {
71277         var members = this.members.slice();
71278         members.splice(index, 1, assignIn({}, members[index], member));
71279         return this.update({members: members});
71280     },
71281
71282
71283     removeMember: function(index) {
71284         var members = this.members.slice();
71285         members.splice(index, 1);
71286         return this.update({members: members});
71287     },
71288
71289
71290     removeMembersWithID: function(id) {
71291         var members = reject(this.members, function(m) { return m.id === id; });
71292         return this.update({members: members});
71293     },
71294
71295
71296     // Wherever a member appears with id `needle.id`, replace it with a member
71297     // with id `replacement.id`, type `replacement.type`, and the original role,
71298     // By default, adding a duplicate member (by id and role) is prevented.
71299     // Return an updated relation.
71300     replaceMember: function(needle, replacement, keepDuplicates) {
71301         if (!this.memberById(needle.id))
71302             return this;
71303
71304         var members = [];
71305
71306         for (var i = 0; i < this.members.length; i++) {
71307             var member = this.members[i];
71308             if (member.id !== needle.id) {
71309                 members.push(member);
71310             } else if (keepDuplicates || !this.memberByIdAndRole(replacement.id, member.role)) {
71311                 members.push({id: replacement.id, type: replacement.type, role: member.role});
71312             }
71313         }
71314
71315         return this.update({members: members});
71316     },
71317
71318
71319     asJXON: function(changeset_id) {
71320         var r = {
71321             relation: {
71322                 '@id': this.osmId(),
71323                 '@version': this.version || 0,
71324                 member: map$4(this.members, function(member) {
71325                     return {
71326                         keyAttributes: {
71327                             type: member.type,
71328                             role: member.role,
71329                             ref: osmEntity.id.toOSM(member.id)
71330                         }
71331                     };
71332                 }),
71333                 tag: map$4(this.tags, function(v, k) {
71334                     return { keyAttributes: { k: k, v: v } };
71335                 })
71336             }
71337         };
71338         if (changeset_id) r.relation['@changeset'] = changeset_id;
71339         return r;
71340     },
71341
71342
71343     asGeoJSON: function(resolver) {
71344         return resolver.transient(this, 'GeoJSON', function () {
71345             if (this.isMultipolygon()) {
71346                 return {
71347                     type: 'MultiPolygon',
71348                     coordinates: this.multipolygon(resolver)
71349                 };
71350             } else {
71351                 return {
71352                     type: 'FeatureCollection',
71353                     properties: this.tags,
71354                     features: this.members.map(function (member) {
71355                         return assignIn({role: member.role}, resolver.entity(member.id).asGeoJSON(resolver));
71356                     })
71357                 };
71358             }
71359         });
71360     },
71361
71362
71363     area: function(resolver) {
71364         return resolver.transient(this, 'area', function() {
71365             return d3_geoArea(this.asGeoJSON(resolver));
71366         });
71367     },
71368
71369
71370     isMultipolygon: function() {
71371         return this.tags.type === 'multipolygon';
71372     },
71373
71374
71375     isComplete: function(resolver) {
71376         for (var i = 0; i < this.members.length; i++) {
71377             if (!resolver.hasEntity(this.members[i].id)) {
71378                 return false;
71379             }
71380         }
71381         return true;
71382     },
71383
71384
71385     isRestriction: function() {
71386         return !!(this.tags.type && this.tags.type.match(/^restriction:?/));
71387     },
71388
71389
71390     // Returns an array [A0, ... An], each Ai being an array of node arrays [Nds0, ... Ndsm],
71391     // where Nds0 is an outer ring and subsequent Ndsi's (if any i > 0) being inner rings.
71392     //
71393     // This corresponds to the structure needed for rendering a multipolygon path using a
71394     // `evenodd` fill rule, as well as the structure of a GeoJSON MultiPolygon geometry.
71395     //
71396     // In the case of invalid geometries, this function will still return a result which
71397     // includes the nodes of all way members, but some Nds may be unclosed and some inner
71398     // rings not matched with the intended outer ring.
71399     //
71400     multipolygon: function(resolver) {
71401         var outers = this.members.filter(function(m) { return 'outer' === (m.role || 'outer'); }),
71402             inners = this.members.filter(function(m) { return 'inner' === m.role; });
71403
71404         outers = osmJoinWays(outers, resolver);
71405         inners = osmJoinWays(inners, resolver);
71406
71407         outers = outers.map(function(outer) { return map$4(outer.nodes, 'loc'); });
71408         inners = inners.map(function(inner) { return map$4(inner.nodes, 'loc'); });
71409
71410         var result = outers.map(function(o) {
71411             // Heuristic for detecting counterclockwise winding order. Assumes
71412             // that OpenStreetMap polygons are not hemisphere-spanning.
71413             return [d3_geoArea({ type: 'Polygon', coordinates: [o] }) > 2 * Math.PI ? o.reverse() : o];
71414         });
71415
71416         function findOuter(inner) {
71417             var o, outer;
71418
71419             for (o = 0; o < outers.length; o++) {
71420                 outer = outers[o];
71421                 if (geoPolygonContainsPolygon(outer, inner))
71422                     return o;
71423             }
71424
71425             for (o = 0; o < outers.length; o++) {
71426                 outer = outers[o];
71427                 if (geoPolygonIntersectsPolygon(outer, inner, false))
71428                     return o;
71429             }
71430         }
71431
71432         for (var i = 0; i < inners.length; i++) {
71433             var inner = inners[i];
71434
71435             if (d3_geoArea({ type: 'Polygon', coordinates: [inner] }) < 2 * Math.PI) {
71436                 inner = inner.reverse();
71437             }
71438
71439             var o = findOuter(inners[i]);
71440             if (o !== undefined)
71441                 result[o].push(inners[i]);
71442             else
71443                 result.push([inners[i]]); // Invalid geometry
71444         }
71445
71446         return result;
71447     }
71448 });
71449
71450 /* Built-in method references for those with the same name as other `lodash` methods. */
71451 var nativeMax$8 = Math.max;
71452
71453 /**
71454  * Gets the index at which the first occurrence of `value` is found in `array`
71455  * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
71456  * for equality comparisons. If `fromIndex` is negative, it's used as the
71457  * offset from the end of `array`.
71458  *
71459  * @static
71460  * @memberOf _
71461  * @since 0.1.0
71462  * @category Array
71463  * @param {Array} array The array to inspect.
71464  * @param {*} value The value to search for.
71465  * @param {number} [fromIndex=0] The index to search from.
71466  * @returns {number} Returns the index of the matched value, else `-1`.
71467  * @example
71468  *
71469  * _.indexOf([1, 2, 1, 2], 2);
71470  * // => 1
71471  *
71472  * // Search from the `fromIndex`.
71473  * _.indexOf([1, 2, 1, 2], 2, 2);
71474  * // => 3
71475  */
71476 function indexOf(array, value, fromIndex) {
71477   var length = array == null ? 0 : array.length;
71478   if (!length) {
71479     return -1;
71480   }
71481   var index = fromIndex == null ? 0 : toInteger(fromIndex);
71482   if (index < 0) {
71483     index = nativeMax$8(length + index, 0);
71484   }
71485   return baseIndexOf(array, value, index);
71486 }
71487
71488 function osmTurn(turn) {
71489     if (!(this instanceof osmTurn))
71490         return new osmTurn(turn);
71491     assignIn(this, turn);
71492 }
71493
71494
71495 function osmIntersection(graph, vertexId) {
71496     var vertex = graph.entity(vertexId),
71497         parentWays = graph.parentWays(vertex),
71498         coincident = [],
71499         highways = {};
71500
71501     function addHighway(way, adjacentNodeId) {
71502         if (highways[adjacentNodeId]) {
71503             coincident.push(adjacentNodeId);
71504         } else {
71505             highways[adjacentNodeId] = way;
71506         }
71507     }
71508
71509     // Pre-split ways that would need to be split in
71510     // order to add a restriction. The real split will
71511     // happen when the restriction is added.
71512     parentWays.forEach(function(way) {
71513         if (!way.tags.highway || way.isArea() || way.isDegenerate())
71514             return;
71515
71516         var isFirst = (vertexId === way.first()),
71517             isLast = (vertexId === way.last()),
71518             isAffix = (isFirst || isLast),
71519             isClosingNode = (isFirst && isLast);
71520
71521         if (isAffix && !isClosingNode) {
71522             var index = (isFirst ? 1 : way.nodes.length - 2);
71523             addHighway(way, way.nodes[index]);
71524
71525         } else {
71526             var splitIndex, wayA, wayB, indexA, indexB;
71527             if (isClosingNode) {
71528                 splitIndex = Math.ceil(way.nodes.length / 2);  // split at midpoint
71529                 wayA = osmWay({id: way.id + '-a', tags: way.tags, nodes: way.nodes.slice(0, splitIndex)});
71530                 wayB = osmWay({id: way.id + '-b', tags: way.tags, nodes: way.nodes.slice(splitIndex)});
71531                 indexA = 1;
71532                 indexB = way.nodes.length - 2;
71533             } else {
71534                 splitIndex = indexOf(way.nodes, vertex.id, 1);  // split at vertexid
71535                 wayA = osmWay({id: way.id + '-a', tags: way.tags, nodes: way.nodes.slice(0, splitIndex + 1)});
71536                 wayB = osmWay({id: way.id + '-b', tags: way.tags, nodes: way.nodes.slice(splitIndex)});
71537                 indexA = splitIndex - 1;
71538                 indexB = splitIndex + 1;
71539             }
71540             graph = graph.replace(wayA).replace(wayB);
71541             addHighway(wayA, way.nodes[indexA]);
71542             addHighway(wayB, way.nodes[indexB]);
71543         }
71544     });
71545
71546     // remove any ways from this intersection that are coincident
71547     // (i.e. any adjacent node used by more than one intersecting way)
71548     coincident.forEach(function (n) {
71549         delete highways[n];
71550     });
71551
71552
71553     var intersection = {
71554         highways: highways,
71555         ways: values$1(highways),
71556         graph: graph
71557     };
71558
71559
71560     intersection.adjacentNodeId = function(fromWayId) {
71561         return find$1(keys$1(highways), function(k) {
71562             return highways[k].id === fromWayId;
71563         });
71564     };
71565
71566
71567     intersection.turns = function(fromNodeId) {
71568         var start = highways[fromNodeId];
71569         if (!start)
71570             return [];
71571
71572         if (start.first() === vertex.id && start.tags.oneway === 'yes')
71573             return [];
71574         if (start.last() === vertex.id && start.tags.oneway === '-1')
71575             return [];
71576
71577         function withRestriction(turn) {
71578             graph.parentRelations(graph.entity(turn.from.way)).forEach(function(relation) {
71579                 if (relation.tags.type !== 'restriction')
71580                     return;
71581
71582                 var f = relation.memberByRole('from'),
71583                     t = relation.memberByRole('to'),
71584                     v = relation.memberByRole('via');
71585
71586                 if (f && f.id === turn.from.way &&
71587                     v && v.id === turn.via.node &&
71588                     t && t.id === turn.to.way) {
71589                     turn.restriction = relation.id;
71590                 } else if (/^only_/.test(relation.tags.restriction) &&
71591                     f && f.id === turn.from.way &&
71592                     v && v.id === turn.via.node &&
71593                     t && t.id !== turn.to.way) {
71594                     turn.restriction = relation.id;
71595                     turn.indirect_restriction = true;
71596                 }
71597             });
71598
71599             return osmTurn(turn);
71600         }
71601
71602
71603         var from = {
71604                 node: fromNodeId,
71605                 way: start.id.split(/-(a|b)/)[0]
71606             },
71607             via = { node: vertex.id },
71608             turns = [];
71609
71610         forEach(highways, function(end, adjacentNodeId) {
71611             if (end === start)
71612                 return;
71613
71614             // backward
71615             if (end.first() !== vertex.id && end.tags.oneway !== 'yes') {
71616                 turns.push(withRestriction({
71617                     from: from,
71618                     via: via,
71619                     to: {
71620                         node: adjacentNodeId,
71621                         way: end.id.split(/-(a|b)/)[0]
71622                     }
71623                 }));
71624             }
71625
71626             // forward
71627             if (end.last() !== vertex.id && end.tags.oneway !== '-1') {
71628                 turns.push(withRestriction({
71629                     from: from,
71630                     via: via,
71631                     to: {
71632                         node: adjacentNodeId,
71633                         way: end.id.split(/-(a|b)/)[0]
71634                     }
71635                 }));
71636             }
71637
71638         });
71639
71640         // U-turn
71641         if (start.tags.oneway !== 'yes' && start.tags.oneway !== '-1') {
71642             turns.push(withRestriction({
71643                 from: from,
71644                 via: via,
71645                 to: from,
71646                 u: true
71647             }));
71648         }
71649
71650         return turns;
71651     };
71652
71653     return intersection;
71654 }
71655
71656
71657 function osmInferRestriction(graph, from, via, to, projection) {
71658     var fromWay = graph.entity(from.way),
71659         fromNode = graph.entity(from.node),
71660         toWay = graph.entity(to.way),
71661         toNode = graph.entity(to.node),
71662         viaNode = graph.entity(via.node),
71663         fromOneWay = (fromWay.tags.oneway === 'yes' && fromWay.last() === via.node) ||
71664             (fromWay.tags.oneway === '-1' && fromWay.first() === via.node),
71665         toOneWay = (toWay.tags.oneway === 'yes' && toWay.first() === via.node) ||
71666             (toWay.tags.oneway === '-1' && toWay.last() === via.node),
71667         angle = geoAngle(viaNode, fromNode, projection) -
71668                 geoAngle(viaNode, toNode, projection);
71669
71670     angle = angle * 180 / Math.PI;
71671
71672     while (angle < 0)
71673         angle += 360;
71674
71675     if (fromNode === toNode)
71676         return 'no_u_turn';
71677     if ((angle < 23 || angle > 336) && fromOneWay && toOneWay)
71678         return 'no_u_turn';
71679     if (angle < 158)
71680         return 'no_right_turn';
71681     if (angle > 202)
71682         return 'no_left_turn';
71683
71684     return 'no_straight_on';
71685 }
71686
71687 function actionAddMember(relationId, member, memberIndex, insertPair) {
71688
71689     return function action(graph) {
71690         var relation = graph.entity(relationId);
71691
71692         if ((isNaN(memberIndex) || insertPair) && member.type === 'way') {
71693             // Try to perform sensible inserts based on how the ways join together
71694             graph = addWayMember(relation, graph);
71695         } else {
71696             graph = graph.replace(relation.addMember(member, memberIndex));
71697         }
71698
71699         return graph;
71700     };
71701
71702
71703     // Add a way member into the relation "wherever it makes sense".
71704     // In this situation we were not supplied a memberIndex.
71705     function addWayMember(relation, graph) {
71706         var groups, tempWay, item, i, j, k;
71707
71708         if (insertPair) {
71709             // We're adding a member that must stay paired with an existing member.
71710             // (This feature is used by `actionSplit`)
71711             //
71712             // This is tricky because the members may exist multiple times in the
71713             // member list, and with different A-B/B-A ordering and different roles.
71714             // (e.g. a bus route that loops out and back - #4589).
71715             //
71716             // Replace the existing member with a temporary way,
71717             // so that `osmJoinWays` can treat the pair like a single way.
71718             tempWay = osmWay({ id: 'wTemp', nodes: insertPair.nodes });
71719             graph = graph.replace(tempWay);
71720             var tempMember = { id: tempWay.id, type: 'way', role: member.role };
71721             var tempRelation = relation.replaceMember({id: insertPair.originalID}, tempMember, true);
71722             groups = groupBy(tempRelation.members, function(m) { return m.type; });
71723             groups.way = groups.way || [];
71724
71725         } else {
71726             // Add the member anywhere, one time. Just push and let `osmJoinWays` decide where to put it.
71727             groups = groupBy(relation.members, function(m) { return m.type; });
71728             groups.way = groups.way || [];
71729             groups.way.push(member);
71730         }
71731
71732         var members = withIndex(groups.way);
71733         var joined = osmJoinWays(members, graph);
71734
71735         // `joined` might not contain all of the way members,
71736         // But will contain only the completed (downloaded) members
71737         for (i = 0; i < joined.length; i++) {
71738             var segment = joined[i];
71739             var nodes = segment.nodes.slice();
71740             var startIndex = segment[0].index;
71741
71742             // j = array index in `members` where this segment starts
71743             for (j = 0; j < members.length; j++) {
71744                 if (members[j].index === startIndex) {
71745                     break;
71746                 }
71747             }
71748
71749             // k = each member in segment
71750             for (k = 0; k < segment.length; k++) {
71751                 item = segment[k];
71752                 var way = graph.entity(item.id);
71753
71754                 // If this is a paired item, generate members in correct order and role
71755                 if (tempWay && item.id === tempWay.id) {
71756                     if (nodes[0].id === insertPair.nodes[0]) {
71757                         item.pair = [
71758                             { id: insertPair.originalID, type: 'way', role: item.role },
71759                             { id: insertPair.insertedID, type: 'way', role: item.role }
71760                         ];
71761                     } else {
71762                         item.pair = [
71763                             { id: insertPair.insertedID, type: 'way', role: item.role },
71764                             { id: insertPair.originalID, type: 'way', role: item.role }
71765                         ];
71766                     }
71767                 }
71768
71769                 // reorder `members` if necessary
71770                 if (k > 0) {
71771                     if (j+k >= members.length || item.index !== members[j+k].index) {
71772                         moveMember(members, item.index, j+k);
71773                     }
71774                 }
71775
71776                 nodes.splice(0, way.nodes.length - 1);
71777             }
71778         }
71779
71780         if (tempWay) {
71781             graph = graph.remove(tempWay);
71782         }
71783
71784         // Final pass: skip dead items, split pairs, remove index properties
71785         var wayMembers = [];
71786         for (i = 0; i < members.length; i++) {
71787             item = members[i];
71788             if (item.index === -1) continue;
71789
71790             if (item.pair) {
71791                 wayMembers.push(item.pair[0]);
71792                 wayMembers.push(item.pair[1]);
71793             } else {
71794                 wayMembers.push(omit(item, 'index'));
71795             }
71796         }
71797
71798         // Write members in the order: nodes, ways, relations
71799         // This is reccomended for Public Transport routes:
71800         // see https://wiki.openstreetmap.org/wiki/Public_transport#Service_routes
71801         var newMembers = (groups.node || []).concat(wayMembers, (groups.relation || []));
71802
71803         return graph.replace(relation.update({members: newMembers}));
71804
71805
71806         // `moveMember()` changes the `members` array in place by splicing
71807         // the item with `.index = findIndex` to where it belongs,
71808         // and marking the old position as "dead" with `.index = -1`
71809         //
71810         // j=5, k=0                jk
71811         // segment                 5 4 7 6
71812         // members       0 1 2 3 4 5 6 7 8 9        keep 5 in j+k
71813         //
71814         // j=5, k=1                j k
71815         // segment                 5 4 7 6
71816         // members       0 1 2 3 4 5 6 7 8 9        move 4 to j+k
71817         // members       0 1 2 3 x 5 4 6 7 8 9      moved
71818         //
71819         // j=5, k=2                j   k
71820         // segment                 5 4 7 6
71821         // members       0 1 2 3 x 5 4 6 7 8 9      move 7 to j+k
71822         // members       0 1 2 3 x 5 4 7 6 x 8 9    moved
71823         //
71824         // j=5, k=3                j     k
71825         // segment                 5 4 7 6
71826         // members       0 1 2 3 x 5 4 7 6 x 8 9    keep 6 in j+k
71827         //
71828         function moveMember(arr, findIndex, toIndex) {
71829             for (var i = 0; i < arr.length; i++) {
71830                 if (arr[i].index === findIndex) {
71831                     break;
71832                 }
71833             }
71834
71835             var item = clone(arr[i]);
71836             arr[i].index = -1;   // mark as dead
71837             item.index = toIndex;
71838             arr.splice(toIndex, 0, item);
71839         }
71840
71841
71842         // This is the same as `Relation.indexedMembers`,
71843         // Except we don't want to index all the members, only the ways
71844         function withIndex(arr) {
71845             var result = new Array(arr.length);
71846             for (var i = 0; i < arr.length; i++) {
71847                 result[i] = arr[i];
71848                 result[i].index = i;
71849             }
71850             return result;
71851         }
71852     }
71853
71854 }
71855
71856 function actionAddMidpoint(midpoint, node) {
71857     return function(graph) {
71858         graph = graph.replace(node.move(midpoint.loc));
71859
71860         var parents = intersection(
71861             graph.parentWays(graph.entity(midpoint.edge[0])),
71862             graph.parentWays(graph.entity(midpoint.edge[1])));
71863
71864         parents.forEach(function(way) {
71865             for (var i = 0; i < way.nodes.length - 1; i++) {
71866                 if (geoEdgeEqual([way.nodes[i], way.nodes[i + 1]], midpoint.edge)) {
71867                     graph = graph.replace(graph.entity(way.id).addNode(node.id, i + 1));
71868
71869                     // Add only one midpoint on doubled-back segments,
71870                     // turning them into self-intersections.
71871                     return;
71872                 }
71873             }
71874         });
71875
71876         return graph;
71877     };
71878 }
71879
71880 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/AddNodeToWayAction.as
71881 function actionAddVertex(wayId, nodeId, index) {
71882     return function(graph) {
71883         return graph.replace(graph.entity(wayId).addNode(nodeId, index));
71884     };
71885 }
71886
71887 function actionChangeMember(relationId, member, memberIndex) {
71888     return function(graph) {
71889         return graph.replace(graph.entity(relationId).updateMember(member, memberIndex));
71890     };
71891 }
71892
71893 function actionChangePreset(entityId, oldPreset, newPreset) {
71894     return function(graph) {
71895         var entity = graph.entity(entityId),
71896             geometry = entity.geometry(graph),
71897             tags = entity.tags;
71898
71899         if (oldPreset) tags = oldPreset.removeTags(tags, geometry);
71900         if (newPreset) tags = newPreset.applyTags(tags, geometry);
71901
71902         return graph.replace(entity.update({tags: tags}));
71903     };
71904 }
71905
71906 function actionChangeTags(entityId, tags) {
71907     return function(graph) {
71908         var entity = graph.entity(entityId);
71909         return graph.replace(entity.update({tags: tags}));
71910     };
71911 }
71912
71913 function actionCircularize(wayId, projection, maxAngle) {
71914     maxAngle = (maxAngle || 20) * Math.PI / 180;
71915
71916
71917     var action = function(graph, t) {
71918         if (t === null || !isFinite(t)) t = 1;
71919         t = Math.min(Math.max(+t, 0), 1);
71920
71921         var way = graph.entity(wayId),
71922             origNodes = {};
71923
71924         graph.childNodes(way).forEach(function(node) {
71925             if (!origNodes[node.id]) origNodes[node.id] = node;
71926         });
71927
71928         if (!way.isConvex(graph)) {
71929             graph = action.makeConvex(graph);
71930         }
71931
71932         var nodes = uniq(graph.childNodes(way)),
71933             keyNodes = nodes.filter(function(n) { return graph.parentWays(n).length !== 1; }),
71934             points = nodes.map(function(n) { return projection(n.loc); }),
71935             keyPoints = keyNodes.map(function(n) { return projection(n.loc); }),
71936             centroid = (points.length === 2) ? geoVecInterp(points[0], points[1], 0.5) : d3_polygonCentroid(points),
71937             radius = d3_median(points, function(p) { return geoVecLength(centroid, p); }),
71938             sign = d3_polygonArea(points) > 0 ? 1 : -1,
71939             ids;
71940
71941         // we need atleast two key nodes for the algorithm to work
71942         if (!keyNodes.length) {
71943             keyNodes = [nodes[0]];
71944             keyPoints = [points[0]];
71945         }
71946
71947         if (keyNodes.length === 1) {
71948             var index = nodes.indexOf(keyNodes[0]),
71949                 oppositeIndex = Math.floor((index + nodes.length / 2) % nodes.length);
71950
71951             keyNodes.push(nodes[oppositeIndex]);
71952             keyPoints.push(points[oppositeIndex]);
71953         }
71954
71955         // key points and nodes are those connected to the ways,
71956         // they are projected onto the circle, inbetween nodes are moved
71957         // to constant intervals between key nodes, extra inbetween nodes are
71958         // added if necessary.
71959         for (var i = 0; i < keyPoints.length; i++) {
71960             var nextKeyNodeIndex = (i + 1) % keyNodes.length,
71961                 startNode = keyNodes[i],
71962                 endNode = keyNodes[nextKeyNodeIndex],
71963                 startNodeIndex = nodes.indexOf(startNode),
71964                 endNodeIndex = nodes.indexOf(endNode),
71965                 numberNewPoints = -1,
71966                 indexRange = endNodeIndex - startNodeIndex,
71967                 nearNodes = {},
71968                 inBetweenNodes = [],
71969                 startAngle, endAngle, totalAngle, eachAngle,
71970                 angle, loc, node, origNode, j;
71971
71972             if (indexRange < 0) {
71973                 indexRange += nodes.length;
71974             }
71975
71976             // position this key node
71977             var distance = geoVecLength(centroid, keyPoints[i]);
71978             if (distance === 0) { distance = 1e-4; }
71979             keyPoints[i] = [
71980                 centroid[0] + (keyPoints[i][0] - centroid[0]) / distance * radius,
71981                 centroid[1] + (keyPoints[i][1] - centroid[1]) / distance * radius
71982             ];
71983             loc = projection.invert(keyPoints[i]);
71984             node = keyNodes[i];
71985             origNode = origNodes[node.id];
71986             node = node.move(geoVecInterp(origNode.loc, loc, t));
71987             graph = graph.replace(node);
71988
71989             // figure out the between delta angle we want to match to
71990             startAngle = Math.atan2(keyPoints[i][1] - centroid[1], keyPoints[i][0] - centroid[0]);
71991             endAngle = Math.atan2(keyPoints[nextKeyNodeIndex][1] - centroid[1], keyPoints[nextKeyNodeIndex][0] - centroid[0]);
71992             totalAngle = endAngle - startAngle;
71993
71994             // detects looping around -pi/pi
71995             if (totalAngle * sign > 0) {
71996                 totalAngle = -sign * (2 * Math.PI - Math.abs(totalAngle));
71997             }
71998
71999             do {
72000                 numberNewPoints++;
72001                 eachAngle = totalAngle / (indexRange + numberNewPoints);
72002             } while (Math.abs(eachAngle) > maxAngle);
72003
72004
72005             // move existing nodes
72006             for (j = 1; j < indexRange; j++) {
72007                 angle = startAngle + j * eachAngle;
72008                 loc = projection.invert([
72009                     centroid[0] + Math.cos(angle) * radius,
72010                     centroid[1] + Math.sin(angle) * radius
72011                 ]);
72012
72013                 node = nodes[(j + startNodeIndex) % nodes.length];
72014                 origNode = origNodes[node.id];
72015                 nearNodes[node.id] = angle;
72016
72017                 node = node.move(geoVecInterp(origNode.loc, loc, t));
72018                 graph = graph.replace(node);
72019             }
72020
72021             // add new inbetween nodes if necessary
72022             for (j = 0; j < numberNewPoints; j++) {
72023                 angle = startAngle + (indexRange + j) * eachAngle;
72024                 loc = projection.invert([
72025                     centroid[0] + Math.cos(angle) * radius,
72026                     centroid[1] + Math.sin(angle) * radius
72027                 ]);
72028
72029                 // choose a nearnode to use as the original
72030                 var min = Infinity;
72031                 for (var nodeId in nearNodes) {
72032                     var nearAngle = nearNodes[nodeId],
72033                         dist = Math.abs(nearAngle - angle);
72034                     if (dist < min) {
72035                         dist = min;
72036                         origNode = origNodes[nodeId];
72037                     }
72038                 }
72039
72040                 node = osmNode({ loc: geoVecInterp(origNode.loc, loc, t) });
72041                 graph = graph.replace(node);
72042
72043                 nodes.splice(endNodeIndex + j, 0, node);
72044                 inBetweenNodes.push(node.id);
72045             }
72046
72047             // Check for other ways that share these keyNodes..
72048             // If keyNodes are adjacent in both ways,
72049             // we can add inBetween nodes to that shared way too..
72050             if (indexRange === 1 && inBetweenNodes.length) {
72051                 var startIndex1 = way.nodes.lastIndexOf(startNode.id),
72052                     endIndex1 = way.nodes.lastIndexOf(endNode.id),
72053                     wayDirection1 = (endIndex1 - startIndex1);
72054                 if (wayDirection1 < -1) { wayDirection1 = 1; }
72055
72056                 /* eslint-disable no-loop-func */
72057                 forEach(without(graph.parentWays(keyNodes[i]), way), function(sharedWay) {
72058                     if (sharedWay.areAdjacent(startNode.id, endNode.id)) {
72059                         var startIndex2 = sharedWay.nodes.lastIndexOf(startNode.id),
72060                             endIndex2 = sharedWay.nodes.lastIndexOf(endNode.id),
72061                             wayDirection2 = (endIndex2 - startIndex2),
72062                             insertAt = endIndex2;
72063                         if (wayDirection2 < -1) { wayDirection2 = 1; }
72064
72065                         if (wayDirection1 !== wayDirection2) {
72066                             inBetweenNodes.reverse();
72067                             insertAt = startIndex2;
72068                         }
72069                         for (j = 0; j < inBetweenNodes.length; j++) {
72070                             sharedWay = sharedWay.addNode(inBetweenNodes[j], insertAt + j);
72071                         }
72072                         graph = graph.replace(sharedWay);
72073                     }
72074                 });
72075                 /* eslint-enable no-loop-func */
72076             }
72077
72078         }
72079
72080         // update the way to have all the new nodes
72081         ids = nodes.map(function(n) { return n.id; });
72082         ids.push(ids[0]);
72083
72084         way = way.update({nodes: ids});
72085         graph = graph.replace(way);
72086
72087         return graph;
72088     };
72089
72090
72091     action.makeConvex = function(graph) {
72092         var way = graph.entity(wayId),
72093             nodes = uniq(graph.childNodes(way)),
72094             points = nodes.map(function(n) { return projection(n.loc); }),
72095             sign = d3_polygonArea(points) > 0 ? 1 : -1,
72096             hull = d3_polygonHull(points);
72097
72098         // D3 convex hulls go counterclockwise..
72099         if (sign === -1) {
72100             nodes.reverse();
72101             points.reverse();
72102         }
72103
72104         for (var i = 0; i < hull.length - 1; i++) {
72105             var startIndex = points.indexOf(hull[i]),
72106                 endIndex = points.indexOf(hull[i+1]),
72107                 indexRange = (endIndex - startIndex);
72108
72109             if (indexRange < 0) {
72110                 indexRange += nodes.length;
72111             }
72112
72113             // move interior nodes to the surface of the convex hull..
72114             for (var j = 1; j < indexRange; j++) {
72115                 var point = geoVecInterp(hull[i], hull[i+1], j / indexRange),
72116                     node = nodes[(j + startIndex) % nodes.length].move(projection.invert(point));
72117                 graph = graph.replace(node);
72118             }
72119         }
72120         return graph;
72121     };
72122
72123
72124     action.disabled = function(graph) {
72125         if (!graph.entity(wayId).isClosed())
72126             return 'not_closed';
72127     };
72128
72129
72130     action.transitionable = true;
72131
72132
72133     return action;
72134 }
72135
72136 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteWayAction.as
72137 function actionDeleteWay(wayId) {
72138
72139
72140     function canDeleteNode(node, graph) {
72141         return !graph.parentWays(node).length &&
72142             !graph.parentRelations(node).length &&
72143             !node.hasInterestingTags();
72144     }
72145
72146
72147     var action = function(graph) {
72148         var way = graph.entity(wayId);
72149
72150         graph.parentRelations(way)
72151             .forEach(function(parent) {
72152                 parent = parent.removeMembersWithID(wayId);
72153                 graph = graph.replace(parent);
72154
72155                 if (parent.isDegenerate()) {
72156                     graph = actionDeleteRelation(parent.id)(graph);
72157                 }
72158             });
72159
72160         uniq(way.nodes).forEach(function(nodeId) {
72161             graph = graph.replace(way.removeNode(nodeId));
72162
72163             var node = graph.entity(nodeId);
72164             if (canDeleteNode(node, graph)) {
72165                 graph = graph.remove(node);
72166             }
72167         });
72168
72169         return graph.remove(way);
72170     };
72171
72172
72173     return action;
72174 }
72175
72176 function actionDeleteMultiple(ids) {
72177     var actions = {
72178         way: actionDeleteWay,
72179         node: actionDeleteNode,
72180         relation: actionDeleteRelation
72181     };
72182
72183
72184     var action = function(graph) {
72185         ids.forEach(function(id) {
72186             if (graph.hasEntity(id)) { // It may have been deleted aready.
72187                 graph = actions[graph.entity(id).type](id)(graph);
72188             }
72189         });
72190
72191         return graph;
72192     };
72193
72194
72195     return action;
72196 }
72197
72198 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteRelationAction.as
72199 function actionDeleteRelation(relationId) {
72200
72201
72202     function canDeleteEntity(entity, graph) {
72203         return !graph.parentWays(entity).length &&
72204             !graph.parentRelations(entity).length &&
72205             !entity.hasInterestingTags();
72206     }
72207
72208
72209     var action = function(graph) {
72210         var relation = graph.entity(relationId);
72211
72212         graph.parentRelations(relation)
72213             .forEach(function(parent) {
72214                 parent = parent.removeMembersWithID(relationId);
72215                 graph = graph.replace(parent);
72216
72217                 if (parent.isDegenerate()) {
72218                     graph = actionDeleteRelation(parent.id)(graph);
72219                 }
72220             });
72221
72222         uniq(map$4(relation.members, 'id')).forEach(function(memberId) {
72223             graph = graph.replace(relation.removeMembersWithID(memberId));
72224
72225             var entity = graph.entity(memberId);
72226             if (canDeleteEntity(entity, graph)) {
72227                 graph = actionDeleteMultiple([memberId])(graph);
72228             }
72229         });
72230
72231         return graph.remove(relation);
72232     };
72233
72234
72235     return action;
72236 }
72237
72238 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteNodeAction.as
72239 function actionDeleteNode(nodeId) {
72240     var action = function(graph) {
72241         var node = graph.entity(nodeId);
72242
72243         graph.parentWays(node)
72244             .forEach(function(parent) {
72245                 parent = parent.removeNode(nodeId);
72246                 graph = graph.replace(parent);
72247
72248                 if (parent.isDegenerate()) {
72249                     graph = actionDeleteWay(parent.id)(graph);
72250                 }
72251             });
72252
72253         graph.parentRelations(node)
72254             .forEach(function(parent) {
72255                 parent = parent.removeMembersWithID(nodeId);
72256                 graph = graph.replace(parent);
72257
72258                 if (parent.isDegenerate()) {
72259                     graph = actionDeleteRelation(parent.id)(graph);
72260                 }
72261             });
72262
72263         return graph.remove(node);
72264     };
72265
72266
72267     return action;
72268 }
72269
72270 // Connect the ways at the given nodes.
72271 //
72272 // The last node will survive. All other nodes will be replaced with
72273 // the surviving node in parent ways, and then removed.
72274 //
72275 // Tags and relation memberships of of non-surviving nodes are merged
72276 // to the survivor.
72277 //
72278 // This is the inverse of `iD.actionDisconnect`.
72279 //
72280 // Reference:
72281 //   https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MergeNodesAction.as
72282 //   https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/MergeNodesAction.java
72283 //
72284 function actionConnect(nodeIds) {
72285     return function(graph) {
72286         var last = nodeIds[nodeIds.length - 1];
72287         var survivor = graph.entity(last);
72288
72289         for (var i = 0; i < nodeIds.length - 1; i++) {
72290             var node = graph.entity(nodeIds[i]);
72291
72292             /* eslint-disable no-loop-func */
72293             graph.parentWays(node).forEach(function(parent) {
72294                 if (!parent.areAdjacent(node.id, survivor.id)) {
72295                     graph = graph.replace(parent.replaceNode(node.id, survivor.id));
72296                 }
72297             });
72298
72299             graph.parentRelations(node).forEach(function(parent) {
72300                 graph = graph.replace(parent.replaceMember(node, survivor));
72301             });
72302             /* eslint-enable no-loop-func */
72303
72304             survivor = survivor.mergeTags(node.tags);
72305             graph = actionDeleteNode(node.id)(graph);
72306         }
72307
72308         graph = graph.replace(survivor);
72309
72310         return graph;
72311     };
72312 }
72313
72314 function actionCopyEntities(ids, fromGraph) {
72315     var copies = {};
72316
72317
72318     var action = function(graph) {
72319         ids.forEach(function(id) {
72320             fromGraph.entity(id).copy(fromGraph, copies);
72321         });
72322
72323         for (var id in copies) {
72324             graph = graph.replace(copies[id]);
72325         }
72326
72327         return graph;
72328     };
72329
72330
72331     action.copies = function() {
72332         return copies;
72333     };
72334
72335
72336     return action;
72337 }
72338
72339 function actionDeleteMember(relationId, memberIndex) {
72340     return function(graph) {
72341         var relation = graph.entity(relationId)
72342             .removeMember(memberIndex);
72343
72344         graph = graph.replace(relation);
72345
72346         if (relation.isDegenerate())
72347             graph = actionDeleteRelation(relation.id)(graph);
72348
72349         return graph;
72350     };
72351 }
72352
72353 function actionDeprecateTags(entityId) {
72354
72355     return function(graph) {
72356         var entity = graph.entity(entityId),
72357             newtags = clone(entity.tags),
72358             change = false,
72359             rule;
72360
72361         // This handles dataDeprecated tags with a single condition
72362         for (var i = 0; i < dataDeprecated.length; i++) {
72363
72364             rule = dataDeprecated[i];
72365             var match = toPairs(rule.old)[0],
72366                 replacements = rule.replace ? toPairs(rule.replace) : null;
72367
72368             if (entity.tags[match[0]] && match[1] === '*') {
72369
72370                 var value = entity.tags[match[0]];
72371                 if (replacements && !newtags[replacements[0][0]]) {
72372                     newtags[replacements[0][0]] = value;
72373                 }
72374                 delete newtags[match[0]];
72375                 change = true;
72376
72377             } else if (entity.tags[match[0]] === match[1]) {
72378                 newtags = assign({}, rule.replace || {}, omit(newtags, match[0]));
72379                 change = true;
72380             }
72381         }
72382
72383         if (change) {
72384             return graph.replace(entity.update({tags: newtags}));
72385         } else {
72386             return graph;
72387         }
72388     };
72389 }
72390
72391 function actionDiscardTags(difference) {
72392
72393     return function(graph) {
72394         function discardTags(entity) {
72395             if (!isEmpty(entity.tags)) {
72396                 var tags = {};
72397                 forEach(entity.tags, function(v, k) {
72398                     if (v) tags[k] = v;
72399                 });
72400
72401                 graph = graph.replace(entity.update({
72402                     tags: omit(tags, dataDiscarded)
72403                 }));
72404             }
72405         }
72406
72407         difference.modified().forEach(discardTags);
72408         difference.created().forEach(discardTags);
72409
72410         return graph;
72411     };
72412 }
72413
72414 // Disconect the ways at the given node.
72415 //
72416 // Optionally, disconnect only the given ways.
72417 //
72418 // For testing convenience, accepts an ID to assign to the (first) new node.
72419 // Normally, this will be undefined and the way will automatically
72420 // be assigned a new ID.
72421 //
72422 // This is the inverse of `iD.actionConnect`.
72423 //
72424 // Reference:
72425 //   https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/UnjoinNodeAction.as
72426 //   https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/UnGlueAction.java
72427 //
72428 function actionDisconnect(nodeId, newNodeId) {
72429     var wayIds;
72430
72431
72432     var action = function(graph) {
72433         var node = graph.entity(nodeId),
72434             connections = action.connections(graph);
72435
72436         connections.forEach(function(connection) {
72437             var way = graph.entity(connection.wayID),
72438                 newNode = osmNode({id: newNodeId, loc: node.loc, tags: node.tags});
72439
72440             graph = graph.replace(newNode);
72441             if (connection.index === 0 && way.isArea()) {
72442                 // replace shared node with shared node..
72443                 graph = graph.replace(way.replaceNode(way.nodes[0], newNode.id));
72444             } else if (way.isClosed() && connection.index === way.nodes.length - 1) {
72445                 // replace closing node with new new node..
72446                 graph = graph.replace(way.unclose().addNode(newNode.id));
72447             } else {
72448                 // replace shared node with multiple new nodes..
72449                 graph = graph.replace(way.updateNode(newNode.id, connection.index));
72450             }
72451         });
72452
72453         return graph;
72454     };
72455
72456
72457     action.connections = function(graph) {
72458         var candidates = [],
72459             keeping = false,
72460             parentWays = graph.parentWays(graph.entity(nodeId));
72461
72462         parentWays.forEach(function(way) {
72463             if (wayIds && wayIds.indexOf(way.id) === -1) {
72464                 keeping = true;
72465                 return;
72466             }
72467             if (way.isArea() && (way.nodes[0] === nodeId)) {
72468                 candidates.push({ wayID: way.id, index: 0 });
72469             } else {
72470                 way.nodes.forEach(function(waynode, index) {
72471                     if (waynode === nodeId) {
72472                         candidates.push({ wayID: way.id, index: index });
72473                     }
72474                 });
72475             }
72476         });
72477
72478         return keeping ? candidates : candidates.slice(1);
72479     };
72480
72481
72482     action.disabled = function(graph) {
72483         var connections = action.connections(graph);
72484         if (connections.length === 0 || (wayIds && wayIds.length !== connections.length))
72485             return 'not_connected';
72486
72487         var parentWays = graph.parentWays(graph.entity(nodeId)),
72488             seenRelationIds = {},
72489             sharedRelation;
72490
72491         parentWays.forEach(function(way) {
72492             if (wayIds && wayIds.indexOf(way.id) === -1)
72493                 return;
72494
72495             var relations = graph.parentRelations(way);
72496             relations.forEach(function(relation) {
72497                 if (relation.id in seenRelationIds) {
72498                     sharedRelation = relation;
72499                 } else {
72500                     seenRelationIds[relation.id] = true;
72501                 }
72502             });
72503         });
72504
72505         if (sharedRelation)
72506             return 'relation';
72507     };
72508
72509
72510     action.limitWays = function(_) {
72511         if (!arguments.length) return wayIds;
72512         wayIds = _;
72513         return action;
72514     };
72515
72516
72517     return action;
72518 }
72519
72520 // Join ways at the end node they share.
72521 //
72522 // This is the inverse of `iD.actionSplit`.
72523 //
72524 // Reference:
72525 //   https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MergeWaysAction.as
72526 //   https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/CombineWayAction.java
72527 //
72528 function actionJoin(ids) {
72529
72530     function groupEntitiesByGeometry(graph) {
72531         var entities = ids.map(function(id) { return graph.entity(id); });
72532         return assignIn({line: []}, groupBy(entities, function(entity) { return entity.geometry(graph); }));
72533     }
72534
72535
72536     var action = function(graph) {
72537         var ways = ids.map(graph.entity, graph);
72538         var survivorID = ways[0].id;
72539
72540         // Prefer to keep an existing way.
72541         for (var i = 0; i < ways.length; i++) {
72542             if (!ways[i].isNew()) {
72543                 survivorID = ways[i].id;
72544                 break;
72545             }
72546         }
72547
72548         var sequences = osmJoinWays(ways, graph);
72549         var joined = sequences[0];
72550
72551         // We might need to reverse some of these ways before joining them.  #4688
72552         // `joined.actions` property will contain any actions we need to apply.
72553         graph = sequences.actions.reduce(function(g, action) { return action(g); }, graph);
72554
72555         var survivor = graph.entity(survivorID);
72556         survivor = survivor.update({ nodes: joined.nodes.map(function(n) { return n.id; }) });
72557         graph = graph.replace(survivor);
72558
72559         joined.forEach(function(way) {
72560             if (way.id === survivorID) return;
72561
72562             graph.parentRelations(way).forEach(function(parent) {
72563                 graph = graph.replace(parent.replaceMember(way, survivor));
72564             });
72565
72566             survivor = survivor.mergeTags(way.tags);
72567
72568             graph = graph.replace(survivor);
72569             graph = actionDeleteWay(way.id)(graph);
72570         });
72571
72572         return graph;
72573     };
72574
72575
72576     action.disabled = function(graph) {
72577         var geometries = groupEntitiesByGeometry(graph);
72578         if (ids.length < 2 || ids.length !== geometries.line.length)
72579             return 'not_eligible';
72580
72581         var joined = osmJoinWays(ids.map(graph.entity, graph), graph);
72582         if (joined.length > 1)
72583             return 'not_adjacent';
72584
72585         var nodeIds = joined[0].nodes.map(function(n) { return n.id; }).slice(1, -1);
72586         var relation;
72587         var tags = {};
72588         var conflicting = false;
72589
72590         joined[0].forEach(function(way) {
72591             var parents = graph.parentRelations(way);
72592             parents.forEach(function(parent) {
72593                 if (parent.isRestriction() && parent.members.some(function(m) { return nodeIds.indexOf(m.id) >= 0; }))
72594                     relation = parent;
72595             });
72596
72597             for (var k in way.tags) {
72598                 if (!(k in tags)) {
72599                     tags[k] = way.tags[k];
72600                 } else if (tags[k] && osmIsInterestingTag(k) && tags[k] !== way.tags[k]) {
72601                     conflicting = true;
72602                 }
72603             }
72604         });
72605
72606         if (relation)
72607             return 'restriction';
72608
72609         if (conflicting)
72610             return 'conflicting_tags';
72611     };
72612
72613
72614     return action;
72615 }
72616
72617 function actionMerge(ids) {
72618
72619     function groupEntitiesByGeometry(graph) {
72620         var entities = ids.map(function(id) { return graph.entity(id); });
72621         return assignIn({point: [], area: [], line: [], relation: []},
72622             groupBy(entities, function(entity) { return entity.geometry(graph); }));
72623     }
72624
72625
72626     var action = function(graph) {
72627         var geometries = groupEntitiesByGeometry(graph),
72628             target = geometries.area[0] || geometries.line[0],
72629             points = geometries.point;
72630
72631         points.forEach(function(point) {
72632             target = target.mergeTags(point.tags);
72633             graph = graph.replace(target);
72634
72635             graph.parentRelations(point).forEach(function(parent) {
72636                 graph = graph.replace(parent.replaceMember(point, target));
72637             });
72638
72639             var nodes = uniq(graph.childNodes(target)),
72640                 removeNode = point;
72641
72642             for (var i = 0; i < nodes.length; i++) {
72643                 var node = nodes[i];
72644                 if (graph.parentWays(node).length > 1 ||
72645                     graph.parentRelations(node).length ||
72646                     node.hasInterestingTags()) {
72647                     continue;
72648                 }
72649
72650                 // Found an uninteresting child node on the target way.
72651                 // Move orig point into its place to preserve point's history. #3683
72652                 graph = graph.replace(point.update({ tags: {}, loc: node.loc }));
72653                 target = target.replaceNode(node.id, point.id);
72654                 graph = graph.replace(target);
72655                 removeNode = node;
72656                 break;
72657             }
72658
72659             graph = graph.remove(removeNode);
72660         });
72661
72662         return graph;
72663     };
72664
72665
72666     action.disabled = function(graph) {
72667         var geometries = groupEntitiesByGeometry(graph);
72668         if (geometries.point.length === 0 ||
72669             (geometries.area.length + geometries.line.length) !== 1 ||
72670             geometries.relation.length !== 0)
72671             return 'not_eligible';
72672     };
72673
72674
72675     return action;
72676 }
72677
72678 function actionMergePolygon(ids, newRelationId) {
72679
72680     function groupEntities(graph) {
72681         var entities = ids.map(function (id) { return graph.entity(id); });
72682         return assignIn({
72683                 closedWay: [],
72684                 multipolygon: [],
72685                 other: []
72686             }, groupBy(entities, function(entity) {
72687                 if (entity.type === 'way' && entity.isClosed()) {
72688                     return 'closedWay';
72689                 } else if (entity.type === 'relation' && entity.isMultipolygon()) {
72690                     return 'multipolygon';
72691                 } else {
72692                     return 'other';
72693                 }
72694             }));
72695     }
72696
72697
72698     var action = function(graph) {
72699         var entities = groupEntities(graph);
72700
72701         // An array representing all the polygons that are part of the multipolygon.
72702         //
72703         // Each element is itself an array of objects with an id property, and has a
72704         // locs property which is an array of the locations forming the polygon.
72705         var polygons = entities.multipolygon.reduce(function(polygons, m) {
72706             return polygons.concat(osmJoinWays(m.members, graph));
72707         }, []).concat(entities.closedWay.map(function(d) {
72708             var member = [{id: d.id}];
72709             member.nodes = graph.childNodes(d);
72710             return member;
72711         }));
72712
72713         // contained is an array of arrays of boolean values,
72714         // where contained[j][k] is true iff the jth way is
72715         // contained by the kth way.
72716         var contained = polygons.map(function(w, i) {
72717             return polygons.map(function(d, n) {
72718                 if (i === n) return null;
72719                 return geoPolygonContainsPolygon(
72720                     map$4(d.nodes, 'loc'),
72721                     map$4(w.nodes, 'loc'));
72722             });
72723         });
72724
72725         // Sort all polygons as either outer or inner ways
72726         var members = [],
72727             outer = true;
72728
72729         while (polygons.length) {
72730             extractUncontained(polygons);
72731             polygons = polygons.filter(isContained);
72732             contained = contained.filter(isContained).map(filterContained);
72733         }
72734
72735         function isContained(d, i) {
72736             return some(contained[i]);
72737         }
72738
72739         function filterContained(d) {
72740             return d.filter(isContained);
72741         }
72742
72743         function extractUncontained(polygons) {
72744             polygons.forEach(function(d, i) {
72745                 if (!isContained(d, i)) {
72746                     d.forEach(function(member) {
72747                         members.push({
72748                             type: 'way',
72749                             id: member.id,
72750                             role: outer ? 'outer' : 'inner'
72751                         });
72752                     });
72753                 }
72754             });
72755             outer = !outer;
72756         }
72757
72758         // Move all tags to one relation
72759         var relation = entities.multipolygon[0] ||
72760             osmRelation({ id: newRelationId, tags: { type: 'multipolygon' }});
72761
72762         entities.multipolygon.slice(1).forEach(function(m) {
72763             relation = relation.mergeTags(m.tags);
72764             graph = graph.remove(m);
72765         });
72766
72767         entities.closedWay.forEach(function(way) {
72768             function isThisOuter(m) {
72769                 return m.id === way.id && m.role !== 'inner';
72770             }
72771             if (members.some(isThisOuter)) {
72772                 relation = relation.mergeTags(way.tags);
72773                 graph = graph.replace(way.update({ tags: {} }));
72774             }
72775         });
72776
72777         return graph.replace(relation.update({
72778             members: members,
72779             tags: omit(relation.tags, 'area')
72780         }));
72781     };
72782
72783
72784     action.disabled = function(graph) {
72785         var entities = groupEntities(graph);
72786         if (entities.other.length > 0 ||
72787             entities.closedWay.length + entities.multipolygon.length < 2)
72788             return 'not_eligible';
72789         if (!entities.multipolygon.every(function(r) { return r.isComplete(graph); }))
72790             return 'incomplete_relation';
72791     };
72792
72793
72794     return action;
72795 }
72796
72797 // Text diff algorithm following Hunt and McIlroy 1976.
72798 // J. W. Hunt and M. D. McIlroy, An algorithm for differential file
72799 // comparison, Bell Telephone Laboratories CSTR #41 (1976)
72800 // http://www.cs.dartmouth.edu/~doug/
72801 //
72802 // Expects two arrays of strings.
72803 function LCS(file1, file2) {
72804   var equivalenceClasses;
72805   var file2indices;
72806   var newCandidate;
72807   var candidates;
72808   var line;
72809   var c, i, j, jX, r, s;
72810
72811   equivalenceClasses = {};
72812   for (j = 0; j < file2.length; j++) {
72813     line = file2[j];
72814     if (equivalenceClasses[line]) {
72815       equivalenceClasses[line].push(j);
72816     } else {
72817       equivalenceClasses[line] = [j];
72818     }
72819   }
72820
72821   candidates = [
72822     { file1index: -1, file2index: -1, chain: null }
72823   ];
72824
72825   for (i = 0; i < file1.length; i++) {
72826     line = file1[i];
72827     file2indices = equivalenceClasses[line] || [];
72828
72829     r = 0;
72830     c = candidates[0];
72831
72832     for (jX = 0; jX < file2indices.length; jX++) {
72833       j = file2indices[jX];
72834
72835       for (s = r; s < candidates.length; s++) {
72836         if ((candidates[s].file2index < j) && ((s === candidates.length - 1) || (candidates[s + 1].file2index > j))) {
72837           break;
72838         }
72839       }
72840
72841       if (s < candidates.length) {
72842         newCandidate = { file1index: i, file2index: j, chain: candidates[s] };
72843         if (r === candidates.length) {
72844           candidates.push(c);
72845         } else {
72846           candidates[r] = c;
72847         }
72848         r = s + 1;
72849         c = newCandidate;
72850         if (r === candidates.length) {
72851           break; // no point in examining further (j)s
72852         }
72853       }
72854     }
72855
72856     candidates[r] = c;
72857   }
72858
72859   // At this point, we know the LCS: it's in the reverse of the
72860   // linked-list through .chain of candidates[candidates.length - 1].
72861
72862   return candidates[candidates.length - 1];
72863 }
72864
72865
72866 // We apply the LCS to give a simple representation of the
72867 // offsets and lengths of mismatched chunks in the input
72868 // files. This is used by diff3MergeIndices below.
72869 function diffIndices(file1, file2) {
72870   var result = [];
72871   var tail1 = file1.length;
72872   var tail2 = file2.length;
72873
72874   for (var candidate = LCS(file1, file2);
72875      candidate !== null;
72876      candidate = candidate.chain)
72877   {
72878     var mismatchLength1 = tail1 - candidate.file1index - 1;
72879     var mismatchLength2 = tail2 - candidate.file2index - 1;
72880     tail1 = candidate.file1index;
72881     tail2 = candidate.file2index;
72882
72883     if (mismatchLength1 || mismatchLength2) {
72884       result.push({
72885         file1: [tail1 + 1, mismatchLength1],
72886         file2: [tail2 + 1, mismatchLength2]
72887       });
72888     }
72889   }
72890
72891   result.reverse();
72892   return result;
72893 }
72894
72895
72896 // Given three files, A, O, and B, where both A and B are
72897 // independently derived from O, returns a fairly complicated
72898 // internal representation of merge decisions it's taken. The
72899 // interested reader may wish to consult
72900 //
72901 // Sanjeev Khanna, Keshav Kunal, and Benjamin C. Pierce.
72902 // 'A Formal Investigation of ' In Arvind and Prasad,
72903 // editors, Foundations of Software Technology and Theoretical
72904 // Computer Science (FSTTCS), December 2007.
72905 //
72906 // (http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf)
72907 function diff3MergeIndices(a, o, b) {
72908   var i;
72909   var m1 = diffIndices(o, a);
72910   var m2 = diffIndices(o, b);
72911
72912   var hunks = [];
72913   function addHunk(h, side) {
72914     hunks.push([h.file1[0], side, h.file1[1], h.file2[0], h.file2[1]]);
72915   }
72916   for (i = 0; i < m1.length; i++) { addHunk(m1[i], 0); }
72917   for (i = 0; i < m2.length; i++) { addHunk(m2[i], 2); }
72918   hunks.sort(function (x, y) { return x[0] - y[0]; });
72919
72920   var result = [];
72921   var commonOffset = 0;
72922   function copyCommon(targetOffset) {
72923     if (targetOffset > commonOffset) {
72924       result.push([1, commonOffset, targetOffset - commonOffset]);
72925       commonOffset = targetOffset;
72926     }
72927   }
72928
72929   for (var hunkIndex = 0; hunkIndex < hunks.length; hunkIndex++) {
72930     var firstHunkIndex = hunkIndex;
72931     var hunk = hunks[hunkIndex];
72932     var regionLhs = hunk[0];
72933     var regionRhs = regionLhs + hunk[2];
72934     while (hunkIndex < hunks.length - 1) {
72935       var maybeOverlapping = hunks[hunkIndex + 1];
72936       var maybeLhs = maybeOverlapping[0];
72937       if (maybeLhs > regionRhs) {
72938         break;
72939       }
72940       regionRhs = Math.max(regionRhs, maybeLhs + maybeOverlapping[2]);
72941       hunkIndex++;
72942     }
72943
72944     copyCommon(regionLhs);
72945     if (firstHunkIndex === hunkIndex) {
72946       // The 'overlap' was only one hunk long, meaning that
72947       // there's no conflict here. Either a and o were the
72948       // same, or b and o were the same.
72949       if (hunk[4] > 0) {
72950         result.push([hunk[1], hunk[3], hunk[4]]);
72951       }
72952     } else {
72953       // A proper conflict. Determine the extents of the
72954       // regions involved from a, o and b. Effectively merge
72955       // all the hunks on the left into one giant hunk, and
72956       // do the same for the right; then, correct for skew
72957       // in the regions of o that each side changed, and
72958       // report appropriate spans for the three sides.
72959       var regions = {
72960         0: [a.length, -1, o.length, -1],
72961         2: [b.length, -1, o.length, -1]
72962       };
72963       for (i = firstHunkIndex; i <= hunkIndex; i++) {
72964         hunk = hunks[i];
72965         var side = hunk[1];
72966         var r = regions[side];
72967         var oLhs = hunk[0];
72968         var oRhs = oLhs + hunk[2];
72969         var abLhs = hunk[3];
72970         var abRhs = abLhs + hunk[4];
72971         r[0] = Math.min(abLhs, r[0]);
72972         r[1] = Math.max(abRhs, r[1]);
72973         r[2] = Math.min(oLhs, r[2]);
72974         r[3] = Math.max(oRhs, r[3]);
72975       }
72976       var aLhs = regions[0][0] + (regionLhs - regions[0][2]);
72977       var aRhs = regions[0][1] + (regionRhs - regions[0][3]);
72978       var bLhs = regions[2][0] + (regionLhs - regions[2][2]);
72979       var bRhs = regions[2][1] + (regionRhs - regions[2][3]);
72980       result.push([-1,
72981                    aLhs,      aRhs      - aLhs,
72982                    regionLhs, regionRhs - regionLhs,
72983                    bLhs,      bRhs      - bLhs]);
72984     }
72985     commonOffset = regionRhs;
72986   }
72987
72988   copyCommon(o.length);
72989   return result;
72990 }
72991
72992
72993 // Applies the output of diff3MergeIndices to actually
72994 // construct the merged file; the returned result alternates
72995 // between 'ok' and 'conflict' blocks.
72996 function diff3Merge(a, o, b, excludeFalseConflicts) {
72997   var result = [];
72998   var files = [a, o, b];
72999   var indices = diff3MergeIndices(a, o, b);
73000
73001   var okLines = [];
73002   function flushOk() {
73003     if (okLines.length) {
73004       result.push({ok: okLines});
73005     }
73006     okLines = [];
73007   }
73008   function pushOk(xs) {
73009     for (var j = 0; j < xs.length; j++) {
73010       okLines.push(xs[j]);
73011     }
73012   }
73013
73014   function isTrueConflict(rec) {
73015     if (rec[2] !== rec[6]) return true;
73016     var aoff = rec[1];
73017     var boff = rec[5];
73018     for (var j = 0; j < rec[2]; j++) {
73019       if (a[j + aoff] !== b[j + boff]) {
73020         return true;
73021       }
73022     }
73023     return false;
73024   }
73025
73026   for (var i = 0; i < indices.length; i++) {
73027     var x = indices[i];
73028     var side = x[0];
73029     if (side === -1) {
73030       if (excludeFalseConflicts && !isTrueConflict(x)) {
73031         pushOk(files[0].slice(x[1], x[1] + x[2]));
73032       } else {
73033         flushOk();
73034         result.push({
73035           conflict: {
73036             a: a.slice(x[1], x[1] + x[2]),
73037             aIndex: x[1],
73038             o: o.slice(x[3], x[3] + x[4]),
73039             oIndex: x[3],
73040             b: b.slice(x[5], x[5] + x[6]),
73041             bIndex: x[5]
73042           }
73043         });
73044       }
73045     } else {
73046       pushOk(files[side].slice(x[1], x[1] + x[2]));
73047     }
73048   }
73049
73050   flushOk();
73051   return result;
73052 }
73053
73054 function actionMergeRemoteChanges(id, localGraph, remoteGraph, formatUser) {
73055     var option = 'safe',  // 'safe', 'force_local', 'force_remote'
73056         conflicts = [];
73057
73058
73059     function user(d) {
73060         return isFunction(formatUser) ? formatUser(d) : d;
73061     }
73062
73063
73064     function mergeLocation(remote, target) {
73065         function pointEqual(a, b) {
73066             var epsilon = 1e-6;
73067             return (Math.abs(a[0] - b[0]) < epsilon) && (Math.abs(a[1] - b[1]) < epsilon);
73068         }
73069
73070         if (option === 'force_local' || pointEqual(target.loc, remote.loc)) {
73071             return target;
73072         }
73073         if (option === 'force_remote') {
73074             return target.update({loc: remote.loc});
73075         }
73076
73077         conflicts.push(t('merge_remote_changes.conflict.location', { user: user(remote.user) }));
73078         return target;
73079     }
73080
73081
73082     function mergeNodes(base, remote, target) {
73083         if (option === 'force_local' || isEqual(target.nodes, remote.nodes)) {
73084             return target;
73085         }
73086         if (option === 'force_remote') {
73087             return target.update({nodes: remote.nodes});
73088         }
73089
73090         var ccount = conflicts.length,
73091             o = base.nodes || [],
73092             a = target.nodes || [],
73093             b = remote.nodes || [],
73094             nodes = [],
73095             hunks = diff3Merge(a, o, b, true);
73096
73097         for (var i = 0; i < hunks.length; i++) {
73098             var hunk = hunks[i];
73099             if (hunk.ok) {
73100                 nodes.push.apply(nodes, hunk.ok);
73101             } else {
73102                 // for all conflicts, we can assume c.a !== c.b
73103                 // because `diff3Merge` called with `true` option to exclude false conflicts..
73104                 var c = hunk.conflict;
73105                 if (isEqual(c.o, c.a)) {  // only changed remotely
73106                     nodes.push.apply(nodes, c.b);
73107                 } else if (isEqual(c.o, c.b)) {  // only changed locally
73108                     nodes.push.apply(nodes, c.a);
73109                 } else {       // changed both locally and remotely
73110                     conflicts.push(t('merge_remote_changes.conflict.nodelist', { user: user(remote.user) }));
73111                     break;
73112                 }
73113             }
73114         }
73115
73116         return (conflicts.length === ccount) ? target.update({nodes: nodes}) : target;
73117     }
73118
73119
73120     function mergeChildren(targetWay, children, updates, graph) {
73121         function isUsed(node, targetWay) {
73122             var parentWays = map$4(graph.parentWays(node), 'id');
73123             return node.hasInterestingTags() ||
73124                 without(parentWays, targetWay.id).length > 0 ||
73125                 graph.parentRelations(node).length > 0;
73126         }
73127
73128         var ccount = conflicts.length;
73129
73130         for (var i = 0; i < children.length; i++) {
73131             var id = children[i],
73132                 node = graph.hasEntity(id);
73133
73134             // remove unused childNodes..
73135             if (targetWay.nodes.indexOf(id) === -1) {
73136                 if (node && !isUsed(node, targetWay)) {
73137                     updates.removeIds.push(id);
73138                 }
73139                 continue;
73140             }
73141
73142             // restore used childNodes..
73143             var local = localGraph.hasEntity(id),
73144                 remote = remoteGraph.hasEntity(id),
73145                 target;
73146
73147             if (option === 'force_remote' && remote && remote.visible) {
73148                 updates.replacements.push(remote);
73149
73150             } else if (option === 'force_local' && local) {
73151                 target = osmEntity(local);
73152                 if (remote) {
73153                     target = target.update({ version: remote.version });
73154                 }
73155                 updates.replacements.push(target);
73156
73157             } else if (option === 'safe' && local && remote && local.version !== remote.version) {
73158                 target = osmEntity(local, { version: remote.version });
73159                 if (remote.visible) {
73160                     target = mergeLocation(remote, target);
73161                 } else {
73162                     conflicts.push(t('merge_remote_changes.conflict.deleted', { user: user(remote.user) }));
73163                 }
73164
73165                 if (conflicts.length !== ccount) break;
73166                 updates.replacements.push(target);
73167             }
73168         }
73169
73170         return targetWay;
73171     }
73172
73173
73174     function updateChildren(updates, graph) {
73175         for (var i = 0; i < updates.replacements.length; i++) {
73176             graph = graph.replace(updates.replacements[i]);
73177         }
73178         if (updates.removeIds.length) {
73179             graph = actionDeleteMultiple(updates.removeIds)(graph);
73180         }
73181         return graph;
73182     }
73183
73184
73185     function mergeMembers(remote, target) {
73186         if (option === 'force_local' || isEqual(target.members, remote.members)) {
73187             return target;
73188         }
73189         if (option === 'force_remote') {
73190             return target.update({members: remote.members});
73191         }
73192
73193         conflicts.push(t('merge_remote_changes.conflict.memberlist', { user: user(remote.user) }));
73194         return target;
73195     }
73196
73197
73198     function mergeTags(base, remote, target) {
73199         function ignoreKey(k) {
73200             return includes(dataDiscarded, k);
73201         }
73202
73203         if (option === 'force_local' || isEqual(target.tags, remote.tags)) {
73204             return target;
73205         }
73206         if (option === 'force_remote') {
73207             return target.update({tags: remote.tags});
73208         }
73209
73210         var ccount = conflicts.length,
73211             o = base.tags || {},
73212             a = target.tags || {},
73213             b = remote.tags || {},
73214             keys = reject(union(keys$1(o), keys$1(a), keys$1(b)), ignoreKey),
73215             tags = clone(a),
73216             changed = false;
73217
73218         for (var i = 0; i < keys.length; i++) {
73219             var k = keys[i];
73220
73221             if (o[k] !== b[k] && a[k] !== b[k]) {    // changed remotely..
73222                 if (o[k] !== a[k]) {      // changed locally..
73223                     conflicts.push(t('merge_remote_changes.conflict.tags',
73224                         { tag: k, local: a[k], remote: b[k], user: user(remote.user) }));
73225
73226                 } else {                  // unchanged locally, accept remote change..
73227                     if (b.hasOwnProperty(k)) {
73228                         tags[k] = b[k];
73229                     } else {
73230                         delete tags[k];
73231                     }
73232                     changed = true;
73233                 }
73234             }
73235         }
73236
73237         return (changed && conflicts.length === ccount) ? target.update({tags: tags}) : target;
73238     }
73239
73240
73241     //  `graph.base()` is the common ancestor of the two graphs.
73242     //  `localGraph` contains user's edits up to saving
73243     //  `remoteGraph` contains remote edits to modified nodes
73244     //  `graph` must be a descendent of `localGraph` and may include
73245     //      some conflict resolution actions performed on it.
73246     //
73247     //                  --- ... --- `localGraph` -- ... -- `graph`
73248     //                 /
73249     //  `graph.base()` --- ... --- `remoteGraph`
73250     //
73251     var action = function(graph) {
73252         var updates = { replacements: [], removeIds: [] },
73253             base = graph.base().entities[id],
73254             local = localGraph.entity(id),
73255             remote = remoteGraph.entity(id),
73256             target = osmEntity(local, { version: remote.version });
73257
73258         // delete/undelete
73259         if (!remote.visible) {
73260             if (option === 'force_remote') {
73261                 return actionDeleteMultiple([id])(graph);
73262
73263             } else if (option === 'force_local') {
73264                 if (target.type === 'way') {
73265                     target = mergeChildren(target, uniq(local.nodes), updates, graph);
73266                     graph = updateChildren(updates, graph);
73267                 }
73268                 return graph.replace(target);
73269
73270             } else {
73271                 conflicts.push(t('merge_remote_changes.conflict.deleted', { user: user(remote.user) }));
73272                 return graph;  // do nothing
73273             }
73274         }
73275
73276         // merge
73277         if (target.type === 'node') {
73278             target = mergeLocation(remote, target);
73279
73280         } else if (target.type === 'way') {
73281             // pull in any child nodes that may not be present locally..
73282             graph.rebase(remoteGraph.childNodes(remote), [graph], false);
73283             target = mergeNodes(base, remote, target);
73284             target = mergeChildren(target, union(local.nodes, remote.nodes), updates, graph);
73285
73286         } else if (target.type === 'relation') {
73287             target = mergeMembers(remote, target);
73288         }
73289
73290         target = mergeTags(base, remote, target);
73291
73292         if (!conflicts.length) {
73293             graph = updateChildren(updates, graph).replace(target);
73294         }
73295
73296         return graph;
73297     };
73298
73299
73300     action.withOption = function(opt) {
73301         option = opt;
73302         return action;
73303     };
73304
73305
73306     action.conflicts = function() {
73307         return conflicts;
73308     };
73309
73310
73311     return action;
73312 }
73313
73314 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/command/MoveCommand.java
73315 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MoveNodeAction.as
73316 function actionMove(moveIds, tryDelta, projection, cache) {
73317     var _delta = tryDelta;
73318
73319     function setupCache(graph) {
73320         function canMove(nodeId) {
73321             // Allow movement of any node that is in the selectedIDs list..
73322             if (moveIds.indexOf(nodeId) !== -1) return true;
73323
73324             // Allow movement of a vertex where 2 ways meet..
73325             var parents = map$4(graph.parentWays(graph.entity(nodeId)), 'id');
73326             if (parents.length < 3) return true;
73327
73328             // Restrict movement of a vertex where >2 ways meet, unless all parentWays are moving too..
73329             var parentsMoving = every(parents, function(id) { return cache.moving[id]; });
73330             if (!parentsMoving) delete cache.moving[nodeId];
73331
73332             return parentsMoving;
73333         }
73334
73335         function cacheEntities(ids) {
73336             for (var i = 0; i < ids.length; i++) {
73337                 var id = ids[i];
73338                 if (cache.moving[id]) continue;
73339                 cache.moving[id] = true;
73340
73341                 var entity = graph.hasEntity(id);
73342                 if (!entity) continue;
73343
73344                 if (entity.type === 'node') {
73345                     cache.nodes.push(id);
73346                     cache.startLoc[id] = entity.loc;
73347                 } else if (entity.type === 'way') {
73348                     cache.ways.push(id);
73349                     cacheEntities(entity.nodes);
73350                 } else {
73351                     cacheEntities(entity.members.map(function(member) {
73352                         return member.id;
73353                     }));
73354                 }
73355             }
73356         }
73357
73358         function cacheIntersections(ids) {
73359             function isEndpoint(way, id) {
73360                 return !way.isClosed() && !!way.affix(id);
73361             }
73362
73363             for (var i = 0; i < ids.length; i++) {
73364                 var id = ids[i];
73365
73366                 // consider only intersections with 1 moved and 1 unmoved way.
73367                 var childNodes = graph.childNodes(graph.entity(id));
73368                 for (var j = 0; j < childNodes.length; j++) {
73369                     var node = childNodes[j];
73370                     var parents = graph.parentWays(node);
73371                     if (parents.length !== 2) continue;
73372
73373                     var moved = graph.entity(id);
73374                     var unmoved = null;
73375                     for (var k = 0; k < parents.length; k++) {
73376                         var way = parents[k];
73377                         if (!cache.moving[way.id]) {
73378                             unmoved = way;
73379                             break;
73380                         }
73381                     }
73382                     if (!unmoved) continue;
73383
73384                     // exclude ways that are overly connected..
73385                     if (intersection(moved.nodes, unmoved.nodes).length > 2) continue;
73386                     if (moved.isArea() || unmoved.isArea()) continue;
73387
73388                     cache.intersections.push({
73389                         nodeId: node.id,
73390                         movedId: moved.id,
73391                         unmovedId: unmoved.id,
73392                         movedIsEP: isEndpoint(moved, node.id),
73393                         unmovedIsEP: isEndpoint(unmoved, node.id)
73394                     });
73395                 }
73396             }
73397         }
73398
73399
73400         if (!cache) {
73401             cache = {};
73402         }
73403         if (!cache.ok) {
73404             cache.moving = {};
73405             cache.intersections = [];
73406             cache.replacedVertex = {};
73407             cache.startLoc = {};
73408             cache.nodes = [];
73409             cache.ways = [];
73410
73411             cacheEntities(moveIds);
73412             cacheIntersections(cache.ways);
73413             cache.nodes = filter(cache.nodes, canMove);
73414
73415             cache.ok = true;
73416         }
73417     }
73418
73419
73420     // Place a vertex where the moved vertex used to be, to preserve way shape..
73421     //
73422     //  Start:
73423     //      b ---- e
73424     //     / \
73425     //    /   \
73426     //   /     \
73427     //  a       c
73428     //
73429     //      *               node '*' added to preserve shape
73430     //     / \
73431     //    /   b ---- e      way `b,e` moved here:
73432     //   /     \
73433     //  a       c
73434     //
73435     //
73436     function replaceMovedVertex(nodeId, wayId, graph, delta) {
73437         var way = graph.entity(wayId);
73438         var moved = graph.entity(nodeId);
73439         var movedIndex = way.nodes.indexOf(nodeId);
73440         var len, prevIndex, nextIndex;
73441
73442         if (way.isClosed()) {
73443             len = way.nodes.length - 1;
73444             prevIndex = (movedIndex + len - 1) % len;
73445             nextIndex = (movedIndex + len + 1) % len;
73446         } else {
73447             len = way.nodes.length;
73448             prevIndex = movedIndex - 1;
73449             nextIndex = movedIndex + 1;
73450         }
73451
73452         var prev = graph.hasEntity(way.nodes[prevIndex]);
73453         var next = graph.hasEntity(way.nodes[nextIndex]);
73454
73455         // Don't add orig vertex at endpoint..
73456         if (!prev || !next) return graph;
73457
73458         var key = wayId + '_' + nodeId;
73459         var orig = cache.replacedVertex[key];
73460         if (!orig) {
73461             orig = osmNode();
73462             cache.replacedVertex[key] = orig;
73463             cache.startLoc[orig.id] = cache.startLoc[nodeId];
73464         }
73465
73466         var start, end;
73467         if (delta) {
73468             start = projection(cache.startLoc[nodeId]);
73469             end = projection.invert(geoVecAdd(start, delta));
73470         } else {
73471             end = cache.startLoc[nodeId];
73472         }
73473         orig = orig.move(end);
73474
73475         var angle = Math.abs(geoAngle(orig, prev, projection) -
73476                 geoAngle(orig, next, projection)) * 180 / Math.PI;
73477
73478         // Don't add orig vertex if it would just make a straight line..
73479         if (angle > 175 && angle < 185) return graph;
73480
73481         // moving forward or backward along way?
73482         var p1 = [prev.loc, orig.loc, moved.loc, next.loc].map(projection);
73483         var p2 = [prev.loc, moved.loc, orig.loc, next.loc].map(projection);
73484         var d1 = geoPathLength(p1);
73485         var d2 = geoPathLength(p2);
73486         var insertAt = (d1 <= d2) ? movedIndex : nextIndex;
73487
73488         // moving around closed loop?
73489         if (way.isClosed() && insertAt === 0) insertAt = len;
73490
73491         way = way.addNode(orig.id, insertAt);
73492         return graph.replace(orig).replace(way);
73493     }
73494
73495
73496     // Remove duplicate vertex that might have been added by
73497     // replaceMovedVertex.  This is done after the unzorro checks.
73498     function removeDuplicateVertices(wayId, graph) {
73499         var way = graph.entity(wayId);
73500         var epsilon = 1e-6;
73501         var prev, curr;
73502
73503         function isInteresting(node, graph) {
73504             return graph.parentWays(node).length > 1 ||
73505                 graph.parentRelations(node).length ||
73506                 node.hasInterestingTags();
73507         }
73508
73509         for (var i = 0; i < way.nodes.length; i++) {
73510             curr = graph.entity(way.nodes[i]);
73511
73512             if (prev && curr && geoVecEqual(prev.loc, curr.loc, epsilon)) {
73513                 if (!isInteresting(prev, graph)) {
73514                     way = way.removeNode(prev.id);
73515                     graph = graph.replace(way).remove(prev);
73516                 } else if (!isInteresting(curr, graph)) {
73517                     way = way.removeNode(curr.id);
73518                     graph = graph.replace(way).remove(curr);
73519                 }
73520             }
73521
73522             prev = curr;
73523         }
73524
73525         return graph;
73526     }
73527
73528
73529     // Reorder nodes around intersections that have moved..
73530     //
73531     //  Start:                way1.nodes: b,e         (moving)
73532     //  a - b - c ----- d     way2.nodes: a,b,c,d     (static)
73533     //      |                 vertex: b
73534     //      e                 isEP1: true,  isEP2, false
73535     //
73536     //  way1 `b,e` moved here:
73537     //  a ----- c = b - d
73538     //              |
73539     //              e
73540     //
73541     //  reorder nodes         way1.nodes: b,e
73542     //  a ----- c - b - d     way2.nodes: a,c,b,d
73543     //              |
73544     //              e
73545     //
73546     function unZorroIntersection(intersection$$1, graph) {
73547         var vertex = graph.entity(intersection$$1.nodeId);
73548         var way1 = graph.entity(intersection$$1.movedId);
73549         var way2 = graph.entity(intersection$$1.unmovedId);
73550         var isEP1 = intersection$$1.movedIsEP;
73551         var isEP2 = intersection$$1.unmovedIsEP;
73552
73553         // don't move the vertex if it is the endpoint of both ways.
73554         if (isEP1 && isEP2) return graph;
73555
73556         var nodes1 = without(graph.childNodes(way1), vertex);
73557         var nodes2 = without(graph.childNodes(way2), vertex);
73558
73559         if (way1.isClosed() && way1.first() === vertex.id) nodes1.push(nodes1[0]);
73560         if (way2.isClosed() && way2.first() === vertex.id) nodes2.push(nodes2[0]);
73561
73562         var edge1 = !isEP1 && geoChooseEdge(nodes1, projection(vertex.loc), projection);
73563         var edge2 = !isEP2 && geoChooseEdge(nodes2, projection(vertex.loc), projection);
73564         var loc;
73565
73566         // snap vertex to nearest edge (or some point between them)..
73567         if (!isEP1 && !isEP2) {
73568             var epsilon = 1e-6, maxIter = 10;
73569             for (var i = 0; i < maxIter; i++) {
73570                 loc = geoVecInterp(edge1.loc, edge2.loc, 0.5);
73571                 edge1 = geoChooseEdge(nodes1, projection(loc), projection);
73572                 edge2 = geoChooseEdge(nodes2, projection(loc), projection);
73573                 if (Math.abs(edge1.distance - edge2.distance) < epsilon) break;
73574             }
73575         } else if (!isEP1) {
73576             loc = edge1.loc;
73577         } else {
73578             loc = edge2.loc;
73579         }
73580
73581         graph = graph.replace(vertex.move(loc));
73582
73583         // if zorro happened, reorder nodes..
73584         if (!isEP1 && edge1.index !== way1.nodes.indexOf(vertex.id)) {
73585             way1 = way1.removeNode(vertex.id).addNode(vertex.id, edge1.index);
73586             graph = graph.replace(way1);
73587         }
73588         if (!isEP2 && edge2.index !== way2.nodes.indexOf(vertex.id)) {
73589             way2 = way2.removeNode(vertex.id).addNode(vertex.id, edge2.index);
73590             graph = graph.replace(way2);
73591         }
73592
73593         return graph;
73594     }
73595
73596
73597     function cleanupIntersections(graph) {
73598         for (var i = 0; i < cache.intersections.length; i++) {
73599             var obj = cache.intersections[i];
73600             graph = replaceMovedVertex(obj.nodeId, obj.movedId, graph, _delta);
73601             graph = replaceMovedVertex(obj.nodeId, obj.unmovedId, graph, null);
73602             graph = unZorroIntersection(obj, graph);
73603             graph = removeDuplicateVertices(obj.movedId, graph);
73604             graph = removeDuplicateVertices(obj.unmovedId, graph);
73605         }
73606
73607         return graph;
73608     }
73609
73610
73611     // check if moving way endpoint can cross an unmoved way, if so limit delta..
73612     function limitDelta(graph) {
73613         function moveNode(loc) {
73614             return geoVecAdd(projection(loc), _delta);
73615         }
73616
73617         for (var i = 0; i < cache.intersections.length; i++) {
73618             var obj = cache.intersections[i];
73619
73620             // Don't limit movement if this is vertex joins 2 endpoints..
73621             if (obj.movedIsEP && obj.unmovedIsEP) continue;
73622             // Don't limit movement if this vertex is not an endpoint anyway..
73623             if (!obj.movedIsEP) continue;
73624
73625             var node = graph.entity(obj.nodeId);
73626             var start = projection(node.loc);
73627             var end = geoVecAdd(start, _delta);
73628             var movedNodes = graph.childNodes(graph.entity(obj.movedId));
73629             var movedPath = map$4(map$4(movedNodes, 'loc'), moveNode);
73630             var unmovedNodes = graph.childNodes(graph.entity(obj.unmovedId));
73631             var unmovedPath = map$4(map$4(unmovedNodes, 'loc'), projection);
73632             var hits = geoPathIntersections(movedPath, unmovedPath);
73633
73634             for (var j = 0; i < hits.length; i++) {
73635                 if (isEqual(hits[j], end)) continue;
73636                 var edge = geoChooseEdge(unmovedNodes, end, projection);
73637                 _delta = geoVecSubtract(projection(edge.loc), start);
73638             }
73639         }
73640     }
73641
73642
73643     var action = function(graph) {
73644         if (_delta[0] === 0 && _delta[1] === 0) return graph;
73645
73646         setupCache(graph);
73647
73648         if (cache.intersections.length) {
73649             limitDelta(graph);
73650         }
73651
73652         for (var i = 0; i < cache.nodes.length; i++) {
73653             var node = graph.entity(cache.nodes[i]);
73654             var start = projection(node.loc);
73655             var end = geoVecAdd(start, _delta);
73656             graph = graph.replace(node.move(projection.invert(end)));
73657         }
73658
73659         if (cache.intersections.length) {
73660             graph = cleanupIntersections(graph);
73661         }
73662
73663         return graph;
73664     };
73665
73666
73667     action.delta = function() {
73668         return _delta;
73669     };
73670
73671
73672     return action;
73673 }
73674
73675 function actionMoveNode(nodeID, toLoc) {
73676
73677     var action = function(graph, t) {
73678         if (t === null || !isFinite(t)) t = 1;
73679         t = Math.min(Math.max(+t, 0), 1);
73680
73681         var node = graph.entity(nodeID);
73682         return graph.replace(
73683             node.move(geoVecInterp(node.loc, toLoc, t))
73684         );
73685     };
73686
73687     action.transitionable = true;
73688
73689     return action;
73690 }
73691
73692 function actionNoop() {
73693     return function(graph) {
73694         return graph;
73695     };
73696 }
73697
73698 /*
73699  * Based on https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/potlatch2/tools/Quadrilateralise.as
73700  */
73701 function actionOrthogonalize(wayId, projection) {
73702     var threshold = 12, // degrees within right or straight to alter
73703         lowerThreshold = Math.cos((90 - threshold) * Math.PI / 180),
73704         upperThreshold = Math.cos(threshold * Math.PI / 180);
73705
73706
73707     var action = function(graph, t) {
73708         if (t === null || !isFinite(t)) t = 1;
73709         t = Math.min(Math.max(+t, 0), 1);
73710
73711         var way = graph.entity(wayId),
73712             nodes = graph.childNodes(way),
73713             points = uniq(nodes).map(function(n) { return projection(n.loc); }),
73714             corner = {i: 0, dotp: 1},
73715             epsilon = 1e-4,
73716             node, loc, score, motions, i, j;
73717
73718         if (points.length === 3) {   // move only one vertex for right triangle
73719             for (i = 0; i < 1000; i++) {
73720                 motions = points.map(calcMotion);
73721                 points[corner.i] = addPoints(points[corner.i], motions[corner.i]);
73722                 score = corner.dotp;
73723                 if (score < epsilon) {
73724                     break;
73725                 }
73726             }
73727
73728             node = graph.entity(nodes[corner.i].id);
73729             loc = projection.invert(points[corner.i]);
73730             graph = graph.replace(node.move(geoVecInterp(node.loc, loc, t)));
73731
73732         } else {
73733             var best,
73734                 originalPoints = clone(points);
73735             score = Infinity;
73736
73737             for (i = 0; i < 1000; i++) {
73738                 motions = points.map(calcMotion);
73739                 for (j = 0; j < motions.length; j++) {
73740                     points[j] = addPoints(points[j],motions[j]);
73741                 }
73742                 var newScore = squareness(points);
73743                 if (newScore < score) {
73744                     best = clone(points);
73745                     score = newScore;
73746                 }
73747                 if (score < epsilon) {
73748                     break;
73749                 }
73750             }
73751
73752             points = best;
73753
73754             for (i = 0; i < points.length; i++) {
73755                 // only move the points that actually moved
73756                 if (originalPoints[i][0] !== points[i][0] || originalPoints[i][1] !== points[i][1]) {
73757                     loc = projection.invert(points[i]);
73758                     node = graph.entity(nodes[i].id);
73759                     graph = graph.replace(node.move(geoVecInterp(node.loc, loc, t)));
73760                 }
73761             }
73762
73763             // remove empty nodes on straight sections
73764             for (i = 0; t === 1 && i < points.length; i++) {
73765                 node = graph.entity(nodes[i].id);
73766
73767                 if (graph.parentWays(node).length > 1 ||
73768                     graph.parentRelations(node).length ||
73769                     node.hasInterestingTags()) {
73770                     continue;
73771                 }
73772
73773                 var dotp = normalizedDotProduct(i, points);
73774                 if (dotp < -1 + epsilon) {
73775                     graph = actionDeleteNode(node.id)(graph);
73776                 }
73777             }
73778         }
73779
73780         return graph;
73781
73782
73783         function calcMotion(b, i, array) {
73784             var a = array[(i - 1 + array.length) % array.length],
73785                 c = array[(i + 1) % array.length],
73786                 p = subtractPoints(a, b),
73787                 q = subtractPoints(c, b),
73788                 scale, dotp;
73789
73790             scale = 2 * Math.min(geoVecLength(p, [0, 0]), geoVecLength(q, [0, 0]));
73791             p = normalizePoint(p, 1.0);
73792             q = normalizePoint(q, 1.0);
73793
73794             dotp = filterDotProduct(p[0] * q[0] + p[1] * q[1]);
73795
73796             // nasty hack to deal with almost-straight segments (angle is closer to 180 than to 90/270).
73797             if (array.length > 3) {
73798                 if (dotp < -0.707106781186547) {
73799                     dotp += 1.0;
73800                 }
73801             } else if (dotp && Math.abs(dotp) < corner.dotp) {
73802                 corner.i = i;
73803                 corner.dotp = Math.abs(dotp);
73804             }
73805
73806             return normalizePoint(addPoints(p, q), 0.1 * dotp * scale);
73807         }
73808     };
73809
73810
73811     function squareness(points) {
73812         return points.reduce(function(sum, val, i, array) {
73813             var dotp = normalizedDotProduct(i, array);
73814
73815             dotp = filterDotProduct(dotp);
73816             return sum + 2.0 * Math.min(Math.abs(dotp - 1.0), Math.min(Math.abs(dotp), Math.abs(dotp + 1)));
73817         }, 0);
73818     }
73819
73820
73821     function normalizedDotProduct(i, points) {
73822         var a = points[(i - 1 + points.length) % points.length],
73823             b = points[i],
73824             c = points[(i + 1) % points.length],
73825             p = subtractPoints(a, b),
73826             q = subtractPoints(c, b);
73827
73828         p = normalizePoint(p, 1.0);
73829         q = normalizePoint(q, 1.0);
73830
73831         return p[0] * q[0] + p[1] * q[1];
73832     }
73833
73834
73835     function subtractPoints(a, b) {
73836         return [a[0] - b[0], a[1] - b[1]];
73837     }
73838
73839
73840     function addPoints(a, b) {
73841         return [a[0] + b[0], a[1] + b[1]];
73842     }
73843
73844
73845     function normalizePoint(point, scale) {
73846         var vector = [0, 0];
73847         var length = Math.sqrt(point[0] * point[0] + point[1] * point[1]);
73848         if (length !== 0) {
73849             vector[0] = point[0] / length;
73850             vector[1] = point[1] / length;
73851         }
73852
73853         vector[0] *= scale;
73854         vector[1] *= scale;
73855
73856         return vector;
73857     }
73858
73859
73860     function filterDotProduct(dotp) {
73861         if (lowerThreshold > Math.abs(dotp) || Math.abs(dotp) > upperThreshold) {
73862             return dotp;
73863         }
73864
73865         return 0;
73866     }
73867
73868
73869     action.disabled = function(graph) {
73870         var way = graph.entity(wayId),
73871             nodes = graph.childNodes(way),
73872             points = uniq(nodes).map(function(n) { return projection(n.loc); });
73873
73874         if (squareness(points)) {
73875             return false;
73876         }
73877
73878         return 'not_squarish';
73879     };
73880
73881
73882     action.transitionable = true;
73883
73884
73885     return action;
73886 }
73887
73888 // Split a way at the given node.
73889 //
73890 // Optionally, split only the given ways, if multiple ways share
73891 // the given node.
73892 //
73893 // This is the inverse of `iD.actionJoin`.
73894 //
73895 // For testing convenience, accepts an ID to assign to the new way.
73896 // Normally, this will be undefined and the way will automatically
73897 // be assigned a new ID.
73898 //
73899 // Reference:
73900 //   https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/SplitWayAction.as
73901 //
73902 function actionSplit(nodeId, newWayIds) {
73903     var _wayIDs;
73904
73905     // if the way is closed, we need to search for a partner node
73906     // to split the way at.
73907     //
73908     // The following looks for a node that is both far away from
73909     // the initial node in terms of way segment length and nearby
73910     // in terms of beeline-distance. This assures that areas get
73911     // split on the most "natural" points (independent of the number
73912     // of nodes).
73913     // For example: bone-shaped areas get split across their waist
73914     // line, circles across the diameter.
73915     function splitArea(nodes, idxA, graph) {
73916         var lengths = new Array(nodes.length);
73917         var length;
73918         var i;
73919         var best = 0;
73920         var idxB;
73921
73922         function wrap(index) {
73923             return utilWrap(index, nodes.length);
73924         }
73925
73926         function dist(nA, nB) {
73927             return geoSphericalDistance(graph.entity(nA).loc, graph.entity(nB).loc);
73928         }
73929
73930         // calculate lengths
73931         length = 0;
73932         for (i = wrap(idxA+1); i !== idxA; i = wrap(i+1)) {
73933             length += dist(nodes[i], nodes[wrap(i-1)]);
73934             lengths[i] = length;
73935         }
73936
73937         length = 0;
73938         for (i = wrap(idxA-1); i !== idxA; i = wrap(i-1)) {
73939             length += dist(nodes[i], nodes[wrap(i+1)]);
73940             if (length < lengths[i])
73941                 lengths[i] = length;
73942         }
73943
73944         // determine best opposite node to split
73945         for (i = 0; i < nodes.length; i++) {
73946             var cost = lengths[i] / dist(nodes[idxA], nodes[i]);
73947             if (cost > best) {
73948                 idxB = i;
73949                 best = cost;
73950             }
73951         }
73952
73953         return idxB;
73954     }
73955
73956
73957     function split(graph, wayA, newWayId) {
73958         var wayB = osmWay({id: newWayId, tags: wayA.tags});
73959         var origNodes = wayA.nodes.slice();
73960         var nodesA;
73961         var nodesB;
73962         var isArea = wayA.isArea();
73963         var isOuter = osmIsSimpleMultipolygonOuterMember(wayA, graph);
73964
73965         if (wayA.isClosed()) {
73966             var nodes = wayA.nodes.slice(0, -1);
73967             var idxA = indexOf(nodes, nodeId);
73968             var idxB = splitArea(nodes, idxA, graph);
73969
73970             if (idxB < idxA) {
73971                 nodesA = nodes.slice(idxA).concat(nodes.slice(0, idxB + 1));
73972                 nodesB = nodes.slice(idxB, idxA + 1);
73973             } else {
73974                 nodesA = nodes.slice(idxA, idxB + 1);
73975                 nodesB = nodes.slice(idxB).concat(nodes.slice(0, idxA + 1));
73976             }
73977         } else {
73978             var idx = indexOf(wayA.nodes, nodeId, 1);
73979             nodesA = wayA.nodes.slice(0, idx + 1);
73980             nodesB = wayA.nodes.slice(idx);
73981         }
73982
73983         wayA = wayA.update({nodes: nodesA});
73984         wayB = wayB.update({nodes: nodesB});
73985
73986         graph = graph.replace(wayA);
73987         graph = graph.replace(wayB);
73988
73989         graph.parentRelations(wayA).forEach(function(relation) {
73990             if (relation.isRestriction()) {
73991                 var via = relation.memberByRole('via');
73992                 if (via && wayB.contains(via.id)) {
73993                     relation = relation.replaceMember(wayA, wayB);
73994                     graph = graph.replace(relation);
73995                 }
73996             } else {
73997                 if (relation === isOuter) {
73998                     graph = graph.replace(relation.mergeTags(wayA.tags));
73999                     graph = graph.replace(wayA.update({tags: {}}));
74000                     graph = graph.replace(wayB.update({tags: {}}));
74001                 }
74002
74003                 var member = {
74004                     id: wayB.id,
74005                     type: 'way',
74006                     role: relation.memberById(wayA.id).role
74007                 };
74008
74009                 var insertPair = {
74010                     originalID: wayA.id,
74011                     insertedID: wayB.id,
74012                     nodes: origNodes
74013                 };
74014
74015                 graph = actionAddMember(relation.id, member, undefined, insertPair)(graph);
74016             }
74017         });
74018
74019         if (!isOuter && isArea) {
74020             var multipolygon = osmRelation({
74021                 tags: assignIn({}, wayA.tags, {type: 'multipolygon'}),
74022                 members: [
74023                     {id: wayA.id, role: 'outer', type: 'way'},
74024                     {id: wayB.id, role: 'outer', type: 'way'}
74025                 ]
74026             });
74027
74028             graph = graph.replace(multipolygon);
74029             graph = graph.replace(wayA.update({tags: {}}));
74030             graph = graph.replace(wayB.update({tags: {}}));
74031         }
74032
74033         return graph;
74034     }
74035
74036
74037     var action = function(graph) {
74038         var candidates = action.ways(graph);
74039         for (var i = 0; i < candidates.length; i++) {
74040             graph = split(graph, candidates[i], newWayIds && newWayIds[i]);
74041         }
74042         return graph;
74043     };
74044
74045
74046     action.ways = function(graph) {
74047         var node = graph.entity(nodeId);
74048         var parents = graph.parentWays(node);
74049         var hasLines = some(parents, function(parent) { return parent.geometry(graph) === 'line'; });
74050
74051         return parents.filter(function(parent) {
74052             if (_wayIDs && _wayIDs.indexOf(parent.id) === -1)
74053                 return false;
74054
74055             if (!_wayIDs && hasLines && parent.geometry(graph) !== 'line')
74056                 return false;
74057
74058             if (parent.isClosed()) {
74059                 return true;
74060             }
74061
74062             for (var i = 1; i < parent.nodes.length - 1; i++) {
74063                 if (parent.nodes[i] === nodeId) {
74064                     return true;
74065                 }
74066             }
74067
74068             return false;
74069         });
74070     };
74071
74072
74073     action.disabled = function(graph) {
74074         var candidates = action.ways(graph);
74075         if (candidates.length === 0 || (_wayIDs && _wayIDs.length !== candidates.length))
74076             return 'not_eligible';
74077     };
74078
74079
74080     action.limitWays = function(_) {
74081         if (!arguments.length) return _wayIDs;
74082         _wayIDs = _;
74083         return action;
74084     };
74085
74086
74087     return action;
74088 }
74089
74090 // Create a restriction relation for `turn`, which must have the following structure:
74091 //
74092 //     {
74093 //         from: { node: <node ID>, way: <way ID> },
74094 //         via:  { node: <node ID> },
74095 //         to:   { node: <node ID>, way: <way ID> },
74096 //         restriction: <'no_right_turn', 'no_left_turn', etc.>
74097 //     }
74098 //
74099 // This specifies a restriction of type `restriction` when traveling from
74100 // `from.node` in `from.way` toward `to.node` in `to.way` via `via.node`.
74101 // (The action does not check that these entities form a valid intersection.)
74102 //
74103 // If `restriction` is not provided, it is automatically determined by
74104 // osmInferRestriction.
74105 //
74106 // If necessary, the `from` and `to` ways are split. In these cases, `from.node`
74107 // and `to.node` are used to determine which portion of the split ways become
74108 // members of the restriction.
74109 //
74110 // For testing convenience, accepts an ID to assign to the new relation.
74111 // Normally, this will be undefined and the relation will automatically
74112 // be assigned a new ID.
74113 //
74114 function actionRestrictTurn(turn, projection, restrictionId) {
74115
74116     return function(graph) {
74117         var from = graph.entity(turn.from.way),
74118             via  = graph.entity(turn.via.node),
74119             to   = graph.entity(turn.to.way);
74120
74121         function isClosingNode(way, nodeId) {
74122             return nodeId === way.first() && nodeId === way.last();
74123         }
74124
74125         function split(toOrFrom) {
74126             var newID = toOrFrom.newID || osmWay().id;
74127             graph = actionSplit(via.id, [newID])
74128                 .limitWays([toOrFrom.way])(graph);
74129
74130             var a = graph.entity(newID),
74131                 b = graph.entity(toOrFrom.way);
74132
74133             if (a.nodes.indexOf(toOrFrom.node) !== -1) {
74134                 return [a, b];
74135             } else {
74136                 return [b, a];
74137             }
74138         }
74139
74140         if (!from.affix(via.id) || isClosingNode(from, via.id)) {
74141             if (turn.from.node === turn.to.node) {
74142                 // U-turn
74143                 from = to = split(turn.from)[0];
74144             } else if (turn.from.way === turn.to.way) {
74145                 // Straight-on or circular
74146                 var s = split(turn.from);
74147                 from = s[0];
74148                 to   = s[1];
74149             } else {
74150                 // Other
74151                 from = split(turn.from)[0];
74152             }
74153         }
74154
74155         if (!to.affix(via.id) || isClosingNode(to, via.id)) {
74156             to = split(turn.to)[0];
74157         }
74158
74159         return graph.replace(osmRelation({
74160             id: restrictionId,
74161             tags: {
74162                 type: 'restriction',
74163                 restriction: turn.restriction ||
74164                     osmInferRestriction(
74165                         graph,
74166                         turn.from,
74167                         turn.via,
74168                         turn.to,
74169                         projection)
74170             },
74171             members: [
74172                 {id: from.id, type: 'way',  role: 'from'},
74173                 {id: via.id,  type: 'node', role: 'via'},
74174                 {id: to.id,   type: 'way',  role: 'to'}
74175             ]
74176         }));
74177     };
74178 }
74179
74180 function actionRevert(id) {
74181     var action = function(graph) {
74182         var entity = graph.hasEntity(id),
74183             base = graph.base().entities[id];
74184
74185         if (entity && !base) {    // entity will be removed..
74186             if (entity.type === 'node') {
74187                 graph.parentWays(entity)
74188                     .forEach(function(parent) {
74189                         parent = parent.removeNode(id);
74190                         graph = graph.replace(parent);
74191
74192                         if (parent.isDegenerate()) {
74193                             graph = actionDeleteWay(parent.id)(graph);
74194                         }
74195                     });
74196             }
74197
74198             graph.parentRelations(entity)
74199                 .forEach(function(parent) {
74200                     parent = parent.removeMembersWithID(id);
74201                     graph = graph.replace(parent);
74202
74203                     if (parent.isDegenerate()) {
74204                         graph = actionDeleteRelation(parent.id)(graph);
74205                     }
74206                 });
74207         }
74208
74209         return graph.revert(id);
74210     };
74211
74212     return action;
74213 }
74214
74215 function actionRotate(rotateIds, pivot, angle, projection) {
74216
74217     var action = function(graph) {
74218         return graph.update(function(graph) {
74219             utilGetAllNodes(rotateIds, graph).forEach(function(node) {
74220                 var point = geoRotate([projection(node.loc)], angle, pivot)[0];
74221                 graph = graph.replace(node.move(projection.invert(point)));
74222             });
74223         });
74224     };
74225
74226     return action;
74227 }
74228
74229 /*
74230  * Based on https://github.com/openstreetmap/potlatch2/net/systemeD/potlatch2/tools/Straighten.as
74231  */
74232 function actionStraighten(wayId, projection) {
74233
74234     function positionAlongWay(n, s, e) {
74235         return ((n[0] - s[0]) * (e[0] - s[0]) + (n[1] - s[1]) * (e[1] - s[1])) /
74236                 (Math.pow(e[0] - s[0], 2) + Math.pow(e[1] - s[1], 2));
74237     }
74238
74239
74240     var action = function(graph, t) {
74241         if (t === null || !isFinite(t)) t = 1;
74242         t = Math.min(Math.max(+t, 0), 1);
74243
74244         var way = graph.entity(wayId),
74245             nodes = graph.childNodes(way),
74246             points = nodes.map(function(n) { return projection(n.loc); }),
74247             startPoint = points[0],
74248             endPoint = points[points.length-1],
74249             toDelete = [],
74250             i;
74251
74252         for (i = 1; i < points.length-1; i++) {
74253             var node = nodes[i],
74254                 point = points[i];
74255
74256             if (t < 1 || graph.parentWays(node).length > 1 ||
74257                 graph.parentRelations(node).length ||
74258                 node.hasInterestingTags()) {
74259
74260                 var u = positionAlongWay(point, startPoint, endPoint),
74261                     p = [
74262                         startPoint[0] + u * (endPoint[0] - startPoint[0]),
74263                         startPoint[1] + u * (endPoint[1] - startPoint[1])
74264                     ],
74265                     loc2 = projection.invert(p);
74266
74267                 graph = graph.replace(node.move(geoVecInterp(node.loc, loc2, t)));
74268
74269             } else {
74270                 // safe to delete
74271                 if (toDelete.indexOf(node) === -1) {
74272                     toDelete.push(node);
74273                 }
74274             }
74275         }
74276
74277         for (i = 0; i < toDelete.length; i++) {
74278             graph = actionDeleteNode(toDelete[i].id)(graph);
74279         }
74280
74281         return graph;
74282     };
74283
74284
74285     action.disabled = function(graph) {
74286         // check way isn't too bendy
74287         var way = graph.entity(wayId),
74288             nodes = graph.childNodes(way),
74289             points = nodes.map(function(n) { return projection(n.loc); }),
74290             startPoint = points[0],
74291             endPoint = points[points.length-1],
74292             threshold = 0.2 * geoVecLength(startPoint, endPoint),
74293             i;
74294
74295         if (threshold === 0) {
74296             return 'too_bendy';
74297         }
74298
74299         for (i = 1; i < points.length-1; i++) {
74300             var point = points[i],
74301                 u = positionAlongWay(point, startPoint, endPoint),
74302                 p0 = startPoint[0] + u * (endPoint[0] - startPoint[0]),
74303                 p1 = startPoint[1] + u * (endPoint[1] - startPoint[1]),
74304                 dist = Math.sqrt(Math.pow(p0 - point[0], 2) + Math.pow(p1 - point[1], 2));
74305
74306             // to bendy if point is off by 20% of total start/end distance in projected space
74307             if (isNaN(dist) || dist > threshold) {
74308                 return 'too_bendy';
74309             }
74310         }
74311     };
74312
74313
74314     action.transitionable = true;
74315
74316
74317     return action;
74318 }
74319
74320 // Remove the effects of `turn.restriction` on `turn`, which must have the
74321 // following structure:
74322 //
74323 //     {
74324 //         from: { node: <node ID>, way: <way ID> },
74325 //         via:  { node: <node ID> },
74326 //         to:   { node: <node ID>, way: <way ID> },
74327 //         restriction: <relation ID>
74328 //     }
74329 //
74330 // In the simple case, `restriction` is a reference to a `no_*` restriction
74331 // on the turn itself. In this case, it is simply deleted.
74332 //
74333 // The more complex case is where `restriction` references an `only_*`
74334 // restriction on a different turn in the same intersection. In that case,
74335 // that restriction is also deleted, but at the same time restrictions on
74336 // the turns other than the first two are created.
74337 //
74338 function actionUnrestrictTurn(turn) {
74339     return function(graph) {
74340         return actionDeleteRelation(turn.restriction)(graph);
74341     };
74342 }
74343
74344 /* Reflect the given area around its axis of symmetry */
74345 function actionReflect(reflectIds, projection) {
74346     var useLongAxis = true;
74347
74348
74349     // http://gis.stackexchange.com/questions/22895/finding-minimum-area-rectangle-for-given-points
74350     // http://gis.stackexchange.com/questions/3739/generalisation-strategies-for-building-outlines/3756#3756
74351     function getSmallestSurroundingRectangle(graph, nodes) {
74352         var points = nodes.map(function(n) { return projection(n.loc); }),
74353             hull = d3_polygonHull(points),
74354             centroid = d3_polygonCentroid(hull),
74355             minArea = Infinity,
74356             ssrExtent = [],
74357             ssrAngle = 0,
74358             c1 = hull[0];
74359
74360         for (var i = 0; i <= hull.length - 1; i++) {
74361             var c2 = (i === hull.length - 1) ? hull[0] : hull[i + 1],
74362                 angle = Math.atan2(c2[1] - c1[1], c2[0] - c1[0]),
74363                 poly = geoRotate(hull, -angle, centroid),
74364                 extent = poly.reduce(function(extent, point) {
74365                         return extent.extend(geoExtent(point));
74366                     }, geoExtent()),
74367                 area = extent.area();
74368
74369             if (area < minArea) {
74370                 minArea = area;
74371                 ssrExtent = extent;
74372                 ssrAngle = angle;
74373             }
74374             c1 = c2;
74375         }
74376
74377         return {
74378             poly: geoRotate(ssrExtent.polygon(), ssrAngle, centroid),
74379             angle: ssrAngle
74380         };
74381     }
74382
74383
74384     var action = function(graph, t) {
74385         if (t === null || !isFinite(t)) t = 1;
74386         t = Math.min(Math.max(+t, 0), 1);
74387
74388         var nodes = utilGetAllNodes(reflectIds, graph),
74389             ssr = getSmallestSurroundingRectangle(graph, nodes);
74390
74391         // Choose line pq = axis of symmetry.
74392         // The shape's surrounding rectangle has 2 axes of symmetry.
74393         // Reflect across the longer axis by default.
74394         var p1 = [(ssr.poly[0][0] + ssr.poly[1][0]) / 2, (ssr.poly[0][1] + ssr.poly[1][1]) / 2 ],
74395             q1 = [(ssr.poly[2][0] + ssr.poly[3][0]) / 2, (ssr.poly[2][1] + ssr.poly[3][1]) / 2 ],
74396             p2 = [(ssr.poly[3][0] + ssr.poly[4][0]) / 2, (ssr.poly[3][1] + ssr.poly[4][1]) / 2 ],
74397             q2 = [(ssr.poly[1][0] + ssr.poly[2][0]) / 2, (ssr.poly[1][1] + ssr.poly[2][1]) / 2 ],
74398             p, q;
74399
74400         var isLong = (geoVecLength(p1, q1) > geoVecLength(p2, q2));
74401         if ((useLongAxis && isLong) || (!useLongAxis && !isLong)) {
74402             p = p1;
74403             q = q1;
74404         } else {
74405             p = p2;
74406             q = q2;
74407         }
74408
74409         // reflect c across pq
74410         // http://math.stackexchange.com/questions/65503/point-reflection-over-a-line
74411         var dx = q[0] - p[0];
74412         var dy = q[1] - p[1];
74413         var a = (dx * dx - dy * dy) / (dx * dx + dy * dy);
74414         var b = 2 * dx * dy / (dx * dx + dy * dy);
74415         for (var i = 0; i < nodes.length; i++) {
74416             var node = nodes[i];
74417             var c = projection(node.loc);
74418             var c2 = [
74419                 a * (c[0] - p[0]) + b * (c[1] - p[1]) + p[0],
74420                 b * (c[0] - p[0]) - a * (c[1] - p[1]) + p[1]
74421             ];
74422             var loc2 = projection.invert(c2);
74423             node = node.move(geoVecInterp(node.loc, loc2, t));
74424             graph = graph.replace(node);
74425         }
74426
74427         return graph;
74428     };
74429
74430
74431     action.useLongAxis = function(_) {
74432         if (!arguments.length) return useLongAxis;
74433         useLongAxis = _;
74434         return action;
74435     };
74436
74437
74438     action.transitionable = true;
74439
74440
74441     return action;
74442 }
74443
74444
74445
74446 var index$4 = Object.freeze({
74447         d3combobox: d3combobox,
74448         d3geoTile: d3geoTile,
74449         d3keybinding: d3keybinding
74450 });
74451
74452 /* export some legacy symbols: */
74453 var Connection = services.osm;
74454 var debug = false;
74455
74456
74457
74458
74459 var iD = Object.freeze({
74460         Connection: Connection,
74461         debug: debug,
74462         lib: index$4,
74463         d3: index$3,
74464         Context: coreContext,
74465         setAreaKeys: setAreaKeys,
74466         Difference: coreDifference,
74467         Graph: coreGraph,
74468         History: coreHistory,
74469         Tree: coreTree,
74470         geoCross: geoVecCross,
74471         geoInterp: geoVecInterp,
74472         geoRoundCoordinates: geoVecFloor,
74473         geoEuclideanDistance: geoVecLength,
74474         Entity: osmEntity,
74475         Node: osmNode,
74476         Relation: osmRelation,
74477         Way: osmWay,
74478         BackgroundSource: rendererBackgroundSource,
74479         Background: rendererBackground,
74480         Features: rendererFeatures,
74481         Map: rendererMap,
74482         TileLayer: rendererTileLayer,
74483         Detect: utilDetect,
74484         uiPreset: uiPresetEditor,
74485         actionAddEntity: actionAddEntity,
74486         actionAddMember: actionAddMember,
74487         actionAddMidpoint: actionAddMidpoint,
74488         actionAddVertex: actionAddVertex,
74489         actionChangeMember: actionChangeMember,
74490         actionChangePreset: actionChangePreset,
74491         actionChangeTags: actionChangeTags,
74492         actionCircularize: actionCircularize,
74493         actionConnect: actionConnect,
74494         actionCopyEntities: actionCopyEntities,
74495         actionDeleteMember: actionDeleteMember,
74496         actionDeleteMultiple: actionDeleteMultiple,
74497         actionDeleteNode: actionDeleteNode,
74498         actionDeleteRelation: actionDeleteRelation,
74499         actionDeleteWay: actionDeleteWay,
74500         actionDeprecateTags: actionDeprecateTags,
74501         actionDiscardTags: actionDiscardTags,
74502         actionDisconnect: actionDisconnect,
74503         actionJoin: actionJoin,
74504         actionMerge: actionMerge,
74505         actionMergePolygon: actionMergePolygon,
74506         actionMergeRemoteChanges: actionMergeRemoteChanges,
74507         actionMove: actionMove,
74508         actionMoveNode: actionMoveNode,
74509         actionNoop: actionNoop,
74510         actionOrthogonalize: actionOrthogonalize,
74511         actionRestrictTurn: actionRestrictTurn,
74512         actionReverse: actionReverse,
74513         actionRevert: actionRevert,
74514         actionRotate: actionRotate,
74515         actionSplit: actionSplit,
74516         actionStraighten: actionStraighten,
74517         actionUnrestrictTurn: actionUnrestrictTurn,
74518         actionReflect: actionReflect,
74519         behaviorAddWay: behaviorAddWay,
74520         behaviorBreathe: behaviorBreathe,
74521         behaviorCopy: behaviorCopy,
74522         behaviorDrag: behaviorDrag,
74523         behaviorDrawWay: behaviorDrawWay,
74524         behaviorDraw: behaviorDraw,
74525         behaviorEdit: behaviorEdit,
74526         behaviorHash: behaviorHash,
74527         behaviorHover: behaviorHover,
74528         behaviorLasso: behaviorLasso,
74529         behaviorOperation: behaviorOperation,
74530         behaviorPaste: behaviorPaste,
74531         behaviorSelect: behaviorSelect,
74532         behaviorTail: behaviorTail,
74533         coreContext: coreContext,
74534         coreDifference: coreDifference,
74535         coreGraph: coreGraph,
74536         coreHistory: coreHistory,
74537         coreTree: coreTree,
74538         dataFeatureIcons: dataFeatureIcons,
74539         data: data,
74540         dataWikipedia: wikipedia$2,
74541         dataSuggestions: dataSuggestions,
74542         dataAddressFormats: dataAddressFormats,
74543         dataDeprecated: dataDeprecated,
74544         dataDiscarded: dataDiscarded,
74545         dataLocales: dataLocales,
74546         dataPhoneFormats: dataPhoneFormats,
74547         dataShortcuts: dataShortcuts,
74548         dataImperial: dataImperial,
74549         dataDriveLeft: dataDriveLeft,
74550         dataEn: en,
74551         geoExtent: geoExtent,
74552         geoLatToMeters: geoLatToMeters,
74553         geoLonToMeters: geoLonToMeters,
74554         geoMetersToLat: geoMetersToLat,
74555         geoMetersToLon: geoMetersToLon,
74556         geoMetersToOffset: geoMetersToOffset,
74557         geoOffsetToMeters: geoOffsetToMeters,
74558         geoScaleToZoom: geoScaleToZoom,
74559         geoSphericalDistance: geoSphericalDistance,
74560         geoZoomToScale: geoZoomToScale,
74561         geoAngle: geoAngle,
74562         geoChooseEdge: geoChooseEdge,
74563         geoEdgeEqual: geoEdgeEqual,
74564         geoHasLineIntersections: geoHasLineIntersections,
74565         geoHasSelfIntersections: geoHasSelfIntersections,
74566         geoRotate: geoRotate,
74567         geoLineIntersection: geoLineIntersection,
74568         geoPathHasIntersections: geoPathHasIntersections,
74569         geoPathIntersections: geoPathIntersections,
74570         geoPathLength: geoPathLength,
74571         geoPointInPolygon: geoPointInPolygon,
74572         geoPolygonContainsPolygon: geoPolygonContainsPolygon,
74573         geoPolygonIntersectsPolygon: geoPolygonIntersectsPolygon,
74574         geoViewportEdge: geoViewportEdge,
74575         geoRawMercator: geoRawMercator,
74576         geoVecAdd: geoVecAdd,
74577         geoVecAngle: geoVecAngle,
74578         geoVecCross: geoVecCross,
74579         geoVecDot: geoVecDot,
74580         geoVecEqual: geoVecEqual,
74581         geoVecFloor: geoVecFloor,
74582         geoVecInterp: geoVecInterp,
74583         geoVecLength: geoVecLength,
74584         geoVecSubtract: geoVecSubtract,
74585         geoVecScale: geoVecScale,
74586         modeAddArea: modeAddArea,
74587         modeAddLine: modeAddLine,
74588         modeAddPoint: modeAddPoint,
74589         modeBrowse: modeBrowse,
74590         modeDragNode: modeDragNode,
74591         modeDrawArea: modeDrawArea,
74592         modeDrawLine: modeDrawLine,
74593         modeMove: modeMove,
74594         modeRotate: modeRotate,
74595         modeSave: modeSave,
74596         modeSelect: modeSelect,
74597         operationCircularize: operationCircularize,
74598         operationContinue: operationContinue,
74599         operationDelete: operationDelete,
74600         operationDisconnect: operationDisconnect,
74601         operationMerge: operationMerge,
74602         operationMove: operationMove,
74603         operationOrthogonalize: operationOrthogonalize,
74604         operationReflectShort: operationReflectShort,
74605         operationReflectLong: operationReflectLong,
74606         operationReverse: operationReverse,
74607         operationRotate: operationRotate,
74608         operationSplit: operationSplit,
74609         operationStraighten: operationStraighten,
74610         osmChangeset: osmChangeset,
74611         osmEntity: osmEntity,
74612         osmNode: osmNode,
74613         osmRelation: osmRelation,
74614         osmWay: osmWay,
74615         osmIntersection: osmIntersection,
74616         osmTurn: osmTurn,
74617         osmInferRestriction: osmInferRestriction,
74618         osmLanes: osmLanes,
74619         osmIsSimpleMultipolygonOuterMember: osmIsSimpleMultipolygonOuterMember,
74620         osmSimpleMultipolygonOuterMember: osmSimpleMultipolygonOuterMember,
74621         osmJoinWays: osmJoinWays,
74622         osmOneWayTags: osmOneWayTags,
74623         osmPavedTags: osmPavedTags,
74624         osmIsInterestingTag: osmIsInterestingTag,
74625         presetCategory: presetCategory,
74626         presetCollection: presetCollection,
74627         presetField: presetField,
74628         presetPreset: presetPreset,
74629         presetIndex: presetIndex,
74630         rendererBackgroundSource: rendererBackgroundSource,
74631         rendererBackground: rendererBackground,
74632         rendererFeatures: rendererFeatures,
74633         rendererMap: rendererMap,
74634         rendererTileLayer: rendererTileLayer,
74635         services: services,
74636         serviceMapillary: serviceMapillary,
74637         serviceNominatim: serviceNominatim,
74638         serviceOpenstreetcam: serviceOpenstreetcam,
74639         serviceOsm: serviceOsm,
74640         serviceTaginfo: serviceTaginfo,
74641         serviceWikidata: serviceWikidata,
74642         serviceWikipedia: serviceWikipedia,
74643         svgAreas: svgAreas,
74644         svgDebug: svgDebug,
74645         svgDefs: svgDefs,
74646         svgGpx: svgGpx,
74647         svgIcon: svgIcon,
74648         svgLabels: svgLabels,
74649         svgLayers: svgLayers,
74650         svgLines: svgLines,
74651         svgMapillaryImages: svgMapillaryImages,
74652         svgMapillarySigns: svgMapillarySigns,
74653         svgMidpoints: svgMidpoints,
74654         svgOneWaySegments: svgOneWaySegments,
74655         svgOpenstreetcamImages: svgOpenstreetcamImages,
74656         svgOsm: svgOsm,
74657         svgPassiveVertex: svgPassiveVertex,
74658         svgPath: svgPath,
74659         svgPointTransform: svgPointTransform,
74660         svgPoints: svgPoints,
74661         svgRelationMemberTags: svgRelationMemberTags,
74662         svgSegmentWay: svgSegmentWay,
74663         svgTagClasses: svgTagClasses,
74664         svgTurns: svgTurns,
74665         svgVertices: svgVertices,
74666         uiFields: uiFields,
74667         uiFieldDefaultCheck: uiFieldCheck,
74668         uiFieldOnewayCheck: uiFieldCheck,
74669         uiFieldCheck: uiFieldCheck,
74670         uiFieldMultiCombo: uiFieldCombo,
74671         uiFieldNetworkCombo: uiFieldCombo,
74672         uiFieldSemiCombo: uiFieldCombo,
74673         uiFieldTypeCombo: uiFieldCombo,
74674         uiFieldCombo: uiFieldCombo,
74675         uiFieldUrl: uiFieldText,
74676         uiFieldNumber: uiFieldText,
74677         uiFieldTel: uiFieldText,
74678         uiFieldEmail: uiFieldText,
74679         uiFieldText: uiFieldText,
74680         uiFieldAccess: uiFieldAccess,
74681         uiFieldAddress: uiFieldAddress,
74682         uiFieldCycleway: uiFieldCycleway,
74683         uiFieldLanes: uiFieldLanes,
74684         uiFieldLocalized: uiFieldLocalized,
74685         uiFieldMaxspeed: uiFieldMaxspeed,
74686         uiFieldStructureRadio: uiFieldRadio,
74687         uiFieldRadio: uiFieldRadio,
74688         uiFieldRestrictions: uiFieldRestrictions,
74689         uiFieldTextarea: uiFieldTextarea,
74690         uiFieldWikipedia: uiFieldWikipedia,
74691         uiIntro: uiIntro,
74692         uiInfoPanels: uiInfoPanels,
74693         uiPanelBackground: uiPanelBackground,
74694         uiPanelHistory: uiPanelHistory,
74695         uiPanelLocation: uiPanelLocation,
74696         uiPanelMeasurement: uiPanelMeasurement,
74697         uiInit: uiInit,
74698         uiAccount: uiAccount,
74699         uiAttribution: uiAttribution,
74700         uiBackground: uiBackground,
74701         uiBackgroundDisplayOptions: uiBackgroundDisplayOptions,
74702         uiBackgroundOffset: uiBackgroundOffset,
74703         uiChangesetEditor: uiChangesetEditor,
74704         uiCmd: uiCmd,
74705         uiCommit: uiCommit,
74706         uiCommitChanges: uiCommitChanges,
74707         uiCommitWarnings: uiCommitWarnings,
74708         uiConfirm: uiConfirm,
74709         uiConflicts: uiConflicts,
74710         uiContributors: uiContributors,
74711         uiCurtain: uiCurtain,
74712         uiDisclosure: uiDisclosure,
74713         uiEditMenu: uiEditMenu,
74714         uiEntityEditor: uiEntityEditor,
74715         uiFeatureInfo: uiFeatureInfo,
74716         uiFeatureList: uiFeatureList,
74717         uiField: uiField,
74718         uiFlash: uiFlash,
74719         uiFormFields: uiFormFields,
74720         uiFullScreen: uiFullScreen,
74721         uiGeolocate: uiGeolocate,
74722         uiHelp: uiHelp,
74723         uiInfo: uiInfo,
74724         uiInspector: uiInspector,
74725         uiLasso: uiLasso,
74726         uiLoading: uiLoading,
74727         uiMapData: uiMapData,
74728         uiMapInMap: uiMapInMap,
74729         uiModal: uiModal,
74730         uiModes: uiModes,
74731         uiNotice: uiNotice,
74732         uiPresetEditor: uiPresetEditor,
74733         uiPresetIcon: uiPresetIcon,
74734         uiPresetList: uiPresetList,
74735         uiRadialMenu: uiRadialMenu,
74736         uiRawMemberEditor: uiRawMemberEditor,
74737         uiRawMembershipEditor: uiRawMembershipEditor,
74738         uiRawTagEditor: uiRawTagEditor,
74739         uiRestore: uiRestore,
74740         uiSave: uiSave,
74741         uiScale: uiScale,
74742         uiSelectionList: uiSelectionList,
74743         uiSidebar: uiSidebar,
74744         uiSourceSwitch: uiSourceSwitch,
74745         uiSpinner: uiSpinner,
74746         uiSplash: uiSplash,
74747         uiStatus: uiStatus,
74748         uiSuccess: uiSuccess,
74749         uiTagReference: uiTagReference,
74750         uiToggle: uiToggle,
74751         uiTooltipHtml: uiTooltipHtml,
74752         uiUndoRedo: uiUndoRedo,
74753         uiVersion: uiVersion,
74754         uiViewOnOSM: uiViewOnOSM,
74755         uiZoom: uiZoom,
74756         utilAsyncMap: utilAsyncMap,
74757         utilCallWhenIdle: utilCallWhenIdle,
74758         utilDisplayName: utilDisplayName,
74759         utilDisplayNameForPath: utilDisplayNameForPath,
74760         utilDisplayType: utilDisplayType,
74761         utilEditDistance: utilEditDistance,
74762         utilEntitySelector: utilEntitySelector,
74763         utilEntityOrMemberSelector: utilEntityOrMemberSelector,
74764         utilFastMouse: utilFastMouse,
74765         utilFunctor: utilFunctor,
74766         utilGetAllNodes: utilGetAllNodes,
74767         utilGetPrototypeOf: utilGetPrototypeOf,
74768         utilGetSetValue: utilGetSetValue,
74769         utilIdleWorker: utilIdleWorker,
74770         utilNoAuto: utilNoAuto,
74771         utilPrefixCSSProperty: utilPrefixCSSProperty,
74772         utilPrefixDOMProperty: utilPrefixDOMProperty,
74773         utilQsString: utilQsString,
74774         utilRebind: utilRebind,
74775         utilSetTransform: utilSetTransform,
74776         utilSessionMutex: utilSessionMutex,
74777         utilStringQs: utilStringQs,
74778         utilSuggestNames: utilSuggestNames,
74779         utilTagText: utilTagText,
74780         utilTriggerEvent: utilTriggerEvent,
74781         utilWrap: utilWrap,
74782         d3combobox: d3combobox,
74783         d3geoTile: d3geoTile,
74784         d3keybinding: d3keybinding,
74785         validationDeprecatedTag: validationDeprecatedTag,
74786         validationDisconnectedHighway: validationDisconnectedHighway,
74787         validationManyDeletions: validationManyDeletions,
74788         validationMissingTag: validationMissingTag,
74789         validationOldMultipolygon: validationOldMultipolygon,
74790         validationTagSuggestsArea: validationTagSuggestsArea
74791 });
74792
74793 window.iD = iD;
74794
74795 }());
74796 //# sourceMappingURL=iD.js.map