]> git.openstreetmap.org Git - rails.git/blob - vendor/assets/iD/iD.js
Update to iD v2.6.0
[rails.git] / vendor / assets / iD / iD.js
1 (function () {
2 var version = "4.12.2";
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 var nextId = 0;
853
854 function local() {
855   return new Local;
856 }
857
858 function Local() {
859   this._ = "@" + (++nextId).toString(36);
860 }
861
862 Local.prototype = local.prototype = {
863   constructor: Local,
864   get: function(node) {
865     var id = this._;
866     while (!(id in node)) if (!(node = node.parentNode)) return;
867     return node[id];
868   },
869   set: function(node, value) {
870     return node[this._] = value;
871   },
872   remove: function(node) {
873     return this._ in node && delete node[this._];
874   },
875   toString: function() {
876     return this._;
877   }
878 };
879
880 var matcher = function(selector) {
881   return function() {
882     return this.matches(selector);
883   };
884 };
885
886 if (typeof document !== "undefined") {
887   var element = document.documentElement;
888   if (!element.matches) {
889     var vendorMatches = element.webkitMatchesSelector
890         || element.msMatchesSelector
891         || element.mozMatchesSelector
892         || element.oMatchesSelector;
893     matcher = function(selector) {
894       return function() {
895         return vendorMatches.call(this, selector);
896       };
897     };
898   }
899 }
900
901 var matcher$1 = matcher;
902
903 var filterEvents = {};
904
905 var event = null;
906
907 if (typeof document !== "undefined") {
908   var element$1 = document.documentElement;
909   if (!("onmouseenter" in element$1)) {
910     filterEvents = {mouseenter: "mouseover", mouseleave: "mouseout"};
911   }
912 }
913
914 function filterContextListener(listener, index, group) {
915   listener = contextListener(listener, index, group);
916   return function(event) {
917     var related = event.relatedTarget;
918     if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) {
919       listener.call(this, event);
920     }
921   };
922 }
923
924 function contextListener(listener, index, group) {
925   return function(event1) {
926     var event0 = event; // Events can be reentrant (e.g., focus).
927     event = event1;
928     try {
929       listener.call(this, this.__data__, index, group);
930     } finally {
931       event = event0;
932     }
933   };
934 }
935
936 function parseTypenames$1(typenames) {
937   return typenames.trim().split(/^|\s+/).map(function(t) {
938     var name = "", i = t.indexOf(".");
939     if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
940     return {type: t, name: name};
941   });
942 }
943
944 function onRemove(typename) {
945   return function() {
946     var on = this.__on;
947     if (!on) return;
948     for (var j = 0, i = -1, m = on.length, o; j < m; ++j) {
949       if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) {
950         this.removeEventListener(o.type, o.listener, o.capture);
951       } else {
952         on[++i] = o;
953       }
954     }
955     if (++i) on.length = i;
956     else delete this.__on;
957   };
958 }
959
960 function onAdd(typename, value, capture) {
961   var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener;
962   return function(d, i, group) {
963     var on = this.__on, o, listener = wrap(value, i, group);
964     if (on) for (var j = 0, m = on.length; j < m; ++j) {
965       if ((o = on[j]).type === typename.type && o.name === typename.name) {
966         this.removeEventListener(o.type, o.listener, o.capture);
967         this.addEventListener(o.type, o.listener = listener, o.capture = capture);
968         o.value = value;
969         return;
970       }
971     }
972     this.addEventListener(typename.type, listener, capture);
973     o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture};
974     if (!on) this.__on = [o];
975     else on.push(o);
976   };
977 }
978
979 function selection_on(typename, value, capture) {
980   var typenames = parseTypenames$1(typename + ""), i, n = typenames.length, t;
981
982   if (arguments.length < 2) {
983     var on = this.node().__on;
984     if (on) for (var j = 0, m = on.length, o; j < m; ++j) {
985       for (i = 0, o = on[j]; i < n; ++i) {
986         if ((t = typenames[i]).type === o.type && t.name === o.name) {
987           return o.value;
988         }
989       }
990     }
991     return;
992   }
993
994   on = value ? onAdd : onRemove;
995   if (capture == null) capture = false;
996   for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture));
997   return this;
998 }
999
1000 function customEvent(event1, listener, that, args) {
1001   var event0 = event;
1002   event1.sourceEvent = event;
1003   event = event1;
1004   try {
1005     return listener.apply(that, args);
1006   } finally {
1007     event = event0;
1008   }
1009 }
1010
1011 function sourceEvent() {
1012   var current = event, source;
1013   while (source = current.sourceEvent) current = source;
1014   return current;
1015 }
1016
1017 function point(node, event) {
1018   var svg = node.ownerSVGElement || node;
1019
1020   if (svg.createSVGPoint) {
1021     var point = svg.createSVGPoint();
1022     point.x = event.clientX, point.y = event.clientY;
1023     point = point.matrixTransform(node.getScreenCTM().inverse());
1024     return [point.x, point.y];
1025   }
1026
1027   var rect = node.getBoundingClientRect();
1028   return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];
1029 }
1030
1031 function d3_mouse(node) {
1032   var event = sourceEvent();
1033   if (event.changedTouches) event = event.changedTouches[0];
1034   return point(node, event);
1035 }
1036
1037 function none() {}
1038
1039 function selector(selector) {
1040   return selector == null ? none : function() {
1041     return this.querySelector(selector);
1042   };
1043 }
1044
1045 function selection_select(select) {
1046   if (typeof select !== "function") select = selector(select);
1047
1048   for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
1049     for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
1050       if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {
1051         if ("__data__" in node) subnode.__data__ = node.__data__;
1052         subgroup[i] = subnode;
1053       }
1054     }
1055   }
1056
1057   return new Selection(subgroups, this._parents);
1058 }
1059
1060 function empty() {
1061   return [];
1062 }
1063
1064 function selectorAll(selector) {
1065   return selector == null ? empty : function() {
1066     return this.querySelectorAll(selector);
1067   };
1068 }
1069
1070 function selection_selectAll(select) {
1071   if (typeof select !== "function") select = selectorAll(select);
1072
1073   for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
1074     for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
1075       if (node = group[i]) {
1076         subgroups.push(select.call(node, node.__data__, i, group));
1077         parents.push(node);
1078       }
1079     }
1080   }
1081
1082   return new Selection(subgroups, parents);
1083 }
1084
1085 function selection_filter(match) {
1086   if (typeof match !== "function") match = matcher$1(match);
1087
1088   for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
1089     for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
1090       if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
1091         subgroup.push(node);
1092       }
1093     }
1094   }
1095
1096   return new Selection(subgroups, this._parents);
1097 }
1098
1099 function sparse(update) {
1100   return new Array(update.length);
1101 }
1102
1103 function selection_enter() {
1104   return new Selection(this._enter || this._groups.map(sparse), this._parents);
1105 }
1106
1107 function EnterNode(parent, datum) {
1108   this.ownerDocument = parent.ownerDocument;
1109   this.namespaceURI = parent.namespaceURI;
1110   this._next = null;
1111   this._parent = parent;
1112   this.__data__ = datum;
1113 }
1114
1115 EnterNode.prototype = {
1116   constructor: EnterNode,
1117   appendChild: function(child) { return this._parent.insertBefore(child, this._next); },
1118   insertBefore: function(child, next) { return this._parent.insertBefore(child, next); },
1119   querySelector: function(selector) { return this._parent.querySelector(selector); },
1120   querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); }
1121 };
1122
1123 function constant$1(x) {
1124   return function() {
1125     return x;
1126   };
1127 }
1128
1129 var keyPrefix = "$"; // Protect against keys like “__proto__”.
1130
1131 function bindIndex(parent, group, enter, update, exit, data) {
1132   var i = 0,
1133       node,
1134       groupLength = group.length,
1135       dataLength = data.length;
1136
1137   // Put any non-null nodes that fit into update.
1138   // Put any null nodes into enter.
1139   // Put any remaining data into enter.
1140   for (; i < dataLength; ++i) {
1141     if (node = group[i]) {
1142       node.__data__ = data[i];
1143       update[i] = node;
1144     } else {
1145       enter[i] = new EnterNode(parent, data[i]);
1146     }
1147   }
1148
1149   // Put any non-null nodes that don’t fit into exit.
1150   for (; i < groupLength; ++i) {
1151     if (node = group[i]) {
1152       exit[i] = node;
1153     }
1154   }
1155 }
1156
1157 function bindKey(parent, group, enter, update, exit, data, key) {
1158   var i,
1159       node,
1160       nodeByKeyValue = {},
1161       groupLength = group.length,
1162       dataLength = data.length,
1163       keyValues = new Array(groupLength),
1164       keyValue;
1165
1166   // Compute the key for each node.
1167   // If multiple nodes have the same key, the duplicates are added to exit.
1168   for (i = 0; i < groupLength; ++i) {
1169     if (node = group[i]) {
1170       keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group);
1171       if (keyValue in nodeByKeyValue) {
1172         exit[i] = node;
1173       } else {
1174         nodeByKeyValue[keyValue] = node;
1175       }
1176     }
1177   }
1178
1179   // Compute the key for each datum.
1180   // If there a node associated with this key, join and add it to update.
1181   // If there is not (or the key is a duplicate), add it to enter.
1182   for (i = 0; i < dataLength; ++i) {
1183     keyValue = keyPrefix + key.call(parent, data[i], i, data);
1184     if (node = nodeByKeyValue[keyValue]) {
1185       update[i] = node;
1186       node.__data__ = data[i];
1187       nodeByKeyValue[keyValue] = null;
1188     } else {
1189       enter[i] = new EnterNode(parent, data[i]);
1190     }
1191   }
1192
1193   // Add any remaining nodes that were not bound to data to exit.
1194   for (i = 0; i < groupLength; ++i) {
1195     if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) {
1196       exit[i] = node;
1197     }
1198   }
1199 }
1200
1201 function selection_data(value, key) {
1202   if (!value) {
1203     data = new Array(this.size()), j = -1;
1204     this.each(function(d) { data[++j] = d; });
1205     return data;
1206   }
1207
1208   var bind = key ? bindKey : bindIndex,
1209       parents = this._parents,
1210       groups = this._groups;
1211
1212   if (typeof value !== "function") value = constant$1(value);
1213
1214   for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {
1215     var parent = parents[j],
1216         group = groups[j],
1217         groupLength = group.length,
1218         data = value.call(parent, parent && parent.__data__, j, parents),
1219         dataLength = data.length,
1220         enterGroup = enter[j] = new Array(dataLength),
1221         updateGroup = update[j] = new Array(dataLength),
1222         exitGroup = exit[j] = new Array(groupLength);
1223
1224     bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);
1225
1226     // Now connect the enter nodes to their following update node, such that
1227     // appendChild can insert the materialized enter node before this node,
1228     // rather than at the end of the parent node.
1229     for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {
1230       if (previous = enterGroup[i0]) {
1231         if (i0 >= i1) i1 = i0 + 1;
1232         while (!(next = updateGroup[i1]) && ++i1 < dataLength);
1233         previous._next = next || null;
1234       }
1235     }
1236   }
1237
1238   update = new Selection(update, parents);
1239   update._enter = enter;
1240   update._exit = exit;
1241   return update;
1242 }
1243
1244 function selection_exit() {
1245   return new Selection(this._exit || this._groups.map(sparse), this._parents);
1246 }
1247
1248 function selection_merge(selection$$1) {
1249
1250   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) {
1251     for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
1252       if (node = group0[i] || group1[i]) {
1253         merge[i] = node;
1254       }
1255     }
1256   }
1257
1258   for (; j < m0; ++j) {
1259     merges[j] = groups0[j];
1260   }
1261
1262   return new Selection(merges, this._parents);
1263 }
1264
1265 function selection_order() {
1266
1267   for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) {
1268     for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) {
1269       if (node = group[i]) {
1270         if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next);
1271         next = node;
1272       }
1273     }
1274   }
1275
1276   return this;
1277 }
1278
1279 function selection_sort(compare) {
1280   if (!compare) compare = ascending;
1281
1282   function compareNode(a, b) {
1283     return a && b ? compare(a.__data__, b.__data__) : !a - !b;
1284   }
1285
1286   for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {
1287     for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) {
1288       if (node = group[i]) {
1289         sortgroup[i] = node;
1290       }
1291     }
1292     sortgroup.sort(compareNode);
1293   }
1294
1295   return new Selection(sortgroups, this._parents).order();
1296 }
1297
1298 function ascending(a, b) {
1299   return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
1300 }
1301
1302 function selection_call() {
1303   var callback = arguments[0];
1304   arguments[0] = this;
1305   callback.apply(null, arguments);
1306   return this;
1307 }
1308
1309 function selection_nodes() {
1310   var nodes = new Array(this.size()), i = -1;
1311   this.each(function() { nodes[++i] = this; });
1312   return nodes;
1313 }
1314
1315 function selection_node() {
1316
1317   for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
1318     for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {
1319       var node = group[i];
1320       if (node) return node;
1321     }
1322   }
1323
1324   return null;
1325 }
1326
1327 function selection_size() {
1328   var size = 0;
1329   this.each(function() { ++size; });
1330   return size;
1331 }
1332
1333 function selection_empty() {
1334   return !this.node();
1335 }
1336
1337 function selection_each(callback) {
1338
1339   for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
1340     for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {
1341       if (node = group[i]) callback.call(node, node.__data__, i, group);
1342     }
1343   }
1344
1345   return this;
1346 }
1347
1348 function attrRemove(name) {
1349   return function() {
1350     this.removeAttribute(name);
1351   };
1352 }
1353
1354 function attrRemoveNS(fullname) {
1355   return function() {
1356     this.removeAttributeNS(fullname.space, fullname.local);
1357   };
1358 }
1359
1360 function attrConstant(name, value) {
1361   return function() {
1362     this.setAttribute(name, value);
1363   };
1364 }
1365
1366 function attrConstantNS(fullname, value) {
1367   return function() {
1368     this.setAttributeNS(fullname.space, fullname.local, value);
1369   };
1370 }
1371
1372 function attrFunction(name, value) {
1373   return function() {
1374     var v = value.apply(this, arguments);
1375     if (v == null) this.removeAttribute(name);
1376     else this.setAttribute(name, v);
1377   };
1378 }
1379
1380 function attrFunctionNS(fullname, value) {
1381   return function() {
1382     var v = value.apply(this, arguments);
1383     if (v == null) this.removeAttributeNS(fullname.space, fullname.local);
1384     else this.setAttributeNS(fullname.space, fullname.local, v);
1385   };
1386 }
1387
1388 function selection_attr(name, value) {
1389   var fullname = namespace(name);
1390
1391   if (arguments.length < 2) {
1392     var node = this.node();
1393     return fullname.local
1394         ? node.getAttributeNS(fullname.space, fullname.local)
1395         : node.getAttribute(fullname);
1396   }
1397
1398   return this.each((value == null
1399       ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function"
1400       ? (fullname.local ? attrFunctionNS : attrFunction)
1401       : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value));
1402 }
1403
1404 function defaultView(node) {
1405   return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node
1406       || (node.document && node) // node is a Window
1407       || node.defaultView; // node is a Document
1408 }
1409
1410 function styleRemove(name) {
1411   return function() {
1412     this.style.removeProperty(name);
1413   };
1414 }
1415
1416 function styleConstant(name, value, priority) {
1417   return function() {
1418     this.style.setProperty(name, value, priority);
1419   };
1420 }
1421
1422 function styleFunction(name, value, priority) {
1423   return function() {
1424     var v = value.apply(this, arguments);
1425     if (v == null) this.style.removeProperty(name);
1426     else this.style.setProperty(name, v, priority);
1427   };
1428 }
1429
1430 function selection_style(name, value, priority) {
1431   return arguments.length > 1
1432       ? this.each((value == null
1433             ? styleRemove : typeof value === "function"
1434             ? styleFunction
1435             : styleConstant)(name, value, priority == null ? "" : priority))
1436       : styleValue(this.node(), name);
1437 }
1438
1439 function styleValue(node, name) {
1440   return node.style.getPropertyValue(name)
1441       || defaultView(node).getComputedStyle(node, null).getPropertyValue(name);
1442 }
1443
1444 function propertyRemove(name) {
1445   return function() {
1446     delete this[name];
1447   };
1448 }
1449
1450 function propertyConstant(name, value) {
1451   return function() {
1452     this[name] = value;
1453   };
1454 }
1455
1456 function propertyFunction(name, value) {
1457   return function() {
1458     var v = value.apply(this, arguments);
1459     if (v == null) delete this[name];
1460     else this[name] = v;
1461   };
1462 }
1463
1464 function selection_property(name, value) {
1465   return arguments.length > 1
1466       ? this.each((value == null
1467           ? propertyRemove : typeof value === "function"
1468           ? propertyFunction
1469           : propertyConstant)(name, value))
1470       : this.node()[name];
1471 }
1472
1473 function classArray(string) {
1474   return string.trim().split(/^|\s+/);
1475 }
1476
1477 function classList(node) {
1478   return node.classList || new ClassList(node);
1479 }
1480
1481 function ClassList(node) {
1482   this._node = node;
1483   this._names = classArray(node.getAttribute("class") || "");
1484 }
1485
1486 ClassList.prototype = {
1487   add: function(name) {
1488     var i = this._names.indexOf(name);
1489     if (i < 0) {
1490       this._names.push(name);
1491       this._node.setAttribute("class", this._names.join(" "));
1492     }
1493   },
1494   remove: function(name) {
1495     var i = this._names.indexOf(name);
1496     if (i >= 0) {
1497       this._names.splice(i, 1);
1498       this._node.setAttribute("class", this._names.join(" "));
1499     }
1500   },
1501   contains: function(name) {
1502     return this._names.indexOf(name) >= 0;
1503   }
1504 };
1505
1506 function classedAdd(node, names) {
1507   var list = classList(node), i = -1, n = names.length;
1508   while (++i < n) list.add(names[i]);
1509 }
1510
1511 function classedRemove(node, names) {
1512   var list = classList(node), i = -1, n = names.length;
1513   while (++i < n) list.remove(names[i]);
1514 }
1515
1516 function classedTrue(names) {
1517   return function() {
1518     classedAdd(this, names);
1519   };
1520 }
1521
1522 function classedFalse(names) {
1523   return function() {
1524     classedRemove(this, names);
1525   };
1526 }
1527
1528 function classedFunction(names, value) {
1529   return function() {
1530     (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);
1531   };
1532 }
1533
1534 function selection_classed(name, value) {
1535   var names = classArray(name + "");
1536
1537   if (arguments.length < 2) {
1538     var list = classList(this.node()), i = -1, n = names.length;
1539     while (++i < n) if (!list.contains(names[i])) return false;
1540     return true;
1541   }
1542
1543   return this.each((typeof value === "function"
1544       ? classedFunction : value
1545       ? classedTrue
1546       : classedFalse)(names, value));
1547 }
1548
1549 function textRemove() {
1550   this.textContent = "";
1551 }
1552
1553 function textConstant(value) {
1554   return function() {
1555     this.textContent = value;
1556   };
1557 }
1558
1559 function textFunction(value) {
1560   return function() {
1561     var v = value.apply(this, arguments);
1562     this.textContent = v == null ? "" : v;
1563   };
1564 }
1565
1566 function selection_text(value) {
1567   return arguments.length
1568       ? this.each(value == null
1569           ? textRemove : (typeof value === "function"
1570           ? textFunction
1571           : textConstant)(value))
1572       : this.node().textContent;
1573 }
1574
1575 function htmlRemove() {
1576   this.innerHTML = "";
1577 }
1578
1579 function htmlConstant(value) {
1580   return function() {
1581     this.innerHTML = value;
1582   };
1583 }
1584
1585 function htmlFunction(value) {
1586   return function() {
1587     var v = value.apply(this, arguments);
1588     this.innerHTML = v == null ? "" : v;
1589   };
1590 }
1591
1592 function selection_html(value) {
1593   return arguments.length
1594       ? this.each(value == null
1595           ? htmlRemove : (typeof value === "function"
1596           ? htmlFunction
1597           : htmlConstant)(value))
1598       : this.node().innerHTML;
1599 }
1600
1601 function raise() {
1602   if (this.nextSibling) this.parentNode.appendChild(this);
1603 }
1604
1605 function selection_raise() {
1606   return this.each(raise);
1607 }
1608
1609 function lower() {
1610   if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild);
1611 }
1612
1613 function selection_lower() {
1614   return this.each(lower);
1615 }
1616
1617 function selection_append(name) {
1618   var create = typeof name === "function" ? name : creator(name);
1619   return this.select(function() {
1620     return this.appendChild(create.apply(this, arguments));
1621   });
1622 }
1623
1624 function constantNull() {
1625   return null;
1626 }
1627
1628 function selection_insert(name, before) {
1629   var create = typeof name === "function" ? name : creator(name),
1630       select = before == null ? constantNull : typeof before === "function" ? before : selector(before);
1631   return this.select(function() {
1632     return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null);
1633   });
1634 }
1635
1636 function remove() {
1637   var parent = this.parentNode;
1638   if (parent) parent.removeChild(this);
1639 }
1640
1641 function selection_remove() {
1642   return this.each(remove);
1643 }
1644
1645 function selection_datum(value) {
1646   return arguments.length
1647       ? this.property("__data__", value)
1648       : this.node().__data__;
1649 }
1650
1651 function dispatchEvent(node, type, params) {
1652   var window = defaultView(node),
1653       event = window.CustomEvent;
1654
1655   if (typeof event === "function") {
1656     event = new event(type, params);
1657   } else {
1658     event = window.document.createEvent("Event");
1659     if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;
1660     else event.initEvent(type, false, false);
1661   }
1662
1663   node.dispatchEvent(event);
1664 }
1665
1666 function dispatchConstant(type, params) {
1667   return function() {
1668     return dispatchEvent(this, type, params);
1669   };
1670 }
1671
1672 function dispatchFunction(type, params) {
1673   return function() {
1674     return dispatchEvent(this, type, params.apply(this, arguments));
1675   };
1676 }
1677
1678 function selection_dispatch(type, params) {
1679   return this.each((typeof params === "function"
1680       ? dispatchFunction
1681       : dispatchConstant)(type, params));
1682 }
1683
1684 var root = [null];
1685
1686 function Selection(groups, parents) {
1687   this._groups = groups;
1688   this._parents = parents;
1689 }
1690
1691 function selection() {
1692   return new Selection([[document.documentElement]], root);
1693 }
1694
1695 Selection.prototype = selection.prototype = {
1696   constructor: Selection,
1697   select: selection_select,
1698   selectAll: selection_selectAll,
1699   filter: selection_filter,
1700   data: selection_data,
1701   enter: selection_enter,
1702   exit: selection_exit,
1703   merge: selection_merge,
1704   order: selection_order,
1705   sort: selection_sort,
1706   call: selection_call,
1707   nodes: selection_nodes,
1708   node: selection_node,
1709   size: selection_size,
1710   empty: selection_empty,
1711   each: selection_each,
1712   attr: selection_attr,
1713   style: selection_style,
1714   property: selection_property,
1715   classed: selection_classed,
1716   text: selection_text,
1717   html: selection_html,
1718   raise: selection_raise,
1719   lower: selection_lower,
1720   append: selection_append,
1721   insert: selection_insert,
1722   remove: selection_remove,
1723   datum: selection_datum,
1724   on: selection_on,
1725   dispatch: selection_dispatch
1726 };
1727
1728 function d3_select(selector) {
1729   return typeof selector === "string"
1730       ? new Selection([[document.querySelector(selector)]], [document.documentElement])
1731       : new Selection([[selector]], root);
1732 }
1733
1734 function d3_selectAll(selector) {
1735   return typeof selector === "string"
1736       ? new Selection([document.querySelectorAll(selector)], [document.documentElement])
1737       : new Selection([selector == null ? [] : selector], root);
1738 }
1739
1740 function touch(node, touches, identifier) {
1741   if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches;
1742
1743   for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) {
1744     if ((touch = touches[i]).identifier === identifier) {
1745       return point(node, touch);
1746     }
1747   }
1748
1749   return null;
1750 }
1751
1752 function d3_touches(node, touches) {
1753   if (touches == null) touches = sourceEvent().touches;
1754
1755   for (var i = 0, n = touches ? touches.length : 0, points = new Array(n); i < n; ++i) {
1756     points[i] = point(node, touches[i]);
1757   }
1758
1759   return points;
1760 }
1761
1762 function nopropagation() {
1763   event.stopImmediatePropagation();
1764 }
1765
1766 function noevent() {
1767   event.preventDefault();
1768   event.stopImmediatePropagation();
1769 }
1770
1771 function dragDisable(view) {
1772   var root = view.document.documentElement,
1773       selection = d3_select(view).on("dragstart.drag", noevent, true);
1774   if ("onselectstart" in root) {
1775     selection.on("selectstart.drag", noevent, true);
1776   } else {
1777     root.__noselect = root.style.MozUserSelect;
1778     root.style.MozUserSelect = "none";
1779   }
1780 }
1781
1782 function yesdrag(view, noclick) {
1783   var root = view.document.documentElement,
1784       selection = d3_select(view).on("dragstart.drag", null);
1785   if (noclick) {
1786     selection.on("click.drag", noevent, true);
1787     setTimeout(function() { selection.on("click.drag", null); }, 0);
1788   }
1789   if ("onselectstart" in root) {
1790     selection.on("selectstart.drag", null);
1791   } else {
1792     root.style.MozUserSelect = root.__noselect;
1793     delete root.__noselect;
1794   }
1795 }
1796
1797 function constant$2(x) {
1798   return function() {
1799     return x;
1800   };
1801 }
1802
1803 function DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch) {
1804   this.target = target;
1805   this.type = type;
1806   this.subject = subject;
1807   this.identifier = id;
1808   this.active = active;
1809   this.x = x;
1810   this.y = y;
1811   this.dx = dx;
1812   this.dy = dy;
1813   this._ = dispatch;
1814 }
1815
1816 DragEvent.prototype.on = function() {
1817   var value = this._.on.apply(this._, arguments);
1818   return value === this._ ? this : value;
1819 };
1820
1821 // Ignore right-click, since that should open the context menu.
1822 function defaultFilter() {
1823   return !event.button;
1824 }
1825
1826 function defaultContainer() {
1827   return this.parentNode;
1828 }
1829
1830 function defaultSubject(d) {
1831   return d == null ? {x: event.x, y: event.y} : d;
1832 }
1833
1834 function defaultTouchable() {
1835   return "ontouchstart" in this;
1836 }
1837
1838 function drag() {
1839   var filter = defaultFilter,
1840       container = defaultContainer,
1841       subject = defaultSubject,
1842       touchable = defaultTouchable,
1843       gestures = {},
1844       listeners = dispatch("start", "drag", "end"),
1845       active = 0,
1846       mousedownx,
1847       mousedowny,
1848       mousemoving,
1849       touchending,
1850       clickDistance2 = 0;
1851
1852   function drag(selection) {
1853     selection
1854         .on("mousedown.drag", mousedowned)
1855       .filter(touchable)
1856         .on("touchstart.drag", touchstarted)
1857         .on("touchmove.drag", touchmoved)
1858         .on("touchend.drag touchcancel.drag", touchended)
1859         .style("touch-action", "none")
1860         .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
1861   }
1862
1863   function mousedowned() {
1864     if (touchending || !filter.apply(this, arguments)) return;
1865     var gesture = beforestart("mouse", container.apply(this, arguments), d3_mouse, this, arguments);
1866     if (!gesture) return;
1867     d3_select(event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true);
1868     dragDisable(event.view);
1869     nopropagation();
1870     mousemoving = false;
1871     mousedownx = event.clientX;
1872     mousedowny = event.clientY;
1873     gesture("start");
1874   }
1875
1876   function mousemoved() {
1877     noevent();
1878     if (!mousemoving) {
1879       var dx = event.clientX - mousedownx, dy = event.clientY - mousedowny;
1880       mousemoving = dx * dx + dy * dy > clickDistance2;
1881     }
1882     gestures.mouse("drag");
1883   }
1884
1885   function mouseupped() {
1886     d3_select(event.view).on("mousemove.drag mouseup.drag", null);
1887     yesdrag(event.view, mousemoving);
1888     noevent();
1889     gestures.mouse("end");
1890   }
1891
1892   function touchstarted() {
1893     if (!filter.apply(this, arguments)) return;
1894     var touches = event.changedTouches,
1895         c = container.apply(this, arguments),
1896         n = touches.length, i, gesture;
1897
1898     for (i = 0; i < n; ++i) {
1899       if (gesture = beforestart(touches[i].identifier, c, touch, this, arguments)) {
1900         nopropagation();
1901         gesture("start");
1902       }
1903     }
1904   }
1905
1906   function touchmoved() {
1907     var touches = event.changedTouches,
1908         n = touches.length, i, gesture;
1909
1910     for (i = 0; i < n; ++i) {
1911       if (gesture = gestures[touches[i].identifier]) {
1912         noevent();
1913         gesture("drag");
1914       }
1915     }
1916   }
1917
1918   function touchended() {
1919     var touches = event.changedTouches,
1920         n = touches.length, i, gesture;
1921
1922     if (touchending) clearTimeout(touchending);
1923     touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
1924     for (i = 0; i < n; ++i) {
1925       if (gesture = gestures[touches[i].identifier]) {
1926         nopropagation();
1927         gesture("end");
1928       }
1929     }
1930   }
1931
1932   function beforestart(id, container, point, that, args) {
1933     var p = point(container, id), s, dx, dy,
1934         sublisteners = listeners.copy();
1935
1936     if (!customEvent(new DragEvent(drag, "beforestart", s, id, active, p[0], p[1], 0, 0, sublisteners), function() {
1937       if ((event.subject = s = subject.apply(that, args)) == null) return false;
1938       dx = s.x - p[0] || 0;
1939       dy = s.y - p[1] || 0;
1940       return true;
1941     })) return;
1942
1943     return function gesture(type) {
1944       var p0 = p, n;
1945       switch (type) {
1946         case "start": gestures[id] = gesture, n = active++; break;
1947         case "end": delete gestures[id], --active; // nobreak
1948         case "drag": p = point(container, id), n = active; break;
1949       }
1950       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]);
1951     };
1952   }
1953
1954   drag.filter = function(_) {
1955     return arguments.length ? (filter = typeof _ === "function" ? _ : constant$2(!!_), drag) : filter;
1956   };
1957
1958   drag.container = function(_) {
1959     return arguments.length ? (container = typeof _ === "function" ? _ : constant$2(_), drag) : container;
1960   };
1961
1962   drag.subject = function(_) {
1963     return arguments.length ? (subject = typeof _ === "function" ? _ : constant$2(_), drag) : subject;
1964   };
1965
1966   drag.touchable = function(_) {
1967     return arguments.length ? (touchable = typeof _ === "function" ? _ : constant$2(!!_), drag) : touchable;
1968   };
1969
1970   drag.on = function() {
1971     var value = listeners.on.apply(listeners, arguments);
1972     return value === listeners ? drag : value;
1973   };
1974
1975   drag.clickDistance = function(_) {
1976     return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2);
1977   };
1978
1979   return drag;
1980 }
1981
1982 function define(constructor, factory, prototype) {
1983   constructor.prototype = factory.prototype = prototype;
1984   prototype.constructor = constructor;
1985 }
1986
1987 function extend(parent, definition) {
1988   var prototype = Object.create(parent.prototype);
1989   for (var key in definition) prototype[key] = definition[key];
1990   return prototype;
1991 }
1992
1993 function Color() {}
1994
1995 var darker = 0.7;
1996 var brighter = 1 / darker;
1997
1998 var reI = "\\s*([+-]?\\d+)\\s*";
1999 var reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*";
2000 var reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*";
2001 var reHex3 = /^#([0-9a-f]{3})$/;
2002 var reHex6 = /^#([0-9a-f]{6})$/;
2003 var reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$");
2004 var reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$");
2005 var reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$");
2006 var reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$");
2007 var reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$");
2008 var reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$");
2009
2010 var named = {
2011   aliceblue: 0xf0f8ff,
2012   antiquewhite: 0xfaebd7,
2013   aqua: 0x00ffff,
2014   aquamarine: 0x7fffd4,
2015   azure: 0xf0ffff,
2016   beige: 0xf5f5dc,
2017   bisque: 0xffe4c4,
2018   black: 0x000000,
2019   blanchedalmond: 0xffebcd,
2020   blue: 0x0000ff,
2021   blueviolet: 0x8a2be2,
2022   brown: 0xa52a2a,
2023   burlywood: 0xdeb887,
2024   cadetblue: 0x5f9ea0,
2025   chartreuse: 0x7fff00,
2026   chocolate: 0xd2691e,
2027   coral: 0xff7f50,
2028   cornflowerblue: 0x6495ed,
2029   cornsilk: 0xfff8dc,
2030   crimson: 0xdc143c,
2031   cyan: 0x00ffff,
2032   darkblue: 0x00008b,
2033   darkcyan: 0x008b8b,
2034   darkgoldenrod: 0xb8860b,
2035   darkgray: 0xa9a9a9,
2036   darkgreen: 0x006400,
2037   darkgrey: 0xa9a9a9,
2038   darkkhaki: 0xbdb76b,
2039   darkmagenta: 0x8b008b,
2040   darkolivegreen: 0x556b2f,
2041   darkorange: 0xff8c00,
2042   darkorchid: 0x9932cc,
2043   darkred: 0x8b0000,
2044   darksalmon: 0xe9967a,
2045   darkseagreen: 0x8fbc8f,
2046   darkslateblue: 0x483d8b,
2047   darkslategray: 0x2f4f4f,
2048   darkslategrey: 0x2f4f4f,
2049   darkturquoise: 0x00ced1,
2050   darkviolet: 0x9400d3,
2051   deeppink: 0xff1493,
2052   deepskyblue: 0x00bfff,
2053   dimgray: 0x696969,
2054   dimgrey: 0x696969,
2055   dodgerblue: 0x1e90ff,
2056   firebrick: 0xb22222,
2057   floralwhite: 0xfffaf0,
2058   forestgreen: 0x228b22,
2059   fuchsia: 0xff00ff,
2060   gainsboro: 0xdcdcdc,
2061   ghostwhite: 0xf8f8ff,
2062   gold: 0xffd700,
2063   goldenrod: 0xdaa520,
2064   gray: 0x808080,
2065   green: 0x008000,
2066   greenyellow: 0xadff2f,
2067   grey: 0x808080,
2068   honeydew: 0xf0fff0,
2069   hotpink: 0xff69b4,
2070   indianred: 0xcd5c5c,
2071   indigo: 0x4b0082,
2072   ivory: 0xfffff0,
2073   khaki: 0xf0e68c,
2074   lavender: 0xe6e6fa,
2075   lavenderblush: 0xfff0f5,
2076   lawngreen: 0x7cfc00,
2077   lemonchiffon: 0xfffacd,
2078   lightblue: 0xadd8e6,
2079   lightcoral: 0xf08080,
2080   lightcyan: 0xe0ffff,
2081   lightgoldenrodyellow: 0xfafad2,
2082   lightgray: 0xd3d3d3,
2083   lightgreen: 0x90ee90,
2084   lightgrey: 0xd3d3d3,
2085   lightpink: 0xffb6c1,
2086   lightsalmon: 0xffa07a,
2087   lightseagreen: 0x20b2aa,
2088   lightskyblue: 0x87cefa,
2089   lightslategray: 0x778899,
2090   lightslategrey: 0x778899,
2091   lightsteelblue: 0xb0c4de,
2092   lightyellow: 0xffffe0,
2093   lime: 0x00ff00,
2094   limegreen: 0x32cd32,
2095   linen: 0xfaf0e6,
2096   magenta: 0xff00ff,
2097   maroon: 0x800000,
2098   mediumaquamarine: 0x66cdaa,
2099   mediumblue: 0x0000cd,
2100   mediumorchid: 0xba55d3,
2101   mediumpurple: 0x9370db,
2102   mediumseagreen: 0x3cb371,
2103   mediumslateblue: 0x7b68ee,
2104   mediumspringgreen: 0x00fa9a,
2105   mediumturquoise: 0x48d1cc,
2106   mediumvioletred: 0xc71585,
2107   midnightblue: 0x191970,
2108   mintcream: 0xf5fffa,
2109   mistyrose: 0xffe4e1,
2110   moccasin: 0xffe4b5,
2111   navajowhite: 0xffdead,
2112   navy: 0x000080,
2113   oldlace: 0xfdf5e6,
2114   olive: 0x808000,
2115   olivedrab: 0x6b8e23,
2116   orange: 0xffa500,
2117   orangered: 0xff4500,
2118   orchid: 0xda70d6,
2119   palegoldenrod: 0xeee8aa,
2120   palegreen: 0x98fb98,
2121   paleturquoise: 0xafeeee,
2122   palevioletred: 0xdb7093,
2123   papayawhip: 0xffefd5,
2124   peachpuff: 0xffdab9,
2125   peru: 0xcd853f,
2126   pink: 0xffc0cb,
2127   plum: 0xdda0dd,
2128   powderblue: 0xb0e0e6,
2129   purple: 0x800080,
2130   rebeccapurple: 0x663399,
2131   red: 0xff0000,
2132   rosybrown: 0xbc8f8f,
2133   royalblue: 0x4169e1,
2134   saddlebrown: 0x8b4513,
2135   salmon: 0xfa8072,
2136   sandybrown: 0xf4a460,
2137   seagreen: 0x2e8b57,
2138   seashell: 0xfff5ee,
2139   sienna: 0xa0522d,
2140   silver: 0xc0c0c0,
2141   skyblue: 0x87ceeb,
2142   slateblue: 0x6a5acd,
2143   slategray: 0x708090,
2144   slategrey: 0x708090,
2145   snow: 0xfffafa,
2146   springgreen: 0x00ff7f,
2147   steelblue: 0x4682b4,
2148   tan: 0xd2b48c,
2149   teal: 0x008080,
2150   thistle: 0xd8bfd8,
2151   tomato: 0xff6347,
2152   turquoise: 0x40e0d0,
2153   violet: 0xee82ee,
2154   wheat: 0xf5deb3,
2155   white: 0xffffff,
2156   whitesmoke: 0xf5f5f5,
2157   yellow: 0xffff00,
2158   yellowgreen: 0x9acd32
2159 };
2160
2161 define(Color, color, {
2162   displayable: function() {
2163     return this.rgb().displayable();
2164   },
2165   toString: function() {
2166     return this.rgb() + "";
2167   }
2168 });
2169
2170 function color(format) {
2171   var m;
2172   format = (format + "").trim().toLowerCase();
2173   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
2174       : (m = reHex6.exec(format)) ? rgbn(parseInt(m[1], 16)) // #ff0000
2175       : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)
2176       : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)
2177       : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)
2178       : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)
2179       : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)
2180       : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)
2181       : named.hasOwnProperty(format) ? rgbn(named[format])
2182       : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0)
2183       : null;
2184 }
2185
2186 function rgbn(n) {
2187   return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);
2188 }
2189
2190 function rgba(r, g, b, a) {
2191   if (a <= 0) r = g = b = NaN;
2192   return new Rgb(r, g, b, a);
2193 }
2194
2195 function rgbConvert(o) {
2196   if (!(o instanceof Color)) o = color(o);
2197   if (!o) return new Rgb;
2198   o = o.rgb();
2199   return new Rgb(o.r, o.g, o.b, o.opacity);
2200 }
2201
2202 function rgb(r, g, b, opacity) {
2203   return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);
2204 }
2205
2206 function Rgb(r, g, b, opacity) {
2207   this.r = +r;
2208   this.g = +g;
2209   this.b = +b;
2210   this.opacity = +opacity;
2211 }
2212
2213 define(Rgb, rgb, extend(Color, {
2214   brighter: function(k) {
2215     k = k == null ? brighter : Math.pow(brighter, k);
2216     return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
2217   },
2218   darker: function(k) {
2219     k = k == null ? darker : Math.pow(darker, k);
2220     return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
2221   },
2222   rgb: function() {
2223     return this;
2224   },
2225   displayable: function() {
2226     return (0 <= this.r && this.r <= 255)
2227         && (0 <= this.g && this.g <= 255)
2228         && (0 <= this.b && this.b <= 255)
2229         && (0 <= this.opacity && this.opacity <= 1);
2230   },
2231   toString: function() {
2232     var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));
2233     return (a === 1 ? "rgb(" : "rgba(")
2234         + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", "
2235         + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", "
2236         + Math.max(0, Math.min(255, Math.round(this.b) || 0))
2237         + (a === 1 ? ")" : ", " + a + ")");
2238   }
2239 }));
2240
2241 function hsla(h, s, l, a) {
2242   if (a <= 0) h = s = l = NaN;
2243   else if (l <= 0 || l >= 1) h = s = NaN;
2244   else if (s <= 0) h = NaN;
2245   return new Hsl(h, s, l, a);
2246 }
2247
2248 function hslConvert(o) {
2249   if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);
2250   if (!(o instanceof Color)) o = color(o);
2251   if (!o) return new Hsl;
2252   if (o instanceof Hsl) return o;
2253   o = o.rgb();
2254   var r = o.r / 255,
2255       g = o.g / 255,
2256       b = o.b / 255,
2257       min = Math.min(r, g, b),
2258       max = Math.max(r, g, b),
2259       h = NaN,
2260       s = max - min,
2261       l = (max + min) / 2;
2262   if (s) {
2263     if (r === max) h = (g - b) / s + (g < b) * 6;
2264     else if (g === max) h = (b - r) / s + 2;
2265     else h = (r - g) / s + 4;
2266     s /= l < 0.5 ? max + min : 2 - max - min;
2267     h *= 60;
2268   } else {
2269     s = l > 0 && l < 1 ? 0 : h;
2270   }
2271   return new Hsl(h, s, l, o.opacity);
2272 }
2273
2274 function hsl(h, s, l, opacity) {
2275   return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);
2276 }
2277
2278 function Hsl(h, s, l, opacity) {
2279   this.h = +h;
2280   this.s = +s;
2281   this.l = +l;
2282   this.opacity = +opacity;
2283 }
2284
2285 define(Hsl, hsl, extend(Color, {
2286   brighter: function(k) {
2287     k = k == null ? brighter : Math.pow(brighter, k);
2288     return new Hsl(this.h, this.s, this.l * k, this.opacity);
2289   },
2290   darker: function(k) {
2291     k = k == null ? darker : Math.pow(darker, k);
2292     return new Hsl(this.h, this.s, this.l * k, this.opacity);
2293   },
2294   rgb: function() {
2295     var h = this.h % 360 + (this.h < 0) * 360,
2296         s = isNaN(h) || isNaN(this.s) ? 0 : this.s,
2297         l = this.l,
2298         m2 = l + (l < 0.5 ? l : 1 - l) * s,
2299         m1 = 2 * l - m2;
2300     return new Rgb(
2301       hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),
2302       hsl2rgb(h, m1, m2),
2303       hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),
2304       this.opacity
2305     );
2306   },
2307   displayable: function() {
2308     return (0 <= this.s && this.s <= 1 || isNaN(this.s))
2309         && (0 <= this.l && this.l <= 1)
2310         && (0 <= this.opacity && this.opacity <= 1);
2311   }
2312 }));
2313
2314 /* From FvD 13.37, CSS Color Module Level 3 */
2315 function hsl2rgb(h, m1, m2) {
2316   return (h < 60 ? m1 + (m2 - m1) * h / 60
2317       : h < 180 ? m2
2318       : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60
2319       : m1) * 255;
2320 }
2321
2322 var deg2rad = Math.PI / 180;
2323 var rad2deg = 180 / Math.PI;
2324
2325 var Kn = 18;
2326 var Xn = 0.950470;
2327 var Yn = 1;
2328 var Zn = 1.088830;
2329 var t0 = 4 / 29;
2330 var t1 = 6 / 29;
2331 var t2 = 3 * t1 * t1;
2332 var t3 = t1 * t1 * t1;
2333
2334 function labConvert(o) {
2335   if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity);
2336   if (o instanceof Hcl) {
2337     var h = o.h * deg2rad;
2338     return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity);
2339   }
2340   if (!(o instanceof Rgb)) o = rgbConvert(o);
2341   var b = rgb2xyz(o.r),
2342       a = rgb2xyz(o.g),
2343       l = rgb2xyz(o.b),
2344       x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn),
2345       y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.0721750 * l) / Yn),
2346       z = xyz2lab((0.0193339 * b + 0.1191920 * a + 0.9503041 * l) / Zn);
2347   return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity);
2348 }
2349
2350 function lab(l, a, b, opacity) {
2351   return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity);
2352 }
2353
2354 function Lab(l, a, b, opacity) {
2355   this.l = +l;
2356   this.a = +a;
2357   this.b = +b;
2358   this.opacity = +opacity;
2359 }
2360
2361 define(Lab, lab, extend(Color, {
2362   brighter: function(k) {
2363     return new Lab(this.l + Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);
2364   },
2365   darker: function(k) {
2366     return new Lab(this.l - Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);
2367   },
2368   rgb: function() {
2369     var y = (this.l + 16) / 116,
2370         x = isNaN(this.a) ? y : y + this.a / 500,
2371         z = isNaN(this.b) ? y : y - this.b / 200;
2372     y = Yn * lab2xyz(y);
2373     x = Xn * lab2xyz(x);
2374     z = Zn * lab2xyz(z);
2375     return new Rgb(
2376       xyz2rgb( 3.2404542 * x - 1.5371385 * y - 0.4985314 * z), // D65 -> sRGB
2377       xyz2rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z),
2378       xyz2rgb( 0.0556434 * x - 0.2040259 * y + 1.0572252 * z),
2379       this.opacity
2380     );
2381   }
2382 }));
2383
2384 function xyz2lab(t) {
2385   return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0;
2386 }
2387
2388 function lab2xyz(t) {
2389   return t > t1 ? t * t * t : t2 * (t - t0);
2390 }
2391
2392 function xyz2rgb(x) {
2393   return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055);
2394 }
2395
2396 function rgb2xyz(x) {
2397   return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
2398 }
2399
2400 function hclConvert(o) {
2401   if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity);
2402   if (!(o instanceof Lab)) o = labConvert(o);
2403   var h = Math.atan2(o.b, o.a) * rad2deg;
2404   return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity);
2405 }
2406
2407 function hcl(h, c, l, opacity) {
2408   return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity);
2409 }
2410
2411 function Hcl(h, c, l, opacity) {
2412   this.h = +h;
2413   this.c = +c;
2414   this.l = +l;
2415   this.opacity = +opacity;
2416 }
2417
2418 define(Hcl, hcl, extend(Color, {
2419   brighter: function(k) {
2420     return new Hcl(this.h, this.c, this.l + Kn * (k == null ? 1 : k), this.opacity);
2421   },
2422   darker: function(k) {
2423     return new Hcl(this.h, this.c, this.l - Kn * (k == null ? 1 : k), this.opacity);
2424   },
2425   rgb: function() {
2426     return labConvert(this).rgb();
2427   }
2428 }));
2429
2430 var A = -0.14861;
2431 var B = +1.78277;
2432 var C = -0.29227;
2433 var D = -0.90649;
2434 var E = +1.97294;
2435 var ED = E * D;
2436 var EB = E * B;
2437 var BC_DA = B * C - D * A;
2438
2439 function cubehelixConvert(o) {
2440   if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity);
2441   if (!(o instanceof Rgb)) o = rgbConvert(o);
2442   var r = o.r / 255,
2443       g = o.g / 255,
2444       b = o.b / 255,
2445       l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB),
2446       bl = b - l,
2447       k = (E * (g - l) - C * bl) / D,
2448       s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1
2449       h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN;
2450   return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity);
2451 }
2452
2453 function cubehelix(h, s, l, opacity) {
2454   return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity);
2455 }
2456
2457 function Cubehelix(h, s, l, opacity) {
2458   this.h = +h;
2459   this.s = +s;
2460   this.l = +l;
2461   this.opacity = +opacity;
2462 }
2463
2464 define(Cubehelix, cubehelix, extend(Color, {
2465   brighter: function(k) {
2466     k = k == null ? brighter : Math.pow(brighter, k);
2467     return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
2468   },
2469   darker: function(k) {
2470     k = k == null ? darker : Math.pow(darker, k);
2471     return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
2472   },
2473   rgb: function() {
2474     var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad,
2475         l = +this.l,
2476         a = isNaN(this.s) ? 0 : this.s * l * (1 - l),
2477         cosh = Math.cos(h),
2478         sinh = Math.sin(h);
2479     return new Rgb(
2480       255 * (l + a * (A * cosh + B * sinh)),
2481       255 * (l + a * (C * cosh + D * sinh)),
2482       255 * (l + a * (E * cosh)),
2483       this.opacity
2484     );
2485   }
2486 }));
2487
2488 function basis(t1, v0, v1, v2, v3) {
2489   var t2 = t1 * t1, t3 = t2 * t1;
2490   return ((1 - 3 * t1 + 3 * t2 - t3) * v0
2491       + (4 - 6 * t2 + 3 * t3) * v1
2492       + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2
2493       + t3 * v3) / 6;
2494 }
2495
2496 function basis$1(values) {
2497   var n = values.length - 1;
2498   return function(t) {
2499     var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n),
2500         v1 = values[i],
2501         v2 = values[i + 1],
2502         v0 = i > 0 ? values[i - 1] : 2 * v1 - v2,
2503         v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1;
2504     return basis((t - i / n) * n, v0, v1, v2, v3);
2505   };
2506 }
2507
2508 function basisClosed(values) {
2509   var n = values.length;
2510   return function(t) {
2511     var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n),
2512         v0 = values[(i + n - 1) % n],
2513         v1 = values[i % n],
2514         v2 = values[(i + 1) % n],
2515         v3 = values[(i + 2) % n];
2516     return basis((t - i / n) * n, v0, v1, v2, v3);
2517   };
2518 }
2519
2520 function constant$3(x) {
2521   return function() {
2522     return x;
2523   };
2524 }
2525
2526 function linear(a, d) {
2527   return function(t) {
2528     return a + t * d;
2529   };
2530 }
2531
2532 function exponential(a, b, y) {
2533   return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {
2534     return Math.pow(a + t * b, y);
2535   };
2536 }
2537
2538 function hue(a, b) {
2539   var d = b - a;
2540   return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant$3(isNaN(a) ? b : a);
2541 }
2542
2543 function gamma(y) {
2544   return (y = +y) === 1 ? nogamma : function(a, b) {
2545     return b - a ? exponential(a, b, y) : constant$3(isNaN(a) ? b : a);
2546   };
2547 }
2548
2549 function nogamma(a, b) {
2550   var d = b - a;
2551   return d ? linear(a, d) : constant$3(isNaN(a) ? b : a);
2552 }
2553
2554 var d3_interpolateRgb = (function rgbGamma(y) {
2555   var color$$1 = gamma(y);
2556
2557   function rgb$$1(start, end) {
2558     var r = color$$1((start = rgb(start)).r, (end = rgb(end)).r),
2559         g = color$$1(start.g, end.g),
2560         b = color$$1(start.b, end.b),
2561         opacity = nogamma(start.opacity, end.opacity);
2562     return function(t) {
2563       start.r = r(t);
2564       start.g = g(t);
2565       start.b = b(t);
2566       start.opacity = opacity(t);
2567       return start + "";
2568     };
2569   }
2570
2571   rgb$$1.gamma = rgbGamma;
2572
2573   return rgb$$1;
2574 })(1);
2575
2576 function rgbSpline(spline) {
2577   return function(colors) {
2578     var n = colors.length,
2579         r = new Array(n),
2580         g = new Array(n),
2581         b = new Array(n),
2582         i, color$$1;
2583     for (i = 0; i < n; ++i) {
2584       color$$1 = rgb(colors[i]);
2585       r[i] = color$$1.r || 0;
2586       g[i] = color$$1.g || 0;
2587       b[i] = color$$1.b || 0;
2588     }
2589     r = spline(r);
2590     g = spline(g);
2591     b = spline(b);
2592     color$$1.opacity = 1;
2593     return function(t) {
2594       color$$1.r = r(t);
2595       color$$1.g = g(t);
2596       color$$1.b = b(t);
2597       return color$$1 + "";
2598     };
2599   };
2600 }
2601
2602 var rgbBasis = rgbSpline(basis$1);
2603 var rgbBasisClosed = rgbSpline(basisClosed);
2604
2605 function array$1(a, b) {
2606   var nb = b ? b.length : 0,
2607       na = a ? Math.min(nb, a.length) : 0,
2608       x = new Array(na),
2609       c = new Array(nb),
2610       i;
2611
2612   for (i = 0; i < na; ++i) x[i] = d3_interpolate(a[i], b[i]);
2613   for (; i < nb; ++i) c[i] = b[i];
2614
2615   return function(t) {
2616     for (i = 0; i < na; ++i) c[i] = x[i](t);
2617     return c;
2618   };
2619 }
2620
2621 function date(a, b) {
2622   var d = new Date;
2623   return a = +a, b -= a, function(t) {
2624     return d.setTime(a + b * t), d;
2625   };
2626 }
2627
2628 function d3_interpolateNumber(a, b) {
2629   return a = +a, b -= a, function(t) {
2630     return a + b * t;
2631   };
2632 }
2633
2634 function object(a, b) {
2635   var i = {},
2636       c = {},
2637       k;
2638
2639   if (a === null || typeof a !== "object") a = {};
2640   if (b === null || typeof b !== "object") b = {};
2641
2642   for (k in b) {
2643     if (k in a) {
2644       i[k] = d3_interpolate(a[k], b[k]);
2645     } else {
2646       c[k] = b[k];
2647     }
2648   }
2649
2650   return function(t) {
2651     for (k in i) c[k] = i[k](t);
2652     return c;
2653   };
2654 }
2655
2656 var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;
2657 var reB = new RegExp(reA.source, "g");
2658
2659 function zero(b) {
2660   return function() {
2661     return b;
2662   };
2663 }
2664
2665 function one(b) {
2666   return function(t) {
2667     return b(t) + "";
2668   };
2669 }
2670
2671 function interpolateString(a, b) {
2672   var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b
2673       am, // current match in a
2674       bm, // current match in b
2675       bs, // string preceding current number in b, if any
2676       i = -1, // index in s
2677       s = [], // string constants and placeholders
2678       q = []; // number interpolators
2679
2680   // Coerce inputs to strings.
2681   a = a + "", b = b + "";
2682
2683   // Interpolate pairs of numbers in a & b.
2684   while ((am = reA.exec(a))
2685       && (bm = reB.exec(b))) {
2686     if ((bs = bm.index) > bi) { // a string precedes the next number in b
2687       bs = b.slice(bi, bs);
2688       if (s[i]) s[i] += bs; // coalesce with previous string
2689       else s[++i] = bs;
2690     }
2691     if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match
2692       if (s[i]) s[i] += bm; // coalesce with previous string
2693       else s[++i] = bm;
2694     } else { // interpolate non-matching numbers
2695       s[++i] = null;
2696       q.push({i: i, x: d3_interpolateNumber(am, bm)});
2697     }
2698     bi = reB.lastIndex;
2699   }
2700
2701   // Add remains of b.
2702   if (bi < b.length) {
2703     bs = b.slice(bi);
2704     if (s[i]) s[i] += bs; // coalesce with previous string
2705     else s[++i] = bs;
2706   }
2707
2708   // Special optimization for only a single match.
2709   // Otherwise, interpolate each of the numbers and rejoin the string.
2710   return s.length < 2 ? (q[0]
2711       ? one(q[0].x)
2712       : zero(b))
2713       : (b = q.length, function(t) {
2714           for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);
2715           return s.join("");
2716         });
2717 }
2718
2719 function d3_interpolate(a, b) {
2720   var t = typeof b, c;
2721   return b == null || t === "boolean" ? constant$3(b)
2722       : (t === "number" ? d3_interpolateNumber
2723       : t === "string" ? ((c = color(b)) ? (b = c, d3_interpolateRgb) : interpolateString)
2724       : b instanceof color ? d3_interpolateRgb
2725       : b instanceof Date ? date
2726       : Array.isArray(b) ? array$1
2727       : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object
2728       : d3_interpolateNumber)(a, b);
2729 }
2730
2731 function interpolateRound(a, b) {
2732   return a = +a, b -= a, function(t) {
2733     return Math.round(a + b * t);
2734   };
2735 }
2736
2737 var degrees = 180 / Math.PI;
2738
2739 var identity$2 = {
2740   translateX: 0,
2741   translateY: 0,
2742   rotate: 0,
2743   skewX: 0,
2744   scaleX: 1,
2745   scaleY: 1
2746 };
2747
2748 function decompose(a, b, c, d, e, f) {
2749   var scaleX, scaleY, skewX;
2750   if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;
2751   if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;
2752   if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;
2753   if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;
2754   return {
2755     translateX: e,
2756     translateY: f,
2757     rotate: Math.atan2(b, a) * degrees,
2758     skewX: Math.atan(skewX) * degrees,
2759     scaleX: scaleX,
2760     scaleY: scaleY
2761   };
2762 }
2763
2764 var cssNode;
2765 var cssRoot;
2766 var cssView;
2767 var svgNode;
2768
2769 function parseCss(value) {
2770   if (value === "none") return identity$2;
2771   if (!cssNode) cssNode = document.createElement("DIV"), cssRoot = document.documentElement, cssView = document.defaultView;
2772   cssNode.style.transform = value;
2773   value = cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).getPropertyValue("transform");
2774   cssRoot.removeChild(cssNode);
2775   value = value.slice(7, -1).split(",");
2776   return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]);
2777 }
2778
2779 function parseSvg(value) {
2780   if (value == null) return identity$2;
2781   if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g");
2782   svgNode.setAttribute("transform", value);
2783   if (!(value = svgNode.transform.baseVal.consolidate())) return identity$2;
2784   value = value.matrix;
2785   return decompose(value.a, value.b, value.c, value.d, value.e, value.f);
2786 }
2787
2788 function interpolateTransform(parse, pxComma, pxParen, degParen) {
2789
2790   function pop(s) {
2791     return s.length ? s.pop() + " " : "";
2792   }
2793
2794   function translate(xa, ya, xb, yb, s, q) {
2795     if (xa !== xb || ya !== yb) {
2796       var i = s.push("translate(", null, pxComma, null, pxParen);
2797       q.push({i: i - 4, x: d3_interpolateNumber(xa, xb)}, {i: i - 2, x: d3_interpolateNumber(ya, yb)});
2798     } else if (xb || yb) {
2799       s.push("translate(" + xb + pxComma + yb + pxParen);
2800     }
2801   }
2802
2803   function rotate(a, b, s, q) {
2804     if (a !== b) {
2805       if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path
2806       q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: d3_interpolateNumber(a, b)});
2807     } else if (b) {
2808       s.push(pop(s) + "rotate(" + b + degParen);
2809     }
2810   }
2811
2812   function skewX(a, b, s, q) {
2813     if (a !== b) {
2814       q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: d3_interpolateNumber(a, b)});
2815     } else if (b) {
2816       s.push(pop(s) + "skewX(" + b + degParen);
2817     }
2818   }
2819
2820   function scale(xa, ya, xb, yb, s, q) {
2821     if (xa !== xb || ya !== yb) {
2822       var i = s.push(pop(s) + "scale(", null, ",", null, ")");
2823       q.push({i: i - 4, x: d3_interpolateNumber(xa, xb)}, {i: i - 2, x: d3_interpolateNumber(ya, yb)});
2824     } else if (xb !== 1 || yb !== 1) {
2825       s.push(pop(s) + "scale(" + xb + "," + yb + ")");
2826     }
2827   }
2828
2829   return function(a, b) {
2830     var s = [], // string constants and placeholders
2831         q = []; // number interpolators
2832     a = parse(a), b = parse(b);
2833     translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);
2834     rotate(a.rotate, b.rotate, s, q);
2835     skewX(a.skewX, b.skewX, s, q);
2836     scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);
2837     a = b = null; // gc
2838     return function(t) {
2839       var i = -1, n = q.length, o;
2840       while (++i < n) s[(o = q[i]).i] = o.x(t);
2841       return s.join("");
2842     };
2843   };
2844 }
2845
2846 var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)");
2847 var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")");
2848
2849 var rho = Math.SQRT2;
2850 var rho2 = 2;
2851 var rho4 = 4;
2852 var epsilon2 = 1e-12;
2853
2854 function cosh(x) {
2855   return ((x = Math.exp(x)) + 1 / x) / 2;
2856 }
2857
2858 function sinh(x) {
2859   return ((x = Math.exp(x)) - 1 / x) / 2;
2860 }
2861
2862 function tanh(x) {
2863   return ((x = Math.exp(2 * x)) - 1) / (x + 1);
2864 }
2865
2866 // p0 = [ux0, uy0, w0]
2867 // p1 = [ux1, uy1, w1]
2868 function interpolateZoom(p0, p1) {
2869   var ux0 = p0[0], uy0 = p0[1], w0 = p0[2],
2870       ux1 = p1[0], uy1 = p1[1], w1 = p1[2],
2871       dx = ux1 - ux0,
2872       dy = uy1 - uy0,
2873       d2 = dx * dx + dy * dy,
2874       i,
2875       S;
2876
2877   // Special case for u0 ≅ u1.
2878   if (d2 < epsilon2) {
2879     S = Math.log(w1 / w0) / rho;
2880     i = function(t) {
2881       return [
2882         ux0 + t * dx,
2883         uy0 + t * dy,
2884         w0 * Math.exp(rho * t * S)
2885       ];
2886     };
2887   }
2888
2889   // General case.
2890   else {
2891     var d1 = Math.sqrt(d2),
2892         b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1),
2893         b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1),
2894         r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0),
2895         r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);
2896     S = (r1 - r0) / rho;
2897     i = function(t) {
2898       var s = t * S,
2899           coshr0 = cosh(r0),
2900           u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0));
2901       return [
2902         ux0 + u * dx,
2903         uy0 + u * dy,
2904         w0 * coshr0 / cosh(rho * s + r0)
2905       ];
2906     };
2907   }
2908
2909   i.duration = S * 1000;
2910
2911   return i;
2912 }
2913
2914 function hsl$1(hue$$1) {
2915   return function(start, end) {
2916     var h = hue$$1((start = hsl(start)).h, (end = hsl(end)).h),
2917         s = nogamma(start.s, end.s),
2918         l = nogamma(start.l, end.l),
2919         opacity = nogamma(start.opacity, end.opacity);
2920     return function(t) {
2921       start.h = h(t);
2922       start.s = s(t);
2923       start.l = l(t);
2924       start.opacity = opacity(t);
2925       return start + "";
2926     };
2927   }
2928 }
2929
2930 var hsl$2 = hsl$1(hue);
2931 var hslLong = hsl$1(nogamma);
2932
2933 function lab$1(start, end) {
2934   var l = nogamma((start = lab(start)).l, (end = lab(end)).l),
2935       a = nogamma(start.a, end.a),
2936       b = nogamma(start.b, end.b),
2937       opacity = nogamma(start.opacity, end.opacity);
2938   return function(t) {
2939     start.l = l(t);
2940     start.a = a(t);
2941     start.b = b(t);
2942     start.opacity = opacity(t);
2943     return start + "";
2944   };
2945 }
2946
2947 function hcl$1(hue$$1) {
2948   return function(start, end) {
2949     var h = hue$$1((start = hcl(start)).h, (end = hcl(end)).h),
2950         c = nogamma(start.c, end.c),
2951         l = nogamma(start.l, end.l),
2952         opacity = nogamma(start.opacity, end.opacity);
2953     return function(t) {
2954       start.h = h(t);
2955       start.c = c(t);
2956       start.l = l(t);
2957       start.opacity = opacity(t);
2958       return start + "";
2959     };
2960   }
2961 }
2962
2963 var hcl$2 = hcl$1(hue);
2964 var hclLong = hcl$1(nogamma);
2965
2966 function cubehelix$1(hue$$1) {
2967   return (function cubehelixGamma(y) {
2968     y = +y;
2969
2970     function cubehelix$$1(start, end) {
2971       var h = hue$$1((start = cubehelix(start)).h, (end = cubehelix(end)).h),
2972           s = nogamma(start.s, end.s),
2973           l = nogamma(start.l, end.l),
2974           opacity = nogamma(start.opacity, end.opacity);
2975       return function(t) {
2976         start.h = h(t);
2977         start.s = s(t);
2978         start.l = l(Math.pow(t, y));
2979         start.opacity = opacity(t);
2980         return start + "";
2981       };
2982     }
2983
2984     cubehelix$$1.gamma = cubehelixGamma;
2985
2986     return cubehelix$$1;
2987   })(1);
2988 }
2989
2990 var cubehelix$2 = cubehelix$1(hue);
2991 var cubehelixLong = cubehelix$1(nogamma);
2992
2993 function d3_quantize(interpolator, n) {
2994   var samples = new Array(n);
2995   for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1));
2996   return samples;
2997 }
2998
2999 var frame = 0;
3000 var timeout = 0;
3001 var interval = 0;
3002 var pokeDelay = 1000;
3003 var taskHead;
3004 var taskTail;
3005 var clockLast = 0;
3006 var clockNow = 0;
3007 var clockSkew = 0;
3008 var clock = typeof performance === "object" && performance.now ? performance : Date;
3009 var setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); };
3010
3011 function now() {
3012   return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);
3013 }
3014
3015 function clearNow() {
3016   clockNow = 0;
3017 }
3018
3019 function Timer() {
3020   this._call =
3021   this._time =
3022   this._next = null;
3023 }
3024
3025 Timer.prototype = timer.prototype = {
3026   constructor: Timer,
3027   restart: function(callback, delay, time) {
3028     if (typeof callback !== "function") throw new TypeError("callback is not a function");
3029     time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);
3030     if (!this._next && taskTail !== this) {
3031       if (taskTail) taskTail._next = this;
3032       else taskHead = this;
3033       taskTail = this;
3034     }
3035     this._call = callback;
3036     this._time = time;
3037     sleep();
3038   },
3039   stop: function() {
3040     if (this._call) {
3041       this._call = null;
3042       this._time = Infinity;
3043       sleep();
3044     }
3045   }
3046 };
3047
3048 function timer(callback, delay, time) {
3049   var t = new Timer;
3050   t.restart(callback, delay, time);
3051   return t;
3052 }
3053
3054 function timerFlush() {
3055   now(); // Get the current time, if not already set.
3056   ++frame; // Pretend we’ve set an alarm, if we haven’t already.
3057   var t = taskHead, e;
3058   while (t) {
3059     if ((e = clockNow - t._time) >= 0) t._call.call(null, e);
3060     t = t._next;
3061   }
3062   --frame;
3063 }
3064
3065 function wake() {
3066   clockNow = (clockLast = clock.now()) + clockSkew;
3067   frame = timeout = 0;
3068   try {
3069     timerFlush();
3070   } finally {
3071     frame = 0;
3072     nap();
3073     clockNow = 0;
3074   }
3075 }
3076
3077 function poke() {
3078   var now = clock.now(), delay = now - clockLast;
3079   if (delay > pokeDelay) clockSkew -= delay, clockLast = now;
3080 }
3081
3082 function nap() {
3083   var t0, t1 = taskHead, t2, time = Infinity;
3084   while (t1) {
3085     if (t1._call) {
3086       if (time > t1._time) time = t1._time;
3087       t0 = t1, t1 = t1._next;
3088     } else {
3089       t2 = t1._next, t1._next = null;
3090       t1 = t0 ? t0._next = t2 : taskHead = t2;
3091     }
3092   }
3093   taskTail = t0;
3094   sleep(time);
3095 }
3096
3097 function sleep(time) {
3098   if (frame) return; // Soonest alarm already set, or will be.
3099   if (timeout) timeout = clearTimeout(timeout);
3100   var delay = time - clockNow; // Strictly less than if we recomputed clockNow.
3101   if (delay > 24) {
3102     if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew);
3103     if (interval) interval = clearInterval(interval);
3104   } else {
3105     if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay);
3106     frame = 1, setFrame(wake);
3107   }
3108 }
3109
3110 function d3_timeout(callback, delay, time) {
3111   var t = new Timer;
3112   delay = delay == null ? 0 : +delay;
3113   t.restart(function(elapsed) {
3114     t.stop();
3115     callback(elapsed + delay);
3116   }, delay, time);
3117   return t;
3118 }
3119
3120 function interval$1(callback, delay, time) {
3121   var t = new Timer, total = delay;
3122   if (delay == null) return t.restart(callback, delay, time), t;
3123   delay = +delay, time = time == null ? now() : +time;
3124   t.restart(function tick(elapsed) {
3125     elapsed += total;
3126     t.restart(tick, total += delay, time);
3127     callback(elapsed);
3128   }, delay, time);
3129   return t;
3130 }
3131
3132 var emptyOn = dispatch("start", "end", "interrupt");
3133 var emptyTween = [];
3134
3135 var CREATED = 0;
3136 var SCHEDULED = 1;
3137 var STARTING = 2;
3138 var STARTED = 3;
3139 var RUNNING = 4;
3140 var ENDING = 5;
3141 var ENDED = 6;
3142
3143 function schedule(node, name, id, index, group, timing) {
3144   var schedules = node.__transition;
3145   if (!schedules) node.__transition = {};
3146   else if (id in schedules) return;
3147   create(node, id, {
3148     name: name,
3149     index: index, // For context during callback.
3150     group: group, // For context during callback.
3151     on: emptyOn,
3152     tween: emptyTween,
3153     time: timing.time,
3154     delay: timing.delay,
3155     duration: timing.duration,
3156     ease: timing.ease,
3157     timer: null,
3158     state: CREATED
3159   });
3160 }
3161
3162 function init(node, id) {
3163   var schedule = get$1(node, id);
3164   if (schedule.state > CREATED) throw new Error("too late; already scheduled");
3165   return schedule;
3166 }
3167
3168 function set$1(node, id) {
3169   var schedule = get$1(node, id);
3170   if (schedule.state > STARTING) throw new Error("too late; already started");
3171   return schedule;
3172 }
3173
3174 function get$1(node, id) {
3175   var schedule = node.__transition;
3176   if (!schedule || !(schedule = schedule[id])) throw new Error("transition not found");
3177   return schedule;
3178 }
3179
3180 function create(node, id, self) {
3181   var schedules = node.__transition,
3182       tween;
3183
3184   // Initialize the self timer when the transition is created.
3185   // Note the actual delay is not known until the first callback!
3186   schedules[id] = self;
3187   self.timer = timer(schedule, 0, self.time);
3188
3189   function schedule(elapsed) {
3190     self.state = SCHEDULED;
3191     self.timer.restart(start, self.delay, self.time);
3192
3193     // If the elapsed delay is less than our first sleep, start immediately.
3194     if (self.delay <= elapsed) start(elapsed - self.delay);
3195   }
3196
3197   function start(elapsed) {
3198     var i, j, n, o;
3199
3200     // If the state is not SCHEDULED, then we previously errored on start.
3201     if (self.state !== SCHEDULED) return stop();
3202
3203     for (i in schedules) {
3204       o = schedules[i];
3205       if (o.name !== self.name) continue;
3206
3207       // While this element already has a starting transition during this frame,
3208       // defer starting an interrupting transition until that transition has a
3209       // chance to tick (and possibly end); see d3/d3-transition#54!
3210       if (o.state === STARTED) return d3_timeout(start);
3211
3212       // Interrupt the active transition, if any.
3213       // Dispatch the interrupt event.
3214       if (o.state === RUNNING) {
3215         o.state = ENDED;
3216         o.timer.stop();
3217         o.on.call("interrupt", node, node.__data__, o.index, o.group);
3218         delete schedules[i];
3219       }
3220
3221       // Cancel any pre-empted transitions. No interrupt event is dispatched
3222       // because the cancelled transitions never started. Note that this also
3223       // removes this transition from the pending list!
3224       else if (+i < id) {
3225         o.state = ENDED;
3226         o.timer.stop();
3227         delete schedules[i];
3228       }
3229     }
3230
3231     // Defer the first tick to end of the current frame; see d3/d3#1576.
3232     // Note the transition may be canceled after start and before the first tick!
3233     // Note this must be scheduled before the start event; see d3/d3-transition#16!
3234     // Assuming this is successful, subsequent callbacks go straight to tick.
3235     d3_timeout(function() {
3236       if (self.state === STARTED) {
3237         self.state = RUNNING;
3238         self.timer.restart(tick, self.delay, self.time);
3239         tick(elapsed);
3240       }
3241     });
3242
3243     // Dispatch the start event.
3244     // Note this must be done before the tween are initialized.
3245     self.state = STARTING;
3246     self.on.call("start", node, node.__data__, self.index, self.group);
3247     if (self.state !== STARTING) return; // interrupted
3248     self.state = STARTED;
3249
3250     // Initialize the tween, deleting null tween.
3251     tween = new Array(n = self.tween.length);
3252     for (i = 0, j = -1; i < n; ++i) {
3253       if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) {
3254         tween[++j] = o;
3255       }
3256     }
3257     tween.length = j + 1;
3258   }
3259
3260   function tick(elapsed) {
3261     var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1),
3262         i = -1,
3263         n = tween.length;
3264
3265     while (++i < n) {
3266       tween[i].call(null, t);
3267     }
3268
3269     // Dispatch the end event.
3270     if (self.state === ENDING) {
3271       self.on.call("end", node, node.__data__, self.index, self.group);
3272       stop();
3273     }
3274   }
3275
3276   function stop() {
3277     self.state = ENDED;
3278     self.timer.stop();
3279     delete schedules[id];
3280     for (var i in schedules) return; // eslint-disable-line no-unused-vars
3281     delete node.__transition;
3282   }
3283 }
3284
3285 function interrupt(node, name) {
3286   var schedules = node.__transition,
3287       schedule$$1,
3288       active,
3289       empty = true,
3290       i;
3291
3292   if (!schedules) return;
3293
3294   name = name == null ? null : name + "";
3295
3296   for (i in schedules) {
3297     if ((schedule$$1 = schedules[i]).name !== name) { empty = false; continue; }
3298     active = schedule$$1.state > STARTING && schedule$$1.state < ENDING;
3299     schedule$$1.state = ENDED;
3300     schedule$$1.timer.stop();
3301     if (active) schedule$$1.on.call("interrupt", node, node.__data__, schedule$$1.index, schedule$$1.group);
3302     delete schedules[i];
3303   }
3304
3305   if (empty) delete node.__transition;
3306 }
3307
3308 function selection_interrupt(name) {
3309   return this.each(function() {
3310     interrupt(this, name);
3311   });
3312 }
3313
3314 function tweenRemove(id, name) {
3315   var tween0, tween1;
3316   return function() {
3317     var schedule$$1 = set$1(this, id),
3318         tween = schedule$$1.tween;
3319
3320     // If this node shared tween with the previous node,
3321     // just assign the updated shared tween and we’re done!
3322     // Otherwise, copy-on-write.
3323     if (tween !== tween0) {
3324       tween1 = tween0 = tween;
3325       for (var i = 0, n = tween1.length; i < n; ++i) {
3326         if (tween1[i].name === name) {
3327           tween1 = tween1.slice();
3328           tween1.splice(i, 1);
3329           break;
3330         }
3331       }
3332     }
3333
3334     schedule$$1.tween = tween1;
3335   };
3336 }
3337
3338 function tweenFunction(id, name, value) {
3339   var tween0, tween1;
3340   if (typeof value !== "function") throw new Error;
3341   return function() {
3342     var schedule$$1 = set$1(this, id),
3343         tween = schedule$$1.tween;
3344
3345     // If this node shared tween with the previous node,
3346     // just assign the updated shared tween and we’re done!
3347     // Otherwise, copy-on-write.
3348     if (tween !== tween0) {
3349       tween1 = (tween0 = tween).slice();
3350       for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) {
3351         if (tween1[i].name === name) {
3352           tween1[i] = t;
3353           break;
3354         }
3355       }
3356       if (i === n) tween1.push(t);
3357     }
3358
3359     schedule$$1.tween = tween1;
3360   };
3361 }
3362
3363 function transition_tween(name, value) {
3364   var id = this._id;
3365
3366   name += "";
3367
3368   if (arguments.length < 2) {
3369     var tween = get$1(this.node(), id).tween;
3370     for (var i = 0, n = tween.length, t; i < n; ++i) {
3371       if ((t = tween[i]).name === name) {
3372         return t.value;
3373       }
3374     }
3375     return null;
3376   }
3377
3378   return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value));
3379 }
3380
3381 function tweenValue(transition, name, value) {
3382   var id = transition._id;
3383
3384   transition.each(function() {
3385     var schedule$$1 = set$1(this, id);
3386     (schedule$$1.value || (schedule$$1.value = {}))[name] = value.apply(this, arguments);
3387   });
3388
3389   return function(node) {
3390     return get$1(node, id).value[name];
3391   };
3392 }
3393
3394 function interpolate(a, b) {
3395   var c;
3396   return (typeof b === "number" ? d3_interpolateNumber
3397       : b instanceof color ? d3_interpolateRgb
3398       : (c = color(b)) ? (b = c, d3_interpolateRgb)
3399       : interpolateString)(a, b);
3400 }
3401
3402 function attrRemove$1(name) {
3403   return function() {
3404     this.removeAttribute(name);
3405   };
3406 }
3407
3408 function attrRemoveNS$1(fullname) {
3409   return function() {
3410     this.removeAttributeNS(fullname.space, fullname.local);
3411   };
3412 }
3413
3414 function attrConstant$1(name, interpolate$$1, value1) {
3415   var value00,
3416       interpolate0;
3417   return function() {
3418     var value0 = this.getAttribute(name);
3419     return value0 === value1 ? null
3420         : value0 === value00 ? interpolate0
3421         : interpolate0 = interpolate$$1(value00 = value0, value1);
3422   };
3423 }
3424
3425 function attrConstantNS$1(fullname, interpolate$$1, value1) {
3426   var value00,
3427       interpolate0;
3428   return function() {
3429     var value0 = this.getAttributeNS(fullname.space, fullname.local);
3430     return value0 === value1 ? null
3431         : value0 === value00 ? interpolate0
3432         : interpolate0 = interpolate$$1(value00 = value0, value1);
3433   };
3434 }
3435
3436 function attrFunction$1(name, interpolate$$1, value) {
3437   var value00,
3438       value10,
3439       interpolate0;
3440   return function() {
3441     var value0, value1 = value(this);
3442     if (value1 == null) return void this.removeAttribute(name);
3443     value0 = this.getAttribute(name);
3444     return value0 === value1 ? null
3445         : value0 === value00 && value1 === value10 ? interpolate0
3446         : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
3447   };
3448 }
3449
3450 function attrFunctionNS$1(fullname, interpolate$$1, value) {
3451   var value00,
3452       value10,
3453       interpolate0;
3454   return function() {
3455     var value0, value1 = value(this);
3456     if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local);
3457     value0 = this.getAttributeNS(fullname.space, fullname.local);
3458     return value0 === value1 ? null
3459         : value0 === value00 && value1 === value10 ? interpolate0
3460         : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
3461   };
3462 }
3463
3464 function transition_attr(name, value) {
3465   var fullname = namespace(name), i = fullname === "transform" ? interpolateTransformSvg : interpolate;
3466   return this.attrTween(name, typeof value === "function"
3467       ? (fullname.local ? attrFunctionNS$1 : attrFunction$1)(fullname, i, tweenValue(this, "attr." + name, value))
3468       : value == null ? (fullname.local ? attrRemoveNS$1 : attrRemove$1)(fullname)
3469       : (fullname.local ? attrConstantNS$1 : attrConstant$1)(fullname, i, value + ""));
3470 }
3471
3472 function attrTweenNS(fullname, value) {
3473   function tween() {
3474     var node = this, i = value.apply(node, arguments);
3475     return i && function(t) {
3476       node.setAttributeNS(fullname.space, fullname.local, i(t));
3477     };
3478   }
3479   tween._value = value;
3480   return tween;
3481 }
3482
3483 function attrTween(name, value) {
3484   function tween() {
3485     var node = this, i = value.apply(node, arguments);
3486     return i && function(t) {
3487       node.setAttribute(name, i(t));
3488     };
3489   }
3490   tween._value = value;
3491   return tween;
3492 }
3493
3494 function transition_attrTween(name, value) {
3495   var key = "attr." + name;
3496   if (arguments.length < 2) return (key = this.tween(key)) && key._value;
3497   if (value == null) return this.tween(key, null);
3498   if (typeof value !== "function") throw new Error;
3499   var fullname = namespace(name);
3500   return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value));
3501 }
3502
3503 function delayFunction(id, value) {
3504   return function() {
3505     init(this, id).delay = +value.apply(this, arguments);
3506   };
3507 }
3508
3509 function delayConstant(id, value) {
3510   return value = +value, function() {
3511     init(this, id).delay = value;
3512   };
3513 }
3514
3515 function transition_delay(value) {
3516   var id = this._id;
3517
3518   return arguments.length
3519       ? this.each((typeof value === "function"
3520           ? delayFunction
3521           : delayConstant)(id, value))
3522       : get$1(this.node(), id).delay;
3523 }
3524
3525 function durationFunction(id, value) {
3526   return function() {
3527     set$1(this, id).duration = +value.apply(this, arguments);
3528   };
3529 }
3530
3531 function durationConstant(id, value) {
3532   return value = +value, function() {
3533     set$1(this, id).duration = value;
3534   };
3535 }
3536
3537 function transition_duration(value) {
3538   var id = this._id;
3539
3540   return arguments.length
3541       ? this.each((typeof value === "function"
3542           ? durationFunction
3543           : durationConstant)(id, value))
3544       : get$1(this.node(), id).duration;
3545 }
3546
3547 function easeConstant(id, value) {
3548   if (typeof value !== "function") throw new Error;
3549   return function() {
3550     set$1(this, id).ease = value;
3551   };
3552 }
3553
3554 function transition_ease(value) {
3555   var id = this._id;
3556
3557   return arguments.length
3558       ? this.each(easeConstant(id, value))
3559       : get$1(this.node(), id).ease;
3560 }
3561
3562 function transition_filter(match) {
3563   if (typeof match !== "function") match = matcher$1(match);
3564
3565   for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
3566     for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
3567       if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
3568         subgroup.push(node);
3569       }
3570     }
3571   }
3572
3573   return new Transition(subgroups, this._parents, this._name, this._id);
3574 }
3575
3576 function transition_merge(transition$$1) {
3577   if (transition$$1._id !== this._id) throw new Error;
3578
3579   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) {
3580     for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
3581       if (node = group0[i] || group1[i]) {
3582         merge[i] = node;
3583       }
3584     }
3585   }
3586
3587   for (; j < m0; ++j) {
3588     merges[j] = groups0[j];
3589   }
3590
3591   return new Transition(merges, this._parents, this._name, this._id);
3592 }
3593
3594 function start(name) {
3595   return (name + "").trim().split(/^|\s+/).every(function(t) {
3596     var i = t.indexOf(".");
3597     if (i >= 0) t = t.slice(0, i);
3598     return !t || t === "start";
3599   });
3600 }
3601
3602 function onFunction(id, name, listener) {
3603   var on0, on1, sit = start(name) ? init : set$1;
3604   return function() {
3605     var schedule$$1 = sit(this, id),
3606         on = schedule$$1.on;
3607
3608     // If this node shared a dispatch with the previous node,
3609     // just assign the updated shared dispatch and we’re done!
3610     // Otherwise, copy-on-write.
3611     if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener);
3612
3613     schedule$$1.on = on1;
3614   };
3615 }
3616
3617 function transition_on(name, listener) {
3618   var id = this._id;
3619
3620   return arguments.length < 2
3621       ? get$1(this.node(), id).on.on(name)
3622       : this.each(onFunction(id, name, listener));
3623 }
3624
3625 function removeFunction(id) {
3626   return function() {
3627     var parent = this.parentNode;
3628     for (var i in this.__transition) if (+i !== id) return;
3629     if (parent) parent.removeChild(this);
3630   };
3631 }
3632
3633 function transition_remove() {
3634   return this.on("end.remove", removeFunction(this._id));
3635 }
3636
3637 function transition_select(select) {
3638   var name = this._name,
3639       id = this._id;
3640
3641   if (typeof select !== "function") select = selector(select);
3642
3643   for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
3644     for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
3645       if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {
3646         if ("__data__" in node) subnode.__data__ = node.__data__;
3647         subgroup[i] = subnode;
3648         schedule(subgroup[i], name, id, i, subgroup, get$1(node, id));
3649       }
3650     }
3651   }
3652
3653   return new Transition(subgroups, this._parents, name, id);
3654 }
3655
3656 function transition_selectAll(select) {
3657   var name = this._name,
3658       id = this._id;
3659
3660   if (typeof select !== "function") select = selectorAll(select);
3661
3662   for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
3663     for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
3664       if (node = group[i]) {
3665         for (var children = select.call(node, node.__data__, i, group), child, inherit = get$1(node, id), k = 0, l = children.length; k < l; ++k) {
3666           if (child = children[k]) {
3667             schedule(child, name, id, k, children, inherit);
3668           }
3669         }
3670         subgroups.push(children);
3671         parents.push(node);
3672       }
3673     }
3674   }
3675
3676   return new Transition(subgroups, parents, name, id);
3677 }
3678
3679 var Selection$1 = selection.prototype.constructor;
3680
3681 function transition_selection() {
3682   return new Selection$1(this._groups, this._parents);
3683 }
3684
3685 function styleRemove$1(name, interpolate$$1) {
3686   var value00,
3687       value10,
3688       interpolate0;
3689   return function() {
3690     var value0 = styleValue(this, name),
3691         value1 = (this.style.removeProperty(name), styleValue(this, name));
3692     return value0 === value1 ? null
3693         : value0 === value00 && value1 === value10 ? interpolate0
3694         : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
3695   };
3696 }
3697
3698 function styleRemoveEnd(name) {
3699   return function() {
3700     this.style.removeProperty(name);
3701   };
3702 }
3703
3704 function styleConstant$1(name, interpolate$$1, value1) {
3705   var value00,
3706       interpolate0;
3707   return function() {
3708     var value0 = styleValue(this, name);
3709     return value0 === value1 ? null
3710         : value0 === value00 ? interpolate0
3711         : interpolate0 = interpolate$$1(value00 = value0, value1);
3712   };
3713 }
3714
3715 function styleFunction$1(name, interpolate$$1, value) {
3716   var value00,
3717       value10,
3718       interpolate0;
3719   return function() {
3720     var value0 = styleValue(this, name),
3721         value1 = value(this);
3722     if (value1 == null) value1 = (this.style.removeProperty(name), styleValue(this, name));
3723     return value0 === value1 ? null
3724         : value0 === value00 && value1 === value10 ? interpolate0
3725         : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
3726   };
3727 }
3728
3729 function transition_style(name, value, priority) {
3730   var i = (name += "") === "transform" ? interpolateTransformCss : interpolate;
3731   return value == null ? this
3732           .styleTween(name, styleRemove$1(name, i))
3733           .on("end.style." + name, styleRemoveEnd(name))
3734       : this.styleTween(name, typeof value === "function"
3735           ? styleFunction$1(name, i, tweenValue(this, "style." + name, value))
3736           : styleConstant$1(name, i, value + ""), priority);
3737 }
3738
3739 function styleTween(name, value, priority) {
3740   function tween() {
3741     var node = this, i = value.apply(node, arguments);
3742     return i && function(t) {
3743       node.style.setProperty(name, i(t), priority);
3744     };
3745   }
3746   tween._value = value;
3747   return tween;
3748 }
3749
3750 function transition_styleTween(name, value, priority) {
3751   var key = "style." + (name += "");
3752   if (arguments.length < 2) return (key = this.tween(key)) && key._value;
3753   if (value == null) return this.tween(key, null);
3754   if (typeof value !== "function") throw new Error;
3755   return this.tween(key, styleTween(name, value, priority == null ? "" : priority));
3756 }
3757
3758 function textConstant$1(value) {
3759   return function() {
3760     this.textContent = value;
3761   };
3762 }
3763
3764 function textFunction$1(value) {
3765   return function() {
3766     var value1 = value(this);
3767     this.textContent = value1 == null ? "" : value1;
3768   };
3769 }
3770
3771 function transition_text(value) {
3772   return this.tween("text", typeof value === "function"
3773       ? textFunction$1(tweenValue(this, "text", value))
3774       : textConstant$1(value == null ? "" : value + ""));
3775 }
3776
3777 function transition_transition() {
3778   var name = this._name,
3779       id0 = this._id,
3780       id1 = newId();
3781
3782   for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {
3783     for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
3784       if (node = group[i]) {
3785         var inherit = get$1(node, id0);
3786         schedule(node, name, id1, i, group, {
3787           time: inherit.time + inherit.delay + inherit.duration,
3788           delay: 0,
3789           duration: inherit.duration,
3790           ease: inherit.ease
3791         });
3792       }
3793     }
3794   }
3795
3796   return new Transition(groups, this._parents, name, id1);
3797 }
3798
3799 var id = 0;
3800
3801 function Transition(groups, parents, name, id) {
3802   this._groups = groups;
3803   this._parents = parents;
3804   this._name = name;
3805   this._id = id;
3806 }
3807
3808 function transition(name) {
3809   return selection().transition(name);
3810 }
3811
3812 function newId() {
3813   return ++id;
3814 }
3815
3816 var selection_prototype = selection.prototype;
3817
3818 Transition.prototype = transition.prototype = {
3819   constructor: Transition,
3820   select: transition_select,
3821   selectAll: transition_selectAll,
3822   filter: transition_filter,
3823   merge: transition_merge,
3824   selection: transition_selection,
3825   transition: transition_transition,
3826   call: selection_prototype.call,
3827   nodes: selection_prototype.nodes,
3828   node: selection_prototype.node,
3829   size: selection_prototype.size,
3830   empty: selection_prototype.empty,
3831   each: selection_prototype.each,
3832   on: transition_on,
3833   attr: transition_attr,
3834   attrTween: transition_attrTween,
3835   style: transition_style,
3836   styleTween: transition_styleTween,
3837   text: transition_text,
3838   remove: transition_remove,
3839   tween: transition_tween,
3840   delay: transition_delay,
3841   duration: transition_duration,
3842   ease: transition_ease
3843 };
3844
3845 function linear$1(t) {
3846   return +t;
3847 }
3848
3849 function quadIn(t) {
3850   return t * t;
3851 }
3852
3853 function quadOut(t) {
3854   return t * (2 - t);
3855 }
3856
3857 function quadInOut(t) {
3858   return ((t *= 2) <= 1 ? t * t : --t * (2 - t) + 1) / 2;
3859 }
3860
3861 function cubicIn(t) {
3862   return t * t * t;
3863 }
3864
3865 function cubicOut(t) {
3866   return --t * t * t + 1;
3867 }
3868
3869 function cubicInOut(t) {
3870   return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
3871 }
3872
3873 var exponent = 3;
3874
3875 var polyIn = (function custom(e) {
3876   e = +e;
3877
3878   function polyIn(t) {
3879     return Math.pow(t, e);
3880   }
3881
3882   polyIn.exponent = custom;
3883
3884   return polyIn;
3885 })(exponent);
3886
3887 var polyOut = (function custom(e) {
3888   e = +e;
3889
3890   function polyOut(t) {
3891     return 1 - Math.pow(1 - t, e);
3892   }
3893
3894   polyOut.exponent = custom;
3895
3896   return polyOut;
3897 })(exponent);
3898
3899 var polyInOut = (function custom(e) {
3900   e = +e;
3901
3902   function polyInOut(t) {
3903     return ((t *= 2) <= 1 ? Math.pow(t, e) : 2 - Math.pow(2 - t, e)) / 2;
3904   }
3905
3906   polyInOut.exponent = custom;
3907
3908   return polyInOut;
3909 })(exponent);
3910
3911 var pi = Math.PI;
3912 var halfPi = pi / 2;
3913
3914 function sinIn(t) {
3915   return 1 - Math.cos(t * halfPi);
3916 }
3917
3918 function sinOut(t) {
3919   return Math.sin(t * halfPi);
3920 }
3921
3922 function sinInOut(t) {
3923   return (1 - Math.cos(pi * t)) / 2;
3924 }
3925
3926 function expIn(t) {
3927   return Math.pow(2, 10 * t - 10);
3928 }
3929
3930 function expOut(t) {
3931   return 1 - Math.pow(2, -10 * t);
3932 }
3933
3934 function expInOut(t) {
3935   return ((t *= 2) <= 1 ? Math.pow(2, 10 * t - 10) : 2 - Math.pow(2, 10 - 10 * t)) / 2;
3936 }
3937
3938 function circleIn(t) {
3939   return 1 - Math.sqrt(1 - t * t);
3940 }
3941
3942 function circleOut(t) {
3943   return Math.sqrt(1 - --t * t);
3944 }
3945
3946 function circleInOut(t) {
3947   return ((t *= 2) <= 1 ? 1 - Math.sqrt(1 - t * t) : Math.sqrt(1 - (t -= 2) * t) + 1) / 2;
3948 }
3949
3950 var b1 = 4 / 11;
3951 var b2 = 6 / 11;
3952 var b3 = 8 / 11;
3953 var b4 = 3 / 4;
3954 var b5 = 9 / 11;
3955 var b6 = 10 / 11;
3956 var b7 = 15 / 16;
3957 var b8 = 21 / 22;
3958 var b9 = 63 / 64;
3959 var b0 = 1 / b1 / b1;
3960
3961 function bounceIn(t) {
3962   return 1 - bounceOut(1 - t);
3963 }
3964
3965 function bounceOut(t) {
3966   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;
3967 }
3968
3969 function bounceInOut(t) {
3970   return ((t *= 2) <= 1 ? 1 - bounceOut(1 - t) : bounceOut(t - 1) + 1) / 2;
3971 }
3972
3973 var overshoot = 1.70158;
3974
3975 var backIn = (function custom(s) {
3976   s = +s;
3977
3978   function backIn(t) {
3979     return t * t * ((s + 1) * t - s);
3980   }
3981
3982   backIn.overshoot = custom;
3983
3984   return backIn;
3985 })(overshoot);
3986
3987 var backOut = (function custom(s) {
3988   s = +s;
3989
3990   function backOut(t) {
3991     return --t * t * ((s + 1) * t + s) + 1;
3992   }
3993
3994   backOut.overshoot = custom;
3995
3996   return backOut;
3997 })(overshoot);
3998
3999 var backInOut = (function custom(s) {
4000   s = +s;
4001
4002   function backInOut(t) {
4003     return ((t *= 2) < 1 ? t * t * ((s + 1) * t - s) : (t -= 2) * t * ((s + 1) * t + s) + 2) / 2;
4004   }
4005
4006   backInOut.overshoot = custom;
4007
4008   return backInOut;
4009 })(overshoot);
4010
4011 var tau = 2 * Math.PI;
4012 var amplitude = 1;
4013 var period = 0.3;
4014
4015 var elasticIn = (function custom(a, p) {
4016   var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
4017
4018   function elasticIn(t) {
4019     return a * Math.pow(2, 10 * --t) * Math.sin((s - t) / p);
4020   }
4021
4022   elasticIn.amplitude = function(a) { return custom(a, p * tau); };
4023   elasticIn.period = function(p) { return custom(a, p); };
4024
4025   return elasticIn;
4026 })(amplitude, period);
4027
4028 var elasticOut = (function custom(a, p) {
4029   var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
4030
4031   function elasticOut(t) {
4032     return 1 - a * Math.pow(2, -10 * (t = +t)) * Math.sin((t + s) / p);
4033   }
4034
4035   elasticOut.amplitude = function(a) { return custom(a, p * tau); };
4036   elasticOut.period = function(p) { return custom(a, p); };
4037
4038   return elasticOut;
4039 })(amplitude, period);
4040
4041 var elasticInOut = (function custom(a, p) {
4042   var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
4043
4044   function elasticInOut(t) {
4045     return ((t = t * 2 - 1) < 0
4046         ? a * Math.pow(2, 10 * t) * Math.sin((s - t) / p)
4047         : 2 - a * Math.pow(2, -10 * t) * Math.sin((s + t) / p)) / 2;
4048   }
4049
4050   elasticInOut.amplitude = function(a) { return custom(a, p * tau); };
4051   elasticInOut.period = function(p) { return custom(a, p); };
4052
4053   return elasticInOut;
4054 })(amplitude, period);
4055
4056 var defaultTiming = {
4057   time: null, // Set on use.
4058   delay: 0,
4059   duration: 250,
4060   ease: cubicInOut
4061 };
4062
4063 function inherit(node, id) {
4064   var timing;
4065   while (!(timing = node.__transition) || !(timing = timing[id])) {
4066     if (!(node = node.parentNode)) {
4067       return defaultTiming.time = now(), defaultTiming;
4068     }
4069   }
4070   return timing;
4071 }
4072
4073 function selection_transition(name) {
4074   var id,
4075       timing;
4076
4077   if (name instanceof Transition) {
4078     id = name._id, name = name._name;
4079   } else {
4080     id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + "";
4081   }
4082
4083   for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {
4084     for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
4085       if (node = group[i]) {
4086         schedule(node, name, id, i, group, timing || inherit(node, id));
4087       }
4088     }
4089   }
4090
4091   return new Transition(groups, this._parents, name, id);
4092 }
4093
4094 selection.prototype.interrupt = selection_interrupt;
4095 selection.prototype.transition = selection_transition;
4096
4097 var root$1 = [null];
4098
4099 function active(node, name) {
4100   var schedules = node.__transition,
4101       schedule$$1,
4102       i;
4103
4104   if (schedules) {
4105     name = name == null ? null : name + "";
4106     for (i in schedules) {
4107       if ((schedule$$1 = schedules[i]).state > SCHEDULED && schedule$$1.name === name) {
4108         return new Transition([[node]], root$1, name, +i);
4109       }
4110     }
4111   }
4112
4113   return null;
4114 }
4115
4116 function constant$4(x) {
4117   return function() {
4118     return x;
4119   };
4120 }
4121
4122 function BrushEvent(target, type, selection) {
4123   this.target = target;
4124   this.type = type;
4125   this.selection = selection;
4126 }
4127
4128 function nopropagation$1() {
4129   event.stopImmediatePropagation();
4130 }
4131
4132 function noevent$1() {
4133   event.preventDefault();
4134   event.stopImmediatePropagation();
4135 }
4136
4137 var MODE_DRAG = {name: "drag"};
4138 var MODE_SPACE = {name: "space"};
4139 var MODE_HANDLE = {name: "handle"};
4140 var MODE_CENTER = {name: "center"};
4141
4142 var X = {
4143   name: "x",
4144   handles: ["e", "w"].map(type),
4145   input: function(x, e) { return x && [[x[0], e[0][1]], [x[1], e[1][1]]]; },
4146   output: function(xy) { return xy && [xy[0][0], xy[1][0]]; }
4147 };
4148
4149 var Y = {
4150   name: "y",
4151   handles: ["n", "s"].map(type),
4152   input: function(y, e) { return y && [[e[0][0], y[0]], [e[1][0], y[1]]]; },
4153   output: function(xy) { return xy && [xy[0][1], xy[1][1]]; }
4154 };
4155
4156 var XY = {
4157   name: "xy",
4158   handles: ["n", "e", "s", "w", "nw", "ne", "se", "sw"].map(type),
4159   input: function(xy) { return xy; },
4160   output: function(xy) { return xy; }
4161 };
4162
4163 var cursors = {
4164   overlay: "crosshair",
4165   selection: "move",
4166   n: "ns-resize",
4167   e: "ew-resize",
4168   s: "ns-resize",
4169   w: "ew-resize",
4170   nw: "nwse-resize",
4171   ne: "nesw-resize",
4172   se: "nwse-resize",
4173   sw: "nesw-resize"
4174 };
4175
4176 var flipX = {
4177   e: "w",
4178   w: "e",
4179   nw: "ne",
4180   ne: "nw",
4181   se: "sw",
4182   sw: "se"
4183 };
4184
4185 var flipY = {
4186   n: "s",
4187   s: "n",
4188   nw: "sw",
4189   ne: "se",
4190   se: "ne",
4191   sw: "nw"
4192 };
4193
4194 var signsX = {
4195   overlay: +1,
4196   selection: +1,
4197   n: null,
4198   e: +1,
4199   s: null,
4200   w: -1,
4201   nw: -1,
4202   ne: +1,
4203   se: +1,
4204   sw: -1
4205 };
4206
4207 var signsY = {
4208   overlay: +1,
4209   selection: +1,
4210   n: -1,
4211   e: null,
4212   s: +1,
4213   w: null,
4214   nw: -1,
4215   ne: -1,
4216   se: +1,
4217   sw: +1
4218 };
4219
4220 function type(t) {
4221   return {type: t};
4222 }
4223
4224 // Ignore right-click, since that should open the context menu.
4225 function defaultFilter$1() {
4226   return !event.button;
4227 }
4228
4229 function defaultExtent() {
4230   var svg = this.ownerSVGElement || this;
4231   return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];
4232 }
4233
4234 // Like d3.local, but with the name “__brush” rather than auto-generated.
4235 function local$1(node) {
4236   while (!node.__brush) if (!(node = node.parentNode)) return;
4237   return node.__brush;
4238 }
4239
4240 function empty$1(extent) {
4241   return extent[0][0] === extent[1][0]
4242       || extent[0][1] === extent[1][1];
4243 }
4244
4245 function brushSelection(node) {
4246   var state = node.__brush;
4247   return state ? state.dim.output(state.selection) : null;
4248 }
4249
4250 function brushX() {
4251   return brush$1(X);
4252 }
4253
4254 function brushY() {
4255   return brush$1(Y);
4256 }
4257
4258 function brush() {
4259   return brush$1(XY);
4260 }
4261
4262 function brush$1(dim) {
4263   var extent = defaultExtent,
4264       filter = defaultFilter$1,
4265       listeners = dispatch(brush, "start", "brush", "end"),
4266       handleSize = 6,
4267       touchending;
4268
4269   function brush(group) {
4270     var overlay = group
4271         .property("__brush", initialize)
4272       .selectAll(".overlay")
4273       .data([type("overlay")]);
4274
4275     overlay.enter().append("rect")
4276         .attr("class", "overlay")
4277         .attr("pointer-events", "all")
4278         .attr("cursor", cursors.overlay)
4279       .merge(overlay)
4280         .each(function() {
4281           var extent = local$1(this).extent;
4282           d3_select(this)
4283               .attr("x", extent[0][0])
4284               .attr("y", extent[0][1])
4285               .attr("width", extent[1][0] - extent[0][0])
4286               .attr("height", extent[1][1] - extent[0][1]);
4287         });
4288
4289     group.selectAll(".selection")
4290       .data([type("selection")])
4291       .enter().append("rect")
4292         .attr("class", "selection")
4293         .attr("cursor", cursors.selection)
4294         .attr("fill", "#777")
4295         .attr("fill-opacity", 0.3)
4296         .attr("stroke", "#fff")
4297         .attr("shape-rendering", "crispEdges");
4298
4299     var handle = group.selectAll(".handle")
4300       .data(dim.handles, function(d) { return d.type; });
4301
4302     handle.exit().remove();
4303
4304     handle.enter().append("rect")
4305         .attr("class", function(d) { return "handle handle--" + d.type; })
4306         .attr("cursor", function(d) { return cursors[d.type]; });
4307
4308     group
4309         .each(redraw)
4310         .attr("fill", "none")
4311         .attr("pointer-events", "all")
4312         .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)")
4313         .on("mousedown.brush touchstart.brush", started);
4314   }
4315
4316   brush.move = function(group, selection) {
4317     if (group.selection) {
4318       group
4319           .on("start.brush", function() { emitter(this, arguments).beforestart().start(); })
4320           .on("interrupt.brush end.brush", function() { emitter(this, arguments).end(); })
4321           .tween("brush", function() {
4322             var that = this,
4323                 state = that.__brush,
4324                 emit = emitter(that, arguments),
4325                 selection0 = state.selection,
4326                 selection1 = dim.input(typeof selection === "function" ? selection.apply(this, arguments) : selection, state.extent),
4327                 i = d3_interpolate(selection0, selection1);
4328
4329             function tween(t) {
4330               state.selection = t === 1 && empty$1(selection1) ? null : i(t);
4331               redraw.call(that);
4332               emit.brush();
4333             }
4334
4335             return selection0 && selection1 ? tween : tween(1);
4336           });
4337     } else {
4338       group
4339           .each(function() {
4340             var that = this,
4341                 args = arguments,
4342                 state = that.__brush,
4343                 selection1 = dim.input(typeof selection === "function" ? selection.apply(that, args) : selection, state.extent),
4344                 emit = emitter(that, args).beforestart();
4345
4346             interrupt(that);
4347             state.selection = selection1 == null || empty$1(selection1) ? null : selection1;
4348             redraw.call(that);
4349             emit.start().brush().end();
4350           });
4351     }
4352   };
4353
4354   function redraw() {
4355     var group = d3_select(this),
4356         selection = local$1(this).selection;
4357
4358     if (selection) {
4359       group.selectAll(".selection")
4360           .style("display", null)
4361           .attr("x", selection[0][0])
4362           .attr("y", selection[0][1])
4363           .attr("width", selection[1][0] - selection[0][0])
4364           .attr("height", selection[1][1] - selection[0][1]);
4365
4366       group.selectAll(".handle")
4367           .style("display", null)
4368           .attr("x", function(d) { return d.type[d.type.length - 1] === "e" ? selection[1][0] - handleSize / 2 : selection[0][0] - handleSize / 2; })
4369           .attr("y", function(d) { return d.type[0] === "s" ? selection[1][1] - handleSize / 2 : selection[0][1] - handleSize / 2; })
4370           .attr("width", function(d) { return d.type === "n" || d.type === "s" ? selection[1][0] - selection[0][0] + handleSize : handleSize; })
4371           .attr("height", function(d) { return d.type === "e" || d.type === "w" ? selection[1][1] - selection[0][1] + handleSize : handleSize; });
4372     }
4373
4374     else {
4375       group.selectAll(".selection,.handle")
4376           .style("display", "none")
4377           .attr("x", null)
4378           .attr("y", null)
4379           .attr("width", null)
4380           .attr("height", null);
4381     }
4382   }
4383
4384   function emitter(that, args) {
4385     return that.__brush.emitter || new Emitter(that, args);
4386   }
4387
4388   function Emitter(that, args) {
4389     this.that = that;
4390     this.args = args;
4391     this.state = that.__brush;
4392     this.active = 0;
4393   }
4394
4395   Emitter.prototype = {
4396     beforestart: function() {
4397       if (++this.active === 1) this.state.emitter = this, this.starting = true;
4398       return this;
4399     },
4400     start: function() {
4401       if (this.starting) this.starting = false, this.emit("start");
4402       return this;
4403     },
4404     brush: function() {
4405       this.emit("brush");
4406       return this;
4407     },
4408     end: function() {
4409       if (--this.active === 0) delete this.state.emitter, this.emit("end");
4410       return this;
4411     },
4412     emit: function(type) {
4413       customEvent(new BrushEvent(brush, type, dim.output(this.state.selection)), listeners.apply, listeners, [type, this.that, this.args]);
4414     }
4415   };
4416
4417   function started() {
4418     if (event.touches) { if (event.changedTouches.length < event.touches.length) return noevent$1(); }
4419     else if (touchending) return;
4420     if (!filter.apply(this, arguments)) return;
4421
4422     var that = this,
4423         type = event.target.__data__.type,
4424         mode = (event.metaKey ? type = "overlay" : type) === "selection" ? MODE_DRAG : (event.altKey ? MODE_CENTER : MODE_HANDLE),
4425         signX = dim === Y ? null : signsX[type],
4426         signY = dim === X ? null : signsY[type],
4427         state = local$1(that),
4428         extent = state.extent,
4429         selection = state.selection,
4430         W = extent[0][0], w0, w1,
4431         N = extent[0][1], n0, n1,
4432         E = extent[1][0], e0, e1,
4433         S = extent[1][1], s0, s1,
4434         dx,
4435         dy,
4436         moving,
4437         shifting = signX && signY && event.shiftKey,
4438         lockX,
4439         lockY,
4440         point0 = d3_mouse(that),
4441         point = point0,
4442         emit = emitter(that, arguments).beforestart();
4443
4444     if (type === "overlay") {
4445       state.selection = selection = [
4446         [w0 = dim === Y ? W : point0[0], n0 = dim === X ? N : point0[1]],
4447         [e0 = dim === Y ? E : w0, s0 = dim === X ? S : n0]
4448       ];
4449     } else {
4450       w0 = selection[0][0];
4451       n0 = selection[0][1];
4452       e0 = selection[1][0];
4453       s0 = selection[1][1];
4454     }
4455
4456     w1 = w0;
4457     n1 = n0;
4458     e1 = e0;
4459     s1 = s0;
4460
4461     var group = d3_select(that)
4462         .attr("pointer-events", "none");
4463
4464     var overlay = group.selectAll(".overlay")
4465         .attr("cursor", cursors[type]);
4466
4467     if (event.touches) {
4468       group
4469           .on("touchmove.brush", moved, true)
4470           .on("touchend.brush touchcancel.brush", ended, true);
4471     } else {
4472       var view = d3_select(event.view)
4473           .on("keydown.brush", keydowned, true)
4474           .on("keyup.brush", keyupped, true)
4475           .on("mousemove.brush", moved, true)
4476           .on("mouseup.brush", ended, true);
4477
4478       dragDisable(event.view);
4479     }
4480
4481     nopropagation$1();
4482     interrupt(that);
4483     redraw.call(that);
4484     emit.start();
4485
4486     function moved() {
4487       var point1 = d3_mouse(that);
4488       if (shifting && !lockX && !lockY) {
4489         if (Math.abs(point1[0] - point[0]) > Math.abs(point1[1] - point[1])) lockY = true;
4490         else lockX = true;
4491       }
4492       point = point1;
4493       moving = true;
4494       noevent$1();
4495       move();
4496     }
4497
4498     function move() {
4499       var t;
4500
4501       dx = point[0] - point0[0];
4502       dy = point[1] - point0[1];
4503
4504       switch (mode) {
4505         case MODE_SPACE:
4506         case MODE_DRAG: {
4507           if (signX) dx = Math.max(W - w0, Math.min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx;
4508           if (signY) dy = Math.max(N - n0, Math.min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy;
4509           break;
4510         }
4511         case MODE_HANDLE: {
4512           if (signX < 0) dx = Math.max(W - w0, Math.min(E - w0, dx)), w1 = w0 + dx, e1 = e0;
4513           else if (signX > 0) dx = Math.max(W - e0, Math.min(E - e0, dx)), w1 = w0, e1 = e0 + dx;
4514           if (signY < 0) dy = Math.max(N - n0, Math.min(S - n0, dy)), n1 = n0 + dy, s1 = s0;
4515           else if (signY > 0) dy = Math.max(N - s0, Math.min(S - s0, dy)), n1 = n0, s1 = s0 + dy;
4516           break;
4517         }
4518         case MODE_CENTER: {
4519           if (signX) w1 = Math.max(W, Math.min(E, w0 - dx * signX)), e1 = Math.max(W, Math.min(E, e0 + dx * signX));
4520           if (signY) n1 = Math.max(N, Math.min(S, n0 - dy * signY)), s1 = Math.max(N, Math.min(S, s0 + dy * signY));
4521           break;
4522         }
4523       }
4524
4525       if (e1 < w1) {
4526         signX *= -1;
4527         t = w0, w0 = e0, e0 = t;
4528         t = w1, w1 = e1, e1 = t;
4529         if (type in flipX) overlay.attr("cursor", cursors[type = flipX[type]]);
4530       }
4531
4532       if (s1 < n1) {
4533         signY *= -1;
4534         t = n0, n0 = s0, s0 = t;
4535         t = n1, n1 = s1, s1 = t;
4536         if (type in flipY) overlay.attr("cursor", cursors[type = flipY[type]]);
4537       }
4538
4539       if (state.selection) selection = state.selection; // May be set by brush.move!
4540       if (lockX) w1 = selection[0][0], e1 = selection[1][0];
4541       if (lockY) n1 = selection[0][1], s1 = selection[1][1];
4542
4543       if (selection[0][0] !== w1
4544           || selection[0][1] !== n1
4545           || selection[1][0] !== e1
4546           || selection[1][1] !== s1) {
4547         state.selection = [[w1, n1], [e1, s1]];
4548         redraw.call(that);
4549         emit.brush();
4550       }
4551     }
4552
4553     function ended() {
4554       nopropagation$1();
4555       if (event.touches) {
4556         if (event.touches.length) return;
4557         if (touchending) clearTimeout(touchending);
4558         touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
4559         group.on("touchmove.brush touchend.brush touchcancel.brush", null);
4560       } else {
4561         yesdrag(event.view, moving);
4562         view.on("keydown.brush keyup.brush mousemove.brush mouseup.brush", null);
4563       }
4564       group.attr("pointer-events", "all");
4565       overlay.attr("cursor", cursors.overlay);
4566       if (state.selection) selection = state.selection; // May be set by brush.move (on start)!
4567       if (empty$1(selection)) state.selection = null, redraw.call(that);
4568       emit.end();
4569     }
4570
4571     function keydowned() {
4572       switch (event.keyCode) {
4573         case 16: { // SHIFT
4574           shifting = signX && signY;
4575           break;
4576         }
4577         case 18: { // ALT
4578           if (mode === MODE_HANDLE) {
4579             if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
4580             if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
4581             mode = MODE_CENTER;
4582             move();
4583           }
4584           break;
4585         }
4586         case 32: { // SPACE; takes priority over ALT
4587           if (mode === MODE_HANDLE || mode === MODE_CENTER) {
4588             if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx;
4589             if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy;
4590             mode = MODE_SPACE;
4591             overlay.attr("cursor", cursors.selection);
4592             move();
4593           }
4594           break;
4595         }
4596         default: return;
4597       }
4598       noevent$1();
4599     }
4600
4601     function keyupped() {
4602       switch (event.keyCode) {
4603         case 16: { // SHIFT
4604           if (shifting) {
4605             lockX = lockY = shifting = false;
4606             move();
4607           }
4608           break;
4609         }
4610         case 18: { // ALT
4611           if (mode === MODE_CENTER) {
4612             if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
4613             if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
4614             mode = MODE_HANDLE;
4615             move();
4616           }
4617           break;
4618         }
4619         case 32: { // SPACE
4620           if (mode === MODE_SPACE) {
4621             if (event.altKey) {
4622               if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
4623               if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
4624               mode = MODE_CENTER;
4625             } else {
4626               if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
4627               if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
4628               mode = MODE_HANDLE;
4629             }
4630             overlay.attr("cursor", cursors[type]);
4631             move();
4632           }
4633           break;
4634         }
4635         default: return;
4636       }
4637       noevent$1();
4638     }
4639   }
4640
4641   function initialize() {
4642     var state = this.__brush || {selection: null};
4643     state.extent = extent.apply(this, arguments);
4644     state.dim = dim;
4645     return state;
4646   }
4647
4648   brush.extent = function(_) {
4649     return arguments.length ? (extent = typeof _ === "function" ? _ : constant$4([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), brush) : extent;
4650   };
4651
4652   brush.filter = function(_) {
4653     return arguments.length ? (filter = typeof _ === "function" ? _ : constant$4(!!_), brush) : filter;
4654   };
4655
4656   brush.handleSize = function(_) {
4657     return arguments.length ? (handleSize = +_, brush) : handleSize;
4658   };
4659
4660   brush.on = function() {
4661     var value = listeners.on.apply(listeners, arguments);
4662     return value === listeners ? brush : value;
4663   };
4664
4665   return brush;
4666 }
4667
4668 var cos = Math.cos;
4669 var sin = Math.sin;
4670 var pi$1 = Math.PI;
4671 var halfPi$1 = pi$1 / 2;
4672 var tau$1 = pi$1 * 2;
4673 var max$1 = Math.max;
4674
4675 function compareValue(compare) {
4676   return function(a, b) {
4677     return compare(
4678       a.source.value + a.target.value,
4679       b.source.value + b.target.value
4680     );
4681   };
4682 }
4683
4684 function chord() {
4685   var padAngle = 0,
4686       sortGroups = null,
4687       sortSubgroups = null,
4688       sortChords = null;
4689
4690   function chord(matrix) {
4691     var n = matrix.length,
4692         groupSums = [],
4693         groupIndex = d3_range(n),
4694         subgroupIndex = [],
4695         chords = [],
4696         groups = chords.groups = new Array(n),
4697         subgroups = new Array(n * n),
4698         k,
4699         x,
4700         x0,
4701         dx,
4702         i,
4703         j;
4704
4705     // Compute the sum.
4706     k = 0, i = -1; while (++i < n) {
4707       x = 0, j = -1; while (++j < n) {
4708         x += matrix[i][j];
4709       }
4710       groupSums.push(x);
4711       subgroupIndex.push(d3_range(n));
4712       k += x;
4713     }
4714
4715     // Sort groups…
4716     if (sortGroups) groupIndex.sort(function(a, b) {
4717       return sortGroups(groupSums[a], groupSums[b]);
4718     });
4719
4720     // Sort subgroups…
4721     if (sortSubgroups) subgroupIndex.forEach(function(d, i) {
4722       d.sort(function(a, b) {
4723         return sortSubgroups(matrix[i][a], matrix[i][b]);
4724       });
4725     });
4726
4727     // Convert the sum to scaling factor for [0, 2pi].
4728     // TODO Allow start and end angle to be specified?
4729     // TODO Allow padding to be specified as percentage?
4730     k = max$1(0, tau$1 - padAngle * n) / k;
4731     dx = k ? padAngle : tau$1 / n;
4732
4733     // Compute the start and end angle for each group and subgroup.
4734     // Note: Opera has a bug reordering object literal properties!
4735     x = 0, i = -1; while (++i < n) {
4736       x0 = x, j = -1; while (++j < n) {
4737         var di = groupIndex[i],
4738             dj = subgroupIndex[di][j],
4739             v = matrix[di][dj],
4740             a0 = x,
4741             a1 = x += v * k;
4742         subgroups[dj * n + di] = {
4743           index: di,
4744           subindex: dj,
4745           startAngle: a0,
4746           endAngle: a1,
4747           value: v
4748         };
4749       }
4750       groups[di] = {
4751         index: di,
4752         startAngle: x0,
4753         endAngle: x,
4754         value: groupSums[di]
4755       };
4756       x += dx;
4757     }
4758
4759     // Generate chords for each (non-empty) subgroup-subgroup link.
4760     i = -1; while (++i < n) {
4761       j = i - 1; while (++j < n) {
4762         var source = subgroups[j * n + i],
4763             target = subgroups[i * n + j];
4764         if (source.value || target.value) {
4765           chords.push(source.value < target.value
4766               ? {source: target, target: source}
4767               : {source: source, target: target});
4768         }
4769       }
4770     }
4771
4772     return sortChords ? chords.sort(sortChords) : chords;
4773   }
4774
4775   chord.padAngle = function(_) {
4776     return arguments.length ? (padAngle = max$1(0, _), chord) : padAngle;
4777   };
4778
4779   chord.sortGroups = function(_) {
4780     return arguments.length ? (sortGroups = _, chord) : sortGroups;
4781   };
4782
4783   chord.sortSubgroups = function(_) {
4784     return arguments.length ? (sortSubgroups = _, chord) : sortSubgroups;
4785   };
4786
4787   chord.sortChords = function(_) {
4788     return arguments.length ? (_ == null ? sortChords = null : (sortChords = compareValue(_))._ = _, chord) : sortChords && sortChords._;
4789   };
4790
4791   return chord;
4792 }
4793
4794 var slice$2 = Array.prototype.slice;
4795
4796 function constant$5(x) {
4797   return function() {
4798     return x;
4799   };
4800 }
4801
4802 var pi$2 = Math.PI;
4803 var tau$2 = 2 * pi$2;
4804 var epsilon$1 = 1e-6;
4805 var tauEpsilon = tau$2 - epsilon$1;
4806
4807 function Path() {
4808   this._x0 = this._y0 = // start of current subpath
4809   this._x1 = this._y1 = null; // end of current subpath
4810   this._ = "";
4811 }
4812
4813 function path() {
4814   return new Path;
4815 }
4816
4817 Path.prototype = path.prototype = {
4818   constructor: Path,
4819   moveTo: function(x, y) {
4820     this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y);
4821   },
4822   closePath: function() {
4823     if (this._x1 !== null) {
4824       this._x1 = this._x0, this._y1 = this._y0;
4825       this._ += "Z";
4826     }
4827   },
4828   lineTo: function(x, y) {
4829     this._ += "L" + (this._x1 = +x) + "," + (this._y1 = +y);
4830   },
4831   quadraticCurveTo: function(x1, y1, x, y) {
4832     this._ += "Q" + (+x1) + "," + (+y1) + "," + (this._x1 = +x) + "," + (this._y1 = +y);
4833   },
4834   bezierCurveTo: function(x1, y1, x2, y2, x, y) {
4835     this._ += "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + "," + (this._x1 = +x) + "," + (this._y1 = +y);
4836   },
4837   arcTo: function(x1, y1, x2, y2, r) {
4838     x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;
4839     var x0 = this._x1,
4840         y0 = this._y1,
4841         x21 = x2 - x1,
4842         y21 = y2 - y1,
4843         x01 = x0 - x1,
4844         y01 = y0 - y1,
4845         l01_2 = x01 * x01 + y01 * y01;
4846
4847     // Is the radius negative? Error.
4848     if (r < 0) throw new Error("negative radius: " + r);
4849
4850     // Is this path empty? Move to (x1,y1).
4851     if (this._x1 === null) {
4852       this._ += "M" + (this._x1 = x1) + "," + (this._y1 = y1);
4853     }
4854
4855     // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.
4856     else if (!(l01_2 > epsilon$1)) {}
4857
4858     // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?
4859     // Equivalently, is (x1,y1) coincident with (x2,y2)?
4860     // Or, is the radius zero? Line to (x1,y1).
4861     else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon$1) || !r) {
4862       this._ += "L" + (this._x1 = x1) + "," + (this._y1 = y1);
4863     }
4864
4865     // Otherwise, draw an arc!
4866     else {
4867       var x20 = x2 - x0,
4868           y20 = y2 - y0,
4869           l21_2 = x21 * x21 + y21 * y21,
4870           l20_2 = x20 * x20 + y20 * y20,
4871           l21 = Math.sqrt(l21_2),
4872           l01 = Math.sqrt(l01_2),
4873           l = r * Math.tan((pi$2 - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),
4874           t01 = l / l01,
4875           t21 = l / l21;
4876
4877       // If the start tangent is not coincident with (x0,y0), line to.
4878       if (Math.abs(t01 - 1) > epsilon$1) {
4879         this._ += "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01);
4880       }
4881
4882       this._ += "A" + r + "," + r + ",0,0," + (+(y01 * x20 > x01 * y20)) + "," + (this._x1 = x1 + t21 * x21) + "," + (this._y1 = y1 + t21 * y21);
4883     }
4884   },
4885   arc: function(x, y, r, a0, a1, ccw) {
4886     x = +x, y = +y, r = +r;
4887     var dx = r * Math.cos(a0),
4888         dy = r * Math.sin(a0),
4889         x0 = x + dx,
4890         y0 = y + dy,
4891         cw = 1 ^ ccw,
4892         da = ccw ? a0 - a1 : a1 - a0;
4893
4894     // Is the radius negative? Error.
4895     if (r < 0) throw new Error("negative radius: " + r);
4896
4897     // Is this path empty? Move to (x0,y0).
4898     if (this._x1 === null) {
4899       this._ += "M" + x0 + "," + y0;
4900     }
4901
4902     // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).
4903     else if (Math.abs(this._x1 - x0) > epsilon$1 || Math.abs(this._y1 - y0) > epsilon$1) {
4904       this._ += "L" + x0 + "," + y0;
4905     }
4906
4907     // Is this arc empty? We’re done.
4908     if (!r) return;
4909
4910     // Does the angle go the wrong way? Flip the direction.
4911     if (da < 0) da = da % tau$2 + tau$2;
4912
4913     // Is this a complete circle? Draw two arcs to complete the circle.
4914     if (da > tauEpsilon) {
4915       this._ += "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," + (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 = x0) + "," + (this._y1 = y0);
4916     }
4917
4918     // Is this arc non-empty? Draw an arc!
4919     else if (da > epsilon$1) {
4920       this._ += "A" + r + "," + r + ",0," + (+(da >= pi$2)) + "," + cw + "," + (this._x1 = x + r * Math.cos(a1)) + "," + (this._y1 = y + r * Math.sin(a1));
4921     }
4922   },
4923   rect: function(x, y, w, h) {
4924     this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y) + "h" + (+w) + "v" + (+h) + "h" + (-w) + "Z";
4925   },
4926   toString: function() {
4927     return this._;
4928   }
4929 };
4930
4931 function defaultSource(d) {
4932   return d.source;
4933 }
4934
4935 function defaultTarget(d) {
4936   return d.target;
4937 }
4938
4939 function defaultRadius(d) {
4940   return d.radius;
4941 }
4942
4943 function defaultStartAngle(d) {
4944   return d.startAngle;
4945 }
4946
4947 function defaultEndAngle(d) {
4948   return d.endAngle;
4949 }
4950
4951 function ribbon() {
4952   var source = defaultSource,
4953       target = defaultTarget,
4954       radius = defaultRadius,
4955       startAngle = defaultStartAngle,
4956       endAngle = defaultEndAngle,
4957       context = null;
4958
4959   function ribbon() {
4960     var buffer,
4961         argv = slice$2.call(arguments),
4962         s = source.apply(this, argv),
4963         t = target.apply(this, argv),
4964         sr = +radius.apply(this, (argv[0] = s, argv)),
4965         sa0 = startAngle.apply(this, argv) - halfPi$1,
4966         sa1 = endAngle.apply(this, argv) - halfPi$1,
4967         sx0 = sr * cos(sa0),
4968         sy0 = sr * sin(sa0),
4969         tr = +radius.apply(this, (argv[0] = t, argv)),
4970         ta0 = startAngle.apply(this, argv) - halfPi$1,
4971         ta1 = endAngle.apply(this, argv) - halfPi$1;
4972
4973     if (!context) context = buffer = path();
4974
4975     context.moveTo(sx0, sy0);
4976     context.arc(0, 0, sr, sa0, sa1);
4977     if (sa0 !== ta0 || sa1 !== ta1) { // TODO sr !== tr?
4978       context.quadraticCurveTo(0, 0, tr * cos(ta0), tr * sin(ta0));
4979       context.arc(0, 0, tr, ta0, ta1);
4980     }
4981     context.quadraticCurveTo(0, 0, sx0, sy0);
4982     context.closePath();
4983
4984     if (buffer) return context = null, buffer + "" || null;
4985   }
4986
4987   ribbon.radius = function(_) {
4988     return arguments.length ? (radius = typeof _ === "function" ? _ : constant$5(+_), ribbon) : radius;
4989   };
4990
4991   ribbon.startAngle = function(_) {
4992     return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$5(+_), ribbon) : startAngle;
4993   };
4994
4995   ribbon.endAngle = function(_) {
4996     return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$5(+_), ribbon) : endAngle;
4997   };
4998
4999   ribbon.source = function(_) {
5000     return arguments.length ? (source = _, ribbon) : source;
5001   };
5002
5003   ribbon.target = function(_) {
5004     return arguments.length ? (target = _, ribbon) : target;
5005   };
5006
5007   ribbon.context = function(_) {
5008     return arguments.length ? (context = _ == null ? null : _, ribbon) : context;
5009   };
5010
5011   return ribbon;
5012 }
5013
5014 var prefix = "$";
5015
5016 function Map() {}
5017
5018 Map.prototype = map$1.prototype = {
5019   constructor: Map,
5020   has: function(key) {
5021     return (prefix + key) in this;
5022   },
5023   get: function(key) {
5024     return this[prefix + key];
5025   },
5026   set: function(key, value) {
5027     this[prefix + key] = value;
5028     return this;
5029   },
5030   remove: function(key) {
5031     var property = prefix + key;
5032     return property in this && delete this[property];
5033   },
5034   clear: function() {
5035     for (var property in this) if (property[0] === prefix) delete this[property];
5036   },
5037   keys: function() {
5038     var keys = [];
5039     for (var property in this) if (property[0] === prefix) keys.push(property.slice(1));
5040     return keys;
5041   },
5042   values: function() {
5043     var values = [];
5044     for (var property in this) if (property[0] === prefix) values.push(this[property]);
5045     return values;
5046   },
5047   entries: function() {
5048     var entries = [];
5049     for (var property in this) if (property[0] === prefix) entries.push({key: property.slice(1), value: this[property]});
5050     return entries;
5051   },
5052   size: function() {
5053     var size = 0;
5054     for (var property in this) if (property[0] === prefix) ++size;
5055     return size;
5056   },
5057   empty: function() {
5058     for (var property in this) if (property[0] === prefix) return false;
5059     return true;
5060   },
5061   each: function(f) {
5062     for (var property in this) if (property[0] === prefix) f(this[property], property.slice(1), this);
5063   }
5064 };
5065
5066 function map$1(object, f) {
5067   var map = new Map;
5068
5069   // Copy constructor.
5070   if (object instanceof Map) object.each(function(value, key) { map.set(key, value); });
5071
5072   // Index array by numeric index or specified key function.
5073   else if (Array.isArray(object)) {
5074     var i = -1,
5075         n = object.length,
5076         o;
5077
5078     if (f == null) while (++i < n) map.set(i, object[i]);
5079     else while (++i < n) map.set(f(o = object[i], i, object), o);
5080   }
5081
5082   // Convert object to map.
5083   else if (object) for (var key in object) map.set(key, object[key]);
5084
5085   return map;
5086 }
5087
5088 function nest() {
5089   var keys = [],
5090       sortKeys = [],
5091       sortValues,
5092       rollup,
5093       nest;
5094
5095   function apply(array, depth, createResult, setResult) {
5096     if (depth >= keys.length) {
5097       if (sortValues != null) array.sort(sortValues);
5098       return rollup != null ? rollup(array) : array;
5099     }
5100
5101     var i = -1,
5102         n = array.length,
5103         key = keys[depth++],
5104         keyValue,
5105         value,
5106         valuesByKey = map$1(),
5107         values,
5108         result = createResult();
5109
5110     while (++i < n) {
5111       if (values = valuesByKey.get(keyValue = key(value = array[i]) + "")) {
5112         values.push(value);
5113       } else {
5114         valuesByKey.set(keyValue, [value]);
5115       }
5116     }
5117
5118     valuesByKey.each(function(values, key) {
5119       setResult(result, key, apply(values, depth, createResult, setResult));
5120     });
5121
5122     return result;
5123   }
5124
5125   function entries(map, depth) {
5126     if (++depth > keys.length) return map;
5127     var array, sortKey = sortKeys[depth - 1];
5128     if (rollup != null && depth >= keys.length) array = map.entries();
5129     else array = [], map.each(function(v, k) { array.push({key: k, values: entries(v, depth)}); });
5130     return sortKey != null ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) : array;
5131   }
5132
5133   return nest = {
5134     object: function(array) { return apply(array, 0, createObject, setObject); },
5135     map: function(array) { return apply(array, 0, createMap, setMap); },
5136     entries: function(array) { return entries(apply(array, 0, createMap, setMap), 0); },
5137     key: function(d) { keys.push(d); return nest; },
5138     sortKeys: function(order) { sortKeys[keys.length - 1] = order; return nest; },
5139     sortValues: function(order) { sortValues = order; return nest; },
5140     rollup: function(f) { rollup = f; return nest; }
5141   };
5142 }
5143
5144 function createObject() {
5145   return {};
5146 }
5147
5148 function setObject(object, key, value) {
5149   object[key] = value;
5150 }
5151
5152 function createMap() {
5153   return map$1();
5154 }
5155
5156 function setMap(map, key, value) {
5157   map.set(key, value);
5158 }
5159
5160 function Set() {}
5161
5162 var proto = map$1.prototype;
5163
5164 Set.prototype = set$2.prototype = {
5165   constructor: Set,
5166   has: proto.has,
5167   add: function(value) {
5168     value += "";
5169     this[prefix + value] = value;
5170     return this;
5171   },
5172   remove: proto.remove,
5173   clear: proto.clear,
5174   values: proto.keys,
5175   size: proto.size,
5176   empty: proto.empty,
5177   each: proto.each
5178 };
5179
5180 function set$2(object, f) {
5181   var set = new Set;
5182
5183   // Copy constructor.
5184   if (object instanceof Set) object.each(function(value) { set.add(value); });
5185
5186   // Otherwise, assume it’s an array.
5187   else if (object) {
5188     var i = -1, n = object.length;
5189     if (f == null) while (++i < n) set.add(object[i]);
5190     else while (++i < n) set.add(f(object[i], i, object));
5191   }
5192
5193   return set;
5194 }
5195
5196 function keys(map) {
5197   var keys = [];
5198   for (var key in map) keys.push(key);
5199   return keys;
5200 }
5201
5202 function values(map) {
5203   var values = [];
5204   for (var key in map) values.push(map[key]);
5205   return values;
5206 }
5207
5208 function entries(map) {
5209   var entries = [];
5210   for (var key in map) entries.push({key: key, value: map[key]});
5211   return entries;
5212 }
5213
5214 var EOL = {};
5215 var EOF = {};
5216 var QUOTE = 34;
5217 var NEWLINE = 10;
5218 var RETURN = 13;
5219
5220 function objectConverter(columns) {
5221   return new Function("d", "return {" + columns.map(function(name, i) {
5222     return JSON.stringify(name) + ": d[" + i + "]";
5223   }).join(",") + "}");
5224 }
5225
5226 function customConverter(columns, f) {
5227   var object = objectConverter(columns);
5228   return function(row, i) {
5229     return f(object(row), i, columns);
5230   };
5231 }
5232
5233 // Compute unique columns in order of discovery.
5234 function inferColumns(rows) {
5235   var columnSet = Object.create(null),
5236       columns = [];
5237
5238   rows.forEach(function(row) {
5239     for (var column in row) {
5240       if (!(column in columnSet)) {
5241         columns.push(columnSet[column] = column);
5242       }
5243     }
5244   });
5245
5246   return columns;
5247 }
5248
5249 function dsv(delimiter) {
5250   var reFormat = new RegExp("[\"" + delimiter + "\n\r]"),
5251       DELIMITER = delimiter.charCodeAt(0);
5252
5253   function parse(text, f) {
5254     var convert, columns, rows = parseRows(text, function(row, i) {
5255       if (convert) return convert(row, i - 1);
5256       columns = row, convert = f ? customConverter(row, f) : objectConverter(row);
5257     });
5258     rows.columns = columns || [];
5259     return rows;
5260   }
5261
5262   function parseRows(text, f) {
5263     var rows = [], // output rows
5264         N = text.length,
5265         I = 0, // current character index
5266         n = 0, // current line number
5267         t, // current token
5268         eof = N <= 0, // current token followed by EOF?
5269         eol = false; // current token followed by EOL?
5270
5271     // Strip the trailing newline.
5272     if (text.charCodeAt(N - 1) === NEWLINE) --N;
5273     if (text.charCodeAt(N - 1) === RETURN) --N;
5274
5275     function token() {
5276       if (eof) return EOF;
5277       if (eol) return eol = false, EOL;
5278
5279       // Unescape quotes.
5280       var i, j = I, c;
5281       if (text.charCodeAt(j) === QUOTE) {
5282         while (I++ < N && text.charCodeAt(I) !== QUOTE || text.charCodeAt(++I) === QUOTE);
5283         if ((i = I) >= N) eof = true;
5284         else if ((c = text.charCodeAt(I++)) === NEWLINE) eol = true;
5285         else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; }
5286         return text.slice(j + 1, i - 1).replace(/""/g, "\"");
5287       }
5288
5289       // Find next delimiter or newline.
5290       while (I < N) {
5291         if ((c = text.charCodeAt(i = I++)) === NEWLINE) eol = true;
5292         else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; }
5293         else if (c !== DELIMITER) continue;
5294         return text.slice(j, i);
5295       }
5296
5297       // Return last token before EOF.
5298       return eof = true, text.slice(j, N);
5299     }
5300
5301     while ((t = token()) !== EOF) {
5302       var row = [];
5303       while (t !== EOL && t !== EOF) row.push(t), t = token();
5304       if (f && (row = f(row, n++)) == null) continue;
5305       rows.push(row);
5306     }
5307
5308     return rows;
5309   }
5310
5311   function format(rows, columns) {
5312     if (columns == null) columns = inferColumns(rows);
5313     return [columns.map(formatValue).join(delimiter)].concat(rows.map(function(row) {
5314       return columns.map(function(column) {
5315         return formatValue(row[column]);
5316       }).join(delimiter);
5317     })).join("\n");
5318   }
5319
5320   function formatRows(rows) {
5321     return rows.map(formatRow).join("\n");
5322   }
5323
5324   function formatRow(row) {
5325     return row.map(formatValue).join(delimiter);
5326   }
5327
5328   function formatValue(text) {
5329     return text == null ? ""
5330         : reFormat.test(text += "") ? "\"" + text.replace(/"/g, "\"\"") + "\""
5331         : text;
5332   }
5333
5334   return {
5335     parse: parse,
5336     parseRows: parseRows,
5337     format: format,
5338     formatRows: formatRows
5339   };
5340 }
5341
5342 var csv = dsv(",");
5343
5344 var csvParse = csv.parse;
5345 var csvParseRows = csv.parseRows;
5346 var csvFormat = csv.format;
5347 var csvFormatRows = csv.formatRows;
5348
5349 var tsv = dsv("\t");
5350
5351 var tsvParse = tsv.parse;
5352 var tsvParseRows = tsv.parseRows;
5353 var tsvFormat = tsv.format;
5354 var tsvFormatRows = tsv.formatRows;
5355
5356 function center$1(x, y) {
5357   var nodes;
5358
5359   if (x == null) x = 0;
5360   if (y == null) y = 0;
5361
5362   function force() {
5363     var i,
5364         n = nodes.length,
5365         node,
5366         sx = 0,
5367         sy = 0;
5368
5369     for (i = 0; i < n; ++i) {
5370       node = nodes[i], sx += node.x, sy += node.y;
5371     }
5372
5373     for (sx = sx / n - x, sy = sy / n - y, i = 0; i < n; ++i) {
5374       node = nodes[i], node.x -= sx, node.y -= sy;
5375     }
5376   }
5377
5378   force.initialize = function(_) {
5379     nodes = _;
5380   };
5381
5382   force.x = function(_) {
5383     return arguments.length ? (x = +_, force) : x;
5384   };
5385
5386   force.y = function(_) {
5387     return arguments.length ? (y = +_, force) : y;
5388   };
5389
5390   return force;
5391 }
5392
5393 function constant$6(x) {
5394   return function() {
5395     return x;
5396   };
5397 }
5398
5399 function jiggle() {
5400   return (Math.random() - 0.5) * 1e-6;
5401 }
5402
5403 function tree_add(d) {
5404   var x = +this._x.call(null, d),
5405       y = +this._y.call(null, d);
5406   return add(this.cover(x, y), x, y, d);
5407 }
5408
5409 function add(tree, x, y, d) {
5410   if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points
5411
5412   var parent,
5413       node = tree._root,
5414       leaf = {data: d},
5415       x0 = tree._x0,
5416       y0 = tree._y0,
5417       x1 = tree._x1,
5418       y1 = tree._y1,
5419       xm,
5420       ym,
5421       xp,
5422       yp,
5423       right,
5424       bottom,
5425       i,
5426       j;
5427
5428   // If the tree is empty, initialize the root as a leaf.
5429   if (!node) return tree._root = leaf, tree;
5430
5431   // Find the existing leaf for the new point, or add it.
5432   while (node.length) {
5433     if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
5434     if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
5435     if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree;
5436   }
5437
5438   // Is the new point is exactly coincident with the existing point?
5439   xp = +tree._x.call(null, node.data);
5440   yp = +tree._y.call(null, node.data);
5441   if (x === xp && y === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree;
5442
5443   // Otherwise, split the leaf node until the old and new point are separated.
5444   do {
5445     parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4);
5446     if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
5447     if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
5448   } while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | (xp >= xm)));
5449   return parent[j] = node, parent[i] = leaf, tree;
5450 }
5451
5452 function addAll(data) {
5453   var d, i, n = data.length,
5454       x,
5455       y,
5456       xz = new Array(n),
5457       yz = new Array(n),
5458       x0 = Infinity,
5459       y0 = Infinity,
5460       x1 = -Infinity,
5461       y1 = -Infinity;
5462
5463   // Compute the points and their extent.
5464   for (i = 0; i < n; ++i) {
5465     if (isNaN(x = +this._x.call(null, d = data[i])) || isNaN(y = +this._y.call(null, d))) continue;
5466     xz[i] = x;
5467     yz[i] = y;
5468     if (x < x0) x0 = x;
5469     if (x > x1) x1 = x;
5470     if (y < y0) y0 = y;
5471     if (y > y1) y1 = y;
5472   }
5473
5474   // If there were no (valid) points, inherit the existing extent.
5475   if (x1 < x0) x0 = this._x0, x1 = this._x1;
5476   if (y1 < y0) y0 = this._y0, y1 = this._y1;
5477
5478   // Expand the tree to cover the new points.
5479   this.cover(x0, y0).cover(x1, y1);
5480
5481   // Add the new points.
5482   for (i = 0; i < n; ++i) {
5483     add(this, xz[i], yz[i], data[i]);
5484   }
5485
5486   return this;
5487 }
5488
5489 function tree_cover(x, y) {
5490   if (isNaN(x = +x) || isNaN(y = +y)) return this; // ignore invalid points
5491
5492   var x0 = this._x0,
5493       y0 = this._y0,
5494       x1 = this._x1,
5495       y1 = this._y1;
5496
5497   // If the quadtree has no extent, initialize them.
5498   // Integer extent are necessary so that if we later double the extent,
5499   // the existing quadrant boundaries don’t change due to floating point error!
5500   if (isNaN(x0)) {
5501     x1 = (x0 = Math.floor(x)) + 1;
5502     y1 = (y0 = Math.floor(y)) + 1;
5503   }
5504
5505   // Otherwise, double repeatedly to cover.
5506   else if (x0 > x || x > x1 || y0 > y || y > y1) {
5507     var z = x1 - x0,
5508         node = this._root,
5509         parent,
5510         i;
5511
5512     switch (i = (y < (y0 + y1) / 2) << 1 | (x < (x0 + x1) / 2)) {
5513       case 0: {
5514         do parent = new Array(4), parent[i] = node, node = parent;
5515         while (z *= 2, x1 = x0 + z, y1 = y0 + z, x > x1 || y > y1);
5516         break;
5517       }
5518       case 1: {
5519         do parent = new Array(4), parent[i] = node, node = parent;
5520         while (z *= 2, x0 = x1 - z, y1 = y0 + z, x0 > x || y > y1);
5521         break;
5522       }
5523       case 2: {
5524         do parent = new Array(4), parent[i] = node, node = parent;
5525         while (z *= 2, x1 = x0 + z, y0 = y1 - z, x > x1 || y0 > y);
5526         break;
5527       }
5528       case 3: {
5529         do parent = new Array(4), parent[i] = node, node = parent;
5530         while (z *= 2, x0 = x1 - z, y0 = y1 - z, x0 > x || y0 > y);
5531         break;
5532       }
5533     }
5534
5535     if (this._root && this._root.length) this._root = node;
5536   }
5537
5538   // If the quadtree covers the point already, just return.
5539   else return this;
5540
5541   this._x0 = x0;
5542   this._y0 = y0;
5543   this._x1 = x1;
5544   this._y1 = y1;
5545   return this;
5546 }
5547
5548 function tree_data() {
5549   var data = [];
5550   this.visit(function(node) {
5551     if (!node.length) do data.push(node.data); while (node = node.next)
5552   });
5553   return data;
5554 }
5555
5556 function tree_extent(_) {
5557   return arguments.length
5558       ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1])
5559       : isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, this._y1]];
5560 }
5561
5562 function Quad(node, x0, y0, x1, y1) {
5563   this.node = node;
5564   this.x0 = x0;
5565   this.y0 = y0;
5566   this.x1 = x1;
5567   this.y1 = y1;
5568 }
5569
5570 function tree_find(x, y, radius) {
5571   var data,
5572       x0 = this._x0,
5573       y0 = this._y0,
5574       x1,
5575       y1,
5576       x2,
5577       y2,
5578       x3 = this._x1,
5579       y3 = this._y1,
5580       quads = [],
5581       node = this._root,
5582       q,
5583       i;
5584
5585   if (node) quads.push(new Quad(node, x0, y0, x3, y3));
5586   if (radius == null) radius = Infinity;
5587   else {
5588     x0 = x - radius, y0 = y - radius;
5589     x3 = x + radius, y3 = y + radius;
5590     radius *= radius;
5591   }
5592
5593   while (q = quads.pop()) {
5594
5595     // Stop searching if this quadrant can’t contain a closer node.
5596     if (!(node = q.node)
5597         || (x1 = q.x0) > x3
5598         || (y1 = q.y0) > y3
5599         || (x2 = q.x1) < x0
5600         || (y2 = q.y1) < y0) continue;
5601
5602     // Bisect the current quadrant.
5603     if (node.length) {
5604       var xm = (x1 + x2) / 2,
5605           ym = (y1 + y2) / 2;
5606
5607       quads.push(
5608         new Quad(node[3], xm, ym, x2, y2),
5609         new Quad(node[2], x1, ym, xm, y2),
5610         new Quad(node[1], xm, y1, x2, ym),
5611         new Quad(node[0], x1, y1, xm, ym)
5612       );
5613
5614       // Visit the closest quadrant first.
5615       if (i = (y >= ym) << 1 | (x >= xm)) {
5616         q = quads[quads.length - 1];
5617         quads[quads.length - 1] = quads[quads.length - 1 - i];
5618         quads[quads.length - 1 - i] = q;
5619       }
5620     }
5621
5622     // Visit this point. (Visiting coincident points isn’t necessary!)
5623     else {
5624       var dx = x - +this._x.call(null, node.data),
5625           dy = y - +this._y.call(null, node.data),
5626           d2 = dx * dx + dy * dy;
5627       if (d2 < radius) {
5628         var d = Math.sqrt(radius = d2);
5629         x0 = x - d, y0 = y - d;
5630         x3 = x + d, y3 = y + d;
5631         data = node.data;
5632       }
5633     }
5634   }
5635
5636   return data;
5637 }
5638
5639 function tree_remove(d) {
5640   if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points
5641
5642   var parent,
5643       node = this._root,
5644       retainer,
5645       previous,
5646       next,
5647       x0 = this._x0,
5648       y0 = this._y0,
5649       x1 = this._x1,
5650       y1 = this._y1,
5651       x,
5652       y,
5653       xm,
5654       ym,
5655       right,
5656       bottom,
5657       i,
5658       j;
5659
5660   // If the tree is empty, initialize the root as a leaf.
5661   if (!node) return this;
5662
5663   // Find the leaf node for the point.
5664   // While descending, also retain the deepest parent with a non-removed sibling.
5665   if (node.length) while (true) {
5666     if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
5667     if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
5668     if (!(parent = node, node = node[i = bottom << 1 | right])) return this;
5669     if (!node.length) break;
5670     if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i;
5671   }
5672
5673   // Find the point to remove.
5674   while (node.data !== d) if (!(previous = node, node = node.next)) return this;
5675   if (next = node.next) delete node.next;
5676
5677   // If there are multiple coincident points, remove just the point.
5678   if (previous) return next ? previous.next = next : delete previous.next, this;
5679
5680   // If this is the root point, remove it.
5681   if (!parent) return this._root = next, this;
5682
5683   // Remove this leaf.
5684   next ? parent[i] = next : delete parent[i];
5685
5686   // If the parent now contains exactly one leaf, collapse superfluous parents.
5687   if ((node = parent[0] || parent[1] || parent[2] || parent[3])
5688       && node === (parent[3] || parent[2] || parent[1] || parent[0])
5689       && !node.length) {
5690     if (retainer) retainer[j] = node;
5691     else this._root = node;
5692   }
5693
5694   return this;
5695 }
5696
5697 function removeAll(data) {
5698   for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]);
5699   return this;
5700 }
5701
5702 function tree_root() {
5703   return this._root;
5704 }
5705
5706 function tree_size() {
5707   var size = 0;
5708   this.visit(function(node) {
5709     if (!node.length) do ++size; while (node = node.next)
5710   });
5711   return size;
5712 }
5713
5714 function tree_visit(callback) {
5715   var quads = [], q, node = this._root, child, x0, y0, x1, y1;
5716   if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y1));
5717   while (q = quads.pop()) {
5718     if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) {
5719       var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
5720       if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
5721       if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
5722       if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
5723       if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
5724     }
5725   }
5726   return this;
5727 }
5728
5729 function tree_visitAfter(callback) {
5730   var quads = [], next = [], q;
5731   if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this._x1, this._y1));
5732   while (q = quads.pop()) {
5733     var node = q.node;
5734     if (node.length) {
5735       var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
5736       if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
5737       if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
5738       if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
5739       if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
5740     }
5741     next.push(q);
5742   }
5743   while (q = next.pop()) {
5744     callback(q.node, q.x0, q.y0, q.x1, q.y1);
5745   }
5746   return this;
5747 }
5748
5749 function defaultX(d) {
5750   return d[0];
5751 }
5752
5753 function tree_x(_) {
5754   return arguments.length ? (this._x = _, this) : this._x;
5755 }
5756
5757 function defaultY(d) {
5758   return d[1];
5759 }
5760
5761 function tree_y(_) {
5762   return arguments.length ? (this._y = _, this) : this._y;
5763 }
5764
5765 function quadtree(nodes, x, y) {
5766   var tree = new Quadtree(x == null ? defaultX : x, y == null ? defaultY : y, NaN, NaN, NaN, NaN);
5767   return nodes == null ? tree : tree.addAll(nodes);
5768 }
5769
5770 function Quadtree(x, y, x0, y0, x1, y1) {
5771   this._x = x;
5772   this._y = y;
5773   this._x0 = x0;
5774   this._y0 = y0;
5775   this._x1 = x1;
5776   this._y1 = y1;
5777   this._root = undefined;
5778 }
5779
5780 function leaf_copy(leaf) {
5781   var copy = {data: leaf.data}, next = copy;
5782   while (leaf = leaf.next) next = next.next = {data: leaf.data};
5783   return copy;
5784 }
5785
5786 var treeProto = quadtree.prototype = Quadtree.prototype;
5787
5788 treeProto.copy = function() {
5789   var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1),
5790       node = this._root,
5791       nodes,
5792       child;
5793
5794   if (!node) return copy;
5795
5796   if (!node.length) return copy._root = leaf_copy(node), copy;
5797
5798   nodes = [{source: node, target: copy._root = new Array(4)}];
5799   while (node = nodes.pop()) {
5800     for (var i = 0; i < 4; ++i) {
5801       if (child = node.source[i]) {
5802         if (child.length) nodes.push({source: child, target: node.target[i] = new Array(4)});
5803         else node.target[i] = leaf_copy(child);
5804       }
5805     }
5806   }
5807
5808   return copy;
5809 };
5810
5811 treeProto.add = tree_add;
5812 treeProto.addAll = addAll;
5813 treeProto.cover = tree_cover;
5814 treeProto.data = tree_data;
5815 treeProto.extent = tree_extent;
5816 treeProto.find = tree_find;
5817 treeProto.remove = tree_remove;
5818 treeProto.removeAll = removeAll;
5819 treeProto.root = tree_root;
5820 treeProto.size = tree_size;
5821 treeProto.visit = tree_visit;
5822 treeProto.visitAfter = tree_visitAfter;
5823 treeProto.x = tree_x;
5824 treeProto.y = tree_y;
5825
5826 function x(d) {
5827   return d.x + d.vx;
5828 }
5829
5830 function y(d) {
5831   return d.y + d.vy;
5832 }
5833
5834 function collide(radius) {
5835   var nodes,
5836       radii,
5837       strength = 1,
5838       iterations = 1;
5839
5840   if (typeof radius !== "function") radius = constant$6(radius == null ? 1 : +radius);
5841
5842   function force() {
5843     var i, n = nodes.length,
5844         tree,
5845         node,
5846         xi,
5847         yi,
5848         ri,
5849         ri2;
5850
5851     for (var k = 0; k < iterations; ++k) {
5852       tree = quadtree(nodes, x, y).visitAfter(prepare);
5853       for (i = 0; i < n; ++i) {
5854         node = nodes[i];
5855         ri = radii[node.index], ri2 = ri * ri;
5856         xi = node.x + node.vx;
5857         yi = node.y + node.vy;
5858         tree.visit(apply);
5859       }
5860     }
5861
5862     function apply(quad, x0, y0, x1, y1) {
5863       var data = quad.data, rj = quad.r, r = ri + rj;
5864       if (data) {
5865         if (data.index > node.index) {
5866           var x = xi - data.x - data.vx,
5867               y = yi - data.y - data.vy,
5868               l = x * x + y * y;
5869           if (l < r * r) {
5870             if (x === 0) x = jiggle(), l += x * x;
5871             if (y === 0) y = jiggle(), l += y * y;
5872             l = (r - (l = Math.sqrt(l))) / l * strength;
5873             node.vx += (x *= l) * (r = (rj *= rj) / (ri2 + rj));
5874             node.vy += (y *= l) * r;
5875             data.vx -= x * (r = 1 - r);
5876             data.vy -= y * r;
5877           }
5878         }
5879         return;
5880       }
5881       return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r;
5882     }
5883   }
5884
5885   function prepare(quad) {
5886     if (quad.data) return quad.r = radii[quad.data.index];
5887     for (var i = quad.r = 0; i < 4; ++i) {
5888       if (quad[i] && quad[i].r > quad.r) {
5889         quad.r = quad[i].r;
5890       }
5891     }
5892   }
5893
5894   function initialize() {
5895     if (!nodes) return;
5896     var i, n = nodes.length, node;
5897     radii = new Array(n);
5898     for (i = 0; i < n; ++i) node = nodes[i], radii[node.index] = +radius(node, i, nodes);
5899   }
5900
5901   force.initialize = function(_) {
5902     nodes = _;
5903     initialize();
5904   };
5905
5906   force.iterations = function(_) {
5907     return arguments.length ? (iterations = +_, force) : iterations;
5908   };
5909
5910   force.strength = function(_) {
5911     return arguments.length ? (strength = +_, force) : strength;
5912   };
5913
5914   force.radius = function(_) {
5915     return arguments.length ? (radius = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : radius;
5916   };
5917
5918   return force;
5919 }
5920
5921 function index(d) {
5922   return d.index;
5923 }
5924
5925 function find(nodeById, nodeId) {
5926   var node = nodeById.get(nodeId);
5927   if (!node) throw new Error("missing: " + nodeId);
5928   return node;
5929 }
5930
5931 function link(links) {
5932   var id = index,
5933       strength = defaultStrength,
5934       strengths,
5935       distance = constant$6(30),
5936       distances,
5937       nodes,
5938       count,
5939       bias,
5940       iterations = 1;
5941
5942   if (links == null) links = [];
5943
5944   function defaultStrength(link) {
5945     return 1 / Math.min(count[link.source.index], count[link.target.index]);
5946   }
5947
5948   function force(alpha) {
5949     for (var k = 0, n = links.length; k < iterations; ++k) {
5950       for (var i = 0, link, source, target, x, y, l, b; i < n; ++i) {
5951         link = links[i], source = link.source, target = link.target;
5952         x = target.x + target.vx - source.x - source.vx || jiggle();
5953         y = target.y + target.vy - source.y - source.vy || jiggle();
5954         l = Math.sqrt(x * x + y * y);
5955         l = (l - distances[i]) / l * alpha * strengths[i];
5956         x *= l, y *= l;
5957         target.vx -= x * (b = bias[i]);
5958         target.vy -= y * b;
5959         source.vx += x * (b = 1 - b);
5960         source.vy += y * b;
5961       }
5962     }
5963   }
5964
5965   function initialize() {
5966     if (!nodes) return;
5967
5968     var i,
5969         n = nodes.length,
5970         m = links.length,
5971         nodeById = map$1(nodes, id),
5972         link;
5973
5974     for (i = 0, count = new Array(n); i < m; ++i) {
5975       link = links[i], link.index = i;
5976       if (typeof link.source !== "object") link.source = find(nodeById, link.source);
5977       if (typeof link.target !== "object") link.target = find(nodeById, link.target);
5978       count[link.source.index] = (count[link.source.index] || 0) + 1;
5979       count[link.target.index] = (count[link.target.index] || 0) + 1;
5980     }
5981
5982     for (i = 0, bias = new Array(m); i < m; ++i) {
5983       link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]);
5984     }
5985
5986     strengths = new Array(m), initializeStrength();
5987     distances = new Array(m), initializeDistance();
5988   }
5989
5990   function initializeStrength() {
5991     if (!nodes) return;
5992
5993     for (var i = 0, n = links.length; i < n; ++i) {
5994       strengths[i] = +strength(links[i], i, links);
5995     }
5996   }
5997
5998   function initializeDistance() {
5999     if (!nodes) return;
6000
6001     for (var i = 0, n = links.length; i < n; ++i) {
6002       distances[i] = +distance(links[i], i, links);
6003     }
6004   }
6005
6006   force.initialize = function(_) {
6007     nodes = _;
6008     initialize();
6009   };
6010
6011   force.links = function(_) {
6012     return arguments.length ? (links = _, initialize(), force) : links;
6013   };
6014
6015   force.id = function(_) {
6016     return arguments.length ? (id = _, force) : id;
6017   };
6018
6019   force.iterations = function(_) {
6020     return arguments.length ? (iterations = +_, force) : iterations;
6021   };
6022
6023   force.strength = function(_) {
6024     return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initializeStrength(), force) : strength;
6025   };
6026
6027   force.distance = function(_) {
6028     return arguments.length ? (distance = typeof _ === "function" ? _ : constant$6(+_), initializeDistance(), force) : distance;
6029   };
6030
6031   return force;
6032 }
6033
6034 function x$1(d) {
6035   return d.x;
6036 }
6037
6038 function y$1(d) {
6039   return d.y;
6040 }
6041
6042 var initialRadius = 10;
6043 var initialAngle = Math.PI * (3 - Math.sqrt(5));
6044
6045 function simulation(nodes) {
6046   var simulation,
6047       alpha = 1,
6048       alphaMin = 0.001,
6049       alphaDecay = 1 - Math.pow(alphaMin, 1 / 300),
6050       alphaTarget = 0,
6051       velocityDecay = 0.6,
6052       forces = map$1(),
6053       stepper = timer(step),
6054       event = dispatch("tick", "end");
6055
6056   if (nodes == null) nodes = [];
6057
6058   function step() {
6059     tick();
6060     event.call("tick", simulation);
6061     if (alpha < alphaMin) {
6062       stepper.stop();
6063       event.call("end", simulation);
6064     }
6065   }
6066
6067   function tick() {
6068     var i, n = nodes.length, node;
6069
6070     alpha += (alphaTarget - alpha) * alphaDecay;
6071
6072     forces.each(function(force) {
6073       force(alpha);
6074     });
6075
6076     for (i = 0; i < n; ++i) {
6077       node = nodes[i];
6078       if (node.fx == null) node.x += node.vx *= velocityDecay;
6079       else node.x = node.fx, node.vx = 0;
6080       if (node.fy == null) node.y += node.vy *= velocityDecay;
6081       else node.y = node.fy, node.vy = 0;
6082     }
6083   }
6084
6085   function initializeNodes() {
6086     for (var i = 0, n = nodes.length, node; i < n; ++i) {
6087       node = nodes[i], node.index = i;
6088       if (isNaN(node.x) || isNaN(node.y)) {
6089         var radius = initialRadius * Math.sqrt(i), angle = i * initialAngle;
6090         node.x = radius * Math.cos(angle);
6091         node.y = radius * Math.sin(angle);
6092       }
6093       if (isNaN(node.vx) || isNaN(node.vy)) {
6094         node.vx = node.vy = 0;
6095       }
6096     }
6097   }
6098
6099   function initializeForce(force) {
6100     if (force.initialize) force.initialize(nodes);
6101     return force;
6102   }
6103
6104   initializeNodes();
6105
6106   return simulation = {
6107     tick: tick,
6108
6109     restart: function() {
6110       return stepper.restart(step), simulation;
6111     },
6112
6113     stop: function() {
6114       return stepper.stop(), simulation;
6115     },
6116
6117     nodes: function(_) {
6118       return arguments.length ? (nodes = _, initializeNodes(), forces.each(initializeForce), simulation) : nodes;
6119     },
6120
6121     alpha: function(_) {
6122       return arguments.length ? (alpha = +_, simulation) : alpha;
6123     },
6124
6125     alphaMin: function(_) {
6126       return arguments.length ? (alphaMin = +_, simulation) : alphaMin;
6127     },
6128
6129     alphaDecay: function(_) {
6130       return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay;
6131     },
6132
6133     alphaTarget: function(_) {
6134       return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget;
6135     },
6136
6137     velocityDecay: function(_) {
6138       return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay;
6139     },
6140
6141     force: function(name, _) {
6142       return arguments.length > 1 ? (_ == null ? forces.remove(name) : forces.set(name, initializeForce(_)), simulation) : forces.get(name);
6143     },
6144
6145     find: function(x, y, radius) {
6146       var i = 0,
6147           n = nodes.length,
6148           dx,
6149           dy,
6150           d2,
6151           node,
6152           closest;
6153
6154       if (radius == null) radius = Infinity;
6155       else radius *= radius;
6156
6157       for (i = 0; i < n; ++i) {
6158         node = nodes[i];
6159         dx = x - node.x;
6160         dy = y - node.y;
6161         d2 = dx * dx + dy * dy;
6162         if (d2 < radius) closest = node, radius = d2;
6163       }
6164
6165       return closest;
6166     },
6167
6168     on: function(name, _) {
6169       return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name);
6170     }
6171   };
6172 }
6173
6174 function manyBody() {
6175   var nodes,
6176       node,
6177       alpha,
6178       strength = constant$6(-30),
6179       strengths,
6180       distanceMin2 = 1,
6181       distanceMax2 = Infinity,
6182       theta2 = 0.81;
6183
6184   function force(_) {
6185     var i, n = nodes.length, tree = quadtree(nodes, x$1, y$1).visitAfter(accumulate);
6186     for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply);
6187   }
6188
6189   function initialize() {
6190     if (!nodes) return;
6191     var i, n = nodes.length, node;
6192     strengths = new Array(n);
6193     for (i = 0; i < n; ++i) node = nodes[i], strengths[node.index] = +strength(node, i, nodes);
6194   }
6195
6196   function accumulate(quad) {
6197     var strength = 0, q, c, weight = 0, x, y, i;
6198
6199     // For internal nodes, accumulate forces from child quadrants.
6200     if (quad.length) {
6201       for (x = y = i = 0; i < 4; ++i) {
6202         if ((q = quad[i]) && (c = Math.abs(q.value))) {
6203           strength += q.value, weight += c, x += c * q.x, y += c * q.y;
6204         }
6205       }
6206       quad.x = x / weight;
6207       quad.y = y / weight;
6208     }
6209
6210     // For leaf nodes, accumulate forces from coincident quadrants.
6211     else {
6212       q = quad;
6213       q.x = q.data.x;
6214       q.y = q.data.y;
6215       do strength += strengths[q.data.index];
6216       while (q = q.next);
6217     }
6218
6219     quad.value = strength;
6220   }
6221
6222   function apply(quad, x1, _, x2) {
6223     if (!quad.value) return true;
6224
6225     var x = quad.x - node.x,
6226         y = quad.y - node.y,
6227         w = x2 - x1,
6228         l = x * x + y * y;
6229
6230     // Apply the Barnes-Hut approximation if possible.
6231     // Limit forces for very close nodes; randomize direction if coincident.
6232     if (w * w / theta2 < l) {
6233       if (l < distanceMax2) {
6234         if (x === 0) x = jiggle(), l += x * x;
6235         if (y === 0) y = jiggle(), l += y * y;
6236         if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
6237         node.vx += x * quad.value * alpha / l;
6238         node.vy += y * quad.value * alpha / l;
6239       }
6240       return true;
6241     }
6242
6243     // Otherwise, process points directly.
6244     else if (quad.length || l >= distanceMax2) return;
6245
6246     // Limit forces for very close nodes; randomize direction if coincident.
6247     if (quad.data !== node || quad.next) {
6248       if (x === 0) x = jiggle(), l += x * x;
6249       if (y === 0) y = jiggle(), l += y * y;
6250       if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
6251     }
6252
6253     do if (quad.data !== node) {
6254       w = strengths[quad.data.index] * alpha / l;
6255       node.vx += x * w;
6256       node.vy += y * w;
6257     } while (quad = quad.next);
6258   }
6259
6260   force.initialize = function(_) {
6261     nodes = _;
6262     initialize();
6263   };
6264
6265   force.strength = function(_) {
6266     return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength;
6267   };
6268
6269   force.distanceMin = function(_) {
6270     return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2);
6271   };
6272
6273   force.distanceMax = function(_) {
6274     return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2);
6275   };
6276
6277   force.theta = function(_) {
6278     return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2);
6279   };
6280
6281   return force;
6282 }
6283
6284 function radial(radius, x, y) {
6285   var nodes,
6286       strength = constant$6(0.1),
6287       strengths,
6288       radiuses;
6289
6290   if (typeof radius !== "function") radius = constant$6(+radius);
6291   if (x == null) x = 0;
6292   if (y == null) y = 0;
6293
6294   function force(alpha) {
6295     for (var i = 0, n = nodes.length; i < n; ++i) {
6296       var node = nodes[i],
6297           dx = node.x - x || 1e-6,
6298           dy = node.y - y || 1e-6,
6299           r = Math.sqrt(dx * dx + dy * dy),
6300           k = (radiuses[i] - r) * strengths[i] * alpha / r;
6301       node.vx += dx * k;
6302       node.vy += dy * k;
6303     }
6304   }
6305
6306   function initialize() {
6307     if (!nodes) return;
6308     var i, n = nodes.length;
6309     strengths = new Array(n);
6310     radiuses = new Array(n);
6311     for (i = 0; i < n; ++i) {
6312       radiuses[i] = +radius(nodes[i], i, nodes);
6313       strengths[i] = isNaN(radiuses[i]) ? 0 : +strength(nodes[i], i, nodes);
6314     }
6315   }
6316
6317   force.initialize = function(_) {
6318     nodes = _, initialize();
6319   };
6320
6321   force.strength = function(_) {
6322     return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength;
6323   };
6324
6325   force.radius = function(_) {
6326     return arguments.length ? (radius = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : radius;
6327   };
6328
6329   force.x = function(_) {
6330     return arguments.length ? (x = +_, force) : x;
6331   };
6332
6333   force.y = function(_) {
6334     return arguments.length ? (y = +_, force) : y;
6335   };
6336
6337   return force;
6338 }
6339
6340 function x$2(x) {
6341   var strength = constant$6(0.1),
6342       nodes,
6343       strengths,
6344       xz;
6345
6346   if (typeof x !== "function") x = constant$6(x == null ? 0 : +x);
6347
6348   function force(alpha) {
6349     for (var i = 0, n = nodes.length, node; i < n; ++i) {
6350       node = nodes[i], node.vx += (xz[i] - node.x) * strengths[i] * alpha;
6351     }
6352   }
6353
6354   function initialize() {
6355     if (!nodes) return;
6356     var i, n = nodes.length;
6357     strengths = new Array(n);
6358     xz = new Array(n);
6359     for (i = 0; i < n; ++i) {
6360       strengths[i] = isNaN(xz[i] = +x(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
6361     }
6362   }
6363
6364   force.initialize = function(_) {
6365     nodes = _;
6366     initialize();
6367   };
6368
6369   force.strength = function(_) {
6370     return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength;
6371   };
6372
6373   force.x = function(_) {
6374     return arguments.length ? (x = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : x;
6375   };
6376
6377   return force;
6378 }
6379
6380 function y$2(y) {
6381   var strength = constant$6(0.1),
6382       nodes,
6383       strengths,
6384       yz;
6385
6386   if (typeof y !== "function") y = constant$6(y == null ? 0 : +y);
6387
6388   function force(alpha) {
6389     for (var i = 0, n = nodes.length, node; i < n; ++i) {
6390       node = nodes[i], node.vy += (yz[i] - node.y) * strengths[i] * alpha;
6391     }
6392   }
6393
6394   function initialize() {
6395     if (!nodes) return;
6396     var i, n = nodes.length;
6397     strengths = new Array(n);
6398     yz = new Array(n);
6399     for (i = 0; i < n; ++i) {
6400       strengths[i] = isNaN(yz[i] = +y(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
6401     }
6402   }
6403
6404   force.initialize = function(_) {
6405     nodes = _;
6406     initialize();
6407   };
6408
6409   force.strength = function(_) {
6410     return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength;
6411   };
6412
6413   force.y = function(_) {
6414     return arguments.length ? (y = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : y;
6415   };
6416
6417   return force;
6418 }
6419
6420 // Computes the decimal coefficient and exponent of the specified number x with
6421 // significant digits p, where x is positive and p is in [1, 21] or undefined.
6422 // For example, formatDecimal(1.23) returns ["123", 0].
6423 function formatDecimal(x, p) {
6424   if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity
6425   var i, coefficient = x.slice(0, i);
6426
6427   // The string returned by toExponential either has the form \d\.\d+e[-+]\d+
6428   // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3).
6429   return [
6430     coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,
6431     +x.slice(i + 1)
6432   ];
6433 }
6434
6435 function exponent$1(x) {
6436   return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN;
6437 }
6438
6439 function formatGroup(grouping, thousands) {
6440   return function(value, width) {
6441     var i = value.length,
6442         t = [],
6443         j = 0,
6444         g = grouping[0],
6445         length = 0;
6446
6447     while (i > 0 && g > 0) {
6448       if (length + g + 1 > width) g = Math.max(1, width - length);
6449       t.push(value.substring(i -= g, i + g));
6450       if ((length += g + 1) > width) break;
6451       g = grouping[j = (j + 1) % grouping.length];
6452     }
6453
6454     return t.reverse().join(thousands);
6455   };
6456 }
6457
6458 function formatNumerals(numerals) {
6459   return function(value) {
6460     return value.replace(/[0-9]/g, function(i) {
6461       return numerals[+i];
6462     });
6463   };
6464 }
6465
6466 function formatDefault(x, p) {
6467   x = x.toPrecision(p);
6468
6469   out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) {
6470     switch (x[i]) {
6471       case ".": i0 = i1 = i; break;
6472       case "0": if (i0 === 0) i0 = i; i1 = i; break;
6473       case "e": break out;
6474       default: if (i0 > 0) i0 = 0; break;
6475     }
6476   }
6477
6478   return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x;
6479 }
6480
6481 var prefixExponent;
6482
6483 function formatPrefixAuto(x, p) {
6484   var d = formatDecimal(x, p);
6485   if (!d) return x + "";
6486   var coefficient = d[0],
6487       exponent = d[1],
6488       i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,
6489       n = coefficient.length;
6490   return i === n ? coefficient
6491       : i > n ? coefficient + new Array(i - n + 1).join("0")
6492       : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i)
6493       : "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y!
6494 }
6495
6496 function formatRounded(x, p) {
6497   var d = formatDecimal(x, p);
6498   if (!d) return x + "";
6499   var coefficient = d[0],
6500       exponent = d[1];
6501   return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient
6502       : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1)
6503       : coefficient + new Array(exponent - coefficient.length + 2).join("0");
6504 }
6505
6506 var formatTypes = {
6507   "": formatDefault,
6508   "%": function(x, p) { return (x * 100).toFixed(p); },
6509   "b": function(x) { return Math.round(x).toString(2); },
6510   "c": function(x) { return x + ""; },
6511   "d": function(x) { return Math.round(x).toString(10); },
6512   "e": function(x, p) { return x.toExponential(p); },
6513   "f": function(x, p) { return x.toFixed(p); },
6514   "g": function(x, p) { return x.toPrecision(p); },
6515   "o": function(x) { return Math.round(x).toString(8); },
6516   "p": function(x, p) { return formatRounded(x * 100, p); },
6517   "r": formatRounded,
6518   "s": formatPrefixAuto,
6519   "X": function(x) { return Math.round(x).toString(16).toUpperCase(); },
6520   "x": function(x) { return Math.round(x).toString(16); }
6521 };
6522
6523 // [[fill]align][sign][symbol][0][width][,][.precision][type]
6524 var re = /^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i;
6525
6526 function formatSpecifier(specifier) {
6527   return new FormatSpecifier(specifier);
6528 }
6529
6530 formatSpecifier.prototype = FormatSpecifier.prototype; // instanceof
6531
6532 function FormatSpecifier(specifier) {
6533   if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier);
6534
6535   var match,
6536       fill = match[1] || " ",
6537       align = match[2] || ">",
6538       sign = match[3] || "-",
6539       symbol = match[4] || "",
6540       zero = !!match[5],
6541       width = match[6] && +match[6],
6542       comma = !!match[7],
6543       precision = match[8] && +match[8].slice(1),
6544       type = match[9] || "";
6545
6546   // The "n" type is an alias for ",g".
6547   if (type === "n") comma = true, type = "g";
6548
6549   // Map invalid types to the default format.
6550   else if (!formatTypes[type]) type = "";
6551
6552   // If zero fill is specified, padding goes after sign and before digits.
6553   if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "=";
6554
6555   this.fill = fill;
6556   this.align = align;
6557   this.sign = sign;
6558   this.symbol = symbol;
6559   this.zero = zero;
6560   this.width = width;
6561   this.comma = comma;
6562   this.precision = precision;
6563   this.type = type;
6564 }
6565
6566 FormatSpecifier.prototype.toString = function() {
6567   return this.fill
6568       + this.align
6569       + this.sign
6570       + this.symbol
6571       + (this.zero ? "0" : "")
6572       + (this.width == null ? "" : Math.max(1, this.width | 0))
6573       + (this.comma ? "," : "")
6574       + (this.precision == null ? "" : "." + Math.max(0, this.precision | 0))
6575       + this.type;
6576 };
6577
6578 function identity$3(x) {
6579   return x;
6580 }
6581
6582 var prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];
6583
6584 function formatLocale(locale) {
6585   var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity$3,
6586       currency = locale.currency,
6587       decimal = locale.decimal,
6588       numerals = locale.numerals ? formatNumerals(locale.numerals) : identity$3,
6589       percent = locale.percent || "%";
6590
6591   function newFormat(specifier) {
6592     specifier = formatSpecifier(specifier);
6593
6594     var fill = specifier.fill,
6595         align = specifier.align,
6596         sign = specifier.sign,
6597         symbol = specifier.symbol,
6598         zero = specifier.zero,
6599         width = specifier.width,
6600         comma = specifier.comma,
6601         precision = specifier.precision,
6602         type = specifier.type;
6603
6604     // Compute the prefix and suffix.
6605     // For SI-prefix, the suffix is lazily computed.
6606     var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "",
6607         suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? percent : "";
6608
6609     // What format function should we use?
6610     // Is this an integer type?
6611     // Can this type generate exponential notation?
6612     var formatType = formatTypes[type],
6613         maybeSuffix = !type || /[defgprs%]/.test(type);
6614
6615     // Set the default precision if not specified,
6616     // or clamp the specified precision to the supported range.
6617     // For significant precision, it must be in [1, 21].
6618     // For fixed precision, it must be in [0, 20].
6619     precision = precision == null ? (type ? 6 : 12)
6620         : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))
6621         : Math.max(0, Math.min(20, precision));
6622
6623     function format(value) {
6624       var valuePrefix = prefix,
6625           valueSuffix = suffix,
6626           i, n, c;
6627
6628       if (type === "c") {
6629         valueSuffix = formatType(value) + valueSuffix;
6630         value = "";
6631       } else {
6632         value = +value;
6633
6634         // Perform the initial formatting.
6635         var valueNegative = value < 0;
6636         value = formatType(Math.abs(value), precision);
6637
6638         // If a negative value rounds to zero during formatting, treat as positive.
6639         if (valueNegative && +value === 0) valueNegative = false;
6640
6641         // Compute the prefix and suffix.
6642         valuePrefix = (valueNegative ? (sign === "(" ? sign : "-") : sign === "-" || sign === "(" ? "" : sign) + valuePrefix;
6643         valueSuffix = valueSuffix + (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + (valueNegative && sign === "(" ? ")" : "");
6644
6645         // Break the formatted value into the integer “value” part that can be
6646         // grouped, and fractional or exponential “suffix” part that is not.
6647         if (maybeSuffix) {
6648           i = -1, n = value.length;
6649           while (++i < n) {
6650             if (c = value.charCodeAt(i), 48 > c || c > 57) {
6651               valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;
6652               value = value.slice(0, i);
6653               break;
6654             }
6655           }
6656         }
6657       }
6658
6659       // If the fill character is not "0", grouping is applied before padding.
6660       if (comma && !zero) value = group(value, Infinity);
6661
6662       // Compute the padding.
6663       var length = valuePrefix.length + value.length + valueSuffix.length,
6664           padding = length < width ? new Array(width - length + 1).join(fill) : "";
6665
6666       // If the fill character is "0", grouping is applied after padding.
6667       if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = "";
6668
6669       // Reconstruct the final output based on the desired alignment.
6670       switch (align) {
6671         case "<": value = valuePrefix + value + valueSuffix + padding; break;
6672         case "=": value = valuePrefix + padding + value + valueSuffix; break;
6673         case "^": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break;
6674         default: value = padding + valuePrefix + value + valueSuffix; break;
6675       }
6676
6677       return numerals(value);
6678     }
6679
6680     format.toString = function() {
6681       return specifier + "";
6682     };
6683
6684     return format;
6685   }
6686
6687   function formatPrefix(specifier, value) {
6688     var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)),
6689         e = Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3,
6690         k = Math.pow(10, -e),
6691         prefix = prefixes[8 + e / 3];
6692     return function(value) {
6693       return f(k * value) + prefix;
6694     };
6695   }
6696
6697   return {
6698     format: newFormat,
6699     formatPrefix: formatPrefix
6700   };
6701 }
6702
6703 var locale;
6704 var format;
6705 var formatPrefix;
6706
6707 defaultLocale({
6708   decimal: ".",
6709   thousands: ",",
6710   grouping: [3],
6711   currency: ["$", ""]
6712 });
6713
6714 function defaultLocale(definition) {
6715   locale = formatLocale(definition);
6716   format = locale.format;
6717   formatPrefix = locale.formatPrefix;
6718   return locale;
6719 }
6720
6721 function precisionFixed(step) {
6722   return Math.max(0, -exponent$1(Math.abs(step)));
6723 }
6724
6725 function precisionPrefix(step, value) {
6726   return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3 - exponent$1(Math.abs(step)));
6727 }
6728
6729 function precisionRound(step, max) {
6730   step = Math.abs(step), max = Math.abs(max) - step;
6731   return Math.max(0, exponent$1(max) - exponent$1(step)) + 1;
6732 }
6733
6734 // Adds floating point numbers with twice the normal precision.
6735 // Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic and
6736 // Fast Robust Geometric Predicates, Discrete & Computational Geometry 18(3)
6737 // 305–363 (1997).
6738 // Code adapted from GeographicLib by Charles F. F. Karney,
6739 // http://geographiclib.sourceforge.net/
6740
6741 function adder() {
6742   return new Adder;
6743 }
6744
6745 function Adder() {
6746   this.reset();
6747 }
6748
6749 Adder.prototype = {
6750   constructor: Adder,
6751   reset: function() {
6752     this.s = // rounded value
6753     this.t = 0; // exact error
6754   },
6755   add: function(y) {
6756     add$1(temp, y, this.t);
6757     add$1(this, temp.s, this.s);
6758     if (this.s) this.t += temp.t;
6759     else this.s = temp.t;
6760   },
6761   valueOf: function() {
6762     return this.s;
6763   }
6764 };
6765
6766 var temp = new Adder;
6767
6768 function add$1(adder, a, b) {
6769   var x = adder.s = a + b,
6770       bv = x - a,
6771       av = x - bv;
6772   adder.t = (a - av) + (b - bv);
6773 }
6774
6775 var epsilon$2 = 1e-6;
6776 var epsilon2$1 = 1e-12;
6777 var pi$3 = Math.PI;
6778 var halfPi$2 = pi$3 / 2;
6779 var quarterPi = pi$3 / 4;
6780 var tau$3 = pi$3 * 2;
6781
6782 var degrees$1 = 180 / pi$3;
6783 var radians = pi$3 / 180;
6784
6785 var abs = Math.abs;
6786 var atan = Math.atan;
6787 var atan2 = Math.atan2;
6788 var cos$1 = Math.cos;
6789 var ceil = Math.ceil;
6790 var exp = Math.exp;
6791
6792 var log = Math.log;
6793 var pow = Math.pow;
6794 var sin$1 = Math.sin;
6795 var sign = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; };
6796 var sqrt = Math.sqrt;
6797 var tan = Math.tan;
6798
6799 function acos(x) {
6800   return x > 1 ? 0 : x < -1 ? pi$3 : Math.acos(x);
6801 }
6802
6803 function asin(x) {
6804   return x > 1 ? halfPi$2 : x < -1 ? -halfPi$2 : Math.asin(x);
6805 }
6806
6807 function haversin(x) {
6808   return (x = sin$1(x / 2)) * x;
6809 }
6810
6811 function noop$1() {}
6812
6813 function streamGeometry(geometry, stream) {
6814   if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) {
6815     streamGeometryType[geometry.type](geometry, stream);
6816   }
6817 }
6818
6819 var streamObjectType = {
6820   Feature: function(object, stream) {
6821     streamGeometry(object.geometry, stream);
6822   },
6823   FeatureCollection: function(object, stream) {
6824     var features = object.features, i = -1, n = features.length;
6825     while (++i < n) streamGeometry(features[i].geometry, stream);
6826   }
6827 };
6828
6829 var streamGeometryType = {
6830   Sphere: function(object, stream) {
6831     stream.sphere();
6832   },
6833   Point: function(object, stream) {
6834     object = object.coordinates;
6835     stream.point(object[0], object[1], object[2]);
6836   },
6837   MultiPoint: function(object, stream) {
6838     var coordinates = object.coordinates, i = -1, n = coordinates.length;
6839     while (++i < n) object = coordinates[i], stream.point(object[0], object[1], object[2]);
6840   },
6841   LineString: function(object, stream) {
6842     streamLine(object.coordinates, stream, 0);
6843   },
6844   MultiLineString: function(object, stream) {
6845     var coordinates = object.coordinates, i = -1, n = coordinates.length;
6846     while (++i < n) streamLine(coordinates[i], stream, 0);
6847   },
6848   Polygon: function(object, stream) {
6849     streamPolygon(object.coordinates, stream);
6850   },
6851   MultiPolygon: function(object, stream) {
6852     var coordinates = object.coordinates, i = -1, n = coordinates.length;
6853     while (++i < n) streamPolygon(coordinates[i], stream);
6854   },
6855   GeometryCollection: function(object, stream) {
6856     var geometries = object.geometries, i = -1, n = geometries.length;
6857     while (++i < n) streamGeometry(geometries[i], stream);
6858   }
6859 };
6860
6861 function streamLine(coordinates, stream, closed) {
6862   var i = -1, n = coordinates.length - closed, coordinate;
6863   stream.lineStart();
6864   while (++i < n) coordinate = coordinates[i], stream.point(coordinate[0], coordinate[1], coordinate[2]);
6865   stream.lineEnd();
6866 }
6867
6868 function streamPolygon(coordinates, stream) {
6869   var i = -1, n = coordinates.length;
6870   stream.polygonStart();
6871   while (++i < n) streamLine(coordinates[i], stream, 1);
6872   stream.polygonEnd();
6873 }
6874
6875 function d3_geoStream(object, stream) {
6876   if (object && streamObjectType.hasOwnProperty(object.type)) {
6877     streamObjectType[object.type](object, stream);
6878   } else {
6879     streamGeometry(object, stream);
6880   }
6881 }
6882
6883 var areaRingSum = adder();
6884
6885 var areaSum = adder();
6886 var lambda00;
6887 var phi00;
6888 var lambda0;
6889 var cosPhi0;
6890 var sinPhi0;
6891
6892 var areaStream = {
6893   point: noop$1,
6894   lineStart: noop$1,
6895   lineEnd: noop$1,
6896   polygonStart: function() {
6897     areaRingSum.reset();
6898     areaStream.lineStart = areaRingStart;
6899     areaStream.lineEnd = areaRingEnd;
6900   },
6901   polygonEnd: function() {
6902     var areaRing = +areaRingSum;
6903     areaSum.add(areaRing < 0 ? tau$3 + areaRing : areaRing);
6904     this.lineStart = this.lineEnd = this.point = noop$1;
6905   },
6906   sphere: function() {
6907     areaSum.add(tau$3);
6908   }
6909 };
6910
6911 function areaRingStart() {
6912   areaStream.point = areaPointFirst;
6913 }
6914
6915 function areaRingEnd() {
6916   areaPoint(lambda00, phi00);
6917 }
6918
6919 function areaPointFirst(lambda, phi) {
6920   areaStream.point = areaPoint;
6921   lambda00 = lambda, phi00 = phi;
6922   lambda *= radians, phi *= radians;
6923   lambda0 = lambda, cosPhi0 = cos$1(phi = phi / 2 + quarterPi), sinPhi0 = sin$1(phi);
6924 }
6925
6926 function areaPoint(lambda, phi) {
6927   lambda *= radians, phi *= radians;
6928   phi = phi / 2 + quarterPi; // half the angular distance from south pole
6929
6930   // Spherical excess E for a spherical triangle with vertices: south pole,
6931   // previous point, current point.  Uses a formula derived from Cagnoli’s
6932   // theorem.  See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2).
6933   var dLambda = lambda - lambda0,
6934       sdLambda = dLambda >= 0 ? 1 : -1,
6935       adLambda = sdLambda * dLambda,
6936       cosPhi = cos$1(phi),
6937       sinPhi = sin$1(phi),
6938       k = sinPhi0 * sinPhi,
6939       u = cosPhi0 * cosPhi + k * cos$1(adLambda),
6940       v = k * sdLambda * sin$1(adLambda);
6941   areaRingSum.add(atan2(v, u));
6942
6943   // Advance the previous points.
6944   lambda0 = lambda, cosPhi0 = cosPhi, sinPhi0 = sinPhi;
6945 }
6946
6947 function d3_geoArea(object) {
6948   areaSum.reset();
6949   d3_geoStream(object, areaStream);
6950   return areaSum * 2;
6951 }
6952
6953 function spherical(cartesian) {
6954   return [atan2(cartesian[1], cartesian[0]), asin(cartesian[2])];
6955 }
6956
6957 function cartesian(spherical) {
6958   var lambda = spherical[0], phi = spherical[1], cosPhi = cos$1(phi);
6959   return [cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi)];
6960 }
6961
6962 function cartesianDot(a, b) {
6963   return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
6964 }
6965
6966 function cartesianCross(a, b) {
6967   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]];
6968 }
6969
6970 // TODO return a
6971 function cartesianAddInPlace(a, b) {
6972   a[0] += b[0], a[1] += b[1], a[2] += b[2];
6973 }
6974
6975 function cartesianScale(vector, k) {
6976   return [vector[0] * k, vector[1] * k, vector[2] * k];
6977 }
6978
6979 // TODO return d
6980 function cartesianNormalizeInPlace(d) {
6981   var l = sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
6982   d[0] /= l, d[1] /= l, d[2] /= l;
6983 }
6984
6985 var lambda0$1;
6986 var phi0;
6987 var lambda1;
6988 var phi1;
6989 var lambda2;
6990 var lambda00$1;
6991 var phi00$1;
6992 var p0;
6993 var deltaSum = adder();
6994 var ranges;
6995 var range;
6996
6997 var boundsStream = {
6998   point: boundsPoint,
6999   lineStart: boundsLineStart,
7000   lineEnd: boundsLineEnd,
7001   polygonStart: function() {
7002     boundsStream.point = boundsRingPoint;
7003     boundsStream.lineStart = boundsRingStart;
7004     boundsStream.lineEnd = boundsRingEnd;
7005     deltaSum.reset();
7006     areaStream.polygonStart();
7007   },
7008   polygonEnd: function() {
7009     areaStream.polygonEnd();
7010     boundsStream.point = boundsPoint;
7011     boundsStream.lineStart = boundsLineStart;
7012     boundsStream.lineEnd = boundsLineEnd;
7013     if (areaRingSum < 0) lambda0$1 = -(lambda1 = 180), phi0 = -(phi1 = 90);
7014     else if (deltaSum > epsilon$2) phi1 = 90;
7015     else if (deltaSum < -epsilon$2) phi0 = -90;
7016     range[0] = lambda0$1, range[1] = lambda1;
7017   }
7018 };
7019
7020 function boundsPoint(lambda, phi) {
7021   ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]);
7022   if (phi < phi0) phi0 = phi;
7023   if (phi > phi1) phi1 = phi;
7024 }
7025
7026 function linePoint(lambda, phi) {
7027   var p = cartesian([lambda * radians, phi * radians]);
7028   if (p0) {
7029     var normal = cartesianCross(p0, p),
7030         equatorial = [normal[1], -normal[0], 0],
7031         inflection = cartesianCross(equatorial, normal);
7032     cartesianNormalizeInPlace(inflection);
7033     inflection = spherical(inflection);
7034     var delta = lambda - lambda2,
7035         sign$$1 = delta > 0 ? 1 : -1,
7036         lambdai = inflection[0] * degrees$1 * sign$$1,
7037         phii,
7038         antimeridian = abs(delta) > 180;
7039     if (antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {
7040       phii = inflection[1] * degrees$1;
7041       if (phii > phi1) phi1 = phii;
7042     } else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {
7043       phii = -inflection[1] * degrees$1;
7044       if (phii < phi0) phi0 = phii;
7045     } else {
7046       if (phi < phi0) phi0 = phi;
7047       if (phi > phi1) phi1 = phi;
7048     }
7049     if (antimeridian) {
7050       if (lambda < lambda2) {
7051         if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;
7052       } else {
7053         if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;
7054       }
7055     } else {
7056       if (lambda1 >= lambda0$1) {
7057         if (lambda < lambda0$1) lambda0$1 = lambda;
7058         if (lambda > lambda1) lambda1 = lambda;
7059       } else {
7060         if (lambda > lambda2) {
7061           if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;
7062         } else {
7063           if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;
7064         }
7065       }
7066     }
7067   } else {
7068     ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]);
7069   }
7070   if (phi < phi0) phi0 = phi;
7071   if (phi > phi1) phi1 = phi;
7072   p0 = p, lambda2 = lambda;
7073 }
7074
7075 function boundsLineStart() {
7076   boundsStream.point = linePoint;
7077 }
7078
7079 function boundsLineEnd() {
7080   range[0] = lambda0$1, range[1] = lambda1;
7081   boundsStream.point = boundsPoint;
7082   p0 = null;
7083 }
7084
7085 function boundsRingPoint(lambda, phi) {
7086   if (p0) {
7087     var delta = lambda - lambda2;
7088     deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta);
7089   } else {
7090     lambda00$1 = lambda, phi00$1 = phi;
7091   }
7092   areaStream.point(lambda, phi);
7093   linePoint(lambda, phi);
7094 }
7095
7096 function boundsRingStart() {
7097   areaStream.lineStart();
7098 }
7099
7100 function boundsRingEnd() {
7101   boundsRingPoint(lambda00$1, phi00$1);
7102   areaStream.lineEnd();
7103   if (abs(deltaSum) > epsilon$2) lambda0$1 = -(lambda1 = 180);
7104   range[0] = lambda0$1, range[1] = lambda1;
7105   p0 = null;
7106 }
7107
7108 // Finds the left-right distance between two longitudes.
7109 // This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want
7110 // the distance between ±180° to be 360°.
7111 function angle(lambda0, lambda1) {
7112   return (lambda1 -= lambda0) < 0 ? lambda1 + 360 : lambda1;
7113 }
7114
7115 function rangeCompare(a, b) {
7116   return a[0] - b[0];
7117 }
7118
7119 function rangeContains(range, x) {
7120   return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x;
7121 }
7122
7123 function d3_geoBounds(feature) {
7124   var i, n, a, b, merged, deltaMax, delta;
7125
7126   phi1 = lambda1 = -(lambda0$1 = phi0 = Infinity);
7127   ranges = [];
7128   d3_geoStream(feature, boundsStream);
7129
7130   // First, sort ranges by their minimum longitudes.
7131   if (n = ranges.length) {
7132     ranges.sort(rangeCompare);
7133
7134     // Then, merge any ranges that overlap.
7135     for (i = 1, a = ranges[0], merged = [a]; i < n; ++i) {
7136       b = ranges[i];
7137       if (rangeContains(a, b[0]) || rangeContains(a, b[1])) {
7138         if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1];
7139         if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0];
7140       } else {
7141         merged.push(a = b);
7142       }
7143     }
7144
7145     // Finally, find the largest gap between the merged ranges.
7146     // The final bounding box will be the inverse of this gap.
7147     for (deltaMax = -Infinity, n = merged.length - 1, i = 0, a = merged[n]; i <= n; a = b, ++i) {
7148       b = merged[i];
7149       if ((delta = angle(a[1], b[0])) > deltaMax) deltaMax = delta, lambda0$1 = b[0], lambda1 = a[1];
7150     }
7151   }
7152
7153   ranges = range = null;
7154
7155   return lambda0$1 === Infinity || phi0 === Infinity
7156       ? [[NaN, NaN], [NaN, NaN]]
7157       : [[lambda0$1, phi0], [lambda1, phi1]];
7158 }
7159
7160 var W0;
7161 var W1;
7162 var X0;
7163 var Y0;
7164 var Z0;
7165 var X1;
7166 var Y1;
7167 var Z1;
7168 var X2;
7169 var Y2;
7170 var Z2;
7171 var lambda00$2;
7172 var phi00$2;
7173 var x0;
7174 var y0;
7175 var z0; // previous point
7176
7177 var centroidStream = {
7178   sphere: noop$1,
7179   point: centroidPoint,
7180   lineStart: centroidLineStart,
7181   lineEnd: centroidLineEnd,
7182   polygonStart: function() {
7183     centroidStream.lineStart = centroidRingStart;
7184     centroidStream.lineEnd = centroidRingEnd;
7185   },
7186   polygonEnd: function() {
7187     centroidStream.lineStart = centroidLineStart;
7188     centroidStream.lineEnd = centroidLineEnd;
7189   }
7190 };
7191
7192 // Arithmetic mean of Cartesian vectors.
7193 function centroidPoint(lambda, phi) {
7194   lambda *= radians, phi *= radians;
7195   var cosPhi = cos$1(phi);
7196   centroidPointCartesian(cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi));
7197 }
7198
7199 function centroidPointCartesian(x, y, z) {
7200   ++W0;
7201   X0 += (x - X0) / W0;
7202   Y0 += (y - Y0) / W0;
7203   Z0 += (z - Z0) / W0;
7204 }
7205
7206 function centroidLineStart() {
7207   centroidStream.point = centroidLinePointFirst;
7208 }
7209
7210 function centroidLinePointFirst(lambda, phi) {
7211   lambda *= radians, phi *= radians;
7212   var cosPhi = cos$1(phi);
7213   x0 = cosPhi * cos$1(lambda);
7214   y0 = cosPhi * sin$1(lambda);
7215   z0 = sin$1(phi);
7216   centroidStream.point = centroidLinePoint;
7217   centroidPointCartesian(x0, y0, z0);
7218 }
7219
7220 function centroidLinePoint(lambda, phi) {
7221   lambda *= radians, phi *= radians;
7222   var cosPhi = cos$1(phi),
7223       x = cosPhi * cos$1(lambda),
7224       y = cosPhi * sin$1(lambda),
7225       z = sin$1(phi),
7226       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);
7227   W1 += w;
7228   X1 += w * (x0 + (x0 = x));
7229   Y1 += w * (y0 + (y0 = y));
7230   Z1 += w * (z0 + (z0 = z));
7231   centroidPointCartesian(x0, y0, z0);
7232 }
7233
7234 function centroidLineEnd() {
7235   centroidStream.point = centroidPoint;
7236 }
7237
7238 // See J. E. Brock, The Inertia Tensor for a Spherical Triangle,
7239 // J. Applied Mechanics 42, 239 (1975).
7240 function centroidRingStart() {
7241   centroidStream.point = centroidRingPointFirst;
7242 }
7243
7244 function centroidRingEnd() {
7245   centroidRingPoint(lambda00$2, phi00$2);
7246   centroidStream.point = centroidPoint;
7247 }
7248
7249 function centroidRingPointFirst(lambda, phi) {
7250   lambda00$2 = lambda, phi00$2 = phi;
7251   lambda *= radians, phi *= radians;
7252   centroidStream.point = centroidRingPoint;
7253   var cosPhi = cos$1(phi);
7254   x0 = cosPhi * cos$1(lambda);
7255   y0 = cosPhi * sin$1(lambda);
7256   z0 = sin$1(phi);
7257   centroidPointCartesian(x0, y0, z0);
7258 }
7259
7260 function centroidRingPoint(lambda, phi) {
7261   lambda *= radians, phi *= radians;
7262   var cosPhi = cos$1(phi),
7263       x = cosPhi * cos$1(lambda),
7264       y = cosPhi * sin$1(lambda),
7265       z = sin$1(phi),
7266       cx = y0 * z - z0 * y,
7267       cy = z0 * x - x0 * z,
7268       cz = x0 * y - y0 * x,
7269       m = sqrt(cx * cx + cy * cy + cz * cz),
7270       w = asin(m), // line weight = angle
7271       v = m && -w / m; // area weight multiplier
7272   X2 += v * cx;
7273   Y2 += v * cy;
7274   Z2 += v * cz;
7275   W1 += w;
7276   X1 += w * (x0 + (x0 = x));
7277   Y1 += w * (y0 + (y0 = y));
7278   Z1 += w * (z0 + (z0 = z));
7279   centroidPointCartesian(x0, y0, z0);
7280 }
7281
7282 function d3_geoCentroid(object) {
7283   W0 = W1 =
7284   X0 = Y0 = Z0 =
7285   X1 = Y1 = Z1 =
7286   X2 = Y2 = Z2 = 0;
7287   d3_geoStream(object, centroidStream);
7288
7289   var x = X2,
7290       y = Y2,
7291       z = Z2,
7292       m = x * x + y * y + z * z;
7293
7294   // If the area-weighted ccentroid is undefined, fall back to length-weighted ccentroid.
7295   if (m < epsilon2$1) {
7296     x = X1, y = Y1, z = Z1;
7297     // If the feature has zero length, fall back to arithmetic mean of point vectors.
7298     if (W1 < epsilon$2) x = X0, y = Y0, z = Z0;
7299     m = x * x + y * y + z * z;
7300     // If the feature still has an undefined ccentroid, then return.
7301     if (m < epsilon2$1) return [NaN, NaN];
7302   }
7303
7304   return [atan2(y, x) * degrees$1, asin(z / sqrt(m)) * degrees$1];
7305 }
7306
7307 function constant$7(x) {
7308   return function() {
7309     return x;
7310   };
7311 }
7312
7313 function compose(a, b) {
7314
7315   function compose(x, y) {
7316     return x = a(x, y), b(x[0], x[1]);
7317   }
7318
7319   if (a.invert && b.invert) compose.invert = function(x, y) {
7320     return x = b.invert(x, y), x && a.invert(x[0], x[1]);
7321   };
7322
7323   return compose;
7324 }
7325
7326 function rotationIdentity(lambda, phi) {
7327   return [lambda > pi$3 ? lambda - tau$3 : lambda < -pi$3 ? lambda + tau$3 : lambda, phi];
7328 }
7329
7330 rotationIdentity.invert = rotationIdentity;
7331
7332 function rotateRadians(deltaLambda, deltaPhi, deltaGamma) {
7333   return (deltaLambda %= tau$3) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma))
7334     : rotationLambda(deltaLambda))
7335     : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma)
7336     : rotationIdentity);
7337 }
7338
7339 function forwardRotationLambda(deltaLambda) {
7340   return function(lambda, phi) {
7341     return lambda += deltaLambda, [lambda > pi$3 ? lambda - tau$3 : lambda < -pi$3 ? lambda + tau$3 : lambda, phi];
7342   };
7343 }
7344
7345 function rotationLambda(deltaLambda) {
7346   var rotation = forwardRotationLambda(deltaLambda);
7347   rotation.invert = forwardRotationLambda(-deltaLambda);
7348   return rotation;
7349 }
7350
7351 function rotationPhiGamma(deltaPhi, deltaGamma) {
7352   var cosDeltaPhi = cos$1(deltaPhi),
7353       sinDeltaPhi = sin$1(deltaPhi),
7354       cosDeltaGamma = cos$1(deltaGamma),
7355       sinDeltaGamma = sin$1(deltaGamma);
7356
7357   function rotation(lambda, phi) {
7358     var cosPhi = cos$1(phi),
7359         x = cos$1(lambda) * cosPhi,
7360         y = sin$1(lambda) * cosPhi,
7361         z = sin$1(phi),
7362         k = z * cosDeltaPhi + x * sinDeltaPhi;
7363     return [
7364       atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi),
7365       asin(k * cosDeltaGamma + y * sinDeltaGamma)
7366     ];
7367   }
7368
7369   rotation.invert = function(lambda, phi) {
7370     var cosPhi = cos$1(phi),
7371         x = cos$1(lambda) * cosPhi,
7372         y = sin$1(lambda) * cosPhi,
7373         z = sin$1(phi),
7374         k = z * cosDeltaGamma - y * sinDeltaGamma;
7375     return [
7376       atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi),
7377       asin(k * cosDeltaPhi - x * sinDeltaPhi)
7378     ];
7379   };
7380
7381   return rotation;
7382 }
7383
7384 function rotation(rotate) {
7385   rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0);
7386
7387   function forward(coordinates) {
7388     coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians);
7389     return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates;
7390   }
7391
7392   forward.invert = function(coordinates) {
7393     coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians);
7394     return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates;
7395   };
7396
7397   return forward;
7398 }
7399
7400 // Generates a circle centered at [0°, 0°], with a given radius and precision.
7401 function circleStream(stream, radius, delta, direction, t0, t1) {
7402   if (!delta) return;
7403   var cosRadius = cos$1(radius),
7404       sinRadius = sin$1(radius),
7405       step = direction * delta;
7406   if (t0 == null) {
7407     t0 = radius + direction * tau$3;
7408     t1 = radius - step / 2;
7409   } else {
7410     t0 = circleRadius(cosRadius, t0);
7411     t1 = circleRadius(cosRadius, t1);
7412     if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau$3;
7413   }
7414   for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) {
7415     point = spherical([cosRadius, -sinRadius * cos$1(t), -sinRadius * sin$1(t)]);
7416     stream.point(point[0], point[1]);
7417   }
7418 }
7419
7420 // Returns the signed angle of a cartesian point relative to [cosRadius, 0, 0].
7421 function circleRadius(cosRadius, point) {
7422   point = cartesian(point), point[0] -= cosRadius;
7423   cartesianNormalizeInPlace(point);
7424   var radius = acos(-point[1]);
7425   return ((-point[2] < 0 ? -radius : radius) + tau$3 - epsilon$2) % tau$3;
7426 }
7427
7428 function circle() {
7429   var center = constant$7([0, 0]),
7430       radius = constant$7(90),
7431       precision = constant$7(6),
7432       ring,
7433       rotate,
7434       stream = {point: point};
7435
7436   function point(x, y) {
7437     ring.push(x = rotate(x, y));
7438     x[0] *= degrees$1, x[1] *= degrees$1;
7439   }
7440
7441   function circle() {
7442     var c = center.apply(this, arguments),
7443         r = radius.apply(this, arguments) * radians,
7444         p = precision.apply(this, arguments) * radians;
7445     ring = [];
7446     rotate = rotateRadians(-c[0] * radians, -c[1] * radians, 0).invert;
7447     circleStream(stream, r, p, 1);
7448     c = {type: "Polygon", coordinates: [ring]};
7449     ring = rotate = null;
7450     return c;
7451   }
7452
7453   circle.center = function(_) {
7454     return arguments.length ? (center = typeof _ === "function" ? _ : constant$7([+_[0], +_[1]]), circle) : center;
7455   };
7456
7457   circle.radius = function(_) {
7458     return arguments.length ? (radius = typeof _ === "function" ? _ : constant$7(+_), circle) : radius;
7459   };
7460
7461   circle.precision = function(_) {
7462     return arguments.length ? (precision = typeof _ === "function" ? _ : constant$7(+_), circle) : precision;
7463   };
7464
7465   return circle;
7466 }
7467
7468 function clipBuffer() {
7469   var lines = [],
7470       line;
7471   return {
7472     point: function(x, y) {
7473       line.push([x, y]);
7474     },
7475     lineStart: function() {
7476       lines.push(line = []);
7477     },
7478     lineEnd: noop$1,
7479     rejoin: function() {
7480       if (lines.length > 1) lines.push(lines.pop().concat(lines.shift()));
7481     },
7482     result: function() {
7483       var result = lines;
7484       lines = [];
7485       line = null;
7486       return result;
7487     }
7488   };
7489 }
7490
7491 function pointEqual(a, b) {
7492   return abs(a[0] - b[0]) < epsilon$2 && abs(a[1] - b[1]) < epsilon$2;
7493 }
7494
7495 function Intersection(point, points, other, entry) {
7496   this.x = point;
7497   this.z = points;
7498   this.o = other; // another intersection
7499   this.e = entry; // is an entry?
7500   this.v = false; // visited
7501   this.n = this.p = null; // next & previous
7502 }
7503
7504 // A generalized polygon clipping algorithm: given a polygon that has been cut
7505 // into its visible line segments, and rejoins the segments by interpolating
7506 // along the clip edge.
7507 function clipRejoin(segments, compareIntersection, startInside, interpolate, stream) {
7508   var subject = [],
7509       clip = [],
7510       i,
7511       n;
7512
7513   segments.forEach(function(segment) {
7514     if ((n = segment.length - 1) <= 0) return;
7515     var n, p0 = segment[0], p1 = segment[n], x;
7516
7517     // If the first and last points of a segment are coincident, then treat as a
7518     // closed ring. TODO if all rings are closed, then the winding order of the
7519     // exterior ring should be checked.
7520     if (pointEqual(p0, p1)) {
7521       stream.lineStart();
7522       for (i = 0; i < n; ++i) stream.point((p0 = segment[i])[0], p0[1]);
7523       stream.lineEnd();
7524       return;
7525     }
7526
7527     subject.push(x = new Intersection(p0, segment, null, true));
7528     clip.push(x.o = new Intersection(p0, null, x, false));
7529     subject.push(x = new Intersection(p1, segment, null, false));
7530     clip.push(x.o = new Intersection(p1, null, x, true));
7531   });
7532
7533   if (!subject.length) return;
7534
7535   clip.sort(compareIntersection);
7536   link$1(subject);
7537   link$1(clip);
7538
7539   for (i = 0, n = clip.length; i < n; ++i) {
7540     clip[i].e = startInside = !startInside;
7541   }
7542
7543   var start = subject[0],
7544       points,
7545       point;
7546
7547   while (1) {
7548     // Find first unvisited intersection.
7549     var current = start,
7550         isSubject = true;
7551     while (current.v) if ((current = current.n) === start) return;
7552     points = current.z;
7553     stream.lineStart();
7554     do {
7555       current.v = current.o.v = true;
7556       if (current.e) {
7557         if (isSubject) {
7558           for (i = 0, n = points.length; i < n; ++i) stream.point((point = points[i])[0], point[1]);
7559         } else {
7560           interpolate(current.x, current.n.x, 1, stream);
7561         }
7562         current = current.n;
7563       } else {
7564         if (isSubject) {
7565           points = current.p.z;
7566           for (i = points.length - 1; i >= 0; --i) stream.point((point = points[i])[0], point[1]);
7567         } else {
7568           interpolate(current.x, current.p.x, -1, stream);
7569         }
7570         current = current.p;
7571       }
7572       current = current.o;
7573       points = current.z;
7574       isSubject = !isSubject;
7575     } while (!current.v);
7576     stream.lineEnd();
7577   }
7578 }
7579
7580 function link$1(array) {
7581   if (!(n = array.length)) return;
7582   var n,
7583       i = 0,
7584       a = array[0],
7585       b;
7586   while (++i < n) {
7587     a.n = b = array[i];
7588     b.p = a;
7589     a = b;
7590   }
7591   a.n = b = array[0];
7592   b.p = a;
7593 }
7594
7595 var sum$1 = adder();
7596
7597 function polygonContains(polygon, point) {
7598   var lambda = point[0],
7599       phi = point[1],
7600       normal = [sin$1(lambda), -cos$1(lambda), 0],
7601       angle = 0,
7602       winding = 0;
7603
7604   sum$1.reset();
7605
7606   for (var i = 0, n = polygon.length; i < n; ++i) {
7607     if (!(m = (ring = polygon[i]).length)) continue;
7608     var ring,
7609         m,
7610         point0 = ring[m - 1],
7611         lambda0 = point0[0],
7612         phi0 = point0[1] / 2 + quarterPi,
7613         sinPhi0 = sin$1(phi0),
7614         cosPhi0 = cos$1(phi0);
7615
7616     for (var j = 0; j < m; ++j, lambda0 = lambda1, sinPhi0 = sinPhi1, cosPhi0 = cosPhi1, point0 = point1) {
7617       var point1 = ring[j],
7618           lambda1 = point1[0],
7619           phi1 = point1[1] / 2 + quarterPi,
7620           sinPhi1 = sin$1(phi1),
7621           cosPhi1 = cos$1(phi1),
7622           delta = lambda1 - lambda0,
7623           sign$$1 = delta >= 0 ? 1 : -1,
7624           absDelta = sign$$1 * delta,
7625           antimeridian = absDelta > pi$3,
7626           k = sinPhi0 * sinPhi1;
7627
7628       sum$1.add(atan2(k * sign$$1 * sin$1(absDelta), cosPhi0 * cosPhi1 + k * cos$1(absDelta)));
7629       angle += antimeridian ? delta + sign$$1 * tau$3 : delta;
7630
7631       // Are the longitudes either side of the point’s meridian (lambda),
7632       // and are the latitudes smaller than the parallel (phi)?
7633       if (antimeridian ^ lambda0 >= lambda ^ lambda1 >= lambda) {
7634         var arc = cartesianCross(cartesian(point0), cartesian(point1));
7635         cartesianNormalizeInPlace(arc);
7636         var intersection = cartesianCross(normal, arc);
7637         cartesianNormalizeInPlace(intersection);
7638         var phiArc = (antimeridian ^ delta >= 0 ? -1 : 1) * asin(intersection[2]);
7639         if (phi > phiArc || phi === phiArc && (arc[0] || arc[1])) {
7640           winding += antimeridian ^ delta >= 0 ? 1 : -1;
7641         }
7642       }
7643     }
7644   }
7645
7646   // First, determine whether the South pole is inside or outside:
7647   //
7648   // It is inside if:
7649   // * the polygon winds around it in a clockwise direction.
7650   // * the polygon does not (cumulatively) wind around it, but has a negative
7651   //   (counter-clockwise) area.
7652   //
7653   // Second, count the (signed) number of times a segment crosses a lambda
7654   // from the point to the South pole.  If it is zero, then the point is the
7655   // same side as the South pole.
7656
7657   return (angle < -epsilon$2 || angle < epsilon$2 && sum$1 < -epsilon$2) ^ (winding & 1);
7658 }
7659
7660 function clip(pointVisible, clipLine, interpolate, start) {
7661   return function(sink) {
7662     var line = clipLine(sink),
7663         ringBuffer = clipBuffer(),
7664         ringSink = clipLine(ringBuffer),
7665         polygonStarted = false,
7666         polygon,
7667         segments,
7668         ring;
7669
7670     var clip = {
7671       point: point,
7672       lineStart: lineStart,
7673       lineEnd: lineEnd,
7674       polygonStart: function() {
7675         clip.point = pointRing;
7676         clip.lineStart = ringStart;
7677         clip.lineEnd = ringEnd;
7678         segments = [];
7679         polygon = [];
7680       },
7681       polygonEnd: function() {
7682         clip.point = point;
7683         clip.lineStart = lineStart;
7684         clip.lineEnd = lineEnd;
7685         segments = merge(segments);
7686         var startInside = polygonContains(polygon, start);
7687         if (segments.length) {
7688           if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
7689           clipRejoin(segments, compareIntersection, startInside, interpolate, sink);
7690         } else if (startInside) {
7691           if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
7692           sink.lineStart();
7693           interpolate(null, null, 1, sink);
7694           sink.lineEnd();
7695         }
7696         if (polygonStarted) sink.polygonEnd(), polygonStarted = false;
7697         segments = polygon = null;
7698       },
7699       sphere: function() {
7700         sink.polygonStart();
7701         sink.lineStart();
7702         interpolate(null, null, 1, sink);
7703         sink.lineEnd();
7704         sink.polygonEnd();
7705       }
7706     };
7707
7708     function point(lambda, phi) {
7709       if (pointVisible(lambda, phi)) sink.point(lambda, phi);
7710     }
7711
7712     function pointLine(lambda, phi) {
7713       line.point(lambda, phi);
7714     }
7715
7716     function lineStart() {
7717       clip.point = pointLine;
7718       line.lineStart();
7719     }
7720
7721     function lineEnd() {
7722       clip.point = point;
7723       line.lineEnd();
7724     }
7725
7726     function pointRing(lambda, phi) {
7727       ring.push([lambda, phi]);
7728       ringSink.point(lambda, phi);
7729     }
7730
7731     function ringStart() {
7732       ringSink.lineStart();
7733       ring = [];
7734     }
7735
7736     function ringEnd() {
7737       pointRing(ring[0][0], ring[0][1]);
7738       ringSink.lineEnd();
7739
7740       var clean = ringSink.clean(),
7741           ringSegments = ringBuffer.result(),
7742           i, n = ringSegments.length, m,
7743           segment,
7744           point;
7745
7746       ring.pop();
7747       polygon.push(ring);
7748       ring = null;
7749
7750       if (!n) return;
7751
7752       // No intersections.
7753       if (clean & 1) {
7754         segment = ringSegments[0];
7755         if ((m = segment.length - 1) > 0) {
7756           if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
7757           sink.lineStart();
7758           for (i = 0; i < m; ++i) sink.point((point = segment[i])[0], point[1]);
7759           sink.lineEnd();
7760         }
7761         return;
7762       }
7763
7764       // Rejoin connected segments.
7765       // TODO reuse ringBuffer.rejoin()?
7766       if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));
7767
7768       segments.push(ringSegments.filter(validSegment));
7769     }
7770
7771     return clip;
7772   };
7773 }
7774
7775 function validSegment(segment) {
7776   return segment.length > 1;
7777 }
7778
7779 // Intersections are sorted along the clip edge. For both antimeridian cutting
7780 // and circle clipping, the same comparison is used.
7781 function compareIntersection(a, b) {
7782   return ((a = a.x)[0] < 0 ? a[1] - halfPi$2 - epsilon$2 : halfPi$2 - a[1])
7783        - ((b = b.x)[0] < 0 ? b[1] - halfPi$2 - epsilon$2 : halfPi$2 - b[1]);
7784 }
7785
7786 var clipAntimeridian = clip(
7787   function() { return true; },
7788   clipAntimeridianLine,
7789   clipAntimeridianInterpolate,
7790   [-pi$3, -halfPi$2]
7791 );
7792
7793 // Takes a line and cuts into visible segments. Return values: 0 - there were
7794 // intersections or the line was empty; 1 - no intersections; 2 - there were
7795 // intersections, and the first and last segments should be rejoined.
7796 function clipAntimeridianLine(stream) {
7797   var lambda0 = NaN,
7798       phi0 = NaN,
7799       sign0 = NaN,
7800       clean; // no intersections
7801
7802   return {
7803     lineStart: function() {
7804       stream.lineStart();
7805       clean = 1;
7806     },
7807     point: function(lambda1, phi1) {
7808       var sign1 = lambda1 > 0 ? pi$3 : -pi$3,
7809           delta = abs(lambda1 - lambda0);
7810       if (abs(delta - pi$3) < epsilon$2) { // line crosses a pole
7811         stream.point(lambda0, phi0 = (phi0 + phi1) / 2 > 0 ? halfPi$2 : -halfPi$2);
7812         stream.point(sign0, phi0);
7813         stream.lineEnd();
7814         stream.lineStart();
7815         stream.point(sign1, phi0);
7816         stream.point(lambda1, phi0);
7817         clean = 0;
7818       } else if (sign0 !== sign1 && delta >= pi$3) { // line crosses antimeridian
7819         if (abs(lambda0 - sign0) < epsilon$2) lambda0 -= sign0 * epsilon$2; // handle degeneracies
7820         if (abs(lambda1 - sign1) < epsilon$2) lambda1 -= sign1 * epsilon$2;
7821         phi0 = clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1);
7822         stream.point(sign0, phi0);
7823         stream.lineEnd();
7824         stream.lineStart();
7825         stream.point(sign1, phi0);
7826         clean = 0;
7827       }
7828       stream.point(lambda0 = lambda1, phi0 = phi1);
7829       sign0 = sign1;
7830     },
7831     lineEnd: function() {
7832       stream.lineEnd();
7833       lambda0 = phi0 = NaN;
7834     },
7835     clean: function() {
7836       return 2 - clean; // if intersections, rejoin first and last segments
7837     }
7838   };
7839 }
7840
7841 function clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) {
7842   var cosPhi0,
7843       cosPhi1,
7844       sinLambda0Lambda1 = sin$1(lambda0 - lambda1);
7845   return abs(sinLambda0Lambda1) > epsilon$2
7846       ? atan((sin$1(phi0) * (cosPhi1 = cos$1(phi1)) * sin$1(lambda1)
7847           - sin$1(phi1) * (cosPhi0 = cos$1(phi0)) * sin$1(lambda0))
7848           / (cosPhi0 * cosPhi1 * sinLambda0Lambda1))
7849       : (phi0 + phi1) / 2;
7850 }
7851
7852 function clipAntimeridianInterpolate(from, to, direction, stream) {
7853   var phi;
7854   if (from == null) {
7855     phi = direction * halfPi$2;
7856     stream.point(-pi$3, phi);
7857     stream.point(0, phi);
7858     stream.point(pi$3, phi);
7859     stream.point(pi$3, 0);
7860     stream.point(pi$3, -phi);
7861     stream.point(0, -phi);
7862     stream.point(-pi$3, -phi);
7863     stream.point(-pi$3, 0);
7864     stream.point(-pi$3, phi);
7865   } else if (abs(from[0] - to[0]) > epsilon$2) {
7866     var lambda = from[0] < to[0] ? pi$3 : -pi$3;
7867     phi = direction * lambda / 2;
7868     stream.point(-lambda, phi);
7869     stream.point(0, phi);
7870     stream.point(lambda, phi);
7871   } else {
7872     stream.point(to[0], to[1]);
7873   }
7874 }
7875
7876 function clipCircle(radius) {
7877   var cr = cos$1(radius),
7878       delta = 6 * radians,
7879       smallRadius = cr > 0,
7880       notHemisphere = abs(cr) > epsilon$2; // TODO optimise for this common case
7881
7882   function interpolate(from, to, direction, stream) {
7883     circleStream(stream, radius, delta, direction, from, to);
7884   }
7885
7886   function visible(lambda, phi) {
7887     return cos$1(lambda) * cos$1(phi) > cr;
7888   }
7889
7890   // Takes a line and cuts into visible segments. Return values used for polygon
7891   // clipping: 0 - there were intersections or the line was empty; 1 - no
7892   // intersections 2 - there were intersections, and the first and last segments
7893   // should be rejoined.
7894   function clipLine(stream) {
7895     var point0, // previous point
7896         c0, // code for previous point
7897         v0, // visibility of previous point
7898         v00, // visibility of first point
7899         clean; // no intersections
7900     return {
7901       lineStart: function() {
7902         v00 = v0 = false;
7903         clean = 1;
7904       },
7905       point: function(lambda, phi) {
7906         var point1 = [lambda, phi],
7907             point2,
7908             v = visible(lambda, phi),
7909             c = smallRadius
7910               ? v ? 0 : code(lambda, phi)
7911               : v ? code(lambda + (lambda < 0 ? pi$3 : -pi$3), phi) : 0;
7912         if (!point0 && (v00 = v0 = v)) stream.lineStart();
7913         // Handle degeneracies.
7914         // TODO ignore if not clipping polygons.
7915         if (v !== v0) {
7916           point2 = intersect(point0, point1);
7917           if (!point2 || pointEqual(point0, point2) || pointEqual(point1, point2)) {
7918             point1[0] += epsilon$2;
7919             point1[1] += epsilon$2;
7920             v = visible(point1[0], point1[1]);
7921           }
7922         }
7923         if (v !== v0) {
7924           clean = 0;
7925           if (v) {
7926             // outside going in
7927             stream.lineStart();
7928             point2 = intersect(point1, point0);
7929             stream.point(point2[0], point2[1]);
7930           } else {
7931             // inside going out
7932             point2 = intersect(point0, point1);
7933             stream.point(point2[0], point2[1]);
7934             stream.lineEnd();
7935           }
7936           point0 = point2;
7937         } else if (notHemisphere && point0 && smallRadius ^ v) {
7938           var t;
7939           // If the codes for two points are different, or are both zero,
7940           // and there this segment intersects with the small circle.
7941           if (!(c & c0) && (t = intersect(point1, point0, true))) {
7942             clean = 0;
7943             if (smallRadius) {
7944               stream.lineStart();
7945               stream.point(t[0][0], t[0][1]);
7946               stream.point(t[1][0], t[1][1]);
7947               stream.lineEnd();
7948             } else {
7949               stream.point(t[1][0], t[1][1]);
7950               stream.lineEnd();
7951               stream.lineStart();
7952               stream.point(t[0][0], t[0][1]);
7953             }
7954           }
7955         }
7956         if (v && (!point0 || !pointEqual(point0, point1))) {
7957           stream.point(point1[0], point1[1]);
7958         }
7959         point0 = point1, v0 = v, c0 = c;
7960       },
7961       lineEnd: function() {
7962         if (v0) stream.lineEnd();
7963         point0 = null;
7964       },
7965       // Rejoin first and last segments if there were intersections and the first
7966       // and last points were visible.
7967       clean: function() {
7968         return clean | ((v00 && v0) << 1);
7969       }
7970     };
7971   }
7972
7973   // Intersects the great circle between a and b with the clip circle.
7974   function intersect(a, b, two) {
7975     var pa = cartesian(a),
7976         pb = cartesian(b);
7977
7978     // We have two planes, n1.p = d1 and n2.p = d2.
7979     // Find intersection line p(t) = c1 n1 + c2 n2 + t (n1 ⨯ n2).
7980     var n1 = [1, 0, 0], // normal
7981         n2 = cartesianCross(pa, pb),
7982         n2n2 = cartesianDot(n2, n2),
7983         n1n2 = n2[0], // cartesianDot(n1, n2),
7984         determinant = n2n2 - n1n2 * n1n2;
7985
7986     // Two polar points.
7987     if (!determinant) return !two && a;
7988
7989     var c1 =  cr * n2n2 / determinant,
7990         c2 = -cr * n1n2 / determinant,
7991         n1xn2 = cartesianCross(n1, n2),
7992         A = cartesianScale(n1, c1),
7993         B = cartesianScale(n2, c2);
7994     cartesianAddInPlace(A, B);
7995
7996     // Solve |p(t)|^2 = 1.
7997     var u = n1xn2,
7998         w = cartesianDot(A, u),
7999         uu = cartesianDot(u, u),
8000         t2 = w * w - uu * (cartesianDot(A, A) - 1);
8001
8002     if (t2 < 0) return;
8003
8004     var t = sqrt(t2),
8005         q = cartesianScale(u, (-w - t) / uu);
8006     cartesianAddInPlace(q, A);
8007     q = spherical(q);
8008
8009     if (!two) return q;
8010
8011     // Two intersection points.
8012     var lambda0 = a[0],
8013         lambda1 = b[0],
8014         phi0 = a[1],
8015         phi1 = b[1],
8016         z;
8017
8018     if (lambda1 < lambda0) z = lambda0, lambda0 = lambda1, lambda1 = z;
8019
8020     var delta = lambda1 - lambda0,
8021         polar = abs(delta - pi$3) < epsilon$2,
8022         meridian = polar || delta < epsilon$2;
8023
8024     if (!polar && phi1 < phi0) z = phi0, phi0 = phi1, phi1 = z;
8025
8026     // Check that the first point is between a and b.
8027     if (meridian
8028         ? polar
8029           ? phi0 + phi1 > 0 ^ q[1] < (abs(q[0] - lambda0) < epsilon$2 ? phi0 : phi1)
8030           : phi0 <= q[1] && q[1] <= phi1
8031         : delta > pi$3 ^ (lambda0 <= q[0] && q[0] <= lambda1)) {
8032       var q1 = cartesianScale(u, (-w + t) / uu);
8033       cartesianAddInPlace(q1, A);
8034       return [q, spherical(q1)];
8035     }
8036   }
8037
8038   // Generates a 4-bit vector representing the location of a point relative to
8039   // the small circle's bounding box.
8040   function code(lambda, phi) {
8041     var r = smallRadius ? radius : pi$3 - radius,
8042         code = 0;
8043     if (lambda < -r) code |= 1; // left
8044     else if (lambda > r) code |= 2; // right
8045     if (phi < -r) code |= 4; // below
8046     else if (phi > r) code |= 8; // above
8047     return code;
8048   }
8049
8050   return clip(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-pi$3, radius - pi$3]);
8051 }
8052
8053 function clipLine(a, b, x0, y0, x1, y1) {
8054   var ax = a[0],
8055       ay = a[1],
8056       bx = b[0],
8057       by = b[1],
8058       t0 = 0,
8059       t1 = 1,
8060       dx = bx - ax,
8061       dy = by - ay,
8062       r;
8063
8064   r = x0 - ax;
8065   if (!dx && r > 0) return;
8066   r /= dx;
8067   if (dx < 0) {
8068     if (r < t0) return;
8069     if (r < t1) t1 = r;
8070   } else if (dx > 0) {
8071     if (r > t1) return;
8072     if (r > t0) t0 = r;
8073   }
8074
8075   r = x1 - ax;
8076   if (!dx && r < 0) return;
8077   r /= dx;
8078   if (dx < 0) {
8079     if (r > t1) return;
8080     if (r > t0) t0 = r;
8081   } else if (dx > 0) {
8082     if (r < t0) return;
8083     if (r < t1) t1 = r;
8084   }
8085
8086   r = y0 - ay;
8087   if (!dy && r > 0) return;
8088   r /= dy;
8089   if (dy < 0) {
8090     if (r < t0) return;
8091     if (r < t1) t1 = r;
8092   } else if (dy > 0) {
8093     if (r > t1) return;
8094     if (r > t0) t0 = r;
8095   }
8096
8097   r = y1 - ay;
8098   if (!dy && r < 0) return;
8099   r /= dy;
8100   if (dy < 0) {
8101     if (r > t1) return;
8102     if (r > t0) t0 = r;
8103   } else if (dy > 0) {
8104     if (r < t0) return;
8105     if (r < t1) t1 = r;
8106   }
8107
8108   if (t0 > 0) a[0] = ax + t0 * dx, a[1] = ay + t0 * dy;
8109   if (t1 < 1) b[0] = ax + t1 * dx, b[1] = ay + t1 * dy;
8110   return true;
8111 }
8112
8113 var clipMax = 1e9;
8114 var clipMin = -clipMax;
8115
8116 // TODO Use d3-polygon’s polygonContains here for the ring check?
8117 // TODO Eliminate duplicate buffering in clipBuffer and polygon.push?
8118
8119 function clipRectangle(x0, y0, x1, y1) {
8120
8121   function visible(x, y) {
8122     return x0 <= x && x <= x1 && y0 <= y && y <= y1;
8123   }
8124
8125   function interpolate(from, to, direction, stream) {
8126     var a = 0, a1 = 0;
8127     if (from == null
8128         || (a = corner(from, direction)) !== (a1 = corner(to, direction))
8129         || comparePoint(from, to) < 0 ^ direction > 0) {
8130       do stream.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0);
8131       while ((a = (a + direction + 4) % 4) !== a1);
8132     } else {
8133       stream.point(to[0], to[1]);
8134     }
8135   }
8136
8137   function corner(p, direction) {
8138     return abs(p[0] - x0) < epsilon$2 ? direction > 0 ? 0 : 3
8139         : abs(p[0] - x1) < epsilon$2 ? direction > 0 ? 2 : 1
8140         : abs(p[1] - y0) < epsilon$2 ? direction > 0 ? 1 : 0
8141         : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon
8142   }
8143
8144   function compareIntersection(a, b) {
8145     return comparePoint(a.x, b.x);
8146   }
8147
8148   function comparePoint(a, b) {
8149     var ca = corner(a, 1),
8150         cb = corner(b, 1);
8151     return ca !== cb ? ca - cb
8152         : ca === 0 ? b[1] - a[1]
8153         : ca === 1 ? a[0] - b[0]
8154         : ca === 2 ? a[1] - b[1]
8155         : b[0] - a[0];
8156   }
8157
8158   return function(stream) {
8159     var activeStream = stream,
8160         bufferStream = clipBuffer(),
8161         segments,
8162         polygon,
8163         ring,
8164         x__, y__, v__, // first point
8165         x_, y_, v_, // previous point
8166         first,
8167         clean;
8168
8169     var clipStream = {
8170       point: point,
8171       lineStart: lineStart,
8172       lineEnd: lineEnd,
8173       polygonStart: polygonStart,
8174       polygonEnd: polygonEnd
8175     };
8176
8177     function point(x, y) {
8178       if (visible(x, y)) activeStream.point(x, y);
8179     }
8180
8181     function polygonInside() {
8182       var winding = 0;
8183
8184       for (var i = 0, n = polygon.length; i < n; ++i) {
8185         for (var ring = polygon[i], j = 1, m = ring.length, point = ring[0], a0, a1, b0 = point[0], b1 = point[1]; j < m; ++j) {
8186           a0 = b0, a1 = b1, point = ring[j], b0 = point[0], b1 = point[1];
8187           if (a1 <= y1) { if (b1 > y1 && (b0 - a0) * (y1 - a1) > (b1 - a1) * (x0 - a0)) ++winding; }
8188           else { if (b1 <= y1 && (b0 - a0) * (y1 - a1) < (b1 - a1) * (x0 - a0)) --winding; }
8189         }
8190       }
8191
8192       return winding;
8193     }
8194
8195     // Buffer geometry within a polygon and then clip it en masse.
8196     function polygonStart() {
8197       activeStream = bufferStream, segments = [], polygon = [], clean = true;
8198     }
8199
8200     function polygonEnd() {
8201       var startInside = polygonInside(),
8202           cleanInside = clean && startInside,
8203           visible = (segments = merge(segments)).length;
8204       if (cleanInside || visible) {
8205         stream.polygonStart();
8206         if (cleanInside) {
8207           stream.lineStart();
8208           interpolate(null, null, 1, stream);
8209           stream.lineEnd();
8210         }
8211         if (visible) {
8212           clipRejoin(segments, compareIntersection, startInside, interpolate, stream);
8213         }
8214         stream.polygonEnd();
8215       }
8216       activeStream = stream, segments = polygon = ring = null;
8217     }
8218
8219     function lineStart() {
8220       clipStream.point = linePoint;
8221       if (polygon) polygon.push(ring = []);
8222       first = true;
8223       v_ = false;
8224       x_ = y_ = NaN;
8225     }
8226
8227     // TODO rather than special-case polygons, simply handle them separately.
8228     // Ideally, coincident intersection points should be jittered to avoid
8229     // clipping issues.
8230     function lineEnd() {
8231       if (segments) {
8232         linePoint(x__, y__);
8233         if (v__ && v_) bufferStream.rejoin();
8234         segments.push(bufferStream.result());
8235       }
8236       clipStream.point = point;
8237       if (v_) activeStream.lineEnd();
8238     }
8239
8240     function linePoint(x, y) {
8241       var v = visible(x, y);
8242       if (polygon) ring.push([x, y]);
8243       if (first) {
8244         x__ = x, y__ = y, v__ = v;
8245         first = false;
8246         if (v) {
8247           activeStream.lineStart();
8248           activeStream.point(x, y);
8249         }
8250       } else {
8251         if (v && v_) activeStream.point(x, y);
8252         else {
8253           var a = [x_ = Math.max(clipMin, Math.min(clipMax, x_)), y_ = Math.max(clipMin, Math.min(clipMax, y_))],
8254               b = [x = Math.max(clipMin, Math.min(clipMax, x)), y = Math.max(clipMin, Math.min(clipMax, y))];
8255           if (clipLine(a, b, x0, y0, x1, y1)) {
8256             if (!v_) {
8257               activeStream.lineStart();
8258               activeStream.point(a[0], a[1]);
8259             }
8260             activeStream.point(b[0], b[1]);
8261             if (!v) activeStream.lineEnd();
8262             clean = false;
8263           } else if (v) {
8264             activeStream.lineStart();
8265             activeStream.point(x, y);
8266             clean = false;
8267           }
8268         }
8269       }
8270       x_ = x, y_ = y, v_ = v;
8271     }
8272
8273     return clipStream;
8274   };
8275 }
8276
8277 function extent$1() {
8278   var x0 = 0,
8279       y0 = 0,
8280       x1 = 960,
8281       y1 = 500,
8282       cache,
8283       cacheStream,
8284       clip;
8285
8286   return clip = {
8287     stream: function(stream) {
8288       return cache && cacheStream === stream ? cache : cache = clipRectangle(x0, y0, x1, y1)(cacheStream = stream);
8289     },
8290     extent: function(_) {
8291       return arguments.length ? (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1], cache = cacheStream = null, clip) : [[x0, y0], [x1, y1]];
8292     }
8293   };
8294 }
8295
8296 var lengthSum = adder();
8297 var lambda0$2;
8298 var sinPhi0$1;
8299 var cosPhi0$1;
8300
8301 var lengthStream = {
8302   sphere: noop$1,
8303   point: noop$1,
8304   lineStart: lengthLineStart,
8305   lineEnd: noop$1,
8306   polygonStart: noop$1,
8307   polygonEnd: noop$1
8308 };
8309
8310 function lengthLineStart() {
8311   lengthStream.point = lengthPointFirst;
8312   lengthStream.lineEnd = lengthLineEnd;
8313 }
8314
8315 function lengthLineEnd() {
8316   lengthStream.point = lengthStream.lineEnd = noop$1;
8317 }
8318
8319 function lengthPointFirst(lambda, phi) {
8320   lambda *= radians, phi *= radians;
8321   lambda0$2 = lambda, sinPhi0$1 = sin$1(phi), cosPhi0$1 = cos$1(phi);
8322   lengthStream.point = lengthPoint;
8323 }
8324
8325 function lengthPoint(lambda, phi) {
8326   lambda *= radians, phi *= radians;
8327   var sinPhi = sin$1(phi),
8328       cosPhi = cos$1(phi),
8329       delta = abs(lambda - lambda0$2),
8330       cosDelta = cos$1(delta),
8331       sinDelta = sin$1(delta),
8332       x = cosPhi * sinDelta,
8333       y = cosPhi0$1 * sinPhi - sinPhi0$1 * cosPhi * cosDelta,
8334       z = sinPhi0$1 * sinPhi + cosPhi0$1 * cosPhi * cosDelta;
8335   lengthSum.add(atan2(sqrt(x * x + y * y), z));
8336   lambda0$2 = lambda, sinPhi0$1 = sinPhi, cosPhi0$1 = cosPhi;
8337 }
8338
8339 function d3_geoLength(object) {
8340   lengthSum.reset();
8341   d3_geoStream(object, lengthStream);
8342   return +lengthSum;
8343 }
8344
8345 var coordinates = [null, null];
8346 var object$1 = {type: "LineString", coordinates: coordinates};
8347
8348 function distance(a, b) {
8349   coordinates[0] = a;
8350   coordinates[1] = b;
8351   return d3_geoLength(object$1);
8352 }
8353
8354 var containsObjectType = {
8355   Feature: function(object, point) {
8356     return containsGeometry(object.geometry, point);
8357   },
8358   FeatureCollection: function(object, point) {
8359     var features = object.features, i = -1, n = features.length;
8360     while (++i < n) if (containsGeometry(features[i].geometry, point)) return true;
8361     return false;
8362   }
8363 };
8364
8365 var containsGeometryType = {
8366   Sphere: function() {
8367     return true;
8368   },
8369   Point: function(object, point) {
8370     return containsPoint(object.coordinates, point);
8371   },
8372   MultiPoint: function(object, point) {
8373     var coordinates = object.coordinates, i = -1, n = coordinates.length;
8374     while (++i < n) if (containsPoint(coordinates[i], point)) return true;
8375     return false;
8376   },
8377   LineString: function(object, point) {
8378     return containsLine(object.coordinates, point);
8379   },
8380   MultiLineString: function(object, point) {
8381     var coordinates = object.coordinates, i = -1, n = coordinates.length;
8382     while (++i < n) if (containsLine(coordinates[i], point)) return true;
8383     return false;
8384   },
8385   Polygon: function(object, point) {
8386     return containsPolygon(object.coordinates, point);
8387   },
8388   MultiPolygon: function(object, point) {
8389     var coordinates = object.coordinates, i = -1, n = coordinates.length;
8390     while (++i < n) if (containsPolygon(coordinates[i], point)) return true;
8391     return false;
8392   },
8393   GeometryCollection: function(object, point) {
8394     var geometries = object.geometries, i = -1, n = geometries.length;
8395     while (++i < n) if (containsGeometry(geometries[i], point)) return true;
8396     return false;
8397   }
8398 };
8399
8400 function containsGeometry(geometry, point) {
8401   return geometry && containsGeometryType.hasOwnProperty(geometry.type)
8402       ? containsGeometryType[geometry.type](geometry, point)
8403       : false;
8404 }
8405
8406 function containsPoint(coordinates, point) {
8407   return distance(coordinates, point) === 0;
8408 }
8409
8410 function containsLine(coordinates, point) {
8411   var ab = distance(coordinates[0], coordinates[1]),
8412       ao = distance(coordinates[0], point),
8413       ob = distance(point, coordinates[1]);
8414   return ao + ob <= ab + epsilon$2;
8415 }
8416
8417 function containsPolygon(coordinates, point) {
8418   return !!polygonContains(coordinates.map(ringRadians), pointRadians(point));
8419 }
8420
8421 function ringRadians(ring) {
8422   return ring = ring.map(pointRadians), ring.pop(), ring;
8423 }
8424
8425 function pointRadians(point) {
8426   return [point[0] * radians, point[1] * radians];
8427 }
8428
8429 function contains(object, point) {
8430   return (object && containsObjectType.hasOwnProperty(object.type)
8431       ? containsObjectType[object.type]
8432       : containsGeometry)(object, point);
8433 }
8434
8435 function graticuleX(y0, y1, dy) {
8436   var y = d3_range(y0, y1 - epsilon$2, dy).concat(y1);
8437   return function(x) { return y.map(function(y) { return [x, y]; }); };
8438 }
8439
8440 function graticuleY(x0, x1, dx) {
8441   var x = d3_range(x0, x1 - epsilon$2, dx).concat(x1);
8442   return function(y) { return x.map(function(x) { return [x, y]; }); };
8443 }
8444
8445 function graticule() {
8446   var x1, x0, X1, X0,
8447       y1, y0, Y1, Y0,
8448       dx = 10, dy = dx, DX = 90, DY = 360,
8449       x, y, X, Y,
8450       precision = 2.5;
8451
8452   function graticule() {
8453     return {type: "MultiLineString", coordinates: lines()};
8454   }
8455
8456   function lines() {
8457     return d3_range(ceil(X0 / DX) * DX, X1, DX).map(X)
8458         .concat(d3_range(ceil(Y0 / DY) * DY, Y1, DY).map(Y))
8459         .concat(d3_range(ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return abs(x % DX) > epsilon$2; }).map(x))
8460         .concat(d3_range(ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return abs(y % DY) > epsilon$2; }).map(y));
8461   }
8462
8463   graticule.lines = function() {
8464     return lines().map(function(coordinates) { return {type: "LineString", coordinates: coordinates}; });
8465   };
8466
8467   graticule.outline = function() {
8468     return {
8469       type: "Polygon",
8470       coordinates: [
8471         X(X0).concat(
8472         Y(Y1).slice(1),
8473         X(X1).reverse().slice(1),
8474         Y(Y0).reverse().slice(1))
8475       ]
8476     };
8477   };
8478
8479   graticule.extent = function(_) {
8480     if (!arguments.length) return graticule.extentMinor();
8481     return graticule.extentMajor(_).extentMinor(_);
8482   };
8483
8484   graticule.extentMajor = function(_) {
8485     if (!arguments.length) return [[X0, Y0], [X1, Y1]];
8486     X0 = +_[0][0], X1 = +_[1][0];
8487     Y0 = +_[0][1], Y1 = +_[1][1];
8488     if (X0 > X1) _ = X0, X0 = X1, X1 = _;
8489     if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _;
8490     return graticule.precision(precision);
8491   };
8492
8493   graticule.extentMinor = function(_) {
8494     if (!arguments.length) return [[x0, y0], [x1, y1]];
8495     x0 = +_[0][0], x1 = +_[1][0];
8496     y0 = +_[0][1], y1 = +_[1][1];
8497     if (x0 > x1) _ = x0, x0 = x1, x1 = _;
8498     if (y0 > y1) _ = y0, y0 = y1, y1 = _;
8499     return graticule.precision(precision);
8500   };
8501
8502   graticule.step = function(_) {
8503     if (!arguments.length) return graticule.stepMinor();
8504     return graticule.stepMajor(_).stepMinor(_);
8505   };
8506
8507   graticule.stepMajor = function(_) {
8508     if (!arguments.length) return [DX, DY];
8509     DX = +_[0], DY = +_[1];
8510     return graticule;
8511   };
8512
8513   graticule.stepMinor = function(_) {
8514     if (!arguments.length) return [dx, dy];
8515     dx = +_[0], dy = +_[1];
8516     return graticule;
8517   };
8518
8519   graticule.precision = function(_) {
8520     if (!arguments.length) return precision;
8521     precision = +_;
8522     x = graticuleX(y0, y1, 90);
8523     y = graticuleY(x0, x1, precision);
8524     X = graticuleX(Y0, Y1, 90);
8525     Y = graticuleY(X0, X1, precision);
8526     return graticule;
8527   };
8528
8529   return graticule
8530       .extentMajor([[-180, -90 + epsilon$2], [180, 90 - epsilon$2]])
8531       .extentMinor([[-180, -80 - epsilon$2], [180, 80 + epsilon$2]]);
8532 }
8533
8534 function graticule10() {
8535   return graticule()();
8536 }
8537
8538 function interpolate$1(a, b) {
8539   var x0 = a[0] * radians,
8540       y0 = a[1] * radians,
8541       x1 = b[0] * radians,
8542       y1 = b[1] * radians,
8543       cy0 = cos$1(y0),
8544       sy0 = sin$1(y0),
8545       cy1 = cos$1(y1),
8546       sy1 = sin$1(y1),
8547       kx0 = cy0 * cos$1(x0),
8548       ky0 = cy0 * sin$1(x0),
8549       kx1 = cy1 * cos$1(x1),
8550       ky1 = cy1 * sin$1(x1),
8551       d = 2 * asin(sqrt(haversin(y1 - y0) + cy0 * cy1 * haversin(x1 - x0))),
8552       k = sin$1(d);
8553
8554   var interpolate = d ? function(t) {
8555     var B = sin$1(t *= d) / k,
8556         A = sin$1(d - t) / k,
8557         x = A * kx0 + B * kx1,
8558         y = A * ky0 + B * ky1,
8559         z = A * sy0 + B * sy1;
8560     return [
8561       atan2(y, x) * degrees$1,
8562       atan2(z, sqrt(x * x + y * y)) * degrees$1
8563     ];
8564   } : function() {
8565     return [x0 * degrees$1, y0 * degrees$1];
8566   };
8567
8568   interpolate.distance = d;
8569
8570   return interpolate;
8571 }
8572
8573 function identity$4(x) {
8574   return x;
8575 }
8576
8577 var areaSum$1 = adder();
8578 var areaRingSum$1 = adder();
8579 var x00;
8580 var y00;
8581 var x0$1;
8582 var y0$1;
8583
8584 var areaStream$1 = {
8585   point: noop$1,
8586   lineStart: noop$1,
8587   lineEnd: noop$1,
8588   polygonStart: function() {
8589     areaStream$1.lineStart = areaRingStart$1;
8590     areaStream$1.lineEnd = areaRingEnd$1;
8591   },
8592   polygonEnd: function() {
8593     areaStream$1.lineStart = areaStream$1.lineEnd = areaStream$1.point = noop$1;
8594     areaSum$1.add(abs(areaRingSum$1));
8595     areaRingSum$1.reset();
8596   },
8597   result: function() {
8598     var area = areaSum$1 / 2;
8599     areaSum$1.reset();
8600     return area;
8601   }
8602 };
8603
8604 function areaRingStart$1() {
8605   areaStream$1.point = areaPointFirst$1;
8606 }
8607
8608 function areaPointFirst$1(x, y) {
8609   areaStream$1.point = areaPoint$1;
8610   x00 = x0$1 = x, y00 = y0$1 = y;
8611 }
8612
8613 function areaPoint$1(x, y) {
8614   areaRingSum$1.add(y0$1 * x - x0$1 * y);
8615   x0$1 = x, y0$1 = y;
8616 }
8617
8618 function areaRingEnd$1() {
8619   areaPoint$1(x00, y00);
8620 }
8621
8622 var x0$2 = Infinity;
8623 var y0$2 = x0$2;
8624 var x1 = -x0$2;
8625 var y1 = x1;
8626
8627 var boundsStream$1 = {
8628   point: boundsPoint$1,
8629   lineStart: noop$1,
8630   lineEnd: noop$1,
8631   polygonStart: noop$1,
8632   polygonEnd: noop$1,
8633   result: function() {
8634     var bounds = [[x0$2, y0$2], [x1, y1]];
8635     x1 = y1 = -(y0$2 = x0$2 = Infinity);
8636     return bounds;
8637   }
8638 };
8639
8640 function boundsPoint$1(x, y) {
8641   if (x < x0$2) x0$2 = x;
8642   if (x > x1) x1 = x;
8643   if (y < y0$2) y0$2 = y;
8644   if (y > y1) y1 = y;
8645 }
8646
8647 // TODO Enforce positive area for exterior, negative area for interior?
8648
8649 var X0$1 = 0;
8650 var Y0$1 = 0;
8651 var Z0$1 = 0;
8652 var X1$1 = 0;
8653 var Y1$1 = 0;
8654 var Z1$1 = 0;
8655 var X2$1 = 0;
8656 var Y2$1 = 0;
8657 var Z2$1 = 0;
8658 var x00$1;
8659 var y00$1;
8660 var x0$3;
8661 var y0$3;
8662
8663 var centroidStream$1 = {
8664   point: centroidPoint$1,
8665   lineStart: centroidLineStart$1,
8666   lineEnd: centroidLineEnd$1,
8667   polygonStart: function() {
8668     centroidStream$1.lineStart = centroidRingStart$1;
8669     centroidStream$1.lineEnd = centroidRingEnd$1;
8670   },
8671   polygonEnd: function() {
8672     centroidStream$1.point = centroidPoint$1;
8673     centroidStream$1.lineStart = centroidLineStart$1;
8674     centroidStream$1.lineEnd = centroidLineEnd$1;
8675   },
8676   result: function() {
8677     var centroid = Z2$1 ? [X2$1 / Z2$1, Y2$1 / Z2$1]
8678         : Z1$1 ? [X1$1 / Z1$1, Y1$1 / Z1$1]
8679         : Z0$1 ? [X0$1 / Z0$1, Y0$1 / Z0$1]
8680         : [NaN, NaN];
8681     X0$1 = Y0$1 = Z0$1 =
8682     X1$1 = Y1$1 = Z1$1 =
8683     X2$1 = Y2$1 = Z2$1 = 0;
8684     return centroid;
8685   }
8686 };
8687
8688 function centroidPoint$1(x, y) {
8689   X0$1 += x;
8690   Y0$1 += y;
8691   ++Z0$1;
8692 }
8693
8694 function centroidLineStart$1() {
8695   centroidStream$1.point = centroidPointFirstLine;
8696 }
8697
8698 function centroidPointFirstLine(x, y) {
8699   centroidStream$1.point = centroidPointLine;
8700   centroidPoint$1(x0$3 = x, y0$3 = y);
8701 }
8702
8703 function centroidPointLine(x, y) {
8704   var dx = x - x0$3, dy = y - y0$3, z = sqrt(dx * dx + dy * dy);
8705   X1$1 += z * (x0$3 + x) / 2;
8706   Y1$1 += z * (y0$3 + y) / 2;
8707   Z1$1 += z;
8708   centroidPoint$1(x0$3 = x, y0$3 = y);
8709 }
8710
8711 function centroidLineEnd$1() {
8712   centroidStream$1.point = centroidPoint$1;
8713 }
8714
8715 function centroidRingStart$1() {
8716   centroidStream$1.point = centroidPointFirstRing;
8717 }
8718
8719 function centroidRingEnd$1() {
8720   centroidPointRing(x00$1, y00$1);
8721 }
8722
8723 function centroidPointFirstRing(x, y) {
8724   centroidStream$1.point = centroidPointRing;
8725   centroidPoint$1(x00$1 = x0$3 = x, y00$1 = y0$3 = y);
8726 }
8727
8728 function centroidPointRing(x, y) {
8729   var dx = x - x0$3,
8730       dy = y - y0$3,
8731       z = sqrt(dx * dx + dy * dy);
8732
8733   X1$1 += z * (x0$3 + x) / 2;
8734   Y1$1 += z * (y0$3 + y) / 2;
8735   Z1$1 += z;
8736
8737   z = y0$3 * x - x0$3 * y;
8738   X2$1 += z * (x0$3 + x);
8739   Y2$1 += z * (y0$3 + y);
8740   Z2$1 += z * 3;
8741   centroidPoint$1(x0$3 = x, y0$3 = y);
8742 }
8743
8744 function PathContext(context) {
8745   this._context = context;
8746 }
8747
8748 PathContext.prototype = {
8749   _radius: 4.5,
8750   pointRadius: function(_) {
8751     return this._radius = _, this;
8752   },
8753   polygonStart: function() {
8754     this._line = 0;
8755   },
8756   polygonEnd: function() {
8757     this._line = NaN;
8758   },
8759   lineStart: function() {
8760     this._point = 0;
8761   },
8762   lineEnd: function() {
8763     if (this._line === 0) this._context.closePath();
8764     this._point = NaN;
8765   },
8766   point: function(x, y) {
8767     switch (this._point) {
8768       case 0: {
8769         this._context.moveTo(x, y);
8770         this._point = 1;
8771         break;
8772       }
8773       case 1: {
8774         this._context.lineTo(x, y);
8775         break;
8776       }
8777       default: {
8778         this._context.moveTo(x + this._radius, y);
8779         this._context.arc(x, y, this._radius, 0, tau$3);
8780         break;
8781       }
8782     }
8783   },
8784   result: noop$1
8785 };
8786
8787 var lengthSum$1 = adder();
8788 var lengthRing;
8789 var x00$2;
8790 var y00$2;
8791 var x0$4;
8792 var y0$4;
8793
8794 var lengthStream$1 = {
8795   point: noop$1,
8796   lineStart: function() {
8797     lengthStream$1.point = lengthPointFirst$1;
8798   },
8799   lineEnd: function() {
8800     if (lengthRing) lengthPoint$1(x00$2, y00$2);
8801     lengthStream$1.point = noop$1;
8802   },
8803   polygonStart: function() {
8804     lengthRing = true;
8805   },
8806   polygonEnd: function() {
8807     lengthRing = null;
8808   },
8809   result: function() {
8810     var length = +lengthSum$1;
8811     lengthSum$1.reset();
8812     return length;
8813   }
8814 };
8815
8816 function lengthPointFirst$1(x, y) {
8817   lengthStream$1.point = lengthPoint$1;
8818   x00$2 = x0$4 = x, y00$2 = y0$4 = y;
8819 }
8820
8821 function lengthPoint$1(x, y) {
8822   x0$4 -= x, y0$4 -= y;
8823   lengthSum$1.add(sqrt(x0$4 * x0$4 + y0$4 * y0$4));
8824   x0$4 = x, y0$4 = y;
8825 }
8826
8827 function PathString() {
8828   this._string = [];
8829 }
8830
8831 PathString.prototype = {
8832   _radius: 4.5,
8833   _circle: circle$1(4.5),
8834   pointRadius: function(_) {
8835     if ((_ = +_) !== this._radius) this._radius = _, this._circle = null;
8836     return this;
8837   },
8838   polygonStart: function() {
8839     this._line = 0;
8840   },
8841   polygonEnd: function() {
8842     this._line = NaN;
8843   },
8844   lineStart: function() {
8845     this._point = 0;
8846   },
8847   lineEnd: function() {
8848     if (this._line === 0) this._string.push("Z");
8849     this._point = NaN;
8850   },
8851   point: function(x, y) {
8852     switch (this._point) {
8853       case 0: {
8854         this._string.push("M", x, ",", y);
8855         this._point = 1;
8856         break;
8857       }
8858       case 1: {
8859         this._string.push("L", x, ",", y);
8860         break;
8861       }
8862       default: {
8863         if (this._circle == null) this._circle = circle$1(this._radius);
8864         this._string.push("M", x, ",", y, this._circle);
8865         break;
8866       }
8867     }
8868   },
8869   result: function() {
8870     if (this._string.length) {
8871       var result = this._string.join("");
8872       this._string = [];
8873       return result;
8874     } else {
8875       return null;
8876     }
8877   }
8878 };
8879
8880 function circle$1(radius) {
8881   return "m0," + radius
8882       + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius
8883       + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius
8884       + "z";
8885 }
8886
8887 function d3_geoPath(projection, context) {
8888   var pointRadius = 4.5,
8889       projectionStream,
8890       contextStream;
8891
8892   function path(object) {
8893     if (object) {
8894       if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments));
8895       d3_geoStream(object, projectionStream(contextStream));
8896     }
8897     return contextStream.result();
8898   }
8899
8900   path.area = function(object) {
8901     d3_geoStream(object, projectionStream(areaStream$1));
8902     return areaStream$1.result();
8903   };
8904
8905   path.measure = function(object) {
8906     d3_geoStream(object, projectionStream(lengthStream$1));
8907     return lengthStream$1.result();
8908   };
8909
8910   path.bounds = function(object) {
8911     d3_geoStream(object, projectionStream(boundsStream$1));
8912     return boundsStream$1.result();
8913   };
8914
8915   path.centroid = function(object) {
8916     d3_geoStream(object, projectionStream(centroidStream$1));
8917     return centroidStream$1.result();
8918   };
8919
8920   path.projection = function(_) {
8921     return arguments.length ? (projectionStream = _ == null ? (projection = null, identity$4) : (projection = _).stream, path) : projection;
8922   };
8923
8924   path.context = function(_) {
8925     if (!arguments.length) return context;
8926     contextStream = _ == null ? (context = null, new PathString) : new PathContext(context = _);
8927     if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius);
8928     return path;
8929   };
8930
8931   path.pointRadius = function(_) {
8932     if (!arguments.length) return pointRadius;
8933     pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_);
8934     return path;
8935   };
8936
8937   return path.projection(projection).context(context);
8938 }
8939
8940 function d3_geoTransform(methods) {
8941   return {
8942     stream: transformer(methods)
8943   };
8944 }
8945
8946 function transformer(methods) {
8947   return function(stream) {
8948     var s = new TransformStream;
8949     for (var key in methods) s[key] = methods[key];
8950     s.stream = stream;
8951     return s;
8952   };
8953 }
8954
8955 function TransformStream() {}
8956
8957 TransformStream.prototype = {
8958   constructor: TransformStream,
8959   point: function(x, y) { this.stream.point(x, y); },
8960   sphere: function() { this.stream.sphere(); },
8961   lineStart: function() { this.stream.lineStart(); },
8962   lineEnd: function() { this.stream.lineEnd(); },
8963   polygonStart: function() { this.stream.polygonStart(); },
8964   polygonEnd: function() { this.stream.polygonEnd(); }
8965 };
8966
8967 function fit(projection, fitBounds, object) {
8968   var clip = projection.clipExtent && projection.clipExtent();
8969   projection.scale(150).translate([0, 0]);
8970   if (clip != null) projection.clipExtent(null);
8971   d3_geoStream(object, projection.stream(boundsStream$1));
8972   fitBounds(boundsStream$1.result());
8973   if (clip != null) projection.clipExtent(clip);
8974   return projection;
8975 }
8976
8977 function fitExtent(projection, extent, object) {
8978   return fit(projection, function(b) {
8979     var w = extent[1][0] - extent[0][0],
8980         h = extent[1][1] - extent[0][1],
8981         k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])),
8982         x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2,
8983         y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2;
8984     projection.scale(150 * k).translate([x, y]);
8985   }, object);
8986 }
8987
8988 function fitSize(projection, size, object) {
8989   return fitExtent(projection, [[0, 0], size], object);
8990 }
8991
8992 function fitWidth(projection, width, object) {
8993   return fit(projection, function(b) {
8994     var w = +width,
8995         k = w / (b[1][0] - b[0][0]),
8996         x = (w - k * (b[1][0] + b[0][0])) / 2,
8997         y = -k * b[0][1];
8998     projection.scale(150 * k).translate([x, y]);
8999   }, object);
9000 }
9001
9002 function fitHeight(projection, height, object) {
9003   return fit(projection, function(b) {
9004     var h = +height,
9005         k = h / (b[1][1] - b[0][1]),
9006         x = -k * b[0][0],
9007         y = (h - k * (b[1][1] + b[0][1])) / 2;
9008     projection.scale(150 * k).translate([x, y]);
9009   }, object);
9010 }
9011
9012 var maxDepth = 16;
9013 var cosMinDistance = cos$1(30 * radians); // cos(minimum angular distance)
9014
9015 function resample(project, delta2) {
9016   return +delta2 ? resample$1(project, delta2) : resampleNone(project);
9017 }
9018
9019 function resampleNone(project) {
9020   return transformer({
9021     point: function(x, y) {
9022       x = project(x, y);
9023       this.stream.point(x[0], x[1]);
9024     }
9025   });
9026 }
9027
9028 function resample$1(project, delta2) {
9029
9030   function resampleLineTo(x0, y0, lambda0, a0, b0, c0, x1, y1, lambda1, a1, b1, c1, depth, stream) {
9031     var dx = x1 - x0,
9032         dy = y1 - y0,
9033         d2 = dx * dx + dy * dy;
9034     if (d2 > 4 * delta2 && depth--) {
9035       var a = a0 + a1,
9036           b = b0 + b1,
9037           c = c0 + c1,
9038           m = sqrt(a * a + b * b + c * c),
9039           phi2 = asin(c /= m),
9040           lambda2 = abs(abs(c) - 1) < epsilon$2 || abs(lambda0 - lambda1) < epsilon$2 ? (lambda0 + lambda1) / 2 : atan2(b, a),
9041           p = project(lambda2, phi2),
9042           x2 = p[0],
9043           y2 = p[1],
9044           dx2 = x2 - x0,
9045           dy2 = y2 - y0,
9046           dz = dy * dx2 - dx * dy2;
9047       if (dz * dz / d2 > delta2 // perpendicular projected distance
9048           || abs((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 // midpoint close to an end
9049           || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance
9050         resampleLineTo(x0, y0, lambda0, a0, b0, c0, x2, y2, lambda2, a /= m, b /= m, c, depth, stream);
9051         stream.point(x2, y2);
9052         resampleLineTo(x2, y2, lambda2, a, b, c, x1, y1, lambda1, a1, b1, c1, depth, stream);
9053       }
9054     }
9055   }
9056   return function(stream) {
9057     var lambda00, x00, y00, a00, b00, c00, // first point
9058         lambda0, x0, y0, a0, b0, c0; // previous point
9059
9060     var resampleStream = {
9061       point: point,
9062       lineStart: lineStart,
9063       lineEnd: lineEnd,
9064       polygonStart: function() { stream.polygonStart(); resampleStream.lineStart = ringStart; },
9065       polygonEnd: function() { stream.polygonEnd(); resampleStream.lineStart = lineStart; }
9066     };
9067
9068     function point(x, y) {
9069       x = project(x, y);
9070       stream.point(x[0], x[1]);
9071     }
9072
9073     function lineStart() {
9074       x0 = NaN;
9075       resampleStream.point = linePoint;
9076       stream.lineStart();
9077     }
9078
9079     function linePoint(lambda, phi) {
9080       var c = cartesian([lambda, phi]), p = project(lambda, phi);
9081       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);
9082       stream.point(x0, y0);
9083     }
9084
9085     function lineEnd() {
9086       resampleStream.point = point;
9087       stream.lineEnd();
9088     }
9089
9090     function ringStart() {
9091       lineStart();
9092       resampleStream.point = ringPoint;
9093       resampleStream.lineEnd = ringEnd;
9094     }
9095
9096     function ringPoint(lambda, phi) {
9097       linePoint(lambda00 = lambda, phi), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;
9098       resampleStream.point = linePoint;
9099     }
9100
9101     function ringEnd() {
9102       resampleLineTo(x0, y0, lambda0, a0, b0, c0, x00, y00, lambda00, a00, b00, c00, maxDepth, stream);
9103       resampleStream.lineEnd = lineEnd;
9104       lineEnd();
9105     }
9106
9107     return resampleStream;
9108   };
9109 }
9110
9111 var transformRadians = transformer({
9112   point: function(x, y) {
9113     this.stream.point(x * radians, y * radians);
9114   }
9115 });
9116
9117 function transformRotate(rotate) {
9118   return transformer({
9119     point: function(x, y) {
9120       var r = rotate(x, y);
9121       return this.stream.point(r[0], r[1]);
9122     }
9123   });
9124 }
9125
9126 function projection(project) {
9127   return projectionMutator(function() { return project; })();
9128 }
9129
9130 function projectionMutator(projectAt) {
9131   var project,
9132       k = 150, // scale
9133       x = 480, y = 250, // translate
9134       dx, dy, lambda = 0, phi = 0, // center
9135       deltaLambda = 0, deltaPhi = 0, deltaGamma = 0, rotate, projectRotate, // rotate
9136       theta = null, preclip = clipAntimeridian, // clip angle
9137       x0 = null, y0, x1, y1, postclip = identity$4, // clip extent
9138       delta2 = 0.5, projectResample = resample(projectTransform, delta2), // precision
9139       cache,
9140       cacheStream;
9141
9142   function projection(point) {
9143     point = projectRotate(point[0] * radians, point[1] * radians);
9144     return [point[0] * k + dx, dy - point[1] * k];
9145   }
9146
9147   function invert(point) {
9148     point = projectRotate.invert((point[0] - dx) / k, (dy - point[1]) / k);
9149     return point && [point[0] * degrees$1, point[1] * degrees$1];
9150   }
9151
9152   function projectTransform(x, y) {
9153     return x = project(x, y), [x[0] * k + dx, dy - x[1] * k];
9154   }
9155
9156   projection.stream = function(stream) {
9157     return cache && cacheStream === stream ? cache : cache = transformRadians(transformRotate(rotate)(preclip(projectResample(postclip(cacheStream = stream)))));
9158   };
9159
9160   projection.preclip = function(_) {
9161     return arguments.length ? (preclip = _, theta = undefined, reset()) : preclip;
9162   };
9163
9164   projection.postclip = function(_) {
9165     return arguments.length ? (postclip = _, x0 = y0 = x1 = y1 = null, reset()) : postclip;
9166   };
9167
9168   projection.clipAngle = function(_) {
9169     return arguments.length ? (preclip = +_ ? clipCircle(theta = _ * radians) : (theta = null, clipAntimeridian), reset()) : theta * degrees$1;
9170   };
9171
9172   projection.clipExtent = function(_) {
9173     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]];
9174   };
9175
9176   projection.scale = function(_) {
9177     return arguments.length ? (k = +_, recenter()) : k;
9178   };
9179
9180   projection.translate = function(_) {
9181     return arguments.length ? (x = +_[0], y = +_[1], recenter()) : [x, y];
9182   };
9183
9184   projection.center = function(_) {
9185     return arguments.length ? (lambda = _[0] % 360 * radians, phi = _[1] % 360 * radians, recenter()) : [lambda * degrees$1, phi * degrees$1];
9186   };
9187
9188   projection.rotate = function(_) {
9189     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];
9190   };
9191
9192   projection.precision = function(_) {
9193     return arguments.length ? (projectResample = resample(projectTransform, delta2 = _ * _), reset()) : sqrt(delta2);
9194   };
9195
9196   projection.fitExtent = function(extent, object) {
9197     return fitExtent(projection, extent, object);
9198   };
9199
9200   projection.fitSize = function(size, object) {
9201     return fitSize(projection, size, object);
9202   };
9203
9204   projection.fitWidth = function(width, object) {
9205     return fitWidth(projection, width, object);
9206   };
9207
9208   projection.fitHeight = function(height, object) {
9209     return fitHeight(projection, height, object);
9210   };
9211
9212   function recenter() {
9213     projectRotate = compose(rotate = rotateRadians(deltaLambda, deltaPhi, deltaGamma), project);
9214     var center = project(lambda, phi);
9215     dx = x - center[0] * k;
9216     dy = y + center[1] * k;
9217     return reset();
9218   }
9219
9220   function reset() {
9221     cache = cacheStream = null;
9222     return projection;
9223   }
9224
9225   return function() {
9226     project = projectAt.apply(this, arguments);
9227     projection.invert = project.invert && invert;
9228     return recenter();
9229   };
9230 }
9231
9232 function conicProjection(projectAt) {
9233   var phi0 = 0,
9234       phi1 = pi$3 / 3,
9235       m = projectionMutator(projectAt),
9236       p = m(phi0, phi1);
9237
9238   p.parallels = function(_) {
9239     return arguments.length ? m(phi0 = _[0] * radians, phi1 = _[1] * radians) : [phi0 * degrees$1, phi1 * degrees$1];
9240   };
9241
9242   return p;
9243 }
9244
9245 function cylindricalEqualAreaRaw(phi0) {
9246   var cosPhi0 = cos$1(phi0);
9247
9248   function forward(lambda, phi) {
9249     return [lambda * cosPhi0, sin$1(phi) / cosPhi0];
9250   }
9251
9252   forward.invert = function(x, y) {
9253     return [x / cosPhi0, asin(y * cosPhi0)];
9254   };
9255
9256   return forward;
9257 }
9258
9259 function conicEqualAreaRaw(y0, y1) {
9260   var sy0 = sin$1(y0), n = (sy0 + sin$1(y1)) / 2;
9261
9262   // Are the parallels symmetrical around the Equator?
9263   if (abs(n) < epsilon$2) return cylindricalEqualAreaRaw(y0);
9264
9265   var c = 1 + sy0 * (2 * n - sy0), r0 = sqrt(c) / n;
9266
9267   function project(x, y) {
9268     var r = sqrt(c - 2 * n * sin$1(y)) / n;
9269     return [r * sin$1(x *= n), r0 - r * cos$1(x)];
9270   }
9271
9272   project.invert = function(x, y) {
9273     var r0y = r0 - y;
9274     return [atan2(x, abs(r0y)) / n * sign(r0y), asin((c - (x * x + r0y * r0y) * n * n) / (2 * n))];
9275   };
9276
9277   return project;
9278 }
9279
9280 function conicEqualArea() {
9281   return conicProjection(conicEqualAreaRaw)
9282       .scale(155.424)
9283       .center([0, 33.6442]);
9284 }
9285
9286 function albers() {
9287   return conicEqualArea()
9288       .parallels([29.5, 45.5])
9289       .scale(1070)
9290       .translate([480, 250])
9291       .rotate([96, 0])
9292       .center([-0.6, 38.7]);
9293 }
9294
9295 // The projections must have mutually exclusive clip regions on the sphere,
9296 // as this will avoid emitting interleaving lines and polygons.
9297 function multiplex(streams) {
9298   var n = streams.length;
9299   return {
9300     point: function(x, y) { var i = -1; while (++i < n) streams[i].point(x, y); },
9301     sphere: function() { var i = -1; while (++i < n) streams[i].sphere(); },
9302     lineStart: function() { var i = -1; while (++i < n) streams[i].lineStart(); },
9303     lineEnd: function() { var i = -1; while (++i < n) streams[i].lineEnd(); },
9304     polygonStart: function() { var i = -1; while (++i < n) streams[i].polygonStart(); },
9305     polygonEnd: function() { var i = -1; while (++i < n) streams[i].polygonEnd(); }
9306   };
9307 }
9308
9309 // A composite projection for the United States, configured by default for
9310 // 960×500. The projection also works quite well at 960×600 if you change the
9311 // scale to 1285 and adjust the translate accordingly. The set of standard
9312 // parallels for each region comes from USGS, which is published here:
9313 // http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers
9314 function albersUsa() {
9315   var cache,
9316       cacheStream,
9317       lower48 = albers(), lower48Point,
9318       alaska = conicEqualArea().rotate([154, 0]).center([-2, 58.5]).parallels([55, 65]), alaskaPoint, // EPSG:3338
9319       hawaii = conicEqualArea().rotate([157, 0]).center([-3, 19.9]).parallels([8, 18]), hawaiiPoint, // ESRI:102007
9320       point, pointStream = {point: function(x, y) { point = [x, y]; }};
9321
9322   function albersUsa(coordinates) {
9323     var x = coordinates[0], y = coordinates[1];
9324     return point = null, (lower48Point.point(x, y), point)
9325         || (alaskaPoint.point(x, y), point)
9326         || (hawaiiPoint.point(x, y), point);
9327   }
9328
9329   albersUsa.invert = function(coordinates) {
9330     var k = lower48.scale(),
9331         t = lower48.translate(),
9332         x = (coordinates[0] - t[0]) / k,
9333         y = (coordinates[1] - t[1]) / k;
9334     return (y >= 0.120 && y < 0.234 && x >= -0.425 && x < -0.214 ? alaska
9335         : y >= 0.166 && y < 0.234 && x >= -0.214 && x < -0.115 ? hawaii
9336         : lower48).invert(coordinates);
9337   };
9338
9339   albersUsa.stream = function(stream) {
9340     return cache && cacheStream === stream ? cache : cache = multiplex([lower48.stream(cacheStream = stream), alaska.stream(stream), hawaii.stream(stream)]);
9341   };
9342
9343   albersUsa.precision = function(_) {
9344     if (!arguments.length) return lower48.precision();
9345     lower48.precision(_), alaska.precision(_), hawaii.precision(_);
9346     return reset();
9347   };
9348
9349   albersUsa.scale = function(_) {
9350     if (!arguments.length) return lower48.scale();
9351     lower48.scale(_), alaska.scale(_ * 0.35), hawaii.scale(_);
9352     return albersUsa.translate(lower48.translate());
9353   };
9354
9355   albersUsa.translate = function(_) {
9356     if (!arguments.length) return lower48.translate();
9357     var k = lower48.scale(), x = +_[0], y = +_[1];
9358
9359     lower48Point = lower48
9360         .translate(_)
9361         .clipExtent([[x - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.238 * k]])
9362         .stream(pointStream);
9363
9364     alaskaPoint = alaska
9365         .translate([x - 0.307 * k, y + 0.201 * k])
9366         .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]])
9367         .stream(pointStream);
9368
9369     hawaiiPoint = hawaii
9370         .translate([x - 0.205 * k, y + 0.212 * k])
9371         .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]])
9372         .stream(pointStream);
9373
9374     return reset();
9375   };
9376
9377   albersUsa.fitExtent = function(extent, object) {
9378     return fitExtent(albersUsa, extent, object);
9379   };
9380
9381   albersUsa.fitSize = function(size, object) {
9382     return fitSize(albersUsa, size, object);
9383   };
9384
9385   albersUsa.fitWidth = function(width, object) {
9386     return fitWidth(albersUsa, width, object);
9387   };
9388
9389   albersUsa.fitHeight = function(height, object) {
9390     return fitHeight(albersUsa, height, object);
9391   };
9392
9393   function reset() {
9394     cache = cacheStream = null;
9395     return albersUsa;
9396   }
9397
9398   return albersUsa.scale(1070);
9399 }
9400
9401 function azimuthalRaw(scale) {
9402   return function(x, y) {
9403     var cx = cos$1(x),
9404         cy = cos$1(y),
9405         k = scale(cx * cy);
9406     return [
9407       k * cy * sin$1(x),
9408       k * sin$1(y)
9409     ];
9410   }
9411 }
9412
9413 function azimuthalInvert(angle) {
9414   return function(x, y) {
9415     var z = sqrt(x * x + y * y),
9416         c = angle(z),
9417         sc = sin$1(c),
9418         cc = cos$1(c);
9419     return [
9420       atan2(x * sc, z * cc),
9421       asin(z && y * sc / z)
9422     ];
9423   }
9424 }
9425
9426 var azimuthalEqualAreaRaw = azimuthalRaw(function(cxcy) {
9427   return sqrt(2 / (1 + cxcy));
9428 });
9429
9430 azimuthalEqualAreaRaw.invert = azimuthalInvert(function(z) {
9431   return 2 * asin(z / 2);
9432 });
9433
9434 function azimuthalEqualArea() {
9435   return projection(azimuthalEqualAreaRaw)
9436       .scale(124.75)
9437       .clipAngle(180 - 1e-3);
9438 }
9439
9440 var azimuthalEquidistantRaw = azimuthalRaw(function(c) {
9441   return (c = acos(c)) && c / sin$1(c);
9442 });
9443
9444 azimuthalEquidistantRaw.invert = azimuthalInvert(function(z) {
9445   return z;
9446 });
9447
9448 function azimuthalEquidistant() {
9449   return projection(azimuthalEquidistantRaw)
9450       .scale(79.4188)
9451       .clipAngle(180 - 1e-3);
9452 }
9453
9454 function mercatorRaw(lambda, phi) {
9455   return [lambda, log(tan((halfPi$2 + phi) / 2))];
9456 }
9457
9458 mercatorRaw.invert = function(x, y) {
9459   return [x, 2 * atan(exp(y)) - halfPi$2];
9460 };
9461
9462 function mercator() {
9463   return mercatorProjection(mercatorRaw)
9464       .scale(961 / tau$3);
9465 }
9466
9467 function mercatorProjection(project) {
9468   var m = projection(project),
9469       center = m.center,
9470       scale = m.scale,
9471       translate = m.translate,
9472       clipExtent = m.clipExtent,
9473       x0 = null, y0, x1, y1; // clip extent
9474
9475   m.scale = function(_) {
9476     return arguments.length ? (scale(_), reclip()) : scale();
9477   };
9478
9479   m.translate = function(_) {
9480     return arguments.length ? (translate(_), reclip()) : translate();
9481   };
9482
9483   m.center = function(_) {
9484     return arguments.length ? (center(_), reclip()) : center();
9485   };
9486
9487   m.clipExtent = function(_) {
9488     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]];
9489   };
9490
9491   function reclip() {
9492     var k = pi$3 * scale(),
9493         t = m(rotation(m.rotate()).invert([0, 0]));
9494     return clipExtent(x0 == null
9495         ? [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]] : project === mercatorRaw
9496         ? [[Math.max(t[0] - k, x0), y0], [Math.min(t[0] + k, x1), y1]]
9497         : [[x0, Math.max(t[1] - k, y0)], [x1, Math.min(t[1] + k, y1)]]);
9498   }
9499
9500   return reclip();
9501 }
9502
9503 function tany(y) {
9504   return tan((halfPi$2 + y) / 2);
9505 }
9506
9507 function conicConformalRaw(y0, y1) {
9508   var cy0 = cos$1(y0),
9509       n = y0 === y1 ? sin$1(y0) : log(cy0 / cos$1(y1)) / log(tany(y1) / tany(y0)),
9510       f = cy0 * pow(tany(y0), n) / n;
9511
9512   if (!n) return mercatorRaw;
9513
9514   function project(x, y) {
9515     if (f > 0) { if (y < -halfPi$2 + epsilon$2) y = -halfPi$2 + epsilon$2; }
9516     else { if (y > halfPi$2 - epsilon$2) y = halfPi$2 - epsilon$2; }
9517     var r = f / pow(tany(y), n);
9518     return [r * sin$1(n * x), f - r * cos$1(n * x)];
9519   }
9520
9521   project.invert = function(x, y) {
9522     var fy = f - y, r = sign(n) * sqrt(x * x + fy * fy);
9523     return [atan2(x, abs(fy)) / n * sign(fy), 2 * atan(pow(f / r, 1 / n)) - halfPi$2];
9524   };
9525
9526   return project;
9527 }
9528
9529 function conicConformal() {
9530   return conicProjection(conicConformalRaw)
9531       .scale(109.5)
9532       .parallels([30, 30]);
9533 }
9534
9535 function equirectangularRaw(lambda, phi) {
9536   return [lambda, phi];
9537 }
9538
9539 equirectangularRaw.invert = equirectangularRaw;
9540
9541 function equirectangular() {
9542   return projection(equirectangularRaw)
9543       .scale(152.63);
9544 }
9545
9546 function conicEquidistantRaw(y0, y1) {
9547   var cy0 = cos$1(y0),
9548       n = y0 === y1 ? sin$1(y0) : (cy0 - cos$1(y1)) / (y1 - y0),
9549       g = cy0 / n + y0;
9550
9551   if (abs(n) < epsilon$2) return equirectangularRaw;
9552
9553   function project(x, y) {
9554     var gy = g - y, nx = n * x;
9555     return [gy * sin$1(nx), g - gy * cos$1(nx)];
9556   }
9557
9558   project.invert = function(x, y) {
9559     var gy = g - y;
9560     return [atan2(x, abs(gy)) / n * sign(gy), g - sign(n) * sqrt(x * x + gy * gy)];
9561   };
9562
9563   return project;
9564 }
9565
9566 function conicEquidistant() {
9567   return conicProjection(conicEquidistantRaw)
9568       .scale(131.154)
9569       .center([0, 13.9389]);
9570 }
9571
9572 function gnomonicRaw(x, y) {
9573   var cy = cos$1(y), k = cos$1(x) * cy;
9574   return [cy * sin$1(x) / k, sin$1(y) / k];
9575 }
9576
9577 gnomonicRaw.invert = azimuthalInvert(atan);
9578
9579 function gnomonic() {
9580   return projection(gnomonicRaw)
9581       .scale(144.049)
9582       .clipAngle(60);
9583 }
9584
9585 function scaleTranslate(kx, ky, tx, ty) {
9586   return kx === 1 && ky === 1 && tx === 0 && ty === 0 ? identity$4 : transformer({
9587     point: function(x, y) {
9588       this.stream.point(x * kx + tx, y * ky + ty);
9589     }
9590   });
9591 }
9592
9593 function d3_geoIdentity() {
9594   var k = 1, tx = 0, ty = 0, sx = 1, sy = 1, transform = identity$4, // scale, translate and reflect
9595       x0 = null, y0, x1, y1, // clip extent
9596       postclip = identity$4,
9597       cache,
9598       cacheStream,
9599       projection;
9600
9601   function reset() {
9602     cache = cacheStream = null;
9603     return projection;
9604   }
9605
9606   return projection = {
9607     stream: function(stream) {
9608       return cache && cacheStream === stream ? cache : cache = transform(postclip(cacheStream = stream));
9609     },
9610     postclip: function(_) {
9611       return arguments.length ? (postclip = _, x0 = y0 = x1 = y1 = null, reset()) : postclip;
9612     },
9613     clipExtent: function(_) {
9614       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]];
9615     },
9616     scale: function(_) {
9617       return arguments.length ? (transform = scaleTranslate((k = +_) * sx, k * sy, tx, ty), reset()) : k;
9618     },
9619     translate: function(_) {
9620       return arguments.length ? (transform = scaleTranslate(k * sx, k * sy, tx = +_[0], ty = +_[1]), reset()) : [tx, ty];
9621     },
9622     reflectX: function(_) {
9623       return arguments.length ? (transform = scaleTranslate(k * (sx = _ ? -1 : 1), k * sy, tx, ty), reset()) : sx < 0;
9624     },
9625     reflectY: function(_) {
9626       return arguments.length ? (transform = scaleTranslate(k * sx, k * (sy = _ ? -1 : 1), tx, ty), reset()) : sy < 0;
9627     },
9628     fitExtent: function(extent, object) {
9629       return fitExtent(projection, extent, object);
9630     },
9631     fitSize: function(size, object) {
9632       return fitSize(projection, size, object);
9633     },
9634     fitWidth: function(width, object) {
9635       return fitWidth(projection, width, object);
9636     },
9637     fitHeight: function(height, object) {
9638       return fitHeight(projection, height, object);
9639     }
9640   };
9641 }
9642
9643 function naturalEarth1Raw(lambda, phi) {
9644   var phi2 = phi * phi, phi4 = phi2 * phi2;
9645   return [
9646     lambda * (0.8707 - 0.131979 * phi2 + phi4 * (-0.013791 + phi4 * (0.003971 * phi2 - 0.001529 * phi4))),
9647     phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4)))
9648   ];
9649 }
9650
9651 naturalEarth1Raw.invert = function(x, y) {
9652   var phi = y, i = 25, delta;
9653   do {
9654     var phi2 = phi * phi, phi4 = phi2 * phi2;
9655     phi -= delta = (phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4))) - y) /
9656         (1.007226 + phi2 * (0.015085 * 3 + phi4 * (-0.044475 * 7 + 0.028874 * 9 * phi2 - 0.005916 * 11 * phi4)));
9657   } while (abs(delta) > epsilon$2 && --i > 0);
9658   return [
9659     x / (0.8707 + (phi2 = phi * phi) * (-0.131979 + phi2 * (-0.013791 + phi2 * phi2 * phi2 * (0.003971 - 0.001529 * phi2)))),
9660     phi
9661   ];
9662 };
9663
9664 function naturalEarth1() {
9665   return projection(naturalEarth1Raw)
9666       .scale(175.295);
9667 }
9668
9669 function orthographicRaw(x, y) {
9670   return [cos$1(y) * sin$1(x), sin$1(y)];
9671 }
9672
9673 orthographicRaw.invert = azimuthalInvert(asin);
9674
9675 function orthographic() {
9676   return projection(orthographicRaw)
9677       .scale(249.5)
9678       .clipAngle(90 + epsilon$2);
9679 }
9680
9681 function stereographicRaw(x, y) {
9682   var cy = cos$1(y), k = 1 + cos$1(x) * cy;
9683   return [cy * sin$1(x) / k, sin$1(y) / k];
9684 }
9685
9686 stereographicRaw.invert = azimuthalInvert(function(z) {
9687   return 2 * atan(z);
9688 });
9689
9690 function stereographic() {
9691   return projection(stereographicRaw)
9692       .scale(250)
9693       .clipAngle(142);
9694 }
9695
9696 function transverseMercatorRaw(lambda, phi) {
9697   return [log(tan((halfPi$2 + phi) / 2)), -lambda];
9698 }
9699
9700 transverseMercatorRaw.invert = function(x, y) {
9701   return [-y, 2 * atan(exp(x)) - halfPi$2];
9702 };
9703
9704 function transverseMercator() {
9705   var m = mercatorProjection(transverseMercatorRaw),
9706       center = m.center,
9707       rotate = m.rotate;
9708
9709   m.center = function(_) {
9710     return arguments.length ? center([-_[1], _[0]]) : (_ = center(), [_[1], -_[0]]);
9711   };
9712
9713   m.rotate = function(_) {
9714     return arguments.length ? rotate([_[0], _[1], _.length > 2 ? _[2] + 90 : 90]) : (_ = rotate(), [_[0], _[1], _[2] - 90]);
9715   };
9716
9717   return rotate([0, 0, 90])
9718       .scale(159.155);
9719 }
9720
9721 function defaultSeparation(a, b) {
9722   return a.parent === b.parent ? 1 : 2;
9723 }
9724
9725 function meanX(children) {
9726   return children.reduce(meanXReduce, 0) / children.length;
9727 }
9728
9729 function meanXReduce(x, c) {
9730   return x + c.x;
9731 }
9732
9733 function maxY(children) {
9734   return 1 + children.reduce(maxYReduce, 0);
9735 }
9736
9737 function maxYReduce(y, c) {
9738   return Math.max(y, c.y);
9739 }
9740
9741 function leafLeft(node) {
9742   var children;
9743   while (children = node.children) node = children[0];
9744   return node;
9745 }
9746
9747 function leafRight(node) {
9748   var children;
9749   while (children = node.children) node = children[children.length - 1];
9750   return node;
9751 }
9752
9753 function cluster() {
9754   var separation = defaultSeparation,
9755       dx = 1,
9756       dy = 1,
9757       nodeSize = false;
9758
9759   function cluster(root) {
9760     var previousNode,
9761         x = 0;
9762
9763     // First walk, computing the initial x & y values.
9764     root.eachAfter(function(node) {
9765       var children = node.children;
9766       if (children) {
9767         node.x = meanX(children);
9768         node.y = maxY(children);
9769       } else {
9770         node.x = previousNode ? x += separation(node, previousNode) : 0;
9771         node.y = 0;
9772         previousNode = node;
9773       }
9774     });
9775
9776     var left = leafLeft(root),
9777         right = leafRight(root),
9778         x0 = left.x - separation(left, right) / 2,
9779         x1 = right.x + separation(right, left) / 2;
9780
9781     // Second walk, normalizing x & y to the desired size.
9782     return root.eachAfter(nodeSize ? function(node) {
9783       node.x = (node.x - root.x) * dx;
9784       node.y = (root.y - node.y) * dy;
9785     } : function(node) {
9786       node.x = (node.x - x0) / (x1 - x0) * dx;
9787       node.y = (1 - (root.y ? node.y / root.y : 1)) * dy;
9788     });
9789   }
9790
9791   cluster.separation = function(x) {
9792     return arguments.length ? (separation = x, cluster) : separation;
9793   };
9794
9795   cluster.size = function(x) {
9796     return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? null : [dx, dy]);
9797   };
9798
9799   cluster.nodeSize = function(x) {
9800     return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? [dx, dy] : null);
9801   };
9802
9803   return cluster;
9804 }
9805
9806 function count(node) {
9807   var sum = 0,
9808       children = node.children,
9809       i = children && children.length;
9810   if (!i) sum = 1;
9811   else while (--i >= 0) sum += children[i].value;
9812   node.value = sum;
9813 }
9814
9815 function node_count() {
9816   return this.eachAfter(count);
9817 }
9818
9819 function node_each(callback) {
9820   var node = this, current, next = [node], children, i, n;
9821   do {
9822     current = next.reverse(), next = [];
9823     while (node = current.pop()) {
9824       callback(node), children = node.children;
9825       if (children) for (i = 0, n = children.length; i < n; ++i) {
9826         next.push(children[i]);
9827       }
9828     }
9829   } while (next.length);
9830   return this;
9831 }
9832
9833 function node_eachBefore(callback) {
9834   var node = this, nodes = [node], children, i;
9835   while (node = nodes.pop()) {
9836     callback(node), children = node.children;
9837     if (children) for (i = children.length - 1; i >= 0; --i) {
9838       nodes.push(children[i]);
9839     }
9840   }
9841   return this;
9842 }
9843
9844 function node_eachAfter(callback) {
9845   var node = this, nodes = [node], next = [], children, i, n;
9846   while (node = nodes.pop()) {
9847     next.push(node), children = node.children;
9848     if (children) for (i = 0, n = children.length; i < n; ++i) {
9849       nodes.push(children[i]);
9850     }
9851   }
9852   while (node = next.pop()) {
9853     callback(node);
9854   }
9855   return this;
9856 }
9857
9858 function node_sum(value) {
9859   return this.eachAfter(function(node) {
9860     var sum = +value(node.data) || 0,
9861         children = node.children,
9862         i = children && children.length;
9863     while (--i >= 0) sum += children[i].value;
9864     node.value = sum;
9865   });
9866 }
9867
9868 function node_sort(compare) {
9869   return this.eachBefore(function(node) {
9870     if (node.children) {
9871       node.children.sort(compare);
9872     }
9873   });
9874 }
9875
9876 function node_path(end) {
9877   var start = this,
9878       ancestor = leastCommonAncestor(start, end),
9879       nodes = [start];
9880   while (start !== ancestor) {
9881     start = start.parent;
9882     nodes.push(start);
9883   }
9884   var k = nodes.length;
9885   while (end !== ancestor) {
9886     nodes.splice(k, 0, end);
9887     end = end.parent;
9888   }
9889   return nodes;
9890 }
9891
9892 function leastCommonAncestor(a, b) {
9893   if (a === b) return a;
9894   var aNodes = a.ancestors(),
9895       bNodes = b.ancestors(),
9896       c = null;
9897   a = aNodes.pop();
9898   b = bNodes.pop();
9899   while (a === b) {
9900     c = a;
9901     a = aNodes.pop();
9902     b = bNodes.pop();
9903   }
9904   return c;
9905 }
9906
9907 function node_ancestors() {
9908   var node = this, nodes = [node];
9909   while (node = node.parent) {
9910     nodes.push(node);
9911   }
9912   return nodes;
9913 }
9914
9915 function node_descendants() {
9916   var nodes = [];
9917   this.each(function(node) {
9918     nodes.push(node);
9919   });
9920   return nodes;
9921 }
9922
9923 function node_leaves() {
9924   var leaves = [];
9925   this.eachBefore(function(node) {
9926     if (!node.children) {
9927       leaves.push(node);
9928     }
9929   });
9930   return leaves;
9931 }
9932
9933 function node_links() {
9934   var root = this, links = [];
9935   root.each(function(node) {
9936     if (node !== root) { // Don’t include the root’s parent, if any.
9937       links.push({source: node.parent, target: node});
9938     }
9939   });
9940   return links;
9941 }
9942
9943 function hierarchy(data, children) {
9944   var root = new Node(data),
9945       valued = +data.value && (root.value = data.value),
9946       node,
9947       nodes = [root],
9948       child,
9949       childs,
9950       i,
9951       n;
9952
9953   if (children == null) children = defaultChildren;
9954
9955   while (node = nodes.pop()) {
9956     if (valued) node.value = +node.data.value;
9957     if ((childs = children(node.data)) && (n = childs.length)) {
9958       node.children = new Array(n);
9959       for (i = n - 1; i >= 0; --i) {
9960         nodes.push(child = node.children[i] = new Node(childs[i]));
9961         child.parent = node;
9962         child.depth = node.depth + 1;
9963       }
9964     }
9965   }
9966
9967   return root.eachBefore(computeHeight);
9968 }
9969
9970 function node_copy() {
9971   return hierarchy(this).eachBefore(copyData);
9972 }
9973
9974 function defaultChildren(d) {
9975   return d.children;
9976 }
9977
9978 function copyData(node) {
9979   node.data = node.data.data;
9980 }
9981
9982 function computeHeight(node) {
9983   var height = 0;
9984   do node.height = height;
9985   while ((node = node.parent) && (node.height < ++height));
9986 }
9987
9988 function Node(data) {
9989   this.data = data;
9990   this.depth =
9991   this.height = 0;
9992   this.parent = null;
9993 }
9994
9995 Node.prototype = hierarchy.prototype = {
9996   constructor: Node,
9997   count: node_count,
9998   each: node_each,
9999   eachAfter: node_eachAfter,
10000   eachBefore: node_eachBefore,
10001   sum: node_sum,
10002   sort: node_sort,
10003   path: node_path,
10004   ancestors: node_ancestors,
10005   descendants: node_descendants,
10006   leaves: node_leaves,
10007   links: node_links,
10008   copy: node_copy
10009 };
10010
10011 var slice$3 = Array.prototype.slice;
10012
10013 function shuffle$1(array) {
10014   var m = array.length,
10015       t,
10016       i;
10017
10018   while (m) {
10019     i = Math.random() * m-- | 0;
10020     t = array[m];
10021     array[m] = array[i];
10022     array[i] = t;
10023   }
10024
10025   return array;
10026 }
10027
10028 function enclose(circles) {
10029   var i = 0, n = (circles = shuffle$1(slice$3.call(circles))).length, B = [], p, e;
10030
10031   while (i < n) {
10032     p = circles[i];
10033     if (e && enclosesWeak(e, p)) ++i;
10034     else e = encloseBasis(B = extendBasis(B, p)), i = 0;
10035   }
10036
10037   return e;
10038 }
10039
10040 function extendBasis(B, p) {
10041   var i, j;
10042
10043   if (enclosesWeakAll(p, B)) return [p];
10044
10045   // If we get here then B must have at least one element.
10046   for (i = 0; i < B.length; ++i) {
10047     if (enclosesNot(p, B[i])
10048         && enclosesWeakAll(encloseBasis2(B[i], p), B)) {
10049       return [B[i], p];
10050     }
10051   }
10052
10053   // If we get here then B must have at least two elements.
10054   for (i = 0; i < B.length - 1; ++i) {
10055     for (j = i + 1; j < B.length; ++j) {
10056       if (enclosesNot(encloseBasis2(B[i], B[j]), p)
10057           && enclosesNot(encloseBasis2(B[i], p), B[j])
10058           && enclosesNot(encloseBasis2(B[j], p), B[i])
10059           && enclosesWeakAll(encloseBasis3(B[i], B[j], p), B)) {
10060         return [B[i], B[j], p];
10061       }
10062     }
10063   }
10064
10065   // If we get here then something is very wrong.
10066   throw new Error;
10067 }
10068
10069 function enclosesNot(a, b) {
10070   var dr = a.r - b.r, dx = b.x - a.x, dy = b.y - a.y;
10071   return dr < 0 || dr * dr < dx * dx + dy * dy;
10072 }
10073
10074 function enclosesWeak(a, b) {
10075   var dr = a.r - b.r + 1e-6, dx = b.x - a.x, dy = b.y - a.y;
10076   return dr > 0 && dr * dr > dx * dx + dy * dy;
10077 }
10078
10079 function enclosesWeakAll(a, B) {
10080   for (var i = 0; i < B.length; ++i) {
10081     if (!enclosesWeak(a, B[i])) {
10082       return false;
10083     }
10084   }
10085   return true;
10086 }
10087
10088 function encloseBasis(B) {
10089   switch (B.length) {
10090     case 1: return encloseBasis1(B[0]);
10091     case 2: return encloseBasis2(B[0], B[1]);
10092     case 3: return encloseBasis3(B[0], B[1], B[2]);
10093   }
10094 }
10095
10096 function encloseBasis1(a) {
10097   return {
10098     x: a.x,
10099     y: a.y,
10100     r: a.r
10101   };
10102 }
10103
10104 function encloseBasis2(a, b) {
10105   var x1 = a.x, y1 = a.y, r1 = a.r,
10106       x2 = b.x, y2 = b.y, r2 = b.r,
10107       x21 = x2 - x1, y21 = y2 - y1, r21 = r2 - r1,
10108       l = Math.sqrt(x21 * x21 + y21 * y21);
10109   return {
10110     x: (x1 + x2 + x21 / l * r21) / 2,
10111     y: (y1 + y2 + y21 / l * r21) / 2,
10112     r: (l + r1 + r2) / 2
10113   };
10114 }
10115
10116 function encloseBasis3(a, b, c) {
10117   var x1 = a.x, y1 = a.y, r1 = a.r,
10118       x2 = b.x, y2 = b.y, r2 = b.r,
10119       x3 = c.x, y3 = c.y, r3 = c.r,
10120       a2 = x1 - x2,
10121       a3 = x1 - x3,
10122       b2 = y1 - y2,
10123       b3 = y1 - y3,
10124       c2 = r2 - r1,
10125       c3 = r3 - r1,
10126       d1 = x1 * x1 + y1 * y1 - r1 * r1,
10127       d2 = d1 - x2 * x2 - y2 * y2 + r2 * r2,
10128       d3 = d1 - x3 * x3 - y3 * y3 + r3 * r3,
10129       ab = a3 * b2 - a2 * b3,
10130       xa = (b2 * d3 - b3 * d2) / (ab * 2) - x1,
10131       xb = (b3 * c2 - b2 * c3) / ab,
10132       ya = (a3 * d2 - a2 * d3) / (ab * 2) - y1,
10133       yb = (a2 * c3 - a3 * c2) / ab,
10134       A = xb * xb + yb * yb - 1,
10135       B = 2 * (r1 + xa * xb + ya * yb),
10136       C = xa * xa + ya * ya - r1 * r1,
10137       r = -(A ? (B + Math.sqrt(B * B - 4 * A * C)) / (2 * A) : C / B);
10138   return {
10139     x: x1 + xa + xb * r,
10140     y: y1 + ya + yb * r,
10141     r: r
10142   };
10143 }
10144
10145 function place(a, b, c) {
10146   var ax = a.x,
10147       ay = a.y,
10148       da = b.r + c.r,
10149       db = a.r + c.r,
10150       dx = b.x - ax,
10151       dy = b.y - ay,
10152       dc = dx * dx + dy * dy;
10153   if (dc) {
10154     var x = 0.5 + ((db *= db) - (da *= da)) / (2 * dc),
10155         y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc);
10156     c.x = ax + x * dx + y * dy;
10157     c.y = ay + x * dy - y * dx;
10158   } else {
10159     c.x = ax + db;
10160     c.y = ay;
10161   }
10162 }
10163
10164 function intersects(a, b) {
10165   var dx = b.x - a.x,
10166       dy = b.y - a.y,
10167       dr = a.r + b.r;
10168   return dr * dr - 1e-6 > dx * dx + dy * dy;
10169 }
10170
10171 function score(node) {
10172   var a = node._,
10173       b = node.next._,
10174       ab = a.r + b.r,
10175       dx = (a.x * b.r + b.x * a.r) / ab,
10176       dy = (a.y * b.r + b.y * a.r) / ab;
10177   return dx * dx + dy * dy;
10178 }
10179
10180 function Node$1(circle) {
10181   this._ = circle;
10182   this.next = null;
10183   this.previous = null;
10184 }
10185
10186 function packEnclose(circles) {
10187   if (!(n = circles.length)) return 0;
10188
10189   var a, b, c, n, aa, ca, i, j, k, sj, sk;
10190
10191   // Place the first circle.
10192   a = circles[0], a.x = 0, a.y = 0;
10193   if (!(n > 1)) return a.r;
10194
10195   // Place the second circle.
10196   b = circles[1], a.x = -b.r, b.x = a.r, b.y = 0;
10197   if (!(n > 2)) return a.r + b.r;
10198
10199   // Place the third circle.
10200   place(b, a, c = circles[2]);
10201
10202   // Initialize the front-chain using the first three circles a, b and c.
10203   a = new Node$1(a), b = new Node$1(b), c = new Node$1(c);
10204   a.next = c.previous = b;
10205   b.next = a.previous = c;
10206   c.next = b.previous = a;
10207
10208   // Attempt to place each remaining circle…
10209   pack: for (i = 3; i < n; ++i) {
10210     place(a._, b._, c = circles[i]), c = new Node$1(c);
10211
10212     // Find the closest intersecting circle on the front-chain, if any.
10213     // “Closeness” is determined by linear distance along the front-chain.
10214     // “Ahead” or “behind” is likewise determined by linear distance.
10215     j = b.next, k = a.previous, sj = b._.r, sk = a._.r;
10216     do {
10217       if (sj <= sk) {
10218         if (intersects(j._, c._)) {
10219           b = j, a.next = b, b.previous = a, --i;
10220           continue pack;
10221         }
10222         sj += j._.r, j = j.next;
10223       } else {
10224         if (intersects(k._, c._)) {
10225           a = k, a.next = b, b.previous = a, --i;
10226           continue pack;
10227         }
10228         sk += k._.r, k = k.previous;
10229       }
10230     } while (j !== k.next);
10231
10232     // Success! Insert the new circle c between a and b.
10233     c.previous = a, c.next = b, a.next = b.previous = b = c;
10234
10235     // Compute the new closest circle pair to the centroid.
10236     aa = score(a);
10237     while ((c = c.next) !== b) {
10238       if ((ca = score(c)) < aa) {
10239         a = c, aa = ca;
10240       }
10241     }
10242     b = a.next;
10243   }
10244
10245   // Compute the enclosing circle of the front chain.
10246   a = [b._], c = b; while ((c = c.next) !== b) a.push(c._); c = enclose(a);
10247
10248   // Translate the circles to put the enclosing circle around the origin.
10249   for (i = 0; i < n; ++i) a = circles[i], a.x -= c.x, a.y -= c.y;
10250
10251   return c.r;
10252 }
10253
10254 function siblings(circles) {
10255   packEnclose(circles);
10256   return circles;
10257 }
10258
10259 function optional(f) {
10260   return f == null ? null : required(f);
10261 }
10262
10263 function required(f) {
10264   if (typeof f !== "function") throw new Error;
10265   return f;
10266 }
10267
10268 function constantZero() {
10269   return 0;
10270 }
10271
10272 function constant$8(x) {
10273   return function() {
10274     return x;
10275   };
10276 }
10277
10278 function defaultRadius$1(d) {
10279   return Math.sqrt(d.value);
10280 }
10281
10282 function index$1() {
10283   var radius = null,
10284       dx = 1,
10285       dy = 1,
10286       padding = constantZero;
10287
10288   function pack(root) {
10289     root.x = dx / 2, root.y = dy / 2;
10290     if (radius) {
10291       root.eachBefore(radiusLeaf(radius))
10292           .eachAfter(packChildren(padding, 0.5))
10293           .eachBefore(translateChild(1));
10294     } else {
10295       root.eachBefore(radiusLeaf(defaultRadius$1))
10296           .eachAfter(packChildren(constantZero, 1))
10297           .eachAfter(packChildren(padding, root.r / Math.min(dx, dy)))
10298           .eachBefore(translateChild(Math.min(dx, dy) / (2 * root.r)));
10299     }
10300     return root;
10301   }
10302
10303   pack.radius = function(x) {
10304     return arguments.length ? (radius = optional(x), pack) : radius;
10305   };
10306
10307   pack.size = function(x) {
10308     return arguments.length ? (dx = +x[0], dy = +x[1], pack) : [dx, dy];
10309   };
10310
10311   pack.padding = function(x) {
10312     return arguments.length ? (padding = typeof x === "function" ? x : constant$8(+x), pack) : padding;
10313   };
10314
10315   return pack;
10316 }
10317
10318 function radiusLeaf(radius) {
10319   return function(node) {
10320     if (!node.children) {
10321       node.r = Math.max(0, +radius(node) || 0);
10322     }
10323   };
10324 }
10325
10326 function packChildren(padding, k) {
10327   return function(node) {
10328     if (children = node.children) {
10329       var children,
10330           i,
10331           n = children.length,
10332           r = padding(node) * k || 0,
10333           e;
10334
10335       if (r) for (i = 0; i < n; ++i) children[i].r += r;
10336       e = packEnclose(children);
10337       if (r) for (i = 0; i < n; ++i) children[i].r -= r;
10338       node.r = e + r;
10339     }
10340   };
10341 }
10342
10343 function translateChild(k) {
10344   return function(node) {
10345     var parent = node.parent;
10346     node.r *= k;
10347     if (parent) {
10348       node.x = parent.x + k * node.x;
10349       node.y = parent.y + k * node.y;
10350     }
10351   };
10352 }
10353
10354 function roundNode(node) {
10355   node.x0 = Math.round(node.x0);
10356   node.y0 = Math.round(node.y0);
10357   node.x1 = Math.round(node.x1);
10358   node.y1 = Math.round(node.y1);
10359 }
10360
10361 function treemapDice(parent, x0, y0, x1, y1) {
10362   var nodes = parent.children,
10363       node,
10364       i = -1,
10365       n = nodes.length,
10366       k = parent.value && (x1 - x0) / parent.value;
10367
10368   while (++i < n) {
10369     node = nodes[i], node.y0 = y0, node.y1 = y1;
10370     node.x0 = x0, node.x1 = x0 += node.value * k;
10371   }
10372 }
10373
10374 function partition() {
10375   var dx = 1,
10376       dy = 1,
10377       padding = 0,
10378       round = false;
10379
10380   function partition(root) {
10381     var n = root.height + 1;
10382     root.x0 =
10383     root.y0 = padding;
10384     root.x1 = dx;
10385     root.y1 = dy / n;
10386     root.eachBefore(positionNode(dy, n));
10387     if (round) root.eachBefore(roundNode);
10388     return root;
10389   }
10390
10391   function positionNode(dy, n) {
10392     return function(node) {
10393       if (node.children) {
10394         treemapDice(node, node.x0, dy * (node.depth + 1) / n, node.x1, dy * (node.depth + 2) / n);
10395       }
10396       var x0 = node.x0,
10397           y0 = node.y0,
10398           x1 = node.x1 - padding,
10399           y1 = node.y1 - padding;
10400       if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
10401       if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
10402       node.x0 = x0;
10403       node.y0 = y0;
10404       node.x1 = x1;
10405       node.y1 = y1;
10406     };
10407   }
10408
10409   partition.round = function(x) {
10410     return arguments.length ? (round = !!x, partition) : round;
10411   };
10412
10413   partition.size = function(x) {
10414     return arguments.length ? (dx = +x[0], dy = +x[1], partition) : [dx, dy];
10415   };
10416
10417   partition.padding = function(x) {
10418     return arguments.length ? (padding = +x, partition) : padding;
10419   };
10420
10421   return partition;
10422 }
10423
10424 var keyPrefix$1 = "$";
10425 var preroot = {depth: -1};
10426 var ambiguous = {};
10427
10428 function defaultId(d) {
10429   return d.id;
10430 }
10431
10432 function defaultParentId(d) {
10433   return d.parentId;
10434 }
10435
10436 function stratify() {
10437   var id = defaultId,
10438       parentId = defaultParentId;
10439
10440   function stratify(data) {
10441     var d,
10442         i,
10443         n = data.length,
10444         root,
10445         parent,
10446         node,
10447         nodes = new Array(n),
10448         nodeId,
10449         nodeKey,
10450         nodeByKey = {};
10451
10452     for (i = 0; i < n; ++i) {
10453       d = data[i], node = nodes[i] = new Node(d);
10454       if ((nodeId = id(d, i, data)) != null && (nodeId += "")) {
10455         nodeKey = keyPrefix$1 + (node.id = nodeId);
10456         nodeByKey[nodeKey] = nodeKey in nodeByKey ? ambiguous : node;
10457       }
10458     }
10459
10460     for (i = 0; i < n; ++i) {
10461       node = nodes[i], nodeId = parentId(data[i], i, data);
10462       if (nodeId == null || !(nodeId += "")) {
10463         if (root) throw new Error("multiple roots");
10464         root = node;
10465       } else {
10466         parent = nodeByKey[keyPrefix$1 + nodeId];
10467         if (!parent) throw new Error("missing: " + nodeId);
10468         if (parent === ambiguous) throw new Error("ambiguous: " + nodeId);
10469         if (parent.children) parent.children.push(node);
10470         else parent.children = [node];
10471         node.parent = parent;
10472       }
10473     }
10474
10475     if (!root) throw new Error("no root");
10476     root.parent = preroot;
10477     root.eachBefore(function(node) { node.depth = node.parent.depth + 1; --n; }).eachBefore(computeHeight);
10478     root.parent = null;
10479     if (n > 0) throw new Error("cycle");
10480
10481     return root;
10482   }
10483
10484   stratify.id = function(x) {
10485     return arguments.length ? (id = required(x), stratify) : id;
10486   };
10487
10488   stratify.parentId = function(x) {
10489     return arguments.length ? (parentId = required(x), stratify) : parentId;
10490   };
10491
10492   return stratify;
10493 }
10494
10495 function defaultSeparation$1(a, b) {
10496   return a.parent === b.parent ? 1 : 2;
10497 }
10498
10499 // function radialSeparation(a, b) {
10500 //   return (a.parent === b.parent ? 1 : 2) / a.depth;
10501 // }
10502
10503 // This function is used to traverse the left contour of a subtree (or
10504 // subforest). It returns the successor of v on this contour. This successor is
10505 // either given by the leftmost child of v or by the thread of v. The function
10506 // returns null if and only if v is on the highest level of its subtree.
10507 function nextLeft(v) {
10508   var children = v.children;
10509   return children ? children[0] : v.t;
10510 }
10511
10512 // This function works analogously to nextLeft.
10513 function nextRight(v) {
10514   var children = v.children;
10515   return children ? children[children.length - 1] : v.t;
10516 }
10517
10518 // Shifts the current subtree rooted at w+. This is done by increasing
10519 // prelim(w+) and mod(w+) by shift.
10520 function moveSubtree(wm, wp, shift) {
10521   var change = shift / (wp.i - wm.i);
10522   wp.c -= change;
10523   wp.s += shift;
10524   wm.c += change;
10525   wp.z += shift;
10526   wp.m += shift;
10527 }
10528
10529 // All other shifts, applied to the smaller subtrees between w- and w+, are
10530 // performed by this function. To prepare the shifts, we have to adjust
10531 // change(w+), shift(w+), and change(w-).
10532 function executeShifts(v) {
10533   var shift = 0,
10534       change = 0,
10535       children = v.children,
10536       i = children.length,
10537       w;
10538   while (--i >= 0) {
10539     w = children[i];
10540     w.z += shift;
10541     w.m += shift;
10542     shift += w.s + (change += w.c);
10543   }
10544 }
10545
10546 // If vi-’s ancestor is a sibling of v, returns vi-’s ancestor. Otherwise,
10547 // returns the specified (default) ancestor.
10548 function nextAncestor(vim, v, ancestor) {
10549   return vim.a.parent === v.parent ? vim.a : ancestor;
10550 }
10551
10552 function TreeNode(node, i) {
10553   this._ = node;
10554   this.parent = null;
10555   this.children = null;
10556   this.A = null; // default ancestor
10557   this.a = this; // ancestor
10558   this.z = 0; // prelim
10559   this.m = 0; // mod
10560   this.c = 0; // change
10561   this.s = 0; // shift
10562   this.t = null; // thread
10563   this.i = i; // number
10564 }
10565
10566 TreeNode.prototype = Object.create(Node.prototype);
10567
10568 function treeRoot(root) {
10569   var tree = new TreeNode(root, 0),
10570       node,
10571       nodes = [tree],
10572       child,
10573       children,
10574       i,
10575       n;
10576
10577   while (node = nodes.pop()) {
10578     if (children = node._.children) {
10579       node.children = new Array(n = children.length);
10580       for (i = n - 1; i >= 0; --i) {
10581         nodes.push(child = node.children[i] = new TreeNode(children[i], i));
10582         child.parent = node;
10583       }
10584     }
10585   }
10586
10587   (tree.parent = new TreeNode(null, 0)).children = [tree];
10588   return tree;
10589 }
10590
10591 // Node-link tree diagram using the Reingold-Tilford "tidy" algorithm
10592 function tree() {
10593   var separation = defaultSeparation$1,
10594       dx = 1,
10595       dy = 1,
10596       nodeSize = null;
10597
10598   function tree(root) {
10599     var t = treeRoot(root);
10600
10601     // Compute the layout using Buchheim et al.’s algorithm.
10602     t.eachAfter(firstWalk), t.parent.m = -t.z;
10603     t.eachBefore(secondWalk);
10604
10605     // If a fixed node size is specified, scale x and y.
10606     if (nodeSize) root.eachBefore(sizeNode);
10607
10608     // If a fixed tree size is specified, scale x and y based on the extent.
10609     // Compute the left-most, right-most, and depth-most nodes for extents.
10610     else {
10611       var left = root,
10612           right = root,
10613           bottom = root;
10614       root.eachBefore(function(node) {
10615         if (node.x < left.x) left = node;
10616         if (node.x > right.x) right = node;
10617         if (node.depth > bottom.depth) bottom = node;
10618       });
10619       var s = left === right ? 1 : separation(left, right) / 2,
10620           tx = s - left.x,
10621           kx = dx / (right.x + s + tx),
10622           ky = dy / (bottom.depth || 1);
10623       root.eachBefore(function(node) {
10624         node.x = (node.x + tx) * kx;
10625         node.y = node.depth * ky;
10626       });
10627     }
10628
10629     return root;
10630   }
10631
10632   // Computes a preliminary x-coordinate for v. Before that, FIRST WALK is
10633   // applied recursively to the children of v, as well as the function
10634   // APPORTION. After spacing out the children by calling EXECUTE SHIFTS, the
10635   // node v is placed to the midpoint of its outermost children.
10636   function firstWalk(v) {
10637     var children = v.children,
10638         siblings = v.parent.children,
10639         w = v.i ? siblings[v.i - 1] : null;
10640     if (children) {
10641       executeShifts(v);
10642       var midpoint = (children[0].z + children[children.length - 1].z) / 2;
10643       if (w) {
10644         v.z = w.z + separation(v._, w._);
10645         v.m = v.z - midpoint;
10646       } else {
10647         v.z = midpoint;
10648       }
10649     } else if (w) {
10650       v.z = w.z + separation(v._, w._);
10651     }
10652     v.parent.A = apportion(v, w, v.parent.A || siblings[0]);
10653   }
10654
10655   // Computes all real x-coordinates by summing up the modifiers recursively.
10656   function secondWalk(v) {
10657     v._.x = v.z + v.parent.m;
10658     v.m += v.parent.m;
10659   }
10660
10661   // The core of the algorithm. Here, a new subtree is combined with the
10662   // previous subtrees. Threads are used to traverse the inside and outside
10663   // contours of the left and right subtree up to the highest common level. The
10664   // vertices used for the traversals are vi+, vi-, vo-, and vo+, where the
10665   // superscript o means outside and i means inside, the subscript - means left
10666   // subtree and + means right subtree. For summing up the modifiers along the
10667   // contour, we use respective variables si+, si-, so-, and so+. Whenever two
10668   // nodes of the inside contours conflict, we compute the left one of the
10669   // greatest uncommon ancestors using the function ANCESTOR and call MOVE
10670   // SUBTREE to shift the subtree and prepare the shifts of smaller subtrees.
10671   // Finally, we add a new thread (if necessary).
10672   function apportion(v, w, ancestor) {
10673     if (w) {
10674       var vip = v,
10675           vop = v,
10676           vim = w,
10677           vom = vip.parent.children[0],
10678           sip = vip.m,
10679           sop = vop.m,
10680           sim = vim.m,
10681           som = vom.m,
10682           shift;
10683       while (vim = nextRight(vim), vip = nextLeft(vip), vim && vip) {
10684         vom = nextLeft(vom);
10685         vop = nextRight(vop);
10686         vop.a = v;
10687         shift = vim.z + sim - vip.z - sip + separation(vim._, vip._);
10688         if (shift > 0) {
10689           moveSubtree(nextAncestor(vim, v, ancestor), v, shift);
10690           sip += shift;
10691           sop += shift;
10692         }
10693         sim += vim.m;
10694         sip += vip.m;
10695         som += vom.m;
10696         sop += vop.m;
10697       }
10698       if (vim && !nextRight(vop)) {
10699         vop.t = vim;
10700         vop.m += sim - sop;
10701       }
10702       if (vip && !nextLeft(vom)) {
10703         vom.t = vip;
10704         vom.m += sip - som;
10705         ancestor = v;
10706       }
10707     }
10708     return ancestor;
10709   }
10710
10711   function sizeNode(node) {
10712     node.x *= dx;
10713     node.y = node.depth * dy;
10714   }
10715
10716   tree.separation = function(x) {
10717     return arguments.length ? (separation = x, tree) : separation;
10718   };
10719
10720   tree.size = function(x) {
10721     return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], tree) : (nodeSize ? null : [dx, dy]);
10722   };
10723
10724   tree.nodeSize = function(x) {
10725     return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], tree) : (nodeSize ? [dx, dy] : null);
10726   };
10727
10728   return tree;
10729 }
10730
10731 function treemapSlice(parent, x0, y0, x1, y1) {
10732   var nodes = parent.children,
10733       node,
10734       i = -1,
10735       n = nodes.length,
10736       k = parent.value && (y1 - y0) / parent.value;
10737
10738   while (++i < n) {
10739     node = nodes[i], node.x0 = x0, node.x1 = x1;
10740     node.y0 = y0, node.y1 = y0 += node.value * k;
10741   }
10742 }
10743
10744 var phi = (1 + Math.sqrt(5)) / 2;
10745
10746 function squarifyRatio(ratio, parent, x0, y0, x1, y1) {
10747   var rows = [],
10748       nodes = parent.children,
10749       row,
10750       nodeValue,
10751       i0 = 0,
10752       i1 = 0,
10753       n = nodes.length,
10754       dx, dy,
10755       value = parent.value,
10756       sumValue,
10757       minValue,
10758       maxValue,
10759       newRatio,
10760       minRatio,
10761       alpha,
10762       beta;
10763
10764   while (i0 < n) {
10765     dx = x1 - x0, dy = y1 - y0;
10766
10767     // Find the next non-empty node.
10768     do sumValue = nodes[i1++].value; while (!sumValue && i1 < n);
10769     minValue = maxValue = sumValue;
10770     alpha = Math.max(dy / dx, dx / dy) / (value * ratio);
10771     beta = sumValue * sumValue * alpha;
10772     minRatio = Math.max(maxValue / beta, beta / minValue);
10773
10774     // Keep adding nodes while the aspect ratio maintains or improves.
10775     for (; i1 < n; ++i1) {
10776       sumValue += nodeValue = nodes[i1].value;
10777       if (nodeValue < minValue) minValue = nodeValue;
10778       if (nodeValue > maxValue) maxValue = nodeValue;
10779       beta = sumValue * sumValue * alpha;
10780       newRatio = Math.max(maxValue / beta, beta / minValue);
10781       if (newRatio > minRatio) { sumValue -= nodeValue; break; }
10782       minRatio = newRatio;
10783     }
10784
10785     // Position and record the row orientation.
10786     rows.push(row = {value: sumValue, dice: dx < dy, children: nodes.slice(i0, i1)});
10787     if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1);
10788     else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1);
10789     value -= sumValue, i0 = i1;
10790   }
10791
10792   return rows;
10793 }
10794
10795 var squarify = (function custom(ratio) {
10796
10797   function squarify(parent, x0, y0, x1, y1) {
10798     squarifyRatio(ratio, parent, x0, y0, x1, y1);
10799   }
10800
10801   squarify.ratio = function(x) {
10802     return custom((x = +x) > 1 ? x : 1);
10803   };
10804
10805   return squarify;
10806 })(phi);
10807
10808 function index$2() {
10809   var tile = squarify,
10810       round = false,
10811       dx = 1,
10812       dy = 1,
10813       paddingStack = [0],
10814       paddingInner = constantZero,
10815       paddingTop = constantZero,
10816       paddingRight = constantZero,
10817       paddingBottom = constantZero,
10818       paddingLeft = constantZero;
10819
10820   function treemap(root) {
10821     root.x0 =
10822     root.y0 = 0;
10823     root.x1 = dx;
10824     root.y1 = dy;
10825     root.eachBefore(positionNode);
10826     paddingStack = [0];
10827     if (round) root.eachBefore(roundNode);
10828     return root;
10829   }
10830
10831   function positionNode(node) {
10832     var p = paddingStack[node.depth],
10833         x0 = node.x0 + p,
10834         y0 = node.y0 + p,
10835         x1 = node.x1 - p,
10836         y1 = node.y1 - p;
10837     if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
10838     if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
10839     node.x0 = x0;
10840     node.y0 = y0;
10841     node.x1 = x1;
10842     node.y1 = y1;
10843     if (node.children) {
10844       p = paddingStack[node.depth + 1] = paddingInner(node) / 2;
10845       x0 += paddingLeft(node) - p;
10846       y0 += paddingTop(node) - p;
10847       x1 -= paddingRight(node) - p;
10848       y1 -= paddingBottom(node) - p;
10849       if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
10850       if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
10851       tile(node, x0, y0, x1, y1);
10852     }
10853   }
10854
10855   treemap.round = function(x) {
10856     return arguments.length ? (round = !!x, treemap) : round;
10857   };
10858
10859   treemap.size = function(x) {
10860     return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy];
10861   };
10862
10863   treemap.tile = function(x) {
10864     return arguments.length ? (tile = required(x), treemap) : tile;
10865   };
10866
10867   treemap.padding = function(x) {
10868     return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner();
10869   };
10870
10871   treemap.paddingInner = function(x) {
10872     return arguments.length ? (paddingInner = typeof x === "function" ? x : constant$8(+x), treemap) : paddingInner;
10873   };
10874
10875   treemap.paddingOuter = function(x) {
10876     return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop();
10877   };
10878
10879   treemap.paddingTop = function(x) {
10880     return arguments.length ? (paddingTop = typeof x === "function" ? x : constant$8(+x), treemap) : paddingTop;
10881   };
10882
10883   treemap.paddingRight = function(x) {
10884     return arguments.length ? (paddingRight = typeof x === "function" ? x : constant$8(+x), treemap) : paddingRight;
10885   };
10886
10887   treemap.paddingBottom = function(x) {
10888     return arguments.length ? (paddingBottom = typeof x === "function" ? x : constant$8(+x), treemap) : paddingBottom;
10889   };
10890
10891   treemap.paddingLeft = function(x) {
10892     return arguments.length ? (paddingLeft = typeof x === "function" ? x : constant$8(+x), treemap) : paddingLeft;
10893   };
10894
10895   return treemap;
10896 }
10897
10898 function binary(parent, x0, y0, x1, y1) {
10899   var nodes = parent.children,
10900       i, n = nodes.length,
10901       sum, sums = new Array(n + 1);
10902
10903   for (sums[0] = sum = i = 0; i < n; ++i) {
10904     sums[i + 1] = sum += nodes[i].value;
10905   }
10906
10907   partition(0, n, parent.value, x0, y0, x1, y1);
10908
10909   function partition(i, j, value, x0, y0, x1, y1) {
10910     if (i >= j - 1) {
10911       var node = nodes[i];
10912       node.x0 = x0, node.y0 = y0;
10913       node.x1 = x1, node.y1 = y1;
10914       return;
10915     }
10916
10917     var valueOffset = sums[i],
10918         valueTarget = (value / 2) + valueOffset,
10919         k = i + 1,
10920         hi = j - 1;
10921
10922     while (k < hi) {
10923       var mid = k + hi >>> 1;
10924       if (sums[mid] < valueTarget) k = mid + 1;
10925       else hi = mid;
10926     }
10927
10928     if ((valueTarget - sums[k - 1]) < (sums[k] - valueTarget) && i + 1 < k) --k;
10929
10930     var valueLeft = sums[k] - valueOffset,
10931         valueRight = value - valueLeft;
10932
10933     if ((x1 - x0) > (y1 - y0)) {
10934       var xk = (x0 * valueRight + x1 * valueLeft) / value;
10935       partition(i, k, valueLeft, x0, y0, xk, y1);
10936       partition(k, j, valueRight, xk, y0, x1, y1);
10937     } else {
10938       var yk = (y0 * valueRight + y1 * valueLeft) / value;
10939       partition(i, k, valueLeft, x0, y0, x1, yk);
10940       partition(k, j, valueRight, x0, yk, x1, y1);
10941     }
10942   }
10943 }
10944
10945 function sliceDice(parent, x0, y0, x1, y1) {
10946   (parent.depth & 1 ? treemapSlice : treemapDice)(parent, x0, y0, x1, y1);
10947 }
10948
10949 var resquarify = (function custom(ratio) {
10950
10951   function resquarify(parent, x0, y0, x1, y1) {
10952     if ((rows = parent._squarify) && (rows.ratio === ratio)) {
10953       var rows,
10954           row,
10955           nodes,
10956           i,
10957           j = -1,
10958           n,
10959           m = rows.length,
10960           value = parent.value;
10961
10962       while (++j < m) {
10963         row = rows[j], nodes = row.children;
10964         for (i = row.value = 0, n = nodes.length; i < n; ++i) row.value += nodes[i].value;
10965         if (row.dice) treemapDice(row, x0, y0, x1, y0 += (y1 - y0) * row.value / value);
10966         else treemapSlice(row, x0, y0, x0 += (x1 - x0) * row.value / value, y1);
10967         value -= row.value;
10968       }
10969     } else {
10970       parent._squarify = rows = squarifyRatio(ratio, parent, x0, y0, x1, y1);
10971       rows.ratio = ratio;
10972     }
10973   }
10974
10975   resquarify.ratio = function(x) {
10976     return custom((x = +x) > 1 ? x : 1);
10977   };
10978
10979   return resquarify;
10980 })(phi);
10981
10982 function d3_polygonArea(polygon) {
10983   var i = -1,
10984       n = polygon.length,
10985       a,
10986       b = polygon[n - 1],
10987       area = 0;
10988
10989   while (++i < n) {
10990     a = b;
10991     b = polygon[i];
10992     area += a[1] * b[0] - a[0] * b[1];
10993   }
10994
10995   return area / 2;
10996 }
10997
10998 function d3_polygonCentroid(polygon) {
10999   var i = -1,
11000       n = polygon.length,
11001       x = 0,
11002       y = 0,
11003       a,
11004       b = polygon[n - 1],
11005       c,
11006       k = 0;
11007
11008   while (++i < n) {
11009     a = b;
11010     b = polygon[i];
11011     k += c = a[0] * b[1] - b[0] * a[1];
11012     x += (a[0] + b[0]) * c;
11013     y += (a[1] + b[1]) * c;
11014   }
11015
11016   return k *= 3, [x / k, y / k];
11017 }
11018
11019 // Returns the 2D cross product of AB and AC vectors, i.e., the z-component of
11020 // the 3D cross product in a quadrant I Cartesian coordinate system (+x is
11021 // right, +y is up). Returns a positive value if ABC is counter-clockwise,
11022 // negative if clockwise, and zero if the points are collinear.
11023 function cross$1(a, b, c) {
11024   return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);
11025 }
11026
11027 function lexicographicOrder(a, b) {
11028   return a[0] - b[0] || a[1] - b[1];
11029 }
11030
11031 // Computes the upper convex hull per the monotone chain algorithm.
11032 // Assumes points.length >= 3, is sorted by x, unique in y.
11033 // Returns an array of indices into points in left-to-right order.
11034 function computeUpperHullIndexes(points) {
11035   var n = points.length,
11036       indexes = [0, 1],
11037       size = 2;
11038
11039   for (var i = 2; i < n; ++i) {
11040     while (size > 1 && cross$1(points[indexes[size - 2]], points[indexes[size - 1]], points[i]) <= 0) --size;
11041     indexes[size++] = i;
11042   }
11043
11044   return indexes.slice(0, size); // remove popped points
11045 }
11046
11047 function d3_polygonHull(points) {
11048   if ((n = points.length) < 3) return null;
11049
11050   var i,
11051       n,
11052       sortedPoints = new Array(n),
11053       flippedPoints = new Array(n);
11054
11055   for (i = 0; i < n; ++i) sortedPoints[i] = [+points[i][0], +points[i][1], i];
11056   sortedPoints.sort(lexicographicOrder);
11057   for (i = 0; i < n; ++i) flippedPoints[i] = [sortedPoints[i][0], -sortedPoints[i][1]];
11058
11059   var upperIndexes = computeUpperHullIndexes(sortedPoints),
11060       lowerIndexes = computeUpperHullIndexes(flippedPoints);
11061
11062   // Construct the hull polygon, removing possible duplicate endpoints.
11063   var skipLeft = lowerIndexes[0] === upperIndexes[0],
11064       skipRight = lowerIndexes[lowerIndexes.length - 1] === upperIndexes[upperIndexes.length - 1],
11065       hull = [];
11066
11067   // Add upper hull in right-to-l order.
11068   // Then add lower hull in left-to-right order.
11069   for (i = upperIndexes.length - 1; i >= 0; --i) hull.push(points[sortedPoints[upperIndexes[i]][2]]);
11070   for (i = +skipLeft; i < lowerIndexes.length - skipRight; ++i) hull.push(points[sortedPoints[lowerIndexes[i]][2]]);
11071
11072   return hull;
11073 }
11074
11075 function contains$1(polygon, point) {
11076   var n = polygon.length,
11077       p = polygon[n - 1],
11078       x = point[0], y = point[1],
11079       x0 = p[0], y0 = p[1],
11080       x1, y1,
11081       inside = false;
11082
11083   for (var i = 0; i < n; ++i) {
11084     p = polygon[i], x1 = p[0], y1 = p[1];
11085     if (((y1 > y) !== (y0 > y)) && (x < (x0 - x1) * (y - y1) / (y0 - y1) + x1)) inside = !inside;
11086     x0 = x1, y0 = y1;
11087   }
11088
11089   return inside;
11090 }
11091
11092 function length$1(polygon) {
11093   var i = -1,
11094       n = polygon.length,
11095       b = polygon[n - 1],
11096       xa,
11097       ya,
11098       xb = b[0],
11099       yb = b[1],
11100       perimeter = 0;
11101
11102   while (++i < n) {
11103     xa = xb;
11104     ya = yb;
11105     b = polygon[i];
11106     xb = b[0];
11107     yb = b[1];
11108     xa -= xb;
11109     ya -= yb;
11110     perimeter += Math.sqrt(xa * xa + ya * ya);
11111   }
11112
11113   return perimeter;
11114 }
11115
11116 var slice$4 = [].slice;
11117
11118 var noabort = {};
11119
11120 function Queue(size) {
11121   this._size = size;
11122   this._call =
11123   this._error = null;
11124   this._tasks = [];
11125   this._data = [];
11126   this._waiting =
11127   this._active =
11128   this._ended =
11129   this._start = 0; // inside a synchronous task callback?
11130 }
11131
11132 Queue.prototype = queue.prototype = {
11133   constructor: Queue,
11134   defer: function(callback) {
11135     if (typeof callback !== "function") throw new Error("invalid callback");
11136     if (this._call) throw new Error("defer after await");
11137     if (this._error != null) return this;
11138     var t = slice$4.call(arguments, 1);
11139     t.push(callback);
11140     ++this._waiting, this._tasks.push(t);
11141     poke$1(this);
11142     return this;
11143   },
11144   abort: function() {
11145     if (this._error == null) abort(this, new Error("abort"));
11146     return this;
11147   },
11148   await: function(callback) {
11149     if (typeof callback !== "function") throw new Error("invalid callback");
11150     if (this._call) throw new Error("multiple await");
11151     this._call = function(error, results) { callback.apply(null, [error].concat(results)); };
11152     maybeNotify(this);
11153     return this;
11154   },
11155   awaitAll: function(callback) {
11156     if (typeof callback !== "function") throw new Error("invalid callback");
11157     if (this._call) throw new Error("multiple await");
11158     this._call = callback;
11159     maybeNotify(this);
11160     return this;
11161   }
11162 };
11163
11164 function poke$1(q) {
11165   if (!q._start) {
11166     try { start$1(q); } // let the current task complete
11167     catch (e) {
11168       if (q._tasks[q._ended + q._active - 1]) abort(q, e); // task errored synchronously
11169       else if (!q._data) throw e; // await callback errored synchronously
11170     }
11171   }
11172 }
11173
11174 function start$1(q) {
11175   while (q._start = q._waiting && q._active < q._size) {
11176     var i = q._ended + q._active,
11177         t = q._tasks[i],
11178         j = t.length - 1,
11179         c = t[j];
11180     t[j] = end(q, i);
11181     --q._waiting, ++q._active;
11182     t = c.apply(null, t);
11183     if (!q._tasks[i]) continue; // task finished synchronously
11184     q._tasks[i] = t || noabort;
11185   }
11186 }
11187
11188 function end(q, i) {
11189   return function(e, r) {
11190     if (!q._tasks[i]) return; // ignore multiple callbacks
11191     --q._active, ++q._ended;
11192     q._tasks[i] = null;
11193     if (q._error != null) return; // ignore secondary errors
11194     if (e != null) {
11195       abort(q, e);
11196     } else {
11197       q._data[i] = r;
11198       if (q._waiting) poke$1(q);
11199       else maybeNotify(q);
11200     }
11201   };
11202 }
11203
11204 function abort(q, e) {
11205   var i = q._tasks.length, t;
11206   q._error = e; // ignore active callbacks
11207   q._data = undefined; // allow gc
11208   q._waiting = NaN; // prevent starting
11209
11210   while (--i >= 0) {
11211     if (t = q._tasks[i]) {
11212       q._tasks[i] = null;
11213       if (t.abort) {
11214         try { t.abort(); }
11215         catch (e) { /* ignore */ }
11216       }
11217     }
11218   }
11219
11220   q._active = NaN; // allow notification
11221   maybeNotify(q);
11222 }
11223
11224 function maybeNotify(q) {
11225   if (!q._active && q._call) {
11226     var d = q._data;
11227     q._data = undefined; // allow gc
11228     q._call(q._error, d);
11229   }
11230 }
11231
11232 function queue(concurrency) {
11233   if (concurrency == null) concurrency = Infinity;
11234   else if (!((concurrency = +concurrency) >= 1)) throw new Error("invalid concurrency");
11235   return new Queue(concurrency);
11236 }
11237
11238 function defaultSource$1() {
11239   return Math.random();
11240 }
11241
11242 var uniform = (function sourceRandomUniform(source) {
11243   function randomUniform(min, max) {
11244     min = min == null ? 0 : +min;
11245     max = max == null ? 1 : +max;
11246     if (arguments.length === 1) max = min, min = 0;
11247     else max -= min;
11248     return function() {
11249       return source() * max + min;
11250     };
11251   }
11252
11253   randomUniform.source = sourceRandomUniform;
11254
11255   return randomUniform;
11256 })(defaultSource$1);
11257
11258 var normal = (function sourceRandomNormal(source) {
11259   function randomNormal(mu, sigma) {
11260     var x, r;
11261     mu = mu == null ? 0 : +mu;
11262     sigma = sigma == null ? 1 : +sigma;
11263     return function() {
11264       var y;
11265
11266       // If available, use the second previously-generated uniform random.
11267       if (x != null) y = x, x = null;
11268
11269       // Otherwise, generate a new x and y.
11270       else do {
11271         x = source() * 2 - 1;
11272         y = source() * 2 - 1;
11273         r = x * x + y * y;
11274       } while (!r || r > 1);
11275
11276       return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r);
11277     };
11278   }
11279
11280   randomNormal.source = sourceRandomNormal;
11281
11282   return randomNormal;
11283 })(defaultSource$1);
11284
11285 var logNormal = (function sourceRandomLogNormal(source) {
11286   function randomLogNormal() {
11287     var randomNormal = normal.source(source).apply(this, arguments);
11288     return function() {
11289       return Math.exp(randomNormal());
11290     };
11291   }
11292
11293   randomLogNormal.source = sourceRandomLogNormal;
11294
11295   return randomLogNormal;
11296 })(defaultSource$1);
11297
11298 var irwinHall = (function sourceRandomIrwinHall(source) {
11299   function randomIrwinHall(n) {
11300     return function() {
11301       for (var sum = 0, i = 0; i < n; ++i) sum += source();
11302       return sum;
11303     };
11304   }
11305
11306   randomIrwinHall.source = sourceRandomIrwinHall;
11307
11308   return randomIrwinHall;
11309 })(defaultSource$1);
11310
11311 var bates = (function sourceRandomBates(source) {
11312   function randomBates(n) {
11313     var randomIrwinHall = irwinHall.source(source)(n);
11314     return function() {
11315       return randomIrwinHall() / n;
11316     };
11317   }
11318
11319   randomBates.source = sourceRandomBates;
11320
11321   return randomBates;
11322 })(defaultSource$1);
11323
11324 var exponential$1 = (function sourceRandomExponential(source) {
11325   function randomExponential(lambda) {
11326     return function() {
11327       return -Math.log(1 - source()) / lambda;
11328     };
11329   }
11330
11331   randomExponential.source = sourceRandomExponential;
11332
11333   return randomExponential;
11334 })(defaultSource$1);
11335
11336 function d3_request(url, callback) {
11337   var request,
11338       event = dispatch("beforesend", "progress", "load", "error"),
11339       mimeType,
11340       headers = map$1(),
11341       xhr = new XMLHttpRequest,
11342       user = null,
11343       password = null,
11344       response,
11345       responseType,
11346       timeout = 0;
11347
11348   // If IE does not support CORS, use XDomainRequest.
11349   if (typeof XDomainRequest !== "undefined"
11350       && !("withCredentials" in xhr)
11351       && /^(http(s)?:)?\/\//.test(url)) xhr = new XDomainRequest;
11352
11353   "onload" in xhr
11354       ? xhr.onload = xhr.onerror = xhr.ontimeout = respond
11355       : xhr.onreadystatechange = function(o) { xhr.readyState > 3 && respond(o); };
11356
11357   function respond(o) {
11358     var status = xhr.status, result;
11359     if (!status && hasResponse(xhr)
11360         || status >= 200 && status < 300
11361         || status === 304) {
11362       if (response) {
11363         try {
11364           result = response.call(request, xhr);
11365         } catch (e) {
11366           event.call("error", request, e);
11367           return;
11368         }
11369       } else {
11370         result = xhr;
11371       }
11372       event.call("load", request, result);
11373     } else {
11374       event.call("error", request, o);
11375     }
11376   }
11377
11378   xhr.onprogress = function(e) {
11379     event.call("progress", request, e);
11380   };
11381
11382   request = {
11383     header: function(name, value) {
11384       name = (name + "").toLowerCase();
11385       if (arguments.length < 2) return headers.get(name);
11386       if (value == null) headers.remove(name);
11387       else headers.set(name, value + "");
11388       return request;
11389     },
11390
11391     // If mimeType is non-null and no Accept header is set, a default is used.
11392     mimeType: function(value) {
11393       if (!arguments.length) return mimeType;
11394       mimeType = value == null ? null : value + "";
11395       return request;
11396     },
11397
11398     // Specifies what type the response value should take;
11399     // for instance, arraybuffer, blob, document, or text.
11400     responseType: function(value) {
11401       if (!arguments.length) return responseType;
11402       responseType = value;
11403       return request;
11404     },
11405
11406     timeout: function(value) {
11407       if (!arguments.length) return timeout;
11408       timeout = +value;
11409       return request;
11410     },
11411
11412     user: function(value) {
11413       return arguments.length < 1 ? user : (user = value == null ? null : value + "", request);
11414     },
11415
11416     password: function(value) {
11417       return arguments.length < 1 ? password : (password = value == null ? null : value + "", request);
11418     },
11419
11420     // Specify how to convert the response content to a specific type;
11421     // changes the callback value on "load" events.
11422     response: function(value) {
11423       response = value;
11424       return request;
11425     },
11426
11427     // Alias for send("GET", …).
11428     get: function(data, callback) {
11429       return request.send("GET", data, callback);
11430     },
11431
11432     // Alias for send("POST", …).
11433     post: function(data, callback) {
11434       return request.send("POST", data, callback);
11435     },
11436
11437     // If callback is non-null, it will be used for error and load events.
11438     send: function(method, data, callback) {
11439       xhr.open(method, url, true, user, password);
11440       if (mimeType != null && !headers.has("accept")) headers.set("accept", mimeType + ",*/*");
11441       if (xhr.setRequestHeader) headers.each(function(value, name) { xhr.setRequestHeader(name, value); });
11442       if (mimeType != null && xhr.overrideMimeType) xhr.overrideMimeType(mimeType);
11443       if (responseType != null) xhr.responseType = responseType;
11444       if (timeout > 0) xhr.timeout = timeout;
11445       if (callback == null && typeof data === "function") callback = data, data = null;
11446       if (callback != null && callback.length === 1) callback = fixCallback(callback);
11447       if (callback != null) request.on("error", callback).on("load", function(xhr) { callback(null, xhr); });
11448       event.call("beforesend", request, xhr);
11449       xhr.send(data == null ? null : data);
11450       return request;
11451     },
11452
11453     abort: function() {
11454       xhr.abort();
11455       return request;
11456     },
11457
11458     on: function() {
11459       var value = event.on.apply(event, arguments);
11460       return value === event ? request : value;
11461     }
11462   };
11463
11464   if (callback != null) {
11465     if (typeof callback !== "function") throw new Error("invalid callback: " + callback);
11466     return request.get(callback);
11467   }
11468
11469   return request;
11470 }
11471
11472 function fixCallback(callback) {
11473   return function(error, xhr) {
11474     callback(error == null ? xhr : null);
11475   };
11476 }
11477
11478 function hasResponse(xhr) {
11479   var type = xhr.responseType;
11480   return type && type !== "text"
11481       ? xhr.response // null on error
11482       : xhr.responseText; // "" on error
11483 }
11484
11485 function type$1(defaultMimeType, response) {
11486   return function(url, callback) {
11487     var r = d3_request(url).mimeType(defaultMimeType).response(response);
11488     if (callback != null) {
11489       if (typeof callback !== "function") throw new Error("invalid callback: " + callback);
11490       return r.get(callback);
11491     }
11492     return r;
11493   };
11494 }
11495
11496 var html = type$1("text/html", function(xhr) {
11497   return document.createRange().createContextualFragment(xhr.responseText);
11498 });
11499
11500 var d3_json = type$1("application/json", function(xhr) {
11501   return JSON.parse(xhr.responseText);
11502 });
11503
11504 var d3_text = type$1("text/plain", function(xhr) {
11505   return xhr.responseText;
11506 });
11507
11508 var d3_xml = type$1("application/xml", function(xhr) {
11509   var xml = xhr.responseXML;
11510   if (!xml) throw new Error("parse error");
11511   return xml;
11512 });
11513
11514 function dsv$1(defaultMimeType, parse) {
11515   return function(url, row, callback) {
11516     if (arguments.length < 3) callback = row, row = null;
11517     var r = d3_request(url).mimeType(defaultMimeType);
11518     r.row = function(_) { return arguments.length ? r.response(responseOf(parse, row = _)) : row; };
11519     r.row(row);
11520     return callback ? r.get(callback) : r;
11521   };
11522 }
11523
11524 function responseOf(parse, row) {
11525   return function(request) {
11526     return parse(request.responseText, row);
11527   };
11528 }
11529
11530 var csv$1 = dsv$1("text/csv", csvParse);
11531
11532 var tsv$1 = dsv$1("text/tab-separated-values", tsvParse);
11533
11534 var array$2 = Array.prototype;
11535
11536 var map$3 = array$2.map;
11537 var slice$5 = array$2.slice;
11538
11539 var implicit = {name: "implicit"};
11540
11541 function ordinal(range) {
11542   var index = map$1(),
11543       domain = [],
11544       unknown = implicit;
11545
11546   range = range == null ? [] : slice$5.call(range);
11547
11548   function scale(d) {
11549     var key = d + "", i = index.get(key);
11550     if (!i) {
11551       if (unknown !== implicit) return unknown;
11552       index.set(key, i = domain.push(d));
11553     }
11554     return range[(i - 1) % range.length];
11555   }
11556
11557   scale.domain = function(_) {
11558     if (!arguments.length) return domain.slice();
11559     domain = [], index = map$1();
11560     var i = -1, n = _.length, d, key;
11561     while (++i < n) if (!index.has(key = (d = _[i]) + "")) index.set(key, domain.push(d));
11562     return scale;
11563   };
11564
11565   scale.range = function(_) {
11566     return arguments.length ? (range = slice$5.call(_), scale) : range.slice();
11567   };
11568
11569   scale.unknown = function(_) {
11570     return arguments.length ? (unknown = _, scale) : unknown;
11571   };
11572
11573   scale.copy = function() {
11574     return ordinal()
11575         .domain(domain)
11576         .range(range)
11577         .unknown(unknown);
11578   };
11579
11580   return scale;
11581 }
11582
11583 function band() {
11584   var scale = ordinal().unknown(undefined),
11585       domain = scale.domain,
11586       ordinalRange = scale.range,
11587       range$$1 = [0, 1],
11588       step,
11589       bandwidth,
11590       round = false,
11591       paddingInner = 0,
11592       paddingOuter = 0,
11593       align = 0.5;
11594
11595   delete scale.unknown;
11596
11597   function rescale() {
11598     var n = domain().length,
11599         reverse = range$$1[1] < range$$1[0],
11600         start = range$$1[reverse - 0],
11601         stop = range$$1[1 - reverse];
11602     step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2);
11603     if (round) step = Math.floor(step);
11604     start += (stop - start - step * (n - paddingInner)) * align;
11605     bandwidth = step * (1 - paddingInner);
11606     if (round) start = Math.round(start), bandwidth = Math.round(bandwidth);
11607     var values = d3_range(n).map(function(i) { return start + step * i; });
11608     return ordinalRange(reverse ? values.reverse() : values);
11609   }
11610
11611   scale.domain = function(_) {
11612     return arguments.length ? (domain(_), rescale()) : domain();
11613   };
11614
11615   scale.range = function(_) {
11616     return arguments.length ? (range$$1 = [+_[0], +_[1]], rescale()) : range$$1.slice();
11617   };
11618
11619   scale.rangeRound = function(_) {
11620     return range$$1 = [+_[0], +_[1]], round = true, rescale();
11621   };
11622
11623   scale.bandwidth = function() {
11624     return bandwidth;
11625   };
11626
11627   scale.step = function() {
11628     return step;
11629   };
11630
11631   scale.round = function(_) {
11632     return arguments.length ? (round = !!_, rescale()) : round;
11633   };
11634
11635   scale.padding = function(_) {
11636     return arguments.length ? (paddingInner = paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;
11637   };
11638
11639   scale.paddingInner = function(_) {
11640     return arguments.length ? (paddingInner = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;
11641   };
11642
11643   scale.paddingOuter = function(_) {
11644     return arguments.length ? (paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingOuter;
11645   };
11646
11647   scale.align = function(_) {
11648     return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align;
11649   };
11650
11651   scale.copy = function() {
11652     return band()
11653         .domain(domain())
11654         .range(range$$1)
11655         .round(round)
11656         .paddingInner(paddingInner)
11657         .paddingOuter(paddingOuter)
11658         .align(align);
11659   };
11660
11661   return rescale();
11662 }
11663
11664 function pointish(scale) {
11665   var copy = scale.copy;
11666
11667   scale.padding = scale.paddingOuter;
11668   delete scale.paddingInner;
11669   delete scale.paddingOuter;
11670
11671   scale.copy = function() {
11672     return pointish(copy());
11673   };
11674
11675   return scale;
11676 }
11677
11678 function point$1() {
11679   return pointish(band().paddingInner(1));
11680 }
11681
11682 function constant$9(x) {
11683   return function() {
11684     return x;
11685   };
11686 }
11687
11688 function number$2(x) {
11689   return +x;
11690 }
11691
11692 var unit = [0, 1];
11693
11694 function deinterpolateLinear(a, b) {
11695   return (b -= (a = +a))
11696       ? function(x) { return (x - a) / b; }
11697       : constant$9(b);
11698 }
11699
11700 function deinterpolateClamp(deinterpolate) {
11701   return function(a, b) {
11702     var d = deinterpolate(a = +a, b = +b);
11703     return function(x) { return x <= a ? 0 : x >= b ? 1 : d(x); };
11704   };
11705 }
11706
11707 function reinterpolateClamp(reinterpolate) {
11708   return function(a, b) {
11709     var r = reinterpolate(a = +a, b = +b);
11710     return function(t) { return t <= 0 ? a : t >= 1 ? b : r(t); };
11711   };
11712 }
11713
11714 function bimap(domain, range, deinterpolate, reinterpolate) {
11715   var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1];
11716   if (d1 < d0) d0 = deinterpolate(d1, d0), r0 = reinterpolate(r1, r0);
11717   else d0 = deinterpolate(d0, d1), r0 = reinterpolate(r0, r1);
11718   return function(x) { return r0(d0(x)); };
11719 }
11720
11721 function polymap(domain, range, deinterpolate, reinterpolate) {
11722   var j = Math.min(domain.length, range.length) - 1,
11723       d = new Array(j),
11724       r = new Array(j),
11725       i = -1;
11726
11727   // Reverse descending domains.
11728   if (domain[j] < domain[0]) {
11729     domain = domain.slice().reverse();
11730     range = range.slice().reverse();
11731   }
11732
11733   while (++i < j) {
11734     d[i] = deinterpolate(domain[i], domain[i + 1]);
11735     r[i] = reinterpolate(range[i], range[i + 1]);
11736   }
11737
11738   return function(x) {
11739     var i = bisectRight(domain, x, 1, j) - 1;
11740     return r[i](d[i](x));
11741   };
11742 }
11743
11744 function copy(source, target) {
11745   return target
11746       .domain(source.domain())
11747       .range(source.range())
11748       .interpolate(source.interpolate())
11749       .clamp(source.clamp());
11750 }
11751
11752 // deinterpolate(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1].
11753 // reinterpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding domain value x in [a,b].
11754 function continuous(deinterpolate, reinterpolate) {
11755   var domain = unit,
11756       range = unit,
11757       interpolate$$1 = d3_interpolate,
11758       clamp = false,
11759       piecewise,
11760       output,
11761       input;
11762
11763   function rescale() {
11764     piecewise = Math.min(domain.length, range.length) > 2 ? polymap : bimap;
11765     output = input = null;
11766     return scale;
11767   }
11768
11769   function scale(x) {
11770     return (output || (output = piecewise(domain, range, clamp ? deinterpolateClamp(deinterpolate) : deinterpolate, interpolate$$1)))(+x);
11771   }
11772
11773   scale.invert = function(y) {
11774     return (input || (input = piecewise(range, domain, deinterpolateLinear, clamp ? reinterpolateClamp(reinterpolate) : reinterpolate)))(+y);
11775   };
11776
11777   scale.domain = function(_) {
11778     return arguments.length ? (domain = map$3.call(_, number$2), rescale()) : domain.slice();
11779   };
11780
11781   scale.range = function(_) {
11782     return arguments.length ? (range = slice$5.call(_), rescale()) : range.slice();
11783   };
11784
11785   scale.rangeRound = function(_) {
11786     return range = slice$5.call(_), interpolate$$1 = interpolateRound, rescale();
11787   };
11788
11789   scale.clamp = function(_) {
11790     return arguments.length ? (clamp = !!_, rescale()) : clamp;
11791   };
11792
11793   scale.interpolate = function(_) {
11794     return arguments.length ? (interpolate$$1 = _, rescale()) : interpolate$$1;
11795   };
11796
11797   return rescale();
11798 }
11799
11800 function tickFormat(domain, count, specifier) {
11801   var start = domain[0],
11802       stop = domain[domain.length - 1],
11803       step = tickStep(start, stop, count == null ? 10 : count),
11804       precision;
11805   specifier = formatSpecifier(specifier == null ? ",f" : specifier);
11806   switch (specifier.type) {
11807     case "s": {
11808       var value = Math.max(Math.abs(start), Math.abs(stop));
11809       if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;
11810       return formatPrefix(specifier, value);
11811     }
11812     case "":
11813     case "e":
11814     case "g":
11815     case "p":
11816     case "r": {
11817       if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e");
11818       break;
11819     }
11820     case "f":
11821     case "%": {
11822       if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2;
11823       break;
11824     }
11825   }
11826   return format(specifier);
11827 }
11828
11829 function linearish(scale) {
11830   var domain = scale.domain;
11831
11832   scale.ticks = function(count) {
11833     var d = domain();
11834     return ticks(d[0], d[d.length - 1], count == null ? 10 : count);
11835   };
11836
11837   scale.tickFormat = function(count, specifier) {
11838     return tickFormat(domain(), count, specifier);
11839   };
11840
11841   scale.nice = function(count) {
11842     if (count == null) count = 10;
11843
11844     var d = domain(),
11845         i0 = 0,
11846         i1 = d.length - 1,
11847         start = d[i0],
11848         stop = d[i1],
11849         step;
11850
11851     if (stop < start) {
11852       step = start, start = stop, stop = step;
11853       step = i0, i0 = i1, i1 = step;
11854     }
11855
11856     step = tickIncrement(start, stop, count);
11857
11858     if (step > 0) {
11859       start = Math.floor(start / step) * step;
11860       stop = Math.ceil(stop / step) * step;
11861       step = tickIncrement(start, stop, count);
11862     } else if (step < 0) {
11863       start = Math.ceil(start * step) / step;
11864       stop = Math.floor(stop * step) / step;
11865       step = tickIncrement(start, stop, count);
11866     }
11867
11868     if (step > 0) {
11869       d[i0] = Math.floor(start / step) * step;
11870       d[i1] = Math.ceil(stop / step) * step;
11871       domain(d);
11872     } else if (step < 0) {
11873       d[i0] = Math.ceil(start * step) / step;
11874       d[i1] = Math.floor(stop * step) / step;
11875       domain(d);
11876     }
11877
11878     return scale;
11879   };
11880
11881   return scale;
11882 }
11883
11884 function linear$2() {
11885   var scale = continuous(deinterpolateLinear, d3_interpolateNumber);
11886
11887   scale.copy = function() {
11888     return copy(scale, linear$2());
11889   };
11890
11891   return linearish(scale);
11892 }
11893
11894 function identity$5() {
11895   var domain = [0, 1];
11896
11897   function scale(x) {
11898     return +x;
11899   }
11900
11901   scale.invert = scale;
11902
11903   scale.domain = scale.range = function(_) {
11904     return arguments.length ? (domain = map$3.call(_, number$2), scale) : domain.slice();
11905   };
11906
11907   scale.copy = function() {
11908     return identity$5().domain(domain);
11909   };
11910
11911   return linearish(scale);
11912 }
11913
11914 function nice(domain, interval) {
11915   domain = domain.slice();
11916
11917   var i0 = 0,
11918       i1 = domain.length - 1,
11919       x0 = domain[i0],
11920       x1 = domain[i1],
11921       t;
11922
11923   if (x1 < x0) {
11924     t = i0, i0 = i1, i1 = t;
11925     t = x0, x0 = x1, x1 = t;
11926   }
11927
11928   domain[i0] = interval.floor(x0);
11929   domain[i1] = interval.ceil(x1);
11930   return domain;
11931 }
11932
11933 function deinterpolate(a, b) {
11934   return (b = Math.log(b / a))
11935       ? function(x) { return Math.log(x / a) / b; }
11936       : constant$9(b);
11937 }
11938
11939 function reinterpolate(a, b) {
11940   return a < 0
11941       ? function(t) { return -Math.pow(-b, t) * Math.pow(-a, 1 - t); }
11942       : function(t) { return Math.pow(b, t) * Math.pow(a, 1 - t); };
11943 }
11944
11945 function pow10(x) {
11946   return isFinite(x) ? +("1e" + x) : x < 0 ? 0 : x;
11947 }
11948
11949 function powp(base) {
11950   return base === 10 ? pow10
11951       : base === Math.E ? Math.exp
11952       : function(x) { return Math.pow(base, x); };
11953 }
11954
11955 function logp(base) {
11956   return base === Math.E ? Math.log
11957       : base === 10 && Math.log10
11958       || base === 2 && Math.log2
11959       || (base = Math.log(base), function(x) { return Math.log(x) / base; });
11960 }
11961
11962 function reflect(f) {
11963   return function(x) {
11964     return -f(-x);
11965   };
11966 }
11967
11968 function log$1() {
11969   var scale = continuous(deinterpolate, reinterpolate).domain([1, 10]),
11970       domain = scale.domain,
11971       base = 10,
11972       logs = logp(10),
11973       pows = powp(10);
11974
11975   function rescale() {
11976     logs = logp(base), pows = powp(base);
11977     if (domain()[0] < 0) logs = reflect(logs), pows = reflect(pows);
11978     return scale;
11979   }
11980
11981   scale.base = function(_) {
11982     return arguments.length ? (base = +_, rescale()) : base;
11983   };
11984
11985   scale.domain = function(_) {
11986     return arguments.length ? (domain(_), rescale()) : domain();
11987   };
11988
11989   scale.ticks = function(count) {
11990     var d = domain(),
11991         u = d[0],
11992         v = d[d.length - 1],
11993         r;
11994
11995     if (r = v < u) i = u, u = v, v = i;
11996
11997     var i = logs(u),
11998         j = logs(v),
11999         p,
12000         k,
12001         t,
12002         n = count == null ? 10 : +count,
12003         z = [];
12004
12005     if (!(base % 1) && j - i < n) {
12006       i = Math.round(i) - 1, j = Math.round(j) + 1;
12007       if (u > 0) for (; i < j; ++i) {
12008         for (k = 1, p = pows(i); k < base; ++k) {
12009           t = p * k;
12010           if (t < u) continue;
12011           if (t > v) break;
12012           z.push(t);
12013         }
12014       } else for (; i < j; ++i) {
12015         for (k = base - 1, p = pows(i); k >= 1; --k) {
12016           t = p * k;
12017           if (t < u) continue;
12018           if (t > v) break;
12019           z.push(t);
12020         }
12021       }
12022     } else {
12023       z = ticks(i, j, Math.min(j - i, n)).map(pows);
12024     }
12025
12026     return r ? z.reverse() : z;
12027   };
12028
12029   scale.tickFormat = function(count, specifier) {
12030     if (specifier == null) specifier = base === 10 ? ".0e" : ",";
12031     if (typeof specifier !== "function") specifier = format(specifier);
12032     if (count === Infinity) return specifier;
12033     if (count == null) count = 10;
12034     var k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate?
12035     return function(d) {
12036       var i = d / pows(Math.round(logs(d)));
12037       if (i * base < base - 0.5) i *= base;
12038       return i <= k ? specifier(d) : "";
12039     };
12040   };
12041
12042   scale.nice = function() {
12043     return domain(nice(domain(), {
12044       floor: function(x) { return pows(Math.floor(logs(x))); },
12045       ceil: function(x) { return pows(Math.ceil(logs(x))); }
12046     }));
12047   };
12048
12049   scale.copy = function() {
12050     return copy(scale, log$1().base(base));
12051   };
12052
12053   return scale;
12054 }
12055
12056 function raise$1(x, exponent) {
12057   return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent);
12058 }
12059
12060 function pow$1() {
12061   var exponent = 1,
12062       scale = continuous(deinterpolate, reinterpolate),
12063       domain = scale.domain;
12064
12065   function deinterpolate(a, b) {
12066     return (b = raise$1(b, exponent) - (a = raise$1(a, exponent)))
12067         ? function(x) { return (raise$1(x, exponent) - a) / b; }
12068         : constant$9(b);
12069   }
12070
12071   function reinterpolate(a, b) {
12072     b = raise$1(b, exponent) - (a = raise$1(a, exponent));
12073     return function(t) { return raise$1(a + b * t, 1 / exponent); };
12074   }
12075
12076   scale.exponent = function(_) {
12077     return arguments.length ? (exponent = +_, domain(domain())) : exponent;
12078   };
12079
12080   scale.copy = function() {
12081     return copy(scale, pow$1().exponent(exponent));
12082   };
12083
12084   return linearish(scale);
12085 }
12086
12087 function sqrt$1() {
12088   return pow$1().exponent(0.5);
12089 }
12090
12091 function quantile$$1() {
12092   var domain = [],
12093       range = [],
12094       thresholds = [];
12095
12096   function rescale() {
12097     var i = 0, n = Math.max(1, range.length);
12098     thresholds = new Array(n - 1);
12099     while (++i < n) thresholds[i - 1] = threshold(domain, i / n);
12100     return scale;
12101   }
12102
12103   function scale(x) {
12104     if (!isNaN(x = +x)) return range[bisectRight(thresholds, x)];
12105   }
12106
12107   scale.invertExtent = function(y) {
12108     var i = range.indexOf(y);
12109     return i < 0 ? [NaN, NaN] : [
12110       i > 0 ? thresholds[i - 1] : domain[0],
12111       i < thresholds.length ? thresholds[i] : domain[domain.length - 1]
12112     ];
12113   };
12114
12115   scale.domain = function(_) {
12116     if (!arguments.length) return domain.slice();
12117     domain = [];
12118     for (var i = 0, n = _.length, d; i < n; ++i) if (d = _[i], d != null && !isNaN(d = +d)) domain.push(d);
12119     domain.sort(d3_ascending);
12120     return rescale();
12121   };
12122
12123   scale.range = function(_) {
12124     return arguments.length ? (range = slice$5.call(_), rescale()) : range.slice();
12125   };
12126
12127   scale.quantiles = function() {
12128     return thresholds.slice();
12129   };
12130
12131   scale.copy = function() {
12132     return quantile$$1()
12133         .domain(domain)
12134         .range(range);
12135   };
12136
12137   return scale;
12138 }
12139
12140 function quantize() {
12141   var x0 = 0,
12142       x1 = 1,
12143       n = 1,
12144       domain = [0.5],
12145       range = [0, 1];
12146
12147   function scale(x) {
12148     if (x <= x) return range[bisectRight(domain, x, 0, n)];
12149   }
12150
12151   function rescale() {
12152     var i = -1;
12153     domain = new Array(n);
12154     while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1);
12155     return scale;
12156   }
12157
12158   scale.domain = function(_) {
12159     return arguments.length ? (x0 = +_[0], x1 = +_[1], rescale()) : [x0, x1];
12160   };
12161
12162   scale.range = function(_) {
12163     return arguments.length ? (n = (range = slice$5.call(_)).length - 1, rescale()) : range.slice();
12164   };
12165
12166   scale.invertExtent = function(y) {
12167     var i = range.indexOf(y);
12168     return i < 0 ? [NaN, NaN]
12169         : i < 1 ? [x0, domain[0]]
12170         : i >= n ? [domain[n - 1], x1]
12171         : [domain[i - 1], domain[i]];
12172   };
12173
12174   scale.copy = function() {
12175     return quantize()
12176         .domain([x0, x1])
12177         .range(range);
12178   };
12179
12180   return linearish(scale);
12181 }
12182
12183 function threshold$1() {
12184   var domain = [0.5],
12185       range = [0, 1],
12186       n = 1;
12187
12188   function scale(x) {
12189     if (x <= x) return range[bisectRight(domain, x, 0, n)];
12190   }
12191
12192   scale.domain = function(_) {
12193     return arguments.length ? (domain = slice$5.call(_), n = Math.min(domain.length, range.length - 1), scale) : domain.slice();
12194   };
12195
12196   scale.range = function(_) {
12197     return arguments.length ? (range = slice$5.call(_), n = Math.min(domain.length, range.length - 1), scale) : range.slice();
12198   };
12199
12200   scale.invertExtent = function(y) {
12201     var i = range.indexOf(y);
12202     return [domain[i - 1], domain[i]];
12203   };
12204
12205   scale.copy = function() {
12206     return threshold$1()
12207         .domain(domain)
12208         .range(range);
12209   };
12210
12211   return scale;
12212 }
12213
12214 var t0$1 = new Date;
12215 var t1$1 = new Date;
12216
12217 function newInterval(floori, offseti, count, field) {
12218
12219   function interval(date) {
12220     return floori(date = new Date(+date)), date;
12221   }
12222
12223   interval.floor = interval;
12224
12225   interval.ceil = function(date) {
12226     return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date;
12227   };
12228
12229   interval.round = function(date) {
12230     var d0 = interval(date),
12231         d1 = interval.ceil(date);
12232     return date - d0 < d1 - date ? d0 : d1;
12233   };
12234
12235   interval.offset = function(date, step) {
12236     return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;
12237   };
12238
12239   interval.range = function(start, stop, step) {
12240     var range = [], previous;
12241     start = interval.ceil(start);
12242     step = step == null ? 1 : Math.floor(step);
12243     if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date
12244     do range.push(previous = new Date(+start)), offseti(start, step), floori(start);
12245     while (previous < start && start < stop);
12246     return range;
12247   };
12248
12249   interval.filter = function(test) {
12250     return newInterval(function(date) {
12251       if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1);
12252     }, function(date, step) {
12253       if (date >= date) {
12254         if (step < 0) while (++step <= 0) {
12255           while (offseti(date, -1), !test(date)) {} // eslint-disable-line no-empty
12256         } else while (--step >= 0) {
12257           while (offseti(date, +1), !test(date)) {} // eslint-disable-line no-empty
12258         }
12259       }
12260     });
12261   };
12262
12263   if (count) {
12264     interval.count = function(start, end) {
12265       t0$1.setTime(+start), t1$1.setTime(+end);
12266       floori(t0$1), floori(t1$1);
12267       return Math.floor(count(t0$1, t1$1));
12268     };
12269
12270     interval.every = function(step) {
12271       step = Math.floor(step);
12272       return !isFinite(step) || !(step > 0) ? null
12273           : !(step > 1) ? interval
12274           : interval.filter(field
12275               ? function(d) { return field(d) % step === 0; }
12276               : function(d) { return interval.count(0, d) % step === 0; });
12277     };
12278   }
12279
12280   return interval;
12281 }
12282
12283 var millisecond = newInterval(function() {
12284   // noop
12285 }, function(date, step) {
12286   date.setTime(+date + step);
12287 }, function(start, end) {
12288   return end - start;
12289 });
12290
12291 // An optimized implementation for this simple case.
12292 millisecond.every = function(k) {
12293   k = Math.floor(k);
12294   if (!isFinite(k) || !(k > 0)) return null;
12295   if (!(k > 1)) return millisecond;
12296   return newInterval(function(date) {
12297     date.setTime(Math.floor(date / k) * k);
12298   }, function(date, step) {
12299     date.setTime(+date + step * k);
12300   }, function(start, end) {
12301     return (end - start) / k;
12302   });
12303 };
12304
12305 var milliseconds = millisecond.range;
12306
12307 var durationSecond = 1e3;
12308 var durationMinute = 6e4;
12309 var durationHour = 36e5;
12310 var durationDay = 864e5;
12311 var durationWeek = 6048e5;
12312
12313 var second = newInterval(function(date) {
12314   date.setTime(Math.floor(date / durationSecond) * durationSecond);
12315 }, function(date, step) {
12316   date.setTime(+date + step * durationSecond);
12317 }, function(start, end) {
12318   return (end - start) / durationSecond;
12319 }, function(date) {
12320   return date.getUTCSeconds();
12321 });
12322
12323 var seconds = second.range;
12324
12325 var minute = newInterval(function(date) {
12326   date.setTime(Math.floor(date / durationMinute) * durationMinute);
12327 }, function(date, step) {
12328   date.setTime(+date + step * durationMinute);
12329 }, function(start, end) {
12330   return (end - start) / durationMinute;
12331 }, function(date) {
12332   return date.getMinutes();
12333 });
12334
12335 var minutes = minute.range;
12336
12337 var hour = newInterval(function(date) {
12338   var offset = date.getTimezoneOffset() * durationMinute % durationHour;
12339   if (offset < 0) offset += durationHour;
12340   date.setTime(Math.floor((+date - offset) / durationHour) * durationHour + offset);
12341 }, function(date, step) {
12342   date.setTime(+date + step * durationHour);
12343 }, function(start, end) {
12344   return (end - start) / durationHour;
12345 }, function(date) {
12346   return date.getHours();
12347 });
12348
12349 var hours = hour.range;
12350
12351 var day = newInterval(function(date) {
12352   date.setHours(0, 0, 0, 0);
12353 }, function(date, step) {
12354   date.setDate(date.getDate() + step);
12355 }, function(start, end) {
12356   return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationDay;
12357 }, function(date) {
12358   return date.getDate() - 1;
12359 });
12360
12361 var days = day.range;
12362
12363 function weekday(i) {
12364   return newInterval(function(date) {
12365     date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);
12366     date.setHours(0, 0, 0, 0);
12367   }, function(date, step) {
12368     date.setDate(date.getDate() + step * 7);
12369   }, function(start, end) {
12370     return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationWeek;
12371   });
12372 }
12373
12374 var sunday = weekday(0);
12375 var monday = weekday(1);
12376 var tuesday = weekday(2);
12377 var wednesday = weekday(3);
12378 var thursday = weekday(4);
12379 var friday = weekday(5);
12380 var saturday = weekday(6);
12381
12382 var sundays = sunday.range;
12383 var mondays = monday.range;
12384 var tuesdays = tuesday.range;
12385 var wednesdays = wednesday.range;
12386 var thursdays = thursday.range;
12387 var fridays = friday.range;
12388 var saturdays = saturday.range;
12389
12390 var month = newInterval(function(date) {
12391   date.setDate(1);
12392   date.setHours(0, 0, 0, 0);
12393 }, function(date, step) {
12394   date.setMonth(date.getMonth() + step);
12395 }, function(start, end) {
12396   return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;
12397 }, function(date) {
12398   return date.getMonth();
12399 });
12400
12401 var months = month.range;
12402
12403 var year = newInterval(function(date) {
12404   date.setMonth(0, 1);
12405   date.setHours(0, 0, 0, 0);
12406 }, function(date, step) {
12407   date.setFullYear(date.getFullYear() + step);
12408 }, function(start, end) {
12409   return end.getFullYear() - start.getFullYear();
12410 }, function(date) {
12411   return date.getFullYear();
12412 });
12413
12414 // An optimized implementation for this simple case.
12415 year.every = function(k) {
12416   return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {
12417     date.setFullYear(Math.floor(date.getFullYear() / k) * k);
12418     date.setMonth(0, 1);
12419     date.setHours(0, 0, 0, 0);
12420   }, function(date, step) {
12421     date.setFullYear(date.getFullYear() + step * k);
12422   });
12423 };
12424
12425 var years = year.range;
12426
12427 var utcMinute = newInterval(function(date) {
12428   date.setUTCSeconds(0, 0);
12429 }, function(date, step) {
12430   date.setTime(+date + step * durationMinute);
12431 }, function(start, end) {
12432   return (end - start) / durationMinute;
12433 }, function(date) {
12434   return date.getUTCMinutes();
12435 });
12436
12437 var utcMinutes = utcMinute.range;
12438
12439 var utcHour = newInterval(function(date) {
12440   date.setUTCMinutes(0, 0, 0);
12441 }, function(date, step) {
12442   date.setTime(+date + step * durationHour);
12443 }, function(start, end) {
12444   return (end - start) / durationHour;
12445 }, function(date) {
12446   return date.getUTCHours();
12447 });
12448
12449 var utcHours = utcHour.range;
12450
12451 var utcDay = newInterval(function(date) {
12452   date.setUTCHours(0, 0, 0, 0);
12453 }, function(date, step) {
12454   date.setUTCDate(date.getUTCDate() + step);
12455 }, function(start, end) {
12456   return (end - start) / durationDay;
12457 }, function(date) {
12458   return date.getUTCDate() - 1;
12459 });
12460
12461 var utcDays = utcDay.range;
12462
12463 function utcWeekday(i) {
12464   return newInterval(function(date) {
12465     date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);
12466     date.setUTCHours(0, 0, 0, 0);
12467   }, function(date, step) {
12468     date.setUTCDate(date.getUTCDate() + step * 7);
12469   }, function(start, end) {
12470     return (end - start) / durationWeek;
12471   });
12472 }
12473
12474 var utcSunday = utcWeekday(0);
12475 var utcMonday = utcWeekday(1);
12476 var utcTuesday = utcWeekday(2);
12477 var utcWednesday = utcWeekday(3);
12478 var utcThursday = utcWeekday(4);
12479 var utcFriday = utcWeekday(5);
12480 var utcSaturday = utcWeekday(6);
12481
12482 var utcSundays = utcSunday.range;
12483 var utcMondays = utcMonday.range;
12484 var utcTuesdays = utcTuesday.range;
12485 var utcWednesdays = utcWednesday.range;
12486 var utcThursdays = utcThursday.range;
12487 var utcFridays = utcFriday.range;
12488 var utcSaturdays = utcSaturday.range;
12489
12490 var utcMonth = newInterval(function(date) {
12491   date.setUTCDate(1);
12492   date.setUTCHours(0, 0, 0, 0);
12493 }, function(date, step) {
12494   date.setUTCMonth(date.getUTCMonth() + step);
12495 }, function(start, end) {
12496   return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;
12497 }, function(date) {
12498   return date.getUTCMonth();
12499 });
12500
12501 var utcMonths = utcMonth.range;
12502
12503 var utcYear = newInterval(function(date) {
12504   date.setUTCMonth(0, 1);
12505   date.setUTCHours(0, 0, 0, 0);
12506 }, function(date, step) {
12507   date.setUTCFullYear(date.getUTCFullYear() + step);
12508 }, function(start, end) {
12509   return end.getUTCFullYear() - start.getUTCFullYear();
12510 }, function(date) {
12511   return date.getUTCFullYear();
12512 });
12513
12514 // An optimized implementation for this simple case.
12515 utcYear.every = function(k) {
12516   return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {
12517     date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);
12518     date.setUTCMonth(0, 1);
12519     date.setUTCHours(0, 0, 0, 0);
12520   }, function(date, step) {
12521     date.setUTCFullYear(date.getUTCFullYear() + step * k);
12522   });
12523 };
12524
12525 var utcYears = utcYear.range;
12526
12527 function localDate(d) {
12528   if (0 <= d.y && d.y < 100) {
12529     var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);
12530     date.setFullYear(d.y);
12531     return date;
12532   }
12533   return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);
12534 }
12535
12536 function utcDate(d) {
12537   if (0 <= d.y && d.y < 100) {
12538     var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));
12539     date.setUTCFullYear(d.y);
12540     return date;
12541   }
12542   return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));
12543 }
12544
12545 function newYear(y) {
12546   return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0};
12547 }
12548
12549 function formatLocale$1(locale) {
12550   var locale_dateTime = locale.dateTime,
12551       locale_date = locale.date,
12552       locale_time = locale.time,
12553       locale_periods = locale.periods,
12554       locale_weekdays = locale.days,
12555       locale_shortWeekdays = locale.shortDays,
12556       locale_months = locale.months,
12557       locale_shortMonths = locale.shortMonths;
12558
12559   var periodRe = formatRe(locale_periods),
12560       periodLookup = formatLookup(locale_periods),
12561       weekdayRe = formatRe(locale_weekdays),
12562       weekdayLookup = formatLookup(locale_weekdays),
12563       shortWeekdayRe = formatRe(locale_shortWeekdays),
12564       shortWeekdayLookup = formatLookup(locale_shortWeekdays),
12565       monthRe = formatRe(locale_months),
12566       monthLookup = formatLookup(locale_months),
12567       shortMonthRe = formatRe(locale_shortMonths),
12568       shortMonthLookup = formatLookup(locale_shortMonths);
12569
12570   var formats = {
12571     "a": formatShortWeekday,
12572     "A": formatWeekday,
12573     "b": formatShortMonth,
12574     "B": formatMonth,
12575     "c": null,
12576     "d": formatDayOfMonth,
12577     "e": formatDayOfMonth,
12578     "f": formatMicroseconds,
12579     "H": formatHour24,
12580     "I": formatHour12,
12581     "j": formatDayOfYear,
12582     "L": formatMilliseconds,
12583     "m": formatMonthNumber,
12584     "M": formatMinutes,
12585     "p": formatPeriod,
12586     "Q": formatUnixTimestamp,
12587     "s": formatUnixTimestampSeconds,
12588     "S": formatSeconds,
12589     "u": formatWeekdayNumberMonday,
12590     "U": formatWeekNumberSunday,
12591     "V": formatWeekNumberISO,
12592     "w": formatWeekdayNumberSunday,
12593     "W": formatWeekNumberMonday,
12594     "x": null,
12595     "X": null,
12596     "y": formatYear,
12597     "Y": formatFullYear,
12598     "Z": formatZone,
12599     "%": formatLiteralPercent
12600   };
12601
12602   var utcFormats = {
12603     "a": formatUTCShortWeekday,
12604     "A": formatUTCWeekday,
12605     "b": formatUTCShortMonth,
12606     "B": formatUTCMonth,
12607     "c": null,
12608     "d": formatUTCDayOfMonth,
12609     "e": formatUTCDayOfMonth,
12610     "f": formatUTCMicroseconds,
12611     "H": formatUTCHour24,
12612     "I": formatUTCHour12,
12613     "j": formatUTCDayOfYear,
12614     "L": formatUTCMilliseconds,
12615     "m": formatUTCMonthNumber,
12616     "M": formatUTCMinutes,
12617     "p": formatUTCPeriod,
12618     "Q": formatUnixTimestamp,
12619     "s": formatUnixTimestampSeconds,
12620     "S": formatUTCSeconds,
12621     "u": formatUTCWeekdayNumberMonday,
12622     "U": formatUTCWeekNumberSunday,
12623     "V": formatUTCWeekNumberISO,
12624     "w": formatUTCWeekdayNumberSunday,
12625     "W": formatUTCWeekNumberMonday,
12626     "x": null,
12627     "X": null,
12628     "y": formatUTCYear,
12629     "Y": formatUTCFullYear,
12630     "Z": formatUTCZone,
12631     "%": formatLiteralPercent
12632   };
12633
12634   var parses = {
12635     "a": parseShortWeekday,
12636     "A": parseWeekday,
12637     "b": parseShortMonth,
12638     "B": parseMonth,
12639     "c": parseLocaleDateTime,
12640     "d": parseDayOfMonth,
12641     "e": parseDayOfMonth,
12642     "f": parseMicroseconds,
12643     "H": parseHour24,
12644     "I": parseHour24,
12645     "j": parseDayOfYear,
12646     "L": parseMilliseconds,
12647     "m": parseMonthNumber,
12648     "M": parseMinutes,
12649     "p": parsePeriod,
12650     "Q": parseUnixTimestamp,
12651     "s": parseUnixTimestampSeconds,
12652     "S": parseSeconds,
12653     "u": parseWeekdayNumberMonday,
12654     "U": parseWeekNumberSunday,
12655     "V": parseWeekNumberISO,
12656     "w": parseWeekdayNumberSunday,
12657     "W": parseWeekNumberMonday,
12658     "x": parseLocaleDate,
12659     "X": parseLocaleTime,
12660     "y": parseYear,
12661     "Y": parseFullYear,
12662     "Z": parseZone,
12663     "%": parseLiteralPercent
12664   };
12665
12666   // These recursive directive definitions must be deferred.
12667   formats.x = newFormat(locale_date, formats);
12668   formats.X = newFormat(locale_time, formats);
12669   formats.c = newFormat(locale_dateTime, formats);
12670   utcFormats.x = newFormat(locale_date, utcFormats);
12671   utcFormats.X = newFormat(locale_time, utcFormats);
12672   utcFormats.c = newFormat(locale_dateTime, utcFormats);
12673
12674   function newFormat(specifier, formats) {
12675     return function(date) {
12676       var string = [],
12677           i = -1,
12678           j = 0,
12679           n = specifier.length,
12680           c,
12681           pad,
12682           format;
12683
12684       if (!(date instanceof Date)) date = new Date(+date);
12685
12686       while (++i < n) {
12687         if (specifier.charCodeAt(i) === 37) {
12688           string.push(specifier.slice(j, i));
12689           if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);
12690           else pad = c === "e" ? " " : "0";
12691           if (format = formats[c]) c = format(date, pad);
12692           string.push(c);
12693           j = i + 1;
12694         }
12695       }
12696
12697       string.push(specifier.slice(j, i));
12698       return string.join("");
12699     };
12700   }
12701
12702   function newParse(specifier, newDate) {
12703     return function(string) {
12704       var d = newYear(1900),
12705           i = parseSpecifier(d, specifier, string += "", 0),
12706           week, day$$1;
12707       if (i != string.length) return null;
12708
12709       // If a UNIX timestamp is specified, return it.
12710       if ("Q" in d) return new Date(d.Q);
12711
12712       // The am-pm flag is 0 for AM, and 1 for PM.
12713       if ("p" in d) d.H = d.H % 12 + d.p * 12;
12714
12715       // Convert day-of-week and week-of-year to day-of-year.
12716       if ("V" in d) {
12717         if (d.V < 1 || d.V > 53) return null;
12718         if (!("w" in d)) d.w = 1;
12719         if ("Z" in d) {
12720           week = utcDate(newYear(d.y)), day$$1 = week.getUTCDay();
12721           week = day$$1 > 4 || day$$1 === 0 ? utcMonday.ceil(week) : utcMonday(week);
12722           week = utcDay.offset(week, (d.V - 1) * 7);
12723           d.y = week.getUTCFullYear();
12724           d.m = week.getUTCMonth();
12725           d.d = week.getUTCDate() + (d.w + 6) % 7;
12726         } else {
12727           week = newDate(newYear(d.y)), day$$1 = week.getDay();
12728           week = day$$1 > 4 || day$$1 === 0 ? monday.ceil(week) : monday(week);
12729           week = day.offset(week, (d.V - 1) * 7);
12730           d.y = week.getFullYear();
12731           d.m = week.getMonth();
12732           d.d = week.getDate() + (d.w + 6) % 7;
12733         }
12734       } else if ("W" in d || "U" in d) {
12735         if (!("w" in d)) d.w = "u" in d ? d.u % 7 : "W" in d ? 1 : 0;
12736         day$$1 = "Z" in d ? utcDate(newYear(d.y)).getUTCDay() : newDate(newYear(d.y)).getDay();
12737         d.m = 0;
12738         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;
12739       }
12740
12741       // If a time zone is specified, all fields are interpreted as UTC and then
12742       // offset according to the specified time zone.
12743       if ("Z" in d) {
12744         d.H += d.Z / 100 | 0;
12745         d.M += d.Z % 100;
12746         return utcDate(d);
12747       }
12748
12749       // Otherwise, all fields are in local time.
12750       return newDate(d);
12751     };
12752   }
12753
12754   function parseSpecifier(d, specifier, string, j) {
12755     var i = 0,
12756         n = specifier.length,
12757         m = string.length,
12758         c,
12759         parse;
12760
12761     while (i < n) {
12762       if (j >= m) return -1;
12763       c = specifier.charCodeAt(i++);
12764       if (c === 37) {
12765         c = specifier.charAt(i++);
12766         parse = parses[c in pads ? specifier.charAt(i++) : c];
12767         if (!parse || ((j = parse(d, string, j)) < 0)) return -1;
12768       } else if (c != string.charCodeAt(j++)) {
12769         return -1;
12770       }
12771     }
12772
12773     return j;
12774   }
12775
12776   function parsePeriod(d, string, i) {
12777     var n = periodRe.exec(string.slice(i));
12778     return n ? (d.p = periodLookup[n[0].toLowerCase()], i + n[0].length) : -1;
12779   }
12780
12781   function parseShortWeekday(d, string, i) {
12782     var n = shortWeekdayRe.exec(string.slice(i));
12783     return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;
12784   }
12785
12786   function parseWeekday(d, string, i) {
12787     var n = weekdayRe.exec(string.slice(i));
12788     return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;
12789   }
12790
12791   function parseShortMonth(d, string, i) {
12792     var n = shortMonthRe.exec(string.slice(i));
12793     return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1;
12794   }
12795
12796   function parseMonth(d, string, i) {
12797     var n = monthRe.exec(string.slice(i));
12798     return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1;
12799   }
12800
12801   function parseLocaleDateTime(d, string, i) {
12802     return parseSpecifier(d, locale_dateTime, string, i);
12803   }
12804
12805   function parseLocaleDate(d, string, i) {
12806     return parseSpecifier(d, locale_date, string, i);
12807   }
12808
12809   function parseLocaleTime(d, string, i) {
12810     return parseSpecifier(d, locale_time, string, i);
12811   }
12812
12813   function formatShortWeekday(d) {
12814     return locale_shortWeekdays[d.getDay()];
12815   }
12816
12817   function formatWeekday(d) {
12818     return locale_weekdays[d.getDay()];
12819   }
12820
12821   function formatShortMonth(d) {
12822     return locale_shortMonths[d.getMonth()];
12823   }
12824
12825   function formatMonth(d) {
12826     return locale_months[d.getMonth()];
12827   }
12828
12829   function formatPeriod(d) {
12830     return locale_periods[+(d.getHours() >= 12)];
12831   }
12832
12833   function formatUTCShortWeekday(d) {
12834     return locale_shortWeekdays[d.getUTCDay()];
12835   }
12836
12837   function formatUTCWeekday(d) {
12838     return locale_weekdays[d.getUTCDay()];
12839   }
12840
12841   function formatUTCShortMonth(d) {
12842     return locale_shortMonths[d.getUTCMonth()];
12843   }
12844
12845   function formatUTCMonth(d) {
12846     return locale_months[d.getUTCMonth()];
12847   }
12848
12849   function formatUTCPeriod(d) {
12850     return locale_periods[+(d.getUTCHours() >= 12)];
12851   }
12852
12853   return {
12854     format: function(specifier) {
12855       var f = newFormat(specifier += "", formats);
12856       f.toString = function() { return specifier; };
12857       return f;
12858     },
12859     parse: function(specifier) {
12860       var p = newParse(specifier += "", localDate);
12861       p.toString = function() { return specifier; };
12862       return p;
12863     },
12864     utcFormat: function(specifier) {
12865       var f = newFormat(specifier += "", utcFormats);
12866       f.toString = function() { return specifier; };
12867       return f;
12868     },
12869     utcParse: function(specifier) {
12870       var p = newParse(specifier, utcDate);
12871       p.toString = function() { return specifier; };
12872       return p;
12873     }
12874   };
12875 }
12876
12877 var pads = {"-": "", "_": " ", "0": "0"};
12878 var numberRe = /^\s*\d+/;
12879 var percentRe = /^%/;
12880 var requoteRe = /[\\^$*+?|[\]().{}]/g;
12881
12882 function pad(value, fill, width) {
12883   var sign = value < 0 ? "-" : "",
12884       string = (sign ? -value : value) + "",
12885       length = string.length;
12886   return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);
12887 }
12888
12889 function requote(s) {
12890   return s.replace(requoteRe, "\\$&");
12891 }
12892
12893 function formatRe(names) {
12894   return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i");
12895 }
12896
12897 function formatLookup(names) {
12898   var map = {}, i = -1, n = names.length;
12899   while (++i < n) map[names[i].toLowerCase()] = i;
12900   return map;
12901 }
12902
12903 function parseWeekdayNumberSunday(d, string, i) {
12904   var n = numberRe.exec(string.slice(i, i + 1));
12905   return n ? (d.w = +n[0], i + n[0].length) : -1;
12906 }
12907
12908 function parseWeekdayNumberMonday(d, string, i) {
12909   var n = numberRe.exec(string.slice(i, i + 1));
12910   return n ? (d.u = +n[0], i + n[0].length) : -1;
12911 }
12912
12913 function parseWeekNumberSunday(d, string, i) {
12914   var n = numberRe.exec(string.slice(i, i + 2));
12915   return n ? (d.U = +n[0], i + n[0].length) : -1;
12916 }
12917
12918 function parseWeekNumberISO(d, string, i) {
12919   var n = numberRe.exec(string.slice(i, i + 2));
12920   return n ? (d.V = +n[0], i + n[0].length) : -1;
12921 }
12922
12923 function parseWeekNumberMonday(d, string, i) {
12924   var n = numberRe.exec(string.slice(i, i + 2));
12925   return n ? (d.W = +n[0], i + n[0].length) : -1;
12926 }
12927
12928 function parseFullYear(d, string, i) {
12929   var n = numberRe.exec(string.slice(i, i + 4));
12930   return n ? (d.y = +n[0], i + n[0].length) : -1;
12931 }
12932
12933 function parseYear(d, string, i) {
12934   var n = numberRe.exec(string.slice(i, i + 2));
12935   return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1;
12936 }
12937
12938 function parseZone(d, string, i) {
12939   var n = /^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(string.slice(i, i + 6));
12940   return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || "00")), i + n[0].length) : -1;
12941 }
12942
12943 function parseMonthNumber(d, string, i) {
12944   var n = numberRe.exec(string.slice(i, i + 2));
12945   return n ? (d.m = n[0] - 1, i + n[0].length) : -1;
12946 }
12947
12948 function parseDayOfMonth(d, string, i) {
12949   var n = numberRe.exec(string.slice(i, i + 2));
12950   return n ? (d.d = +n[0], i + n[0].length) : -1;
12951 }
12952
12953 function parseDayOfYear(d, string, i) {
12954   var n = numberRe.exec(string.slice(i, i + 3));
12955   return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;
12956 }
12957
12958 function parseHour24(d, string, i) {
12959   var n = numberRe.exec(string.slice(i, i + 2));
12960   return n ? (d.H = +n[0], i + n[0].length) : -1;
12961 }
12962
12963 function parseMinutes(d, string, i) {
12964   var n = numberRe.exec(string.slice(i, i + 2));
12965   return n ? (d.M = +n[0], i + n[0].length) : -1;
12966 }
12967
12968 function parseSeconds(d, string, i) {
12969   var n = numberRe.exec(string.slice(i, i + 2));
12970   return n ? (d.S = +n[0], i + n[0].length) : -1;
12971 }
12972
12973 function parseMilliseconds(d, string, i) {
12974   var n = numberRe.exec(string.slice(i, i + 3));
12975   return n ? (d.L = +n[0], i + n[0].length) : -1;
12976 }
12977
12978 function parseMicroseconds(d, string, i) {
12979   var n = numberRe.exec(string.slice(i, i + 6));
12980   return n ? (d.L = Math.floor(n[0] / 1000), i + n[0].length) : -1;
12981 }
12982
12983 function parseLiteralPercent(d, string, i) {
12984   var n = percentRe.exec(string.slice(i, i + 1));
12985   return n ? i + n[0].length : -1;
12986 }
12987
12988 function parseUnixTimestamp(d, string, i) {
12989   var n = numberRe.exec(string.slice(i));
12990   return n ? (d.Q = +n[0], i + n[0].length) : -1;
12991 }
12992
12993 function parseUnixTimestampSeconds(d, string, i) {
12994   var n = numberRe.exec(string.slice(i));
12995   return n ? (d.Q = (+n[0]) * 1000, i + n[0].length) : -1;
12996 }
12997
12998 function formatDayOfMonth(d, p) {
12999   return pad(d.getDate(), p, 2);
13000 }
13001
13002 function formatHour24(d, p) {
13003   return pad(d.getHours(), p, 2);
13004 }
13005
13006 function formatHour12(d, p) {
13007   return pad(d.getHours() % 12 || 12, p, 2);
13008 }
13009
13010 function formatDayOfYear(d, p) {
13011   return pad(1 + day.count(year(d), d), p, 3);
13012 }
13013
13014 function formatMilliseconds(d, p) {
13015   return pad(d.getMilliseconds(), p, 3);
13016 }
13017
13018 function formatMicroseconds(d, p) {
13019   return formatMilliseconds(d, p) + "000";
13020 }
13021
13022 function formatMonthNumber(d, p) {
13023   return pad(d.getMonth() + 1, p, 2);
13024 }
13025
13026 function formatMinutes(d, p) {
13027   return pad(d.getMinutes(), p, 2);
13028 }
13029
13030 function formatSeconds(d, p) {
13031   return pad(d.getSeconds(), p, 2);
13032 }
13033
13034 function formatWeekdayNumberMonday(d) {
13035   var day$$1 = d.getDay();
13036   return day$$1 === 0 ? 7 : day$$1;
13037 }
13038
13039 function formatWeekNumberSunday(d, p) {
13040   return pad(sunday.count(year(d), d), p, 2);
13041 }
13042
13043 function formatWeekNumberISO(d, p) {
13044   var day$$1 = d.getDay();
13045   d = (day$$1 >= 4 || day$$1 === 0) ? thursday(d) : thursday.ceil(d);
13046   return pad(thursday.count(year(d), d) + (year(d).getDay() === 4), p, 2);
13047 }
13048
13049 function formatWeekdayNumberSunday(d) {
13050   return d.getDay();
13051 }
13052
13053 function formatWeekNumberMonday(d, p) {
13054   return pad(monday.count(year(d), d), p, 2);
13055 }
13056
13057 function formatYear(d, p) {
13058   return pad(d.getFullYear() % 100, p, 2);
13059 }
13060
13061 function formatFullYear(d, p) {
13062   return pad(d.getFullYear() % 10000, p, 4);
13063 }
13064
13065 function formatZone(d) {
13066   var z = d.getTimezoneOffset();
13067   return (z > 0 ? "-" : (z *= -1, "+"))
13068       + pad(z / 60 | 0, "0", 2)
13069       + pad(z % 60, "0", 2);
13070 }
13071
13072 function formatUTCDayOfMonth(d, p) {
13073   return pad(d.getUTCDate(), p, 2);
13074 }
13075
13076 function formatUTCHour24(d, p) {
13077   return pad(d.getUTCHours(), p, 2);
13078 }
13079
13080 function formatUTCHour12(d, p) {
13081   return pad(d.getUTCHours() % 12 || 12, p, 2);
13082 }
13083
13084 function formatUTCDayOfYear(d, p) {
13085   return pad(1 + utcDay.count(utcYear(d), d), p, 3);
13086 }
13087
13088 function formatUTCMilliseconds(d, p) {
13089   return pad(d.getUTCMilliseconds(), p, 3);
13090 }
13091
13092 function formatUTCMicroseconds(d, p) {
13093   return formatUTCMilliseconds(d, p) + "000";
13094 }
13095
13096 function formatUTCMonthNumber(d, p) {
13097   return pad(d.getUTCMonth() + 1, p, 2);
13098 }
13099
13100 function formatUTCMinutes(d, p) {
13101   return pad(d.getUTCMinutes(), p, 2);
13102 }
13103
13104 function formatUTCSeconds(d, p) {
13105   return pad(d.getUTCSeconds(), p, 2);
13106 }
13107
13108 function formatUTCWeekdayNumberMonday(d) {
13109   var dow = d.getUTCDay();
13110   return dow === 0 ? 7 : dow;
13111 }
13112
13113 function formatUTCWeekNumberSunday(d, p) {
13114   return pad(utcSunday.count(utcYear(d), d), p, 2);
13115 }
13116
13117 function formatUTCWeekNumberISO(d, p) {
13118   var day$$1 = d.getUTCDay();
13119   d = (day$$1 >= 4 || day$$1 === 0) ? utcThursday(d) : utcThursday.ceil(d);
13120   return pad(utcThursday.count(utcYear(d), d) + (utcYear(d).getUTCDay() === 4), p, 2);
13121 }
13122
13123 function formatUTCWeekdayNumberSunday(d) {
13124   return d.getUTCDay();
13125 }
13126
13127 function formatUTCWeekNumberMonday(d, p) {
13128   return pad(utcMonday.count(utcYear(d), d), p, 2);
13129 }
13130
13131 function formatUTCYear(d, p) {
13132   return pad(d.getUTCFullYear() % 100, p, 2);
13133 }
13134
13135 function formatUTCFullYear(d, p) {
13136   return pad(d.getUTCFullYear() % 10000, p, 4);
13137 }
13138
13139 function formatUTCZone() {
13140   return "+0000";
13141 }
13142
13143 function formatLiteralPercent() {
13144   return "%";
13145 }
13146
13147 function formatUnixTimestamp(d) {
13148   return +d;
13149 }
13150
13151 function formatUnixTimestampSeconds(d) {
13152   return Math.floor(+d / 1000);
13153 }
13154
13155 var locale$1;
13156 var timeFormat;
13157 var timeParse;
13158 var utcFormat;
13159 var utcParse;
13160
13161 defaultLocale$1({
13162   dateTime: "%x, %X",
13163   date: "%-m/%-d/%Y",
13164   time: "%-I:%M:%S %p",
13165   periods: ["AM", "PM"],
13166   days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
13167   shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
13168   months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
13169   shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
13170 });
13171
13172 function defaultLocale$1(definition) {
13173   locale$1 = formatLocale$1(definition);
13174   timeFormat = locale$1.format;
13175   timeParse = locale$1.parse;
13176   utcFormat = locale$1.utcFormat;
13177   utcParse = locale$1.utcParse;
13178   return locale$1;
13179 }
13180
13181 var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ";
13182
13183 function formatIsoNative(date) {
13184   return date.toISOString();
13185 }
13186
13187 var formatIso = Date.prototype.toISOString
13188     ? formatIsoNative
13189     : utcFormat(isoSpecifier);
13190
13191 function parseIsoNative(string) {
13192   var date = new Date(string);
13193   return isNaN(date) ? null : date;
13194 }
13195
13196 var parseIso = +new Date("2000-01-01T00:00:00.000Z")
13197     ? parseIsoNative
13198     : utcParse(isoSpecifier);
13199
13200 var durationSecond$1 = 1000;
13201 var durationMinute$1 = durationSecond$1 * 60;
13202 var durationHour$1 = durationMinute$1 * 60;
13203 var durationDay$1 = durationHour$1 * 24;
13204 var durationWeek$1 = durationDay$1 * 7;
13205 var durationMonth = durationDay$1 * 30;
13206 var durationYear = durationDay$1 * 365;
13207
13208 function date$1(t) {
13209   return new Date(t);
13210 }
13211
13212 function number$3(t) {
13213   return t instanceof Date ? +t : +new Date(+t);
13214 }
13215
13216 function calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format) {
13217   var scale = continuous(deinterpolateLinear, d3_interpolateNumber),
13218       invert = scale.invert,
13219       domain = scale.domain;
13220
13221   var formatMillisecond = format(".%L"),
13222       formatSecond = format(":%S"),
13223       formatMinute = format("%I:%M"),
13224       formatHour = format("%I %p"),
13225       formatDay = format("%a %d"),
13226       formatWeek = format("%b %d"),
13227       formatMonth = format("%B"),
13228       formatYear = format("%Y");
13229
13230   var tickIntervals = [
13231     [second$$1,  1,      durationSecond$1],
13232     [second$$1,  5,  5 * durationSecond$1],
13233     [second$$1, 15, 15 * durationSecond$1],
13234     [second$$1, 30, 30 * durationSecond$1],
13235     [minute$$1,  1,      durationMinute$1],
13236     [minute$$1,  5,  5 * durationMinute$1],
13237     [minute$$1, 15, 15 * durationMinute$1],
13238     [minute$$1, 30, 30 * durationMinute$1],
13239     [  hour$$1,  1,      durationHour$1  ],
13240     [  hour$$1,  3,  3 * durationHour$1  ],
13241     [  hour$$1,  6,  6 * durationHour$1  ],
13242     [  hour$$1, 12, 12 * durationHour$1  ],
13243     [   day$$1,  1,      durationDay$1   ],
13244     [   day$$1,  2,  2 * durationDay$1   ],
13245     [  week,  1,      durationWeek$1  ],
13246     [ month$$1,  1,      durationMonth ],
13247     [ month$$1,  3,  3 * durationMonth ],
13248     [  year$$1,  1,      durationYear  ]
13249   ];
13250
13251   function tickFormat(date) {
13252     return (second$$1(date) < date ? formatMillisecond
13253         : minute$$1(date) < date ? formatSecond
13254         : hour$$1(date) < date ? formatMinute
13255         : day$$1(date) < date ? formatHour
13256         : month$$1(date) < date ? (week(date) < date ? formatDay : formatWeek)
13257         : year$$1(date) < date ? formatMonth
13258         : formatYear)(date);
13259   }
13260
13261   function tickInterval(interval, start, stop, step) {
13262     if (interval == null) interval = 10;
13263
13264     // If a desired tick count is specified, pick a reasonable tick interval
13265     // based on the extent of the domain and a rough estimate of tick size.
13266     // Otherwise, assume interval is already a time interval and use it.
13267     if (typeof interval === "number") {
13268       var target = Math.abs(stop - start) / interval,
13269           i = d3_bisector(function(i) { return i[2]; }).right(tickIntervals, target);
13270       if (i === tickIntervals.length) {
13271         step = tickStep(start / durationYear, stop / durationYear, interval);
13272         interval = year$$1;
13273       } else if (i) {
13274         i = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i];
13275         step = i[1];
13276         interval = i[0];
13277       } else {
13278         step = Math.max(tickStep(start, stop, interval), 1);
13279         interval = millisecond$$1;
13280       }
13281     }
13282
13283     return step == null ? interval : interval.every(step);
13284   }
13285
13286   scale.invert = function(y) {
13287     return new Date(invert(y));
13288   };
13289
13290   scale.domain = function(_) {
13291     return arguments.length ? domain(map$3.call(_, number$3)) : domain().map(date$1);
13292   };
13293
13294   scale.ticks = function(interval, step) {
13295     var d = domain(),
13296         t0 = d[0],
13297         t1 = d[d.length - 1],
13298         r = t1 < t0,
13299         t;
13300     if (r) t = t0, t0 = t1, t1 = t;
13301     t = tickInterval(interval, t0, t1, step);
13302     t = t ? t.range(t0, t1 + 1) : []; // inclusive stop
13303     return r ? t.reverse() : t;
13304   };
13305
13306   scale.tickFormat = function(count, specifier) {
13307     return specifier == null ? tickFormat : format(specifier);
13308   };
13309
13310   scale.nice = function(interval, step) {
13311     var d = domain();
13312     return (interval = tickInterval(interval, d[0], d[d.length - 1], step))
13313         ? domain(nice(d, interval))
13314         : scale;
13315   };
13316
13317   scale.copy = function() {
13318     return copy(scale, calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format));
13319   };
13320
13321   return scale;
13322 }
13323
13324 function time() {
13325   return calendar(year, month, sunday, day, hour, minute, second, millisecond, timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]);
13326 }
13327
13328 function utcTime() {
13329   return calendar(utcYear, utcMonth, utcSunday, utcDay, utcHour, utcMinute, second, millisecond, utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]);
13330 }
13331
13332 function colors(s) {
13333   return s.match(/.{6}/g).map(function(x) {
13334     return "#" + x;
13335   });
13336 }
13337
13338 var category10 = colors("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf");
13339
13340 var category20b = colors("393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6");
13341
13342 var category20c = colors("3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9");
13343
13344 var category20 = colors("1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5");
13345
13346 var cubehelix$3 = cubehelixLong(cubehelix(300, 0.5, 0.0), cubehelix(-240, 0.5, 1.0));
13347
13348 var warm = cubehelixLong(cubehelix(-100, 0.75, 0.35), cubehelix(80, 1.50, 0.8));
13349
13350 var cool = cubehelixLong(cubehelix(260, 0.75, 0.35), cubehelix(80, 1.50, 0.8));
13351
13352 var rainbow = cubehelix();
13353
13354 function rainbow$1(t) {
13355   if (t < 0 || t > 1) t -= Math.floor(t);
13356   var ts = Math.abs(t - 0.5);
13357   rainbow.h = 360 * t - 100;
13358   rainbow.s = 1.5 - 1.5 * ts;
13359   rainbow.l = 0.8 - 0.9 * ts;
13360   return rainbow + "";
13361 }
13362
13363 function ramp(range) {
13364   var n = range.length;
13365   return function(t) {
13366     return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))];
13367   };
13368 }
13369
13370 var viridis = ramp(colors("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));
13371
13372 var magma = ramp(colors("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf"));
13373
13374 var inferno = ramp(colors("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4"));
13375
13376 var plasma = ramp(colors("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921"));
13377
13378 function sequential(interpolator) {
13379   var x0 = 0,
13380       x1 = 1,
13381       clamp = false;
13382
13383   function scale(x) {
13384     var t = (x - x0) / (x1 - x0);
13385     return interpolator(clamp ? Math.max(0, Math.min(1, t)) : t);
13386   }
13387
13388   scale.domain = function(_) {
13389     return arguments.length ? (x0 = +_[0], x1 = +_[1], scale) : [x0, x1];
13390   };
13391
13392   scale.clamp = function(_) {
13393     return arguments.length ? (clamp = !!_, scale) : clamp;
13394   };
13395
13396   scale.interpolator = function(_) {
13397     return arguments.length ? (interpolator = _, scale) : interpolator;
13398   };
13399
13400   scale.copy = function() {
13401     return sequential(interpolator).domain([x0, x1]).clamp(clamp);
13402   };
13403
13404   return linearish(scale);
13405 }
13406
13407 function constant$10(x) {
13408   return function constant() {
13409     return x;
13410   };
13411 }
13412
13413 var abs$1 = Math.abs;
13414 var atan2$1 = Math.atan2;
13415 var cos$2 = Math.cos;
13416 var max$2 = Math.max;
13417 var min$1 = Math.min;
13418 var sin$2 = Math.sin;
13419 var sqrt$2 = Math.sqrt;
13420
13421 var epsilon$3 = 1e-12;
13422 var pi$4 = Math.PI;
13423 var halfPi$3 = pi$4 / 2;
13424 var tau$4 = 2 * pi$4;
13425
13426 function acos$1(x) {
13427   return x > 1 ? 0 : x < -1 ? pi$4 : Math.acos(x);
13428 }
13429
13430 function asin$1(x) {
13431   return x >= 1 ? halfPi$3 : x <= -1 ? -halfPi$3 : Math.asin(x);
13432 }
13433
13434 function arcInnerRadius(d) {
13435   return d.innerRadius;
13436 }
13437
13438 function arcOuterRadius(d) {
13439   return d.outerRadius;
13440 }
13441
13442 function arcStartAngle(d) {
13443   return d.startAngle;
13444 }
13445
13446 function arcEndAngle(d) {
13447   return d.endAngle;
13448 }
13449
13450 function arcPadAngle(d) {
13451   return d && d.padAngle; // Note: optional!
13452 }
13453
13454 function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
13455   var x10 = x1 - x0, y10 = y1 - y0,
13456       x32 = x3 - x2, y32 = y3 - y2,
13457       t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / (y32 * x10 - x32 * y10);
13458   return [x0 + t * x10, y0 + t * y10];
13459 }
13460
13461 // Compute perpendicular offset line of length rc.
13462 // http://mathworld.wolfram.com/Circle-LineIntersection.html
13463 function cornerTangents(x0, y0, x1, y1, r1, rc, cw) {
13464   var x01 = x0 - x1,
13465       y01 = y0 - y1,
13466       lo = (cw ? rc : -rc) / sqrt$2(x01 * x01 + y01 * y01),
13467       ox = lo * y01,
13468       oy = -lo * x01,
13469       x11 = x0 + ox,
13470       y11 = y0 + oy,
13471       x10 = x1 + ox,
13472       y10 = y1 + oy,
13473       x00 = (x11 + x10) / 2,
13474       y00 = (y11 + y10) / 2,
13475       dx = x10 - x11,
13476       dy = y10 - y11,
13477       d2 = dx * dx + dy * dy,
13478       r = r1 - rc,
13479       D = x11 * y10 - x10 * y11,
13480       d = (dy < 0 ? -1 : 1) * sqrt$2(max$2(0, r * r * d2 - D * D)),
13481       cx0 = (D * dy - dx * d) / d2,
13482       cy0 = (-D * dx - dy * d) / d2,
13483       cx1 = (D * dy + dx * d) / d2,
13484       cy1 = (-D * dx + dy * d) / d2,
13485       dx0 = cx0 - x00,
13486       dy0 = cy0 - y00,
13487       dx1 = cx1 - x00,
13488       dy1 = cy1 - y00;
13489
13490   // Pick the closer of the two intersection points.
13491   // TODO Is there a faster way to determine which intersection to use?
13492   if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;
13493
13494   return {
13495     cx: cx0,
13496     cy: cy0,
13497     x01: -ox,
13498     y01: -oy,
13499     x11: cx0 * (r1 / r - 1),
13500     y11: cy0 * (r1 / r - 1)
13501   };
13502 }
13503
13504 function arc() {
13505   var innerRadius = arcInnerRadius,
13506       outerRadius = arcOuterRadius,
13507       cornerRadius = constant$10(0),
13508       padRadius = null,
13509       startAngle = arcStartAngle,
13510       endAngle = arcEndAngle,
13511       padAngle = arcPadAngle,
13512       context = null;
13513
13514   function arc() {
13515     var buffer,
13516         r,
13517         r0 = +innerRadius.apply(this, arguments),
13518         r1 = +outerRadius.apply(this, arguments),
13519         a0 = startAngle.apply(this, arguments) - halfPi$3,
13520         a1 = endAngle.apply(this, arguments) - halfPi$3,
13521         da = abs$1(a1 - a0),
13522         cw = a1 > a0;
13523
13524     if (!context) context = buffer = path();
13525
13526     // Ensure that the outer radius is always larger than the inner radius.
13527     if (r1 < r0) r = r1, r1 = r0, r0 = r;
13528
13529     // Is it a point?
13530     if (!(r1 > epsilon$3)) context.moveTo(0, 0);
13531
13532     // Or is it a circle or annulus?
13533     else if (da > tau$4 - epsilon$3) {
13534       context.moveTo(r1 * cos$2(a0), r1 * sin$2(a0));
13535       context.arc(0, 0, r1, a0, a1, !cw);
13536       if (r0 > epsilon$3) {
13537         context.moveTo(r0 * cos$2(a1), r0 * sin$2(a1));
13538         context.arc(0, 0, r0, a1, a0, cw);
13539       }
13540     }
13541
13542     // Or is it a circular or annular sector?
13543     else {
13544       var a01 = a0,
13545           a11 = a1,
13546           a00 = a0,
13547           a10 = a1,
13548           da0 = da,
13549           da1 = da,
13550           ap = padAngle.apply(this, arguments) / 2,
13551           rp = (ap > epsilon$3) && (padRadius ? +padRadius.apply(this, arguments) : sqrt$2(r0 * r0 + r1 * r1)),
13552           rc = min$1(abs$1(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),
13553           rc0 = rc,
13554           rc1 = rc,
13555           t0,
13556           t1;
13557
13558       // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.
13559       if (rp > epsilon$3) {
13560         var p0 = asin$1(rp / r0 * sin$2(ap)),
13561             p1 = asin$1(rp / r1 * sin$2(ap));
13562         if ((da0 -= p0 * 2) > epsilon$3) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;
13563         else da0 = 0, a00 = a10 = (a0 + a1) / 2;
13564         if ((da1 -= p1 * 2) > epsilon$3) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;
13565         else da1 = 0, a01 = a11 = (a0 + a1) / 2;
13566       }
13567
13568       var x01 = r1 * cos$2(a01),
13569           y01 = r1 * sin$2(a01),
13570           x10 = r0 * cos$2(a10),
13571           y10 = r0 * sin$2(a10);
13572
13573       // Apply rounded corners?
13574       if (rc > epsilon$3) {
13575         var x11 = r1 * cos$2(a11),
13576             y11 = r1 * sin$2(a11),
13577             x00 = r0 * cos$2(a00),
13578             y00 = r0 * sin$2(a00);
13579
13580         // Restrict the corner radius according to the sector angle.
13581         if (da < pi$4) {
13582           var oc = da0 > epsilon$3 ? intersect(x01, y01, x00, y00, x11, y11, x10, y10) : [x10, y10],
13583               ax = x01 - oc[0],
13584               ay = y01 - oc[1],
13585               bx = x11 - oc[0],
13586               by = y11 - oc[1],
13587               kc = 1 / sin$2(acos$1((ax * bx + ay * by) / (sqrt$2(ax * ax + ay * ay) * sqrt$2(bx * bx + by * by))) / 2),
13588               lc = sqrt$2(oc[0] * oc[0] + oc[1] * oc[1]);
13589           rc0 = min$1(rc, (r0 - lc) / (kc - 1));
13590           rc1 = min$1(rc, (r1 - lc) / (kc + 1));
13591         }
13592       }
13593
13594       // Is the sector collapsed to a line?
13595       if (!(da1 > epsilon$3)) context.moveTo(x01, y01);
13596
13597       // Does the sector’s outer ring have rounded corners?
13598       else if (rc1 > epsilon$3) {
13599         t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);
13600         t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);
13601
13602         context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);
13603
13604         // Have the corners merged?
13605         if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01), atan2$1(t1.y01, t1.x01), !cw);
13606
13607         // Otherwise, draw the two corners and the ring.
13608         else {
13609           context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01), atan2$1(t0.y11, t0.x11), !cw);
13610           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);
13611           context.arc(t1.cx, t1.cy, rc1, atan2$1(t1.y11, t1.x11), atan2$1(t1.y01, t1.x01), !cw);
13612         }
13613       }
13614
13615       // Or is the outer ring just a circular arc?
13616       else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);
13617
13618       // Is there no inner ring, and it’s a circular sector?
13619       // Or perhaps it’s an annular sector collapsed due to padding?
13620       if (!(r0 > epsilon$3) || !(da0 > epsilon$3)) context.lineTo(x10, y10);
13621
13622       // Does the sector’s inner ring (or point) have rounded corners?
13623       else if (rc0 > epsilon$3) {
13624         t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);
13625         t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);
13626
13627         context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);
13628
13629         // Have the corners merged?
13630         if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01), atan2$1(t1.y01, t1.x01), !cw);
13631
13632         // Otherwise, draw the two corners and the ring.
13633         else {
13634           context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01), atan2$1(t0.y11, t0.x11), !cw);
13635           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);
13636           context.arc(t1.cx, t1.cy, rc0, atan2$1(t1.y11, t1.x11), atan2$1(t1.y01, t1.x01), !cw);
13637         }
13638       }
13639
13640       // Or is the inner ring just a circular arc?
13641       else context.arc(0, 0, r0, a10, a00, cw);
13642     }
13643
13644     context.closePath();
13645
13646     if (buffer) return context = null, buffer + "" || null;
13647   }
13648
13649   arc.centroid = function() {
13650     var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,
13651         a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi$4 / 2;
13652     return [cos$2(a) * r, sin$2(a) * r];
13653   };
13654
13655   arc.innerRadius = function(_) {
13656     return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant$10(+_), arc) : innerRadius;
13657   };
13658
13659   arc.outerRadius = function(_) {
13660     return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant$10(+_), arc) : outerRadius;
13661   };
13662
13663   arc.cornerRadius = function(_) {
13664     return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant$10(+_), arc) : cornerRadius;
13665   };
13666
13667   arc.padRadius = function(_) {
13668     return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant$10(+_), arc) : padRadius;
13669   };
13670
13671   arc.startAngle = function(_) {
13672     return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$10(+_), arc) : startAngle;
13673   };
13674
13675   arc.endAngle = function(_) {
13676     return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$10(+_), arc) : endAngle;
13677   };
13678
13679   arc.padAngle = function(_) {
13680     return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$10(+_), arc) : padAngle;
13681   };
13682
13683   arc.context = function(_) {
13684     return arguments.length ? (context = _ == null ? null : _, arc) : context;
13685   };
13686
13687   return arc;
13688 }
13689
13690 function Linear(context) {
13691   this._context = context;
13692 }
13693
13694 Linear.prototype = {
13695   areaStart: function() {
13696     this._line = 0;
13697   },
13698   areaEnd: function() {
13699     this._line = NaN;
13700   },
13701   lineStart: function() {
13702     this._point = 0;
13703   },
13704   lineEnd: function() {
13705     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
13706     this._line = 1 - this._line;
13707   },
13708   point: function(x, y) {
13709     x = +x, y = +y;
13710     switch (this._point) {
13711       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
13712       case 1: this._point = 2; // proceed
13713       default: this._context.lineTo(x, y); break;
13714     }
13715   }
13716 };
13717
13718 function curveLinear(context) {
13719   return new Linear(context);
13720 }
13721
13722 function x$3(p) {
13723   return p[0];
13724 }
13725
13726 function y$3(p) {
13727   return p[1];
13728 }
13729
13730 function line() {
13731   var x$$1 = x$3,
13732       y$$1 = y$3,
13733       defined = constant$10(true),
13734       context = null,
13735       curve = curveLinear,
13736       output = null;
13737
13738   function line(data) {
13739     var i,
13740         n = data.length,
13741         d,
13742         defined0 = false,
13743         buffer;
13744
13745     if (context == null) output = curve(buffer = path());
13746
13747     for (i = 0; i <= n; ++i) {
13748       if (!(i < n && defined(d = data[i], i, data)) === defined0) {
13749         if (defined0 = !defined0) output.lineStart();
13750         else output.lineEnd();
13751       }
13752       if (defined0) output.point(+x$$1(d, i, data), +y$$1(d, i, data));
13753     }
13754
13755     if (buffer) return output = null, buffer + "" || null;
13756   }
13757
13758   line.x = function(_) {
13759     return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$10(+_), line) : x$$1;
13760   };
13761
13762   line.y = function(_) {
13763     return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$10(+_), line) : y$$1;
13764   };
13765
13766   line.defined = function(_) {
13767     return arguments.length ? (defined = typeof _ === "function" ? _ : constant$10(!!_), line) : defined;
13768   };
13769
13770   line.curve = function(_) {
13771     return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;
13772   };
13773
13774   line.context = function(_) {
13775     return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;
13776   };
13777
13778   return line;
13779 }
13780
13781 function area() {
13782   var x0 = x$3,
13783       x1 = null,
13784       y0 = constant$10(0),
13785       y1 = y$3,
13786       defined = constant$10(true),
13787       context = null,
13788       curve = curveLinear,
13789       output = null;
13790
13791   function area(data) {
13792     var i,
13793         j,
13794         k,
13795         n = data.length,
13796         d,
13797         defined0 = false,
13798         buffer,
13799         x0z = new Array(n),
13800         y0z = new Array(n);
13801
13802     if (context == null) output = curve(buffer = path());
13803
13804     for (i = 0; i <= n; ++i) {
13805       if (!(i < n && defined(d = data[i], i, data)) === defined0) {
13806         if (defined0 = !defined0) {
13807           j = i;
13808           output.areaStart();
13809           output.lineStart();
13810         } else {
13811           output.lineEnd();
13812           output.lineStart();
13813           for (k = i - 1; k >= j; --k) {
13814             output.point(x0z[k], y0z[k]);
13815           }
13816           output.lineEnd();
13817           output.areaEnd();
13818         }
13819       }
13820       if (defined0) {
13821         x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);
13822         output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);
13823       }
13824     }
13825
13826     if (buffer) return output = null, buffer + "" || null;
13827   }
13828
13829   function arealine() {
13830     return line().defined(defined).curve(curve).context(context);
13831   }
13832
13833   area.x = function(_) {
13834     return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$10(+_), x1 = null, area) : x0;
13835   };
13836
13837   area.x0 = function(_) {
13838     return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$10(+_), area) : x0;
13839   };
13840
13841   area.x1 = function(_) {
13842     return arguments.length ? (x1 = _ == null ? null : typeof _ === "function" ? _ : constant$10(+_), area) : x1;
13843   };
13844
13845   area.y = function(_) {
13846     return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$10(+_), y1 = null, area) : y0;
13847   };
13848
13849   area.y0 = function(_) {
13850     return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$10(+_), area) : y0;
13851   };
13852
13853   area.y1 = function(_) {
13854     return arguments.length ? (y1 = _ == null ? null : typeof _ === "function" ? _ : constant$10(+_), area) : y1;
13855   };
13856
13857   area.lineX0 =
13858   area.lineY0 = function() {
13859     return arealine().x(x0).y(y0);
13860   };
13861
13862   area.lineY1 = function() {
13863     return arealine().x(x0).y(y1);
13864   };
13865
13866   area.lineX1 = function() {
13867     return arealine().x(x1).y(y0);
13868   };
13869
13870   area.defined = function(_) {
13871     return arguments.length ? (defined = typeof _ === "function" ? _ : constant$10(!!_), area) : defined;
13872   };
13873
13874   area.curve = function(_) {
13875     return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve;
13876   };
13877
13878   area.context = function(_) {
13879     return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;
13880   };
13881
13882   return area;
13883 }
13884
13885 function descending(a, b) {
13886   return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
13887 }
13888
13889 function identity$6(d) {
13890   return d;
13891 }
13892
13893 function pie() {
13894   var value = identity$6,
13895       sortValues = descending,
13896       sort = null,
13897       startAngle = constant$10(0),
13898       endAngle = constant$10(tau$4),
13899       padAngle = constant$10(0);
13900
13901   function pie(data) {
13902     var i,
13903         n = data.length,
13904         j,
13905         k,
13906         sum = 0,
13907         index = new Array(n),
13908         arcs = new Array(n),
13909         a0 = +startAngle.apply(this, arguments),
13910         da = Math.min(tau$4, Math.max(-tau$4, endAngle.apply(this, arguments) - a0)),
13911         a1,
13912         p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)),
13913         pa = p * (da < 0 ? -1 : 1),
13914         v;
13915
13916     for (i = 0; i < n; ++i) {
13917       if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) {
13918         sum += v;
13919       }
13920     }
13921
13922     // Optionally sort the arcs by previously-computed values or by data.
13923     if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); });
13924     else if (sort != null) index.sort(function(i, j) { return sort(data[i], data[j]); });
13925
13926     // Compute the arcs! They are stored in the original data's order.
13927     for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) {
13928       j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = {
13929         data: data[j],
13930         index: i,
13931         value: v,
13932         startAngle: a0,
13933         endAngle: a1,
13934         padAngle: p
13935       };
13936     }
13937
13938     return arcs;
13939   }
13940
13941   pie.value = function(_) {
13942     return arguments.length ? (value = typeof _ === "function" ? _ : constant$10(+_), pie) : value;
13943   };
13944
13945   pie.sortValues = function(_) {
13946     return arguments.length ? (sortValues = _, sort = null, pie) : sortValues;
13947   };
13948
13949   pie.sort = function(_) {
13950     return arguments.length ? (sort = _, sortValues = null, pie) : sort;
13951   };
13952
13953   pie.startAngle = function(_) {
13954     return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$10(+_), pie) : startAngle;
13955   };
13956
13957   pie.endAngle = function(_) {
13958     return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$10(+_), pie) : endAngle;
13959   };
13960
13961   pie.padAngle = function(_) {
13962     return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$10(+_), pie) : padAngle;
13963   };
13964
13965   return pie;
13966 }
13967
13968 var curveRadialLinear = curveRadial(curveLinear);
13969
13970 function Radial(curve) {
13971   this._curve = curve;
13972 }
13973
13974 Radial.prototype = {
13975   areaStart: function() {
13976     this._curve.areaStart();
13977   },
13978   areaEnd: function() {
13979     this._curve.areaEnd();
13980   },
13981   lineStart: function() {
13982     this._curve.lineStart();
13983   },
13984   lineEnd: function() {
13985     this._curve.lineEnd();
13986   },
13987   point: function(a, r) {
13988     this._curve.point(r * Math.sin(a), r * -Math.cos(a));
13989   }
13990 };
13991
13992 function curveRadial(curve) {
13993
13994   function radial(context) {
13995     return new Radial(curve(context));
13996   }
13997
13998   radial._curve = curve;
13999
14000   return radial;
14001 }
14002
14003 function lineRadial(l) {
14004   var c = l.curve;
14005
14006   l.angle = l.x, delete l.x;
14007   l.radius = l.y, delete l.y;
14008
14009   l.curve = function(_) {
14010     return arguments.length ? c(curveRadial(_)) : c()._curve;
14011   };
14012
14013   return l;
14014 }
14015
14016 function lineRadial$1() {
14017   return lineRadial(line().curve(curveRadialLinear));
14018 }
14019
14020 function areaRadial() {
14021   var a = area().curve(curveRadialLinear),
14022       c = a.curve,
14023       x0 = a.lineX0,
14024       x1 = a.lineX1,
14025       y0 = a.lineY0,
14026       y1 = a.lineY1;
14027
14028   a.angle = a.x, delete a.x;
14029   a.startAngle = a.x0, delete a.x0;
14030   a.endAngle = a.x1, delete a.x1;
14031   a.radius = a.y, delete a.y;
14032   a.innerRadius = a.y0, delete a.y0;
14033   a.outerRadius = a.y1, delete a.y1;
14034   a.lineStartAngle = function() { return lineRadial(x0()); }, delete a.lineX0;
14035   a.lineEndAngle = function() { return lineRadial(x1()); }, delete a.lineX1;
14036   a.lineInnerRadius = function() { return lineRadial(y0()); }, delete a.lineY0;
14037   a.lineOuterRadius = function() { return lineRadial(y1()); }, delete a.lineY1;
14038
14039   a.curve = function(_) {
14040     return arguments.length ? c(curveRadial(_)) : c()._curve;
14041   };
14042
14043   return a;
14044 }
14045
14046 function pointRadial(x, y) {
14047   return [(y = +y) * Math.cos(x -= Math.PI / 2), y * Math.sin(x)];
14048 }
14049
14050 var slice$6 = Array.prototype.slice;
14051
14052 function linkSource(d) {
14053   return d.source;
14054 }
14055
14056 function linkTarget(d) {
14057   return d.target;
14058 }
14059
14060 function link$2(curve) {
14061   var source = linkSource,
14062       target = linkTarget,
14063       x$$1 = x$3,
14064       y$$1 = y$3,
14065       context = null;
14066
14067   function link() {
14068     var buffer, argv = slice$6.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv);
14069     if (!context) context = buffer = path();
14070     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));
14071     if (buffer) return context = null, buffer + "" || null;
14072   }
14073
14074   link.source = function(_) {
14075     return arguments.length ? (source = _, link) : source;
14076   };
14077
14078   link.target = function(_) {
14079     return arguments.length ? (target = _, link) : target;
14080   };
14081
14082   link.x = function(_) {
14083     return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$10(+_), link) : x$$1;
14084   };
14085
14086   link.y = function(_) {
14087     return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$10(+_), link) : y$$1;
14088   };
14089
14090   link.context = function(_) {
14091     return arguments.length ? (context = _ == null ? null : _, link) : context;
14092   };
14093
14094   return link;
14095 }
14096
14097 function curveHorizontal(context, x0, y0, x1, y1) {
14098   context.moveTo(x0, y0);
14099   context.bezierCurveTo(x0 = (x0 + x1) / 2, y0, x0, y1, x1, y1);
14100 }
14101
14102 function curveVertical(context, x0, y0, x1, y1) {
14103   context.moveTo(x0, y0);
14104   context.bezierCurveTo(x0, y0 = (y0 + y1) / 2, x1, y0, x1, y1);
14105 }
14106
14107 function curveRadial$1(context, x0, y0, x1, y1) {
14108   var p0 = pointRadial(x0, y0),
14109       p1 = pointRadial(x0, y0 = (y0 + y1) / 2),
14110       p2 = pointRadial(x1, y0),
14111       p3 = pointRadial(x1, y1);
14112   context.moveTo(p0[0], p0[1]);
14113   context.bezierCurveTo(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]);
14114 }
14115
14116 function linkHorizontal() {
14117   return link$2(curveHorizontal);
14118 }
14119
14120 function linkVertical() {
14121   return link$2(curveVertical);
14122 }
14123
14124 function linkRadial() {
14125   var l = link$2(curveRadial$1);
14126   l.angle = l.x, delete l.x;
14127   l.radius = l.y, delete l.y;
14128   return l;
14129 }
14130
14131 var circle$2 = {
14132   draw: function(context, size) {
14133     var r = Math.sqrt(size / pi$4);
14134     context.moveTo(r, 0);
14135     context.arc(0, 0, r, 0, tau$4);
14136   }
14137 };
14138
14139 var cross$2 = {
14140   draw: function(context, size) {
14141     var r = Math.sqrt(size / 5) / 2;
14142     context.moveTo(-3 * r, -r);
14143     context.lineTo(-r, -r);
14144     context.lineTo(-r, -3 * r);
14145     context.lineTo(r, -3 * r);
14146     context.lineTo(r, -r);
14147     context.lineTo(3 * r, -r);
14148     context.lineTo(3 * r, r);
14149     context.lineTo(r, r);
14150     context.lineTo(r, 3 * r);
14151     context.lineTo(-r, 3 * r);
14152     context.lineTo(-r, r);
14153     context.lineTo(-3 * r, r);
14154     context.closePath();
14155   }
14156 };
14157
14158 var tan30 = Math.sqrt(1 / 3);
14159 var tan30_2 = tan30 * 2;
14160
14161 var diamond = {
14162   draw: function(context, size) {
14163     var y = Math.sqrt(size / tan30_2),
14164         x = y * tan30;
14165     context.moveTo(0, -y);
14166     context.lineTo(x, 0);
14167     context.lineTo(0, y);
14168     context.lineTo(-x, 0);
14169     context.closePath();
14170   }
14171 };
14172
14173 var ka = 0.89081309152928522810;
14174 var kr = Math.sin(pi$4 / 10) / Math.sin(7 * pi$4 / 10);
14175 var kx = Math.sin(tau$4 / 10) * kr;
14176 var ky = -Math.cos(tau$4 / 10) * kr;
14177
14178 var star = {
14179   draw: function(context, size) {
14180     var r = Math.sqrt(size * ka),
14181         x = kx * r,
14182         y = ky * r;
14183     context.moveTo(0, -r);
14184     context.lineTo(x, y);
14185     for (var i = 1; i < 5; ++i) {
14186       var a = tau$4 * i / 5,
14187           c = Math.cos(a),
14188           s = Math.sin(a);
14189       context.lineTo(s * r, -c * r);
14190       context.lineTo(c * x - s * y, s * x + c * y);
14191     }
14192     context.closePath();
14193   }
14194 };
14195
14196 var square = {
14197   draw: function(context, size) {
14198     var w = Math.sqrt(size),
14199         x = -w / 2;
14200     context.rect(x, x, w, w);
14201   }
14202 };
14203
14204 var sqrt3 = Math.sqrt(3);
14205
14206 var triangle = {
14207   draw: function(context, size) {
14208     var y = -Math.sqrt(size / (sqrt3 * 3));
14209     context.moveTo(0, y * 2);
14210     context.lineTo(-sqrt3 * y, -y);
14211     context.lineTo(sqrt3 * y, -y);
14212     context.closePath();
14213   }
14214 };
14215
14216 var c = -0.5;
14217 var s = Math.sqrt(3) / 2;
14218 var k = 1 / Math.sqrt(12);
14219 var a = (k / 2 + 1) * 3;
14220
14221 var wye = {
14222   draw: function(context, size) {
14223     var r = Math.sqrt(size / a),
14224         x0 = r / 2,
14225         y0 = r * k,
14226         x1 = x0,
14227         y1 = r * k + r,
14228         x2 = -x1,
14229         y2 = y1;
14230     context.moveTo(x0, y0);
14231     context.lineTo(x1, y1);
14232     context.lineTo(x2, y2);
14233     context.lineTo(c * x0 - s * y0, s * x0 + c * y0);
14234     context.lineTo(c * x1 - s * y1, s * x1 + c * y1);
14235     context.lineTo(c * x2 - s * y2, s * x2 + c * y2);
14236     context.lineTo(c * x0 + s * y0, c * y0 - s * x0);
14237     context.lineTo(c * x1 + s * y1, c * y1 - s * x1);
14238     context.lineTo(c * x2 + s * y2, c * y2 - s * x2);
14239     context.closePath();
14240   }
14241 };
14242
14243 var symbols = [
14244   circle$2,
14245   cross$2,
14246   diamond,
14247   square,
14248   star,
14249   triangle,
14250   wye
14251 ];
14252
14253 function symbol() {
14254   var type = constant$10(circle$2),
14255       size = constant$10(64),
14256       context = null;
14257
14258   function symbol() {
14259     var buffer;
14260     if (!context) context = buffer = path();
14261     type.apply(this, arguments).draw(context, +size.apply(this, arguments));
14262     if (buffer) return context = null, buffer + "" || null;
14263   }
14264
14265   symbol.type = function(_) {
14266     return arguments.length ? (type = typeof _ === "function" ? _ : constant$10(_), symbol) : type;
14267   };
14268
14269   symbol.size = function(_) {
14270     return arguments.length ? (size = typeof _ === "function" ? _ : constant$10(+_), symbol) : size;
14271   };
14272
14273   symbol.context = function(_) {
14274     return arguments.length ? (context = _ == null ? null : _, symbol) : context;
14275   };
14276
14277   return symbol;
14278 }
14279
14280 function noop$2() {}
14281
14282 function point$2(that, x, y) {
14283   that._context.bezierCurveTo(
14284     (2 * that._x0 + that._x1) / 3,
14285     (2 * that._y0 + that._y1) / 3,
14286     (that._x0 + 2 * that._x1) / 3,
14287     (that._y0 + 2 * that._y1) / 3,
14288     (that._x0 + 4 * that._x1 + x) / 6,
14289     (that._y0 + 4 * that._y1 + y) / 6
14290   );
14291 }
14292
14293 function Basis(context) {
14294   this._context = context;
14295 }
14296
14297 Basis.prototype = {
14298   areaStart: function() {
14299     this._line = 0;
14300   },
14301   areaEnd: function() {
14302     this._line = NaN;
14303   },
14304   lineStart: function() {
14305     this._x0 = this._x1 =
14306     this._y0 = this._y1 = NaN;
14307     this._point = 0;
14308   },
14309   lineEnd: function() {
14310     switch (this._point) {
14311       case 3: point$2(this, this._x1, this._y1); // proceed
14312       case 2: this._context.lineTo(this._x1, this._y1); break;
14313     }
14314     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
14315     this._line = 1 - this._line;
14316   },
14317   point: function(x, y) {
14318     x = +x, y = +y;
14319     switch (this._point) {
14320       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
14321       case 1: this._point = 2; break;
14322       case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed
14323       default: point$2(this, x, y); break;
14324     }
14325     this._x0 = this._x1, this._x1 = x;
14326     this._y0 = this._y1, this._y1 = y;
14327   }
14328 };
14329
14330 function basis$2(context) {
14331   return new Basis(context);
14332 }
14333
14334 function BasisClosed(context) {
14335   this._context = context;
14336 }
14337
14338 BasisClosed.prototype = {
14339   areaStart: noop$2,
14340   areaEnd: noop$2,
14341   lineStart: function() {
14342     this._x0 = this._x1 = this._x2 = this._x3 = this._x4 =
14343     this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;
14344     this._point = 0;
14345   },
14346   lineEnd: function() {
14347     switch (this._point) {
14348       case 1: {
14349         this._context.moveTo(this._x2, this._y2);
14350         this._context.closePath();
14351         break;
14352       }
14353       case 2: {
14354         this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3);
14355         this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3);
14356         this._context.closePath();
14357         break;
14358       }
14359       case 3: {
14360         this.point(this._x2, this._y2);
14361         this.point(this._x3, this._y3);
14362         this.point(this._x4, this._y4);
14363         break;
14364       }
14365     }
14366   },
14367   point: function(x, y) {
14368     x = +x, y = +y;
14369     switch (this._point) {
14370       case 0: this._point = 1; this._x2 = x, this._y2 = y; break;
14371       case 1: this._point = 2; this._x3 = x, this._y3 = y; break;
14372       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;
14373       default: point$2(this, x, y); break;
14374     }
14375     this._x0 = this._x1, this._x1 = x;
14376     this._y0 = this._y1, this._y1 = y;
14377   }
14378 };
14379
14380 function basisClosed$1(context) {
14381   return new BasisClosed(context);
14382 }
14383
14384 function BasisOpen(context) {
14385   this._context = context;
14386 }
14387
14388 BasisOpen.prototype = {
14389   areaStart: function() {
14390     this._line = 0;
14391   },
14392   areaEnd: function() {
14393     this._line = NaN;
14394   },
14395   lineStart: function() {
14396     this._x0 = this._x1 =
14397     this._y0 = this._y1 = NaN;
14398     this._point = 0;
14399   },
14400   lineEnd: function() {
14401     if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
14402     this._line = 1 - this._line;
14403   },
14404   point: function(x, y) {
14405     x = +x, y = +y;
14406     switch (this._point) {
14407       case 0: this._point = 1; break;
14408       case 1: this._point = 2; break;
14409       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;
14410       case 3: this._point = 4; // proceed
14411       default: point$2(this, x, y); break;
14412     }
14413     this._x0 = this._x1, this._x1 = x;
14414     this._y0 = this._y1, this._y1 = y;
14415   }
14416 };
14417
14418 function basisOpen(context) {
14419   return new BasisOpen(context);
14420 }
14421
14422 function Bundle(context, beta) {
14423   this._basis = new Basis(context);
14424   this._beta = beta;
14425 }
14426
14427 Bundle.prototype = {
14428   lineStart: function() {
14429     this._x = [];
14430     this._y = [];
14431     this._basis.lineStart();
14432   },
14433   lineEnd: function() {
14434     var x = this._x,
14435         y = this._y,
14436         j = x.length - 1;
14437
14438     if (j > 0) {
14439       var x0 = x[0],
14440           y0 = y[0],
14441           dx = x[j] - x0,
14442           dy = y[j] - y0,
14443           i = -1,
14444           t;
14445
14446       while (++i <= j) {
14447         t = i / j;
14448         this._basis.point(
14449           this._beta * x[i] + (1 - this._beta) * (x0 + t * dx),
14450           this._beta * y[i] + (1 - this._beta) * (y0 + t * dy)
14451         );
14452       }
14453     }
14454
14455     this._x = this._y = null;
14456     this._basis.lineEnd();
14457   },
14458   point: function(x, y) {
14459     this._x.push(+x);
14460     this._y.push(+y);
14461   }
14462 };
14463
14464 var bundle = (function custom(beta) {
14465
14466   function bundle(context) {
14467     return beta === 1 ? new Basis(context) : new Bundle(context, beta);
14468   }
14469
14470   bundle.beta = function(beta) {
14471     return custom(+beta);
14472   };
14473
14474   return bundle;
14475 })(0.85);
14476
14477 function point$3(that, x, y) {
14478   that._context.bezierCurveTo(
14479     that._x1 + that._k * (that._x2 - that._x0),
14480     that._y1 + that._k * (that._y2 - that._y0),
14481     that._x2 + that._k * (that._x1 - x),
14482     that._y2 + that._k * (that._y1 - y),
14483     that._x2,
14484     that._y2
14485   );
14486 }
14487
14488 function Cardinal(context, tension) {
14489   this._context = context;
14490   this._k = (1 - tension) / 6;
14491 }
14492
14493 Cardinal.prototype = {
14494   areaStart: function() {
14495     this._line = 0;
14496   },
14497   areaEnd: function() {
14498     this._line = NaN;
14499   },
14500   lineStart: function() {
14501     this._x0 = this._x1 = this._x2 =
14502     this._y0 = this._y1 = this._y2 = NaN;
14503     this._point = 0;
14504   },
14505   lineEnd: function() {
14506     switch (this._point) {
14507       case 2: this._context.lineTo(this._x2, this._y2); break;
14508       case 3: point$3(this, this._x1, this._y1); break;
14509     }
14510     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
14511     this._line = 1 - this._line;
14512   },
14513   point: function(x, y) {
14514     x = +x, y = +y;
14515     switch (this._point) {
14516       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
14517       case 1: this._point = 2; this._x1 = x, this._y1 = y; break;
14518       case 2: this._point = 3; // proceed
14519       default: point$3(this, x, y); break;
14520     }
14521     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
14522     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
14523   }
14524 };
14525
14526 var cardinal = (function custom(tension) {
14527
14528   function cardinal(context) {
14529     return new Cardinal(context, tension);
14530   }
14531
14532   cardinal.tension = function(tension) {
14533     return custom(+tension);
14534   };
14535
14536   return cardinal;
14537 })(0);
14538
14539 function CardinalClosed(context, tension) {
14540   this._context = context;
14541   this._k = (1 - tension) / 6;
14542 }
14543
14544 CardinalClosed.prototype = {
14545   areaStart: noop$2,
14546   areaEnd: noop$2,
14547   lineStart: function() {
14548     this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
14549     this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
14550     this._point = 0;
14551   },
14552   lineEnd: function() {
14553     switch (this._point) {
14554       case 1: {
14555         this._context.moveTo(this._x3, this._y3);
14556         this._context.closePath();
14557         break;
14558       }
14559       case 2: {
14560         this._context.lineTo(this._x3, this._y3);
14561         this._context.closePath();
14562         break;
14563       }
14564       case 3: {
14565         this.point(this._x3, this._y3);
14566         this.point(this._x4, this._y4);
14567         this.point(this._x5, this._y5);
14568         break;
14569       }
14570     }
14571   },
14572   point: function(x, y) {
14573     x = +x, y = +y;
14574     switch (this._point) {
14575       case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
14576       case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
14577       case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
14578       default: point$3(this, x, y); break;
14579     }
14580     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
14581     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
14582   }
14583 };
14584
14585 var cardinalClosed = (function custom(tension) {
14586
14587   function cardinal$$1(context) {
14588     return new CardinalClosed(context, tension);
14589   }
14590
14591   cardinal$$1.tension = function(tension) {
14592     return custom(+tension);
14593   };
14594
14595   return cardinal$$1;
14596 })(0);
14597
14598 function CardinalOpen(context, tension) {
14599   this._context = context;
14600   this._k = (1 - tension) / 6;
14601 }
14602
14603 CardinalOpen.prototype = {
14604   areaStart: function() {
14605     this._line = 0;
14606   },
14607   areaEnd: function() {
14608     this._line = NaN;
14609   },
14610   lineStart: function() {
14611     this._x0 = this._x1 = this._x2 =
14612     this._y0 = this._y1 = this._y2 = NaN;
14613     this._point = 0;
14614   },
14615   lineEnd: function() {
14616     if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
14617     this._line = 1 - this._line;
14618   },
14619   point: function(x, y) {
14620     x = +x, y = +y;
14621     switch (this._point) {
14622       case 0: this._point = 1; break;
14623       case 1: this._point = 2; break;
14624       case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
14625       case 3: this._point = 4; // proceed
14626       default: point$3(this, x, y); break;
14627     }
14628     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
14629     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
14630   }
14631 };
14632
14633 var cardinalOpen = (function custom(tension) {
14634
14635   function cardinal$$1(context) {
14636     return new CardinalOpen(context, tension);
14637   }
14638
14639   cardinal$$1.tension = function(tension) {
14640     return custom(+tension);
14641   };
14642
14643   return cardinal$$1;
14644 })(0);
14645
14646 function point$4(that, x, y) {
14647   var x1 = that._x1,
14648       y1 = that._y1,
14649       x2 = that._x2,
14650       y2 = that._y2;
14651
14652   if (that._l01_a > epsilon$3) {
14653     var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a,
14654         n = 3 * that._l01_a * (that._l01_a + that._l12_a);
14655     x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n;
14656     y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n;
14657   }
14658
14659   if (that._l23_a > epsilon$3) {
14660     var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a,
14661         m = 3 * that._l23_a * (that._l23_a + that._l12_a);
14662     x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m;
14663     y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m;
14664   }
14665
14666   that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);
14667 }
14668
14669 function CatmullRom(context, alpha) {
14670   this._context = context;
14671   this._alpha = alpha;
14672 }
14673
14674 CatmullRom.prototype = {
14675   areaStart: function() {
14676     this._line = 0;
14677   },
14678   areaEnd: function() {
14679     this._line = NaN;
14680   },
14681   lineStart: function() {
14682     this._x0 = this._x1 = this._x2 =
14683     this._y0 = this._y1 = this._y2 = NaN;
14684     this._l01_a = this._l12_a = this._l23_a =
14685     this._l01_2a = this._l12_2a = this._l23_2a =
14686     this._point = 0;
14687   },
14688   lineEnd: function() {
14689     switch (this._point) {
14690       case 2: this._context.lineTo(this._x2, this._y2); break;
14691       case 3: this.point(this._x2, this._y2); break;
14692     }
14693     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
14694     this._line = 1 - this._line;
14695   },
14696   point: function(x, y) {
14697     x = +x, y = +y;
14698
14699     if (this._point) {
14700       var x23 = this._x2 - x,
14701           y23 = this._y2 - y;
14702       this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
14703     }
14704
14705     switch (this._point) {
14706       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
14707       case 1: this._point = 2; break;
14708       case 2: this._point = 3; // proceed
14709       default: point$4(this, x, y); break;
14710     }
14711
14712     this._l01_a = this._l12_a, this._l12_a = this._l23_a;
14713     this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
14714     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
14715     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
14716   }
14717 };
14718
14719 var catmullRom = (function custom(alpha) {
14720
14721   function catmullRom(context) {
14722     return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0);
14723   }
14724
14725   catmullRom.alpha = function(alpha) {
14726     return custom(+alpha);
14727   };
14728
14729   return catmullRom;
14730 })(0.5);
14731
14732 function CatmullRomClosed(context, alpha) {
14733   this._context = context;
14734   this._alpha = alpha;
14735 }
14736
14737 CatmullRomClosed.prototype = {
14738   areaStart: noop$2,
14739   areaEnd: noop$2,
14740   lineStart: function() {
14741     this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
14742     this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
14743     this._l01_a = this._l12_a = this._l23_a =
14744     this._l01_2a = this._l12_2a = this._l23_2a =
14745     this._point = 0;
14746   },
14747   lineEnd: function() {
14748     switch (this._point) {
14749       case 1: {
14750         this._context.moveTo(this._x3, this._y3);
14751         this._context.closePath();
14752         break;
14753       }
14754       case 2: {
14755         this._context.lineTo(this._x3, this._y3);
14756         this._context.closePath();
14757         break;
14758       }
14759       case 3: {
14760         this.point(this._x3, this._y3);
14761         this.point(this._x4, this._y4);
14762         this.point(this._x5, this._y5);
14763         break;
14764       }
14765     }
14766   },
14767   point: function(x, y) {
14768     x = +x, y = +y;
14769
14770     if (this._point) {
14771       var x23 = this._x2 - x,
14772           y23 = this._y2 - y;
14773       this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
14774     }
14775
14776     switch (this._point) {
14777       case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
14778       case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
14779       case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
14780       default: point$4(this, x, y); break;
14781     }
14782
14783     this._l01_a = this._l12_a, this._l12_a = this._l23_a;
14784     this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
14785     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
14786     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
14787   }
14788 };
14789
14790 var catmullRomClosed = (function custom(alpha) {
14791
14792   function catmullRom$$1(context) {
14793     return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0);
14794   }
14795
14796   catmullRom$$1.alpha = function(alpha) {
14797     return custom(+alpha);
14798   };
14799
14800   return catmullRom$$1;
14801 })(0.5);
14802
14803 function CatmullRomOpen(context, alpha) {
14804   this._context = context;
14805   this._alpha = alpha;
14806 }
14807
14808 CatmullRomOpen.prototype = {
14809   areaStart: function() {
14810     this._line = 0;
14811   },
14812   areaEnd: function() {
14813     this._line = NaN;
14814   },
14815   lineStart: function() {
14816     this._x0 = this._x1 = this._x2 =
14817     this._y0 = this._y1 = this._y2 = NaN;
14818     this._l01_a = this._l12_a = this._l23_a =
14819     this._l01_2a = this._l12_2a = this._l23_2a =
14820     this._point = 0;
14821   },
14822   lineEnd: function() {
14823     if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
14824     this._line = 1 - this._line;
14825   },
14826   point: function(x, y) {
14827     x = +x, y = +y;
14828
14829     if (this._point) {
14830       var x23 = this._x2 - x,
14831           y23 = this._y2 - y;
14832       this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
14833     }
14834
14835     switch (this._point) {
14836       case 0: this._point = 1; break;
14837       case 1: this._point = 2; break;
14838       case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
14839       case 3: this._point = 4; // proceed
14840       default: point$4(this, x, y); break;
14841     }
14842
14843     this._l01_a = this._l12_a, this._l12_a = this._l23_a;
14844     this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
14845     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
14846     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
14847   }
14848 };
14849
14850 var catmullRomOpen = (function custom(alpha) {
14851
14852   function catmullRom$$1(context) {
14853     return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0);
14854   }
14855
14856   catmullRom$$1.alpha = function(alpha) {
14857     return custom(+alpha);
14858   };
14859
14860   return catmullRom$$1;
14861 })(0.5);
14862
14863 function LinearClosed(context) {
14864   this._context = context;
14865 }
14866
14867 LinearClosed.prototype = {
14868   areaStart: noop$2,
14869   areaEnd: noop$2,
14870   lineStart: function() {
14871     this._point = 0;
14872   },
14873   lineEnd: function() {
14874     if (this._point) this._context.closePath();
14875   },
14876   point: function(x, y) {
14877     x = +x, y = +y;
14878     if (this._point) this._context.lineTo(x, y);
14879     else this._point = 1, this._context.moveTo(x, y);
14880   }
14881 };
14882
14883 function linearClosed(context) {
14884   return new LinearClosed(context);
14885 }
14886
14887 function sign$1(x) {
14888   return x < 0 ? -1 : 1;
14889 }
14890
14891 // Calculate the slopes of the tangents (Hermite-type interpolation) based on
14892 // the following paper: Steffen, M. 1990. A Simple Method for Monotonic
14893 // Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.
14894 // NOV(II), P. 443, 1990.
14895 function slope3(that, x2, y2) {
14896   var h0 = that._x1 - that._x0,
14897       h1 = x2 - that._x1,
14898       s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),
14899       s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),
14900       p = (s0 * h1 + s1 * h0) / (h0 + h1);
14901   return (sign$1(s0) + sign$1(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;
14902 }
14903
14904 // Calculate a one-sided slope.
14905 function slope2(that, t) {
14906   var h = that._x1 - that._x0;
14907   return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;
14908 }
14909
14910 // According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations
14911 // "you can express cubic Hermite interpolation in terms of cubic Bézier curves
14912 // with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1".
14913 function point$5(that, t0, t1) {
14914   var x0 = that._x0,
14915       y0 = that._y0,
14916       x1 = that._x1,
14917       y1 = that._y1,
14918       dx = (x1 - x0) / 3;
14919   that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);
14920 }
14921
14922 function MonotoneX(context) {
14923   this._context = context;
14924 }
14925
14926 MonotoneX.prototype = {
14927   areaStart: function() {
14928     this._line = 0;
14929   },
14930   areaEnd: function() {
14931     this._line = NaN;
14932   },
14933   lineStart: function() {
14934     this._x0 = this._x1 =
14935     this._y0 = this._y1 =
14936     this._t0 = NaN;
14937     this._point = 0;
14938   },
14939   lineEnd: function() {
14940     switch (this._point) {
14941       case 2: this._context.lineTo(this._x1, this._y1); break;
14942       case 3: point$5(this, this._t0, slope2(this, this._t0)); break;
14943     }
14944     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
14945     this._line = 1 - this._line;
14946   },
14947   point: function(x, y) {
14948     var t1 = NaN;
14949
14950     x = +x, y = +y;
14951     if (x === this._x1 && y === this._y1) return; // Ignore coincident points.
14952     switch (this._point) {
14953       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
14954       case 1: this._point = 2; break;
14955       case 2: this._point = 3; point$5(this, slope2(this, t1 = slope3(this, x, y)), t1); break;
14956       default: point$5(this, this._t0, t1 = slope3(this, x, y)); break;
14957     }
14958
14959     this._x0 = this._x1, this._x1 = x;
14960     this._y0 = this._y1, this._y1 = y;
14961     this._t0 = t1;
14962   }
14963 };
14964
14965 function MonotoneY(context) {
14966   this._context = new ReflectContext(context);
14967 }
14968
14969 (MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {
14970   MonotoneX.prototype.point.call(this, y, x);
14971 };
14972
14973 function ReflectContext(context) {
14974   this._context = context;
14975 }
14976
14977 ReflectContext.prototype = {
14978   moveTo: function(x, y) { this._context.moveTo(y, x); },
14979   closePath: function() { this._context.closePath(); },
14980   lineTo: function(x, y) { this._context.lineTo(y, x); },
14981   bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }
14982 };
14983
14984 function monotoneX(context) {
14985   return new MonotoneX(context);
14986 }
14987
14988 function monotoneY(context) {
14989   return new MonotoneY(context);
14990 }
14991
14992 function Natural(context) {
14993   this._context = context;
14994 }
14995
14996 Natural.prototype = {
14997   areaStart: function() {
14998     this._line = 0;
14999   },
15000   areaEnd: function() {
15001     this._line = NaN;
15002   },
15003   lineStart: function() {
15004     this._x = [];
15005     this._y = [];
15006   },
15007   lineEnd: function() {
15008     var x = this._x,
15009         y = this._y,
15010         n = x.length;
15011
15012     if (n) {
15013       this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);
15014       if (n === 2) {
15015         this._context.lineTo(x[1], y[1]);
15016       } else {
15017         var px = controlPoints(x),
15018             py = controlPoints(y);
15019         for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {
15020           this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);
15021         }
15022       }
15023     }
15024
15025     if (this._line || (this._line !== 0 && n === 1)) this._context.closePath();
15026     this._line = 1 - this._line;
15027     this._x = this._y = null;
15028   },
15029   point: function(x, y) {
15030     this._x.push(+x);
15031     this._y.push(+y);
15032   }
15033 };
15034
15035 // See https://www.particleincell.com/2012/bezier-splines/ for derivation.
15036 function controlPoints(x) {
15037   var i,
15038       n = x.length - 1,
15039       m,
15040       a = new Array(n),
15041       b = new Array(n),
15042       r = new Array(n);
15043   a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];
15044   for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];
15045   a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];
15046   for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];
15047   a[n - 1] = r[n - 1] / b[n - 1];
15048   for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];
15049   b[n - 1] = (x[n] + a[n - 1]) / 2;
15050   for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];
15051   return [a, b];
15052 }
15053
15054 function natural(context) {
15055   return new Natural(context);
15056 }
15057
15058 function Step(context, t) {
15059   this._context = context;
15060   this._t = t;
15061 }
15062
15063 Step.prototype = {
15064   areaStart: function() {
15065     this._line = 0;
15066   },
15067   areaEnd: function() {
15068     this._line = NaN;
15069   },
15070   lineStart: function() {
15071     this._x = this._y = NaN;
15072     this._point = 0;
15073   },
15074   lineEnd: function() {
15075     if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);
15076     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
15077     if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;
15078   },
15079   point: function(x, y) {
15080     x = +x, y = +y;
15081     switch (this._point) {
15082       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
15083       case 1: this._point = 2; // proceed
15084       default: {
15085         if (this._t <= 0) {
15086           this._context.lineTo(this._x, y);
15087           this._context.lineTo(x, y);
15088         } else {
15089           var x1 = this._x * (1 - this._t) + x * this._t;
15090           this._context.lineTo(x1, this._y);
15091           this._context.lineTo(x1, y);
15092         }
15093         break;
15094       }
15095     }
15096     this._x = x, this._y = y;
15097   }
15098 };
15099
15100 function step(context) {
15101   return new Step(context, 0.5);
15102 }
15103
15104 function stepBefore(context) {
15105   return new Step(context, 0);
15106 }
15107
15108 function stepAfter(context) {
15109   return new Step(context, 1);
15110 }
15111
15112 function none$1(series, order) {
15113   if (!((n = series.length) > 1)) return;
15114   for (var i = 1, j, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) {
15115     s0 = s1, s1 = series[order[i]];
15116     for (j = 0; j < m; ++j) {
15117       s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1];
15118     }
15119   }
15120 }
15121
15122 function none$2(series) {
15123   var n = series.length, o = new Array(n);
15124   while (--n >= 0) o[n] = n;
15125   return o;
15126 }
15127
15128 function stackValue(d, key) {
15129   return d[key];
15130 }
15131
15132 function stack() {
15133   var keys = constant$10([]),
15134       order = none$2,
15135       offset = none$1,
15136       value = stackValue;
15137
15138   function stack(data) {
15139     var kz = keys.apply(this, arguments),
15140         i,
15141         m = data.length,
15142         n = kz.length,
15143         sz = new Array(n),
15144         oz;
15145
15146     for (i = 0; i < n; ++i) {
15147       for (var ki = kz[i], si = sz[i] = new Array(m), j = 0, sij; j < m; ++j) {
15148         si[j] = sij = [0, +value(data[j], ki, j, data)];
15149         sij.data = data[j];
15150       }
15151       si.key = ki;
15152     }
15153
15154     for (i = 0, oz = order(sz); i < n; ++i) {
15155       sz[oz[i]].index = i;
15156     }
15157
15158     offset(sz, oz);
15159     return sz;
15160   }
15161
15162   stack.keys = function(_) {
15163     return arguments.length ? (keys = typeof _ === "function" ? _ : constant$10(slice$6.call(_)), stack) : keys;
15164   };
15165
15166   stack.value = function(_) {
15167     return arguments.length ? (value = typeof _ === "function" ? _ : constant$10(+_), stack) : value;
15168   };
15169
15170   stack.order = function(_) {
15171     return arguments.length ? (order = _ == null ? none$2 : typeof _ === "function" ? _ : constant$10(slice$6.call(_)), stack) : order;
15172   };
15173
15174   stack.offset = function(_) {
15175     return arguments.length ? (offset = _ == null ? none$1 : _, stack) : offset;
15176   };
15177
15178   return stack;
15179 }
15180
15181 function expand(series, order) {
15182   if (!((n = series.length) > 0)) return;
15183   for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) {
15184     for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0;
15185     if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y;
15186   }
15187   none$1(series, order);
15188 }
15189
15190 function diverging(series, order) {
15191   if (!((n = series.length) > 1)) return;
15192   for (var i, j = 0, d, dy, yp, yn, n, m = series[order[0]].length; j < m; ++j) {
15193     for (yp = yn = 0, i = 0; i < n; ++i) {
15194       if ((dy = (d = series[order[i]][j])[1] - d[0]) >= 0) {
15195         d[0] = yp, d[1] = yp += dy;
15196       } else if (dy < 0) {
15197         d[1] = yn, d[0] = yn += dy;
15198       } else {
15199         d[0] = yp;
15200       }
15201     }
15202   }
15203 }
15204
15205 function silhouette(series, order) {
15206   if (!((n = series.length) > 0)) return;
15207   for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) {
15208     for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0;
15209     s0[j][1] += s0[j][0] = -y / 2;
15210   }
15211   none$1(series, order);
15212 }
15213
15214 function wiggle(series, order) {
15215   if (!((n = series.length) > 0) || !((m = (s0 = series[order[0]]).length) > 0)) return;
15216   for (var y = 0, j = 1, s0, m, n; j < m; ++j) {
15217     for (var i = 0, s1 = 0, s2 = 0; i < n; ++i) {
15218       var si = series[order[i]],
15219           sij0 = si[j][1] || 0,
15220           sij1 = si[j - 1][1] || 0,
15221           s3 = (sij0 - sij1) / 2;
15222       for (var k = 0; k < i; ++k) {
15223         var sk = series[order[k]],
15224             skj0 = sk[j][1] || 0,
15225             skj1 = sk[j - 1][1] || 0;
15226         s3 += skj0 - skj1;
15227       }
15228       s1 += sij0, s2 += s3 * sij0;
15229     }
15230     s0[j - 1][1] += s0[j - 1][0] = y;
15231     if (s1) y -= s2 / s1;
15232   }
15233   s0[j - 1][1] += s0[j - 1][0] = y;
15234   none$1(series, order);
15235 }
15236
15237 function ascending$1(series) {
15238   var sums = series.map(sum$2);
15239   return none$2(series).sort(function(a, b) { return sums[a] - sums[b]; });
15240 }
15241
15242 function sum$2(series) {
15243   var s = 0, i = -1, n = series.length, v;
15244   while (++i < n) if (v = +series[i][1]) s += v;
15245   return s;
15246 }
15247
15248 function descending$1(series) {
15249   return ascending$1(series).reverse();
15250 }
15251
15252 function insideOut(series) {
15253   var n = series.length,
15254       i,
15255       j,
15256       sums = series.map(sum$2),
15257       order = none$2(series).sort(function(a, b) { return sums[b] - sums[a]; }),
15258       top = 0,
15259       bottom = 0,
15260       tops = [],
15261       bottoms = [];
15262
15263   for (i = 0; i < n; ++i) {
15264     j = order[i];
15265     if (top < bottom) {
15266       top += sums[j];
15267       tops.push(j);
15268     } else {
15269       bottom += sums[j];
15270       bottoms.push(j);
15271     }
15272   }
15273
15274   return bottoms.reverse().concat(tops);
15275 }
15276
15277 function reverse(series) {
15278   return none$2(series).reverse();
15279 }
15280
15281 function constant$11(x) {
15282   return function() {
15283     return x;
15284   };
15285 }
15286
15287 function x$4(d) {
15288   return d[0];
15289 }
15290
15291 function y$4(d) {
15292   return d[1];
15293 }
15294
15295 function RedBlackTree() {
15296   this._ = null; // root node
15297 }
15298
15299 function RedBlackNode(node) {
15300   node.U = // parent node
15301   node.C = // color - true for red, false for black
15302   node.L = // left node
15303   node.R = // right node
15304   node.P = // previous node
15305   node.N = null; // next node
15306 }
15307
15308 RedBlackTree.prototype = {
15309   constructor: RedBlackTree,
15310
15311   insert: function(after, node) {
15312     var parent, grandpa, uncle;
15313
15314     if (after) {
15315       node.P = after;
15316       node.N = after.N;
15317       if (after.N) after.N.P = node;
15318       after.N = node;
15319       if (after.R) {
15320         after = after.R;
15321         while (after.L) after = after.L;
15322         after.L = node;
15323       } else {
15324         after.R = node;
15325       }
15326       parent = after;
15327     } else if (this._) {
15328       after = RedBlackFirst(this._);
15329       node.P = null;
15330       node.N = after;
15331       after.P = after.L = node;
15332       parent = after;
15333     } else {
15334       node.P = node.N = null;
15335       this._ = node;
15336       parent = null;
15337     }
15338     node.L = node.R = null;
15339     node.U = parent;
15340     node.C = true;
15341
15342     after = node;
15343     while (parent && parent.C) {
15344       grandpa = parent.U;
15345       if (parent === grandpa.L) {
15346         uncle = grandpa.R;
15347         if (uncle && uncle.C) {
15348           parent.C = uncle.C = false;
15349           grandpa.C = true;
15350           after = grandpa;
15351         } else {
15352           if (after === parent.R) {
15353             RedBlackRotateLeft(this, parent);
15354             after = parent;
15355             parent = after.U;
15356           }
15357           parent.C = false;
15358           grandpa.C = true;
15359           RedBlackRotateRight(this, grandpa);
15360         }
15361       } else {
15362         uncle = grandpa.L;
15363         if (uncle && uncle.C) {
15364           parent.C = uncle.C = false;
15365           grandpa.C = true;
15366           after = grandpa;
15367         } else {
15368           if (after === parent.L) {
15369             RedBlackRotateRight(this, parent);
15370             after = parent;
15371             parent = after.U;
15372           }
15373           parent.C = false;
15374           grandpa.C = true;
15375           RedBlackRotateLeft(this, grandpa);
15376         }
15377       }
15378       parent = after.U;
15379     }
15380     this._.C = false;
15381   },
15382
15383   remove: function(node) {
15384     if (node.N) node.N.P = node.P;
15385     if (node.P) node.P.N = node.N;
15386     node.N = node.P = null;
15387
15388     var parent = node.U,
15389         sibling,
15390         left = node.L,
15391         right = node.R,
15392         next,
15393         red;
15394
15395     if (!left) next = right;
15396     else if (!right) next = left;
15397     else next = RedBlackFirst(right);
15398
15399     if (parent) {
15400       if (parent.L === node) parent.L = next;
15401       else parent.R = next;
15402     } else {
15403       this._ = next;
15404     }
15405
15406     if (left && right) {
15407       red = next.C;
15408       next.C = node.C;
15409       next.L = left;
15410       left.U = next;
15411       if (next !== right) {
15412         parent = next.U;
15413         next.U = node.U;
15414         node = next.R;
15415         parent.L = node;
15416         next.R = right;
15417         right.U = next;
15418       } else {
15419         next.U = parent;
15420         parent = next;
15421         node = next.R;
15422       }
15423     } else {
15424       red = node.C;
15425       node = next;
15426     }
15427
15428     if (node) node.U = parent;
15429     if (red) return;
15430     if (node && node.C) { node.C = false; return; }
15431
15432     do {
15433       if (node === this._) break;
15434       if (node === parent.L) {
15435         sibling = parent.R;
15436         if (sibling.C) {
15437           sibling.C = false;
15438           parent.C = true;
15439           RedBlackRotateLeft(this, parent);
15440           sibling = parent.R;
15441         }
15442         if ((sibling.L && sibling.L.C)
15443             || (sibling.R && sibling.R.C)) {
15444           if (!sibling.R || !sibling.R.C) {
15445             sibling.L.C = false;
15446             sibling.C = true;
15447             RedBlackRotateRight(this, sibling);
15448             sibling = parent.R;
15449           }
15450           sibling.C = parent.C;
15451           parent.C = sibling.R.C = false;
15452           RedBlackRotateLeft(this, parent);
15453           node = this._;
15454           break;
15455         }
15456       } else {
15457         sibling = parent.L;
15458         if (sibling.C) {
15459           sibling.C = false;
15460           parent.C = true;
15461           RedBlackRotateRight(this, parent);
15462           sibling = parent.L;
15463         }
15464         if ((sibling.L && sibling.L.C)
15465           || (sibling.R && sibling.R.C)) {
15466           if (!sibling.L || !sibling.L.C) {
15467             sibling.R.C = false;
15468             sibling.C = true;
15469             RedBlackRotateLeft(this, sibling);
15470             sibling = parent.L;
15471           }
15472           sibling.C = parent.C;
15473           parent.C = sibling.L.C = false;
15474           RedBlackRotateRight(this, parent);
15475           node = this._;
15476           break;
15477         }
15478       }
15479       sibling.C = true;
15480       node = parent;
15481       parent = parent.U;
15482     } while (!node.C);
15483
15484     if (node) node.C = false;
15485   }
15486 };
15487
15488 function RedBlackRotateLeft(tree, node) {
15489   var p = node,
15490       q = node.R,
15491       parent = p.U;
15492
15493   if (parent) {
15494     if (parent.L === p) parent.L = q;
15495     else parent.R = q;
15496   } else {
15497     tree._ = q;
15498   }
15499
15500   q.U = parent;
15501   p.U = q;
15502   p.R = q.L;
15503   if (p.R) p.R.U = p;
15504   q.L = p;
15505 }
15506
15507 function RedBlackRotateRight(tree, node) {
15508   var p = node,
15509       q = node.L,
15510       parent = p.U;
15511
15512   if (parent) {
15513     if (parent.L === p) parent.L = q;
15514     else parent.R = q;
15515   } else {
15516     tree._ = q;
15517   }
15518
15519   q.U = parent;
15520   p.U = q;
15521   p.L = q.R;
15522   if (p.L) p.L.U = p;
15523   q.R = p;
15524 }
15525
15526 function RedBlackFirst(node) {
15527   while (node.L) node = node.L;
15528   return node;
15529 }
15530
15531 function createEdge(left, right, v0, v1) {
15532   var edge = [null, null],
15533       index = edges.push(edge) - 1;
15534   edge.left = left;
15535   edge.right = right;
15536   if (v0) setEdgeEnd(edge, left, right, v0);
15537   if (v1) setEdgeEnd(edge, right, left, v1);
15538   cells[left.index].halfedges.push(index);
15539   cells[right.index].halfedges.push(index);
15540   return edge;
15541 }
15542
15543 function createBorderEdge(left, v0, v1) {
15544   var edge = [v0, v1];
15545   edge.left = left;
15546   return edge;
15547 }
15548
15549 function setEdgeEnd(edge, left, right, vertex) {
15550   if (!edge[0] && !edge[1]) {
15551     edge[0] = vertex;
15552     edge.left = left;
15553     edge.right = right;
15554   } else if (edge.left === right) {
15555     edge[1] = vertex;
15556   } else {
15557     edge[0] = vertex;
15558   }
15559 }
15560
15561 // Liang–Barsky line clipping.
15562 function clipEdge(edge, x0, y0, x1, y1) {
15563   var a = edge[0],
15564       b = edge[1],
15565       ax = a[0],
15566       ay = a[1],
15567       bx = b[0],
15568       by = b[1],
15569       t0 = 0,
15570       t1 = 1,
15571       dx = bx - ax,
15572       dy = by - ay,
15573       r;
15574
15575   r = x0 - ax;
15576   if (!dx && r > 0) return;
15577   r /= dx;
15578   if (dx < 0) {
15579     if (r < t0) return;
15580     if (r < t1) t1 = r;
15581   } else if (dx > 0) {
15582     if (r > t1) return;
15583     if (r > t0) t0 = r;
15584   }
15585
15586   r = x1 - ax;
15587   if (!dx && r < 0) return;
15588   r /= dx;
15589   if (dx < 0) {
15590     if (r > t1) return;
15591     if (r > t0) t0 = r;
15592   } else if (dx > 0) {
15593     if (r < t0) return;
15594     if (r < t1) t1 = r;
15595   }
15596
15597   r = y0 - ay;
15598   if (!dy && r > 0) return;
15599   r /= dy;
15600   if (dy < 0) {
15601     if (r < t0) return;
15602     if (r < t1) t1 = r;
15603   } else if (dy > 0) {
15604     if (r > t1) return;
15605     if (r > t0) t0 = r;
15606   }
15607
15608   r = y1 - ay;
15609   if (!dy && r < 0) return;
15610   r /= dy;
15611   if (dy < 0) {
15612     if (r > t1) return;
15613     if (r > t0) t0 = r;
15614   } else if (dy > 0) {
15615     if (r < t0) return;
15616     if (r < t1) t1 = r;
15617   }
15618
15619   if (!(t0 > 0) && !(t1 < 1)) return true; // TODO Better check?
15620
15621   if (t0 > 0) edge[0] = [ax + t0 * dx, ay + t0 * dy];
15622   if (t1 < 1) edge[1] = [ax + t1 * dx, ay + t1 * dy];
15623   return true;
15624 }
15625
15626 function connectEdge(edge, x0, y0, x1, y1) {
15627   var v1 = edge[1];
15628   if (v1) return true;
15629
15630   var v0 = edge[0],
15631       left = edge.left,
15632       right = edge.right,
15633       lx = left[0],
15634       ly = left[1],
15635       rx = right[0],
15636       ry = right[1],
15637       fx = (lx + rx) / 2,
15638       fy = (ly + ry) / 2,
15639       fm,
15640       fb;
15641
15642   if (ry === ly) {
15643     if (fx < x0 || fx >= x1) return;
15644     if (lx > rx) {
15645       if (!v0) v0 = [fx, y0];
15646       else if (v0[1] >= y1) return;
15647       v1 = [fx, y1];
15648     } else {
15649       if (!v0) v0 = [fx, y1];
15650       else if (v0[1] < y0) return;
15651       v1 = [fx, y0];
15652     }
15653   } else {
15654     fm = (lx - rx) / (ry - ly);
15655     fb = fy - fm * fx;
15656     if (fm < -1 || fm > 1) {
15657       if (lx > rx) {
15658         if (!v0) v0 = [(y0 - fb) / fm, y0];
15659         else if (v0[1] >= y1) return;
15660         v1 = [(y1 - fb) / fm, y1];
15661       } else {
15662         if (!v0) v0 = [(y1 - fb) / fm, y1];
15663         else if (v0[1] < y0) return;
15664         v1 = [(y0 - fb) / fm, y0];
15665       }
15666     } else {
15667       if (ly < ry) {
15668         if (!v0) v0 = [x0, fm * x0 + fb];
15669         else if (v0[0] >= x1) return;
15670         v1 = [x1, fm * x1 + fb];
15671       } else {
15672         if (!v0) v0 = [x1, fm * x1 + fb];
15673         else if (v0[0] < x0) return;
15674         v1 = [x0, fm * x0 + fb];
15675       }
15676     }
15677   }
15678
15679   edge[0] = v0;
15680   edge[1] = v1;
15681   return true;
15682 }
15683
15684 function clipEdges(x0, y0, x1, y1) {
15685   var i = edges.length,
15686       edge;
15687
15688   while (i--) {
15689     if (!connectEdge(edge = edges[i], x0, y0, x1, y1)
15690         || !clipEdge(edge, x0, y0, x1, y1)
15691         || !(Math.abs(edge[0][0] - edge[1][0]) > epsilon$4
15692             || Math.abs(edge[0][1] - edge[1][1]) > epsilon$4)) {
15693       delete edges[i];
15694     }
15695   }
15696 }
15697
15698 function createCell(site) {
15699   return cells[site.index] = {
15700     site: site,
15701     halfedges: []
15702   };
15703 }
15704
15705 function cellHalfedgeAngle(cell, edge) {
15706   var site = cell.site,
15707       va = edge.left,
15708       vb = edge.right;
15709   if (site === vb) vb = va, va = site;
15710   if (vb) return Math.atan2(vb[1] - va[1], vb[0] - va[0]);
15711   if (site === va) va = edge[1], vb = edge[0];
15712   else va = edge[0], vb = edge[1];
15713   return Math.atan2(va[0] - vb[0], vb[1] - va[1]);
15714 }
15715
15716 function cellHalfedgeStart(cell, edge) {
15717   return edge[+(edge.left !== cell.site)];
15718 }
15719
15720 function cellHalfedgeEnd(cell, edge) {
15721   return edge[+(edge.left === cell.site)];
15722 }
15723
15724 function sortCellHalfedges() {
15725   for (var i = 0, n = cells.length, cell, halfedges, j, m; i < n; ++i) {
15726     if ((cell = cells[i]) && (m = (halfedges = cell.halfedges).length)) {
15727       var index = new Array(m),
15728           array = new Array(m);
15729       for (j = 0; j < m; ++j) index[j] = j, array[j] = cellHalfedgeAngle(cell, edges[halfedges[j]]);
15730       index.sort(function(i, j) { return array[j] - array[i]; });
15731       for (j = 0; j < m; ++j) array[j] = halfedges[index[j]];
15732       for (j = 0; j < m; ++j) halfedges[j] = array[j];
15733     }
15734   }
15735 }
15736
15737 function clipCells(x0, y0, x1, y1) {
15738   var nCells = cells.length,
15739       iCell,
15740       cell,
15741       site,
15742       iHalfedge,
15743       halfedges,
15744       nHalfedges,
15745       start,
15746       startX,
15747       startY,
15748       end,
15749       endX,
15750       endY,
15751       cover = true;
15752
15753   for (iCell = 0; iCell < nCells; ++iCell) {
15754     if (cell = cells[iCell]) {
15755       site = cell.site;
15756       halfedges = cell.halfedges;
15757       iHalfedge = halfedges.length;
15758
15759       // Remove any dangling clipped edges.
15760       while (iHalfedge--) {
15761         if (!edges[halfedges[iHalfedge]]) {
15762           halfedges.splice(iHalfedge, 1);
15763         }
15764       }
15765
15766       // Insert any border edges as necessary.
15767       iHalfedge = 0, nHalfedges = halfedges.length;
15768       while (iHalfedge < nHalfedges) {
15769         end = cellHalfedgeEnd(cell, edges[halfedges[iHalfedge]]), endX = end[0], endY = end[1];
15770         start = cellHalfedgeStart(cell, edges[halfedges[++iHalfedge % nHalfedges]]), startX = start[0], startY = start[1];
15771         if (Math.abs(endX - startX) > epsilon$4 || Math.abs(endY - startY) > epsilon$4) {
15772           halfedges.splice(iHalfedge, 0, edges.push(createBorderEdge(site, end,
15773               Math.abs(endX - x0) < epsilon$4 && y1 - endY > epsilon$4 ? [x0, Math.abs(startX - x0) < epsilon$4 ? startY : y1]
15774               : Math.abs(endY - y1) < epsilon$4 && x1 - endX > epsilon$4 ? [Math.abs(startY - y1) < epsilon$4 ? startX : x1, y1]
15775               : Math.abs(endX - x1) < epsilon$4 && endY - y0 > epsilon$4 ? [x1, Math.abs(startX - x1) < epsilon$4 ? startY : y0]
15776               : Math.abs(endY - y0) < epsilon$4 && endX - x0 > epsilon$4 ? [Math.abs(startY - y0) < epsilon$4 ? startX : x0, y0]
15777               : null)) - 1);
15778           ++nHalfedges;
15779         }
15780       }
15781
15782       if (nHalfedges) cover = false;
15783     }
15784   }
15785
15786   // If there weren’t any edges, have the closest site cover the extent.
15787   // It doesn’t matter which corner of the extent we measure!
15788   if (cover) {
15789     var dx, dy, d2, dc = Infinity;
15790
15791     for (iCell = 0, cover = null; iCell < nCells; ++iCell) {
15792       if (cell = cells[iCell]) {
15793         site = cell.site;
15794         dx = site[0] - x0;
15795         dy = site[1] - y0;
15796         d2 = dx * dx + dy * dy;
15797         if (d2 < dc) dc = d2, cover = cell;
15798       }
15799     }
15800
15801     if (cover) {
15802       var v00 = [x0, y0], v01 = [x0, y1], v11 = [x1, y1], v10 = [x1, y0];
15803       cover.halfedges.push(
15804         edges.push(createBorderEdge(site = cover.site, v00, v01)) - 1,
15805         edges.push(createBorderEdge(site, v01, v11)) - 1,
15806         edges.push(createBorderEdge(site, v11, v10)) - 1,
15807         edges.push(createBorderEdge(site, v10, v00)) - 1
15808       );
15809     }
15810   }
15811
15812   // Lastly delete any cells with no edges; these were entirely clipped.
15813   for (iCell = 0; iCell < nCells; ++iCell) {
15814     if (cell = cells[iCell]) {
15815       if (!cell.halfedges.length) {
15816         delete cells[iCell];
15817       }
15818     }
15819   }
15820 }
15821
15822 var circlePool = [];
15823
15824 var firstCircle;
15825
15826 function Circle() {
15827   RedBlackNode(this);
15828   this.x =
15829   this.y =
15830   this.arc =
15831   this.site =
15832   this.cy = null;
15833 }
15834
15835 function attachCircle(arc) {
15836   var lArc = arc.P,
15837       rArc = arc.N;
15838
15839   if (!lArc || !rArc) return;
15840
15841   var lSite = lArc.site,
15842       cSite = arc.site,
15843       rSite = rArc.site;
15844
15845   if (lSite === rSite) return;
15846
15847   var bx = cSite[0],
15848       by = cSite[1],
15849       ax = lSite[0] - bx,
15850       ay = lSite[1] - by,
15851       cx = rSite[0] - bx,
15852       cy = rSite[1] - by;
15853
15854   var d = 2 * (ax * cy - ay * cx);
15855   if (d >= -epsilon2$2) return;
15856
15857   var ha = ax * ax + ay * ay,
15858       hc = cx * cx + cy * cy,
15859       x = (cy * ha - ay * hc) / d,
15860       y = (ax * hc - cx * ha) / d;
15861
15862   var circle = circlePool.pop() || new Circle;
15863   circle.arc = arc;
15864   circle.site = cSite;
15865   circle.x = x + bx;
15866   circle.y = (circle.cy = y + by) + Math.sqrt(x * x + y * y); // y bottom
15867
15868   arc.circle = circle;
15869
15870   var before = null,
15871       node = circles._;
15872
15873   while (node) {
15874     if (circle.y < node.y || (circle.y === node.y && circle.x <= node.x)) {
15875       if (node.L) node = node.L;
15876       else { before = node.P; break; }
15877     } else {
15878       if (node.R) node = node.R;
15879       else { before = node; break; }
15880     }
15881   }
15882
15883   circles.insert(before, circle);
15884   if (!before) firstCircle = circle;
15885 }
15886
15887 function detachCircle(arc) {
15888   var circle = arc.circle;
15889   if (circle) {
15890     if (!circle.P) firstCircle = circle.N;
15891     circles.remove(circle);
15892     circlePool.push(circle);
15893     RedBlackNode(circle);
15894     arc.circle = null;
15895   }
15896 }
15897
15898 var beachPool = [];
15899
15900 function Beach() {
15901   RedBlackNode(this);
15902   this.edge =
15903   this.site =
15904   this.circle = null;
15905 }
15906
15907 function createBeach(site) {
15908   var beach = beachPool.pop() || new Beach;
15909   beach.site = site;
15910   return beach;
15911 }
15912
15913 function detachBeach(beach) {
15914   detachCircle(beach);
15915   beaches.remove(beach);
15916   beachPool.push(beach);
15917   RedBlackNode(beach);
15918 }
15919
15920 function removeBeach(beach) {
15921   var circle = beach.circle,
15922       x = circle.x,
15923       y = circle.cy,
15924       vertex = [x, y],
15925       previous = beach.P,
15926       next = beach.N,
15927       disappearing = [beach];
15928
15929   detachBeach(beach);
15930
15931   var lArc = previous;
15932   while (lArc.circle
15933       && Math.abs(x - lArc.circle.x) < epsilon$4
15934       && Math.abs(y - lArc.circle.cy) < epsilon$4) {
15935     previous = lArc.P;
15936     disappearing.unshift(lArc);
15937     detachBeach(lArc);
15938     lArc = previous;
15939   }
15940
15941   disappearing.unshift(lArc);
15942   detachCircle(lArc);
15943
15944   var rArc = next;
15945   while (rArc.circle
15946       && Math.abs(x - rArc.circle.x) < epsilon$4
15947       && Math.abs(y - rArc.circle.cy) < epsilon$4) {
15948     next = rArc.N;
15949     disappearing.push(rArc);
15950     detachBeach(rArc);
15951     rArc = next;
15952   }
15953
15954   disappearing.push(rArc);
15955   detachCircle(rArc);
15956
15957   var nArcs = disappearing.length,
15958       iArc;
15959   for (iArc = 1; iArc < nArcs; ++iArc) {
15960     rArc = disappearing[iArc];
15961     lArc = disappearing[iArc - 1];
15962     setEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex);
15963   }
15964
15965   lArc = disappearing[0];
15966   rArc = disappearing[nArcs - 1];
15967   rArc.edge = createEdge(lArc.site, rArc.site, null, vertex);
15968
15969   attachCircle(lArc);
15970   attachCircle(rArc);
15971 }
15972
15973 function addBeach(site) {
15974   var x = site[0],
15975       directrix = site[1],
15976       lArc,
15977       rArc,
15978       dxl,
15979       dxr,
15980       node = beaches._;
15981
15982   while (node) {
15983     dxl = leftBreakPoint(node, directrix) - x;
15984     if (dxl > epsilon$4) node = node.L; else {
15985       dxr = x - rightBreakPoint(node, directrix);
15986       if (dxr > epsilon$4) {
15987         if (!node.R) {
15988           lArc = node;
15989           break;
15990         }
15991         node = node.R;
15992       } else {
15993         if (dxl > -epsilon$4) {
15994           lArc = node.P;
15995           rArc = node;
15996         } else if (dxr > -epsilon$4) {
15997           lArc = node;
15998           rArc = node.N;
15999         } else {
16000           lArc = rArc = node;
16001         }
16002         break;
16003       }
16004     }
16005   }
16006
16007   createCell(site);
16008   var newArc = createBeach(site);
16009   beaches.insert(lArc, newArc);
16010
16011   if (!lArc && !rArc) return;
16012
16013   if (lArc === rArc) {
16014     detachCircle(lArc);
16015     rArc = createBeach(lArc.site);
16016     beaches.insert(newArc, rArc);
16017     newArc.edge = rArc.edge = createEdge(lArc.site, newArc.site);
16018     attachCircle(lArc);
16019     attachCircle(rArc);
16020     return;
16021   }
16022
16023   if (!rArc) { // && lArc
16024     newArc.edge = createEdge(lArc.site, newArc.site);
16025     return;
16026   }
16027
16028   // else lArc !== rArc
16029   detachCircle(lArc);
16030   detachCircle(rArc);
16031
16032   var lSite = lArc.site,
16033       ax = lSite[0],
16034       ay = lSite[1],
16035       bx = site[0] - ax,
16036       by = site[1] - ay,
16037       rSite = rArc.site,
16038       cx = rSite[0] - ax,
16039       cy = rSite[1] - ay,
16040       d = 2 * (bx * cy - by * cx),
16041       hb = bx * bx + by * by,
16042       hc = cx * cx + cy * cy,
16043       vertex = [(cy * hb - by * hc) / d + ax, (bx * hc - cx * hb) / d + ay];
16044
16045   setEdgeEnd(rArc.edge, lSite, rSite, vertex);
16046   newArc.edge = createEdge(lSite, site, null, vertex);
16047   rArc.edge = createEdge(site, rSite, null, vertex);
16048   attachCircle(lArc);
16049   attachCircle(rArc);
16050 }
16051
16052 function leftBreakPoint(arc, directrix) {
16053   var site = arc.site,
16054       rfocx = site[0],
16055       rfocy = site[1],
16056       pby2 = rfocy - directrix;
16057
16058   if (!pby2) return rfocx;
16059
16060   var lArc = arc.P;
16061   if (!lArc) return -Infinity;
16062
16063   site = lArc.site;
16064   var lfocx = site[0],
16065       lfocy = site[1],
16066       plby2 = lfocy - directrix;
16067
16068   if (!plby2) return lfocx;
16069
16070   var hl = lfocx - rfocx,
16071       aby2 = 1 / pby2 - 1 / plby2,
16072       b = hl / plby2;
16073
16074   if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx;
16075
16076   return (rfocx + lfocx) / 2;
16077 }
16078
16079 function rightBreakPoint(arc, directrix) {
16080   var rArc = arc.N;
16081   if (rArc) return leftBreakPoint(rArc, directrix);
16082   var site = arc.site;
16083   return site[1] === directrix ? site[0] : Infinity;
16084 }
16085
16086 var epsilon$4 = 1e-6;
16087 var epsilon2$2 = 1e-12;
16088 var beaches;
16089 var cells;
16090 var circles;
16091 var edges;
16092
16093 function triangleArea(a, b, c) {
16094   return (a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]);
16095 }
16096
16097 function lexicographic(a, b) {
16098   return b[1] - a[1]
16099       || b[0] - a[0];
16100 }
16101
16102 function Diagram(sites, extent) {
16103   var site = sites.sort(lexicographic).pop(),
16104       x,
16105       y,
16106       circle;
16107
16108   edges = [];
16109   cells = new Array(sites.length);
16110   beaches = new RedBlackTree;
16111   circles = new RedBlackTree;
16112
16113   while (true) {
16114     circle = firstCircle;
16115     if (site && (!circle || site[1] < circle.y || (site[1] === circle.y && site[0] < circle.x))) {
16116       if (site[0] !== x || site[1] !== y) {
16117         addBeach(site);
16118         x = site[0], y = site[1];
16119       }
16120       site = sites.pop();
16121     } else if (circle) {
16122       removeBeach(circle.arc);
16123     } else {
16124       break;
16125     }
16126   }
16127
16128   sortCellHalfedges();
16129
16130   if (extent) {
16131     var x0 = +extent[0][0],
16132         y0 = +extent[0][1],
16133         x1 = +extent[1][0],
16134         y1 = +extent[1][1];
16135     clipEdges(x0, y0, x1, y1);
16136     clipCells(x0, y0, x1, y1);
16137   }
16138
16139   this.edges = edges;
16140   this.cells = cells;
16141
16142   beaches =
16143   circles =
16144   edges =
16145   cells = null;
16146 }
16147
16148 Diagram.prototype = {
16149   constructor: Diagram,
16150
16151   polygons: function() {
16152     var edges = this.edges;
16153
16154     return this.cells.map(function(cell) {
16155       var polygon = cell.halfedges.map(function(i) { return cellHalfedgeStart(cell, edges[i]); });
16156       polygon.data = cell.site.data;
16157       return polygon;
16158     });
16159   },
16160
16161   triangles: function() {
16162     var triangles = [],
16163         edges = this.edges;
16164
16165     this.cells.forEach(function(cell, i) {
16166       if (!(m = (halfedges = cell.halfedges).length)) return;
16167       var site = cell.site,
16168           halfedges,
16169           j = -1,
16170           m,
16171           s0,
16172           e1 = edges[halfedges[m - 1]],
16173           s1 = e1.left === site ? e1.right : e1.left;
16174
16175       while (++j < m) {
16176         s0 = s1;
16177         e1 = edges[halfedges[j]];
16178         s1 = e1.left === site ? e1.right : e1.left;
16179         if (s0 && s1 && i < s0.index && i < s1.index && triangleArea(site, s0, s1) < 0) {
16180           triangles.push([site.data, s0.data, s1.data]);
16181         }
16182       }
16183     });
16184
16185     return triangles;
16186   },
16187
16188   links: function() {
16189     return this.edges.filter(function(edge) {
16190       return edge.right;
16191     }).map(function(edge) {
16192       return {
16193         source: edge.left.data,
16194         target: edge.right.data
16195       };
16196     });
16197   },
16198
16199   find: function(x, y, radius) {
16200     var that = this, i0, i1 = that._found || 0, n = that.cells.length, cell;
16201
16202     // Use the previously-found cell, or start with an arbitrary one.
16203     while (!(cell = that.cells[i1])) if (++i1 >= n) return null;
16204     var dx = x - cell.site[0], dy = y - cell.site[1], d2 = dx * dx + dy * dy;
16205
16206     // Traverse the half-edges to find a closer cell, if any.
16207     do {
16208       cell = that.cells[i0 = i1], i1 = null;
16209       cell.halfedges.forEach(function(e) {
16210         var edge = that.edges[e], v = edge.left;
16211         if ((v === cell.site || !v) && !(v = edge.right)) return;
16212         var vx = x - v[0], vy = y - v[1], v2 = vx * vx + vy * vy;
16213         if (v2 < d2) d2 = v2, i1 = v.index;
16214       });
16215     } while (i1 !== null);
16216
16217     that._found = i0;
16218
16219     return radius == null || d2 <= radius * radius ? cell.site : null;
16220   }
16221 };
16222
16223 function voronoi() {
16224   var x$$1 = x$4,
16225       y$$1 = y$4,
16226       extent = null;
16227
16228   function voronoi(data) {
16229     return new Diagram(data.map(function(d, i) {
16230       var s = [Math.round(x$$1(d, i, data) / epsilon$4) * epsilon$4, Math.round(y$$1(d, i, data) / epsilon$4) * epsilon$4];
16231       s.index = i;
16232       s.data = d;
16233       return s;
16234     }), extent);
16235   }
16236
16237   voronoi.polygons = function(data) {
16238     return voronoi(data).polygons();
16239   };
16240
16241   voronoi.links = function(data) {
16242     return voronoi(data).links();
16243   };
16244
16245   voronoi.triangles = function(data) {
16246     return voronoi(data).triangles();
16247   };
16248
16249   voronoi.x = function(_) {
16250     return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$11(+_), voronoi) : x$$1;
16251   };
16252
16253   voronoi.y = function(_) {
16254     return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$11(+_), voronoi) : y$$1;
16255   };
16256
16257   voronoi.extent = function(_) {
16258     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]]];
16259   };
16260
16261   voronoi.size = function(_) {
16262     return arguments.length ? (extent = _ == null ? null : [[0, 0], [+_[0], +_[1]]], voronoi) : extent && [extent[1][0] - extent[0][0], extent[1][1] - extent[0][1]];
16263   };
16264
16265   return voronoi;
16266 }
16267
16268 function constant$12(x) {
16269   return function() {
16270     return x;
16271   };
16272 }
16273
16274 function ZoomEvent(target, type, transform) {
16275   this.target = target;
16276   this.type = type;
16277   this.transform = transform;
16278 }
16279
16280 function Transform(k, x, y) {
16281   this.k = k;
16282   this.x = x;
16283   this.y = y;
16284 }
16285
16286 Transform.prototype = {
16287   constructor: Transform,
16288   scale: function(k) {
16289     return k === 1 ? this : new Transform(this.k * k, this.x, this.y);
16290   },
16291   translate: function(x, y) {
16292     return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y);
16293   },
16294   apply: function(point) {
16295     return [point[0] * this.k + this.x, point[1] * this.k + this.y];
16296   },
16297   applyX: function(x) {
16298     return x * this.k + this.x;
16299   },
16300   applyY: function(y) {
16301     return y * this.k + this.y;
16302   },
16303   invert: function(location) {
16304     return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k];
16305   },
16306   invertX: function(x) {
16307     return (x - this.x) / this.k;
16308   },
16309   invertY: function(y) {
16310     return (y - this.y) / this.k;
16311   },
16312   rescaleX: function(x) {
16313     return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x));
16314   },
16315   rescaleY: function(y) {
16316     return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y));
16317   },
16318   toString: function() {
16319     return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")";
16320   }
16321 };
16322
16323 var identity$7 = new Transform(1, 0, 0);
16324
16325 transform.prototype = Transform.prototype;
16326
16327 function transform(node) {
16328   return node.__zoom || identity$7;
16329 }
16330
16331 function nopropagation$2() {
16332   event.stopImmediatePropagation();
16333 }
16334
16335 function noevent$2() {
16336   event.preventDefault();
16337   event.stopImmediatePropagation();
16338 }
16339
16340 // Ignore right-click, since that should open the context menu.
16341 function defaultFilter$2() {
16342   return !event.button;
16343 }
16344
16345 function defaultExtent$1() {
16346   var e = this, w, h;
16347   if (e instanceof SVGElement) {
16348     e = e.ownerSVGElement || e;
16349     w = e.width.baseVal.value;
16350     h = e.height.baseVal.value;
16351   } else {
16352     w = e.clientWidth;
16353     h = e.clientHeight;
16354   }
16355   return [[0, 0], [w, h]];
16356 }
16357
16358 function defaultTransform() {
16359   return this.__zoom || identity$7;
16360 }
16361
16362 function defaultWheelDelta() {
16363   return -event.deltaY * (event.deltaMode ? 120 : 1) / 500;
16364 }
16365
16366 function defaultTouchable$1() {
16367   return "ontouchstart" in this;
16368 }
16369
16370 function defaultConstrain(transform$$1, extent, translateExtent) {
16371   var dx0 = transform$$1.invertX(extent[0][0]) - translateExtent[0][0],
16372       dx1 = transform$$1.invertX(extent[1][0]) - translateExtent[1][0],
16373       dy0 = transform$$1.invertY(extent[0][1]) - translateExtent[0][1],
16374       dy1 = transform$$1.invertY(extent[1][1]) - translateExtent[1][1];
16375   return transform$$1.translate(
16376     dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1),
16377     dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1)
16378   );
16379 }
16380
16381 function d3_zoom() {
16382   var filter = defaultFilter$2,
16383       extent = defaultExtent$1,
16384       constrain = defaultConstrain,
16385       wheelDelta = defaultWheelDelta,
16386       touchable = defaultTouchable$1,
16387       scaleExtent = [0, Infinity],
16388       translateExtent = [[-Infinity, -Infinity], [Infinity, Infinity]],
16389       duration = 250,
16390       interpolate = interpolateZoom,
16391       gestures = [],
16392       listeners = dispatch("start", "zoom", "end"),
16393       touchstarting,
16394       touchending,
16395       touchDelay = 500,
16396       wheelDelay = 150,
16397       clickDistance2 = 0;
16398
16399   function zoom(selection) {
16400     selection
16401         .property("__zoom", defaultTransform)
16402         .on("wheel.zoom", wheeled)
16403         .on("mousedown.zoom", mousedowned)
16404         .on("dblclick.zoom", dblclicked)
16405       .filter(touchable)
16406         .on("touchstart.zoom", touchstarted)
16407         .on("touchmove.zoom", touchmoved)
16408         .on("touchend.zoom touchcancel.zoom", touchended)
16409         .style("touch-action", "none")
16410         .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
16411   }
16412
16413   zoom.transform = function(collection, transform$$1) {
16414     var selection = collection.selection ? collection.selection() : collection;
16415     selection.property("__zoom", defaultTransform);
16416     if (collection !== selection) {
16417       schedule(collection, transform$$1);
16418     } else {
16419       selection.interrupt().each(function() {
16420         gesture(this, arguments)
16421             .start()
16422             .zoom(null, typeof transform$$1 === "function" ? transform$$1.apply(this, arguments) : transform$$1)
16423             .end();
16424       });
16425     }
16426   };
16427
16428   zoom.scaleBy = function(selection, k) {
16429     zoom.scaleTo(selection, function() {
16430       var k0 = this.__zoom.k,
16431           k1 = typeof k === "function" ? k.apply(this, arguments) : k;
16432       return k0 * k1;
16433     });
16434   };
16435
16436   zoom.scaleTo = function(selection, k) {
16437     zoom.transform(selection, function() {
16438       var e = extent.apply(this, arguments),
16439           t0 = this.__zoom,
16440           p0 = centroid(e),
16441           p1 = t0.invert(p0),
16442           k1 = typeof k === "function" ? k.apply(this, arguments) : k;
16443       return constrain(translate(scale(t0, k1), p0, p1), e, translateExtent);
16444     });
16445   };
16446
16447   zoom.translateBy = function(selection, x, y) {
16448     zoom.transform(selection, function() {
16449       return constrain(this.__zoom.translate(
16450         typeof x === "function" ? x.apply(this, arguments) : x,
16451         typeof y === "function" ? y.apply(this, arguments) : y
16452       ), extent.apply(this, arguments), translateExtent);
16453     });
16454   };
16455
16456   zoom.translateTo = function(selection, x, y) {
16457     zoom.transform(selection, function() {
16458       var e = extent.apply(this, arguments),
16459           t = this.__zoom,
16460           p = centroid(e);
16461       return constrain(identity$7.translate(p[0], p[1]).scale(t.k).translate(
16462         typeof x === "function" ? -x.apply(this, arguments) : -x,
16463         typeof y === "function" ? -y.apply(this, arguments) : -y
16464       ), e, translateExtent);
16465     });
16466   };
16467
16468   function scale(transform$$1, k) {
16469     k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], k));
16470     return k === transform$$1.k ? transform$$1 : new Transform(k, transform$$1.x, transform$$1.y);
16471   }
16472
16473   function translate(transform$$1, p0, p1) {
16474     var x = p0[0] - p1[0] * transform$$1.k, y = p0[1] - p1[1] * transform$$1.k;
16475     return x === transform$$1.x && y === transform$$1.y ? transform$$1 : new Transform(transform$$1.k, x, y);
16476   }
16477
16478   function centroid(extent) {
16479     return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2];
16480   }
16481
16482   function schedule(transition, transform$$1, center) {
16483     transition
16484         .on("start.zoom", function() { gesture(this, arguments).start(); })
16485         .on("interrupt.zoom end.zoom", function() { gesture(this, arguments).end(); })
16486         .tween("zoom", function() {
16487           var that = this,
16488               args = arguments,
16489               g = gesture(that, args),
16490               e = extent.apply(that, args),
16491               p = center || centroid(e),
16492               w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]),
16493               a = that.__zoom,
16494               b = typeof transform$$1 === "function" ? transform$$1.apply(that, args) : transform$$1,
16495               i = interpolate(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k));
16496           return function(t) {
16497             if (t === 1) t = b; // Avoid rounding error on end.
16498             else { var l = i(t), k = w / l[2]; t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); }
16499             g.zoom(null, t);
16500           };
16501         });
16502   }
16503
16504   function gesture(that, args) {
16505     for (var i = 0, n = gestures.length, g; i < n; ++i) {
16506       if ((g = gestures[i]).that === that) {
16507         return g;
16508       }
16509     }
16510     return new Gesture(that, args);
16511   }
16512
16513   function Gesture(that, args) {
16514     this.that = that;
16515     this.args = args;
16516     this.index = -1;
16517     this.active = 0;
16518     this.extent = extent.apply(that, args);
16519   }
16520
16521   Gesture.prototype = {
16522     start: function() {
16523       if (++this.active === 1) {
16524         this.index = gestures.push(this) - 1;
16525         this.emit("start");
16526       }
16527       return this;
16528     },
16529     zoom: function(key, transform$$1) {
16530       if (this.mouse && key !== "mouse") this.mouse[1] = transform$$1.invert(this.mouse[0]);
16531       if (this.touch0 && key !== "touch") this.touch0[1] = transform$$1.invert(this.touch0[0]);
16532       if (this.touch1 && key !== "touch") this.touch1[1] = transform$$1.invert(this.touch1[0]);
16533       this.that.__zoom = transform$$1;
16534       this.emit("zoom");
16535       return this;
16536     },
16537     end: function() {
16538       if (--this.active === 0) {
16539         gestures.splice(this.index, 1);
16540         this.index = -1;
16541         this.emit("end");
16542       }
16543       return this;
16544     },
16545     emit: function(type) {
16546       customEvent(new ZoomEvent(zoom, type, this.that.__zoom), listeners.apply, listeners, [type, this.that, this.args]);
16547     }
16548   };
16549
16550   function wheeled() {
16551     if (!filter.apply(this, arguments)) return;
16552     var g = gesture(this, arguments),
16553         t = this.__zoom,
16554         k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], t.k * Math.pow(2, wheelDelta.apply(this, arguments)))),
16555         p = d3_mouse(this);
16556
16557     // If the mouse is in the same location as before, reuse it.
16558     // If there were recent wheel events, reset the wheel idle timeout.
16559     if (g.wheel) {
16560       if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) {
16561         g.mouse[1] = t.invert(g.mouse[0] = p);
16562       }
16563       clearTimeout(g.wheel);
16564     }
16565
16566     // If this wheel event won’t trigger a transform change, ignore it.
16567     else if (t.k === k) return;
16568
16569     // Otherwise, capture the mouse point and location at the start.
16570     else {
16571       g.mouse = [p, t.invert(p)];
16572       interrupt(this);
16573       g.start();
16574     }
16575
16576     noevent$2();
16577     g.wheel = setTimeout(wheelidled, wheelDelay);
16578     g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent, translateExtent));
16579
16580     function wheelidled() {
16581       g.wheel = null;
16582       g.end();
16583     }
16584   }
16585
16586   function mousedowned() {
16587     if (touchending || !filter.apply(this, arguments)) return;
16588     var g = gesture(this, arguments),
16589         v = d3_select(event.view).on("mousemove.zoom", mousemoved, true).on("mouseup.zoom", mouseupped, true),
16590         p = d3_mouse(this),
16591         x0 = event.clientX,
16592         y0 = event.clientY;
16593
16594     dragDisable(event.view);
16595     nopropagation$2();
16596     g.mouse = [p, this.__zoom.invert(p)];
16597     interrupt(this);
16598     g.start();
16599
16600     function mousemoved() {
16601       noevent$2();
16602       if (!g.moved) {
16603         var dx = event.clientX - x0, dy = event.clientY - y0;
16604         g.moved = dx * dx + dy * dy > clickDistance2;
16605       }
16606       g.zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = d3_mouse(g.that), g.mouse[1]), g.extent, translateExtent));
16607     }
16608
16609     function mouseupped() {
16610       v.on("mousemove.zoom mouseup.zoom", null);
16611       yesdrag(event.view, g.moved);
16612       noevent$2();
16613       g.end();
16614     }
16615   }
16616
16617   function dblclicked() {
16618     if (!filter.apply(this, arguments)) return;
16619     var t0 = this.__zoom,
16620         p0 = d3_mouse(this),
16621         p1 = t0.invert(p0),
16622         k1 = t0.k * (event.shiftKey ? 0.5 : 2),
16623         t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, arguments), translateExtent);
16624
16625     noevent$2();
16626     if (duration > 0) d3_select(this).transition().duration(duration).call(schedule, t1, p0);
16627     else d3_select(this).call(zoom.transform, t1);
16628   }
16629
16630   function touchstarted() {
16631     if (!filter.apply(this, arguments)) return;
16632     var g = gesture(this, arguments),
16633         touches = event.changedTouches,
16634         started,
16635         n = touches.length, i, t, p;
16636
16637     nopropagation$2();
16638     for (i = 0; i < n; ++i) {
16639       t = touches[i], p = touch(this, touches, t.identifier);
16640       p = [p, this.__zoom.invert(p), t.identifier];
16641       if (!g.touch0) g.touch0 = p, started = true;
16642       else if (!g.touch1) g.touch1 = p;
16643     }
16644
16645     // If this is a dbltap, reroute to the (optional) dblclick.zoom handler.
16646     if (touchstarting) {
16647       touchstarting = clearTimeout(touchstarting);
16648       if (!g.touch1) {
16649         g.end();
16650         p = d3_select(this).on("dblclick.zoom");
16651         if (p) p.apply(this, arguments);
16652         return;
16653       }
16654     }
16655
16656     if (started) {
16657       touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay);
16658       interrupt(this);
16659       g.start();
16660     }
16661   }
16662
16663   function touchmoved() {
16664     var g = gesture(this, arguments),
16665         touches = event.changedTouches,
16666         n = touches.length, i, t, p, l;
16667
16668     noevent$2();
16669     if (touchstarting) touchstarting = clearTimeout(touchstarting);
16670     for (i = 0; i < n; ++i) {
16671       t = touches[i], p = touch(this, touches, t.identifier);
16672       if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p;
16673       else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p;
16674     }
16675     t = g.that.__zoom;
16676     if (g.touch1) {
16677       var p0 = g.touch0[0], l0 = g.touch0[1],
16678           p1 = g.touch1[0], l1 = g.touch1[1],
16679           dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp,
16680           dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl;
16681       t = scale(t, Math.sqrt(dp / dl));
16682       p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2];
16683       l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];
16684     }
16685     else if (g.touch0) p = g.touch0[0], l = g.touch0[1];
16686     else return;
16687     g.zoom("touch", constrain(translate(t, p, l), g.extent, translateExtent));
16688   }
16689
16690   function touchended() {
16691     var g = gesture(this, arguments),
16692         touches = event.changedTouches,
16693         n = touches.length, i, t;
16694
16695     nopropagation$2();
16696     if (touchending) clearTimeout(touchending);
16697     touchending = setTimeout(function() { touchending = null; }, touchDelay);
16698     for (i = 0; i < n; ++i) {
16699       t = touches[i];
16700       if (g.touch0 && g.touch0[2] === t.identifier) delete g.touch0;
16701       else if (g.touch1 && g.touch1[2] === t.identifier) delete g.touch1;
16702     }
16703     if (g.touch1 && !g.touch0) g.touch0 = g.touch1, delete g.touch1;
16704     if (g.touch0) g.touch0[1] = this.__zoom.invert(g.touch0[0]);
16705     else g.end();
16706   }
16707
16708   zoom.wheelDelta = function(_) {
16709     return arguments.length ? (wheelDelta = typeof _ === "function" ? _ : constant$12(+_), zoom) : wheelDelta;
16710   };
16711
16712   zoom.filter = function(_) {
16713     return arguments.length ? (filter = typeof _ === "function" ? _ : constant$12(!!_), zoom) : filter;
16714   };
16715
16716   zoom.touchable = function(_) {
16717     return arguments.length ? (touchable = typeof _ === "function" ? _ : constant$12(!!_), zoom) : touchable;
16718   };
16719
16720   zoom.extent = function(_) {
16721     return arguments.length ? (extent = typeof _ === "function" ? _ : constant$12([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent;
16722   };
16723
16724   zoom.scaleExtent = function(_) {
16725     return arguments.length ? (scaleExtent[0] = +_[0], scaleExtent[1] = +_[1], zoom) : [scaleExtent[0], scaleExtent[1]];
16726   };
16727
16728   zoom.translateExtent = function(_) {
16729     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]]];
16730   };
16731
16732   zoom.constrain = function(_) {
16733     return arguments.length ? (constrain = _, zoom) : constrain;
16734   };
16735
16736   zoom.duration = function(_) {
16737     return arguments.length ? (duration = +_, zoom) : duration;
16738   };
16739
16740   zoom.interpolate = function(_) {
16741     return arguments.length ? (interpolate = _, zoom) : interpolate;
16742   };
16743
16744   zoom.on = function() {
16745     var value = listeners.on.apply(listeners, arguments);
16746     return value === listeners ? zoom : value;
16747   };
16748
16749   zoom.clickDistance = function(_) {
16750     return arguments.length ? (clickDistance2 = (_ = +_) * _, zoom) : Math.sqrt(clickDistance2);
16751   };
16752
16753   return zoom;
16754 }
16755
16756
16757
16758 var index$3 = Object.freeze({
16759         version: version,
16760         bisect: bisectRight,
16761         bisectRight: bisectRight,
16762         bisectLeft: bisectLeft,
16763         ascending: d3_ascending,
16764         bisector: d3_bisector,
16765         cross: cross,
16766         descending: d3_descending,
16767         deviation: deviation,
16768         extent: extent,
16769         histogram: histogram,
16770         thresholdFreedmanDiaconis: freedmanDiaconis,
16771         thresholdScott: scott,
16772         thresholdSturges: sturges,
16773         max: max,
16774         mean: mean,
16775         median: d3_median,
16776         merge: merge,
16777         min: min,
16778         pairs: pairs,
16779         permute: permute,
16780         quantile: threshold,
16781         range: d3_range,
16782         scan: scan,
16783         shuffle: shuffle,
16784         sum: sum,
16785         ticks: ticks,
16786         tickIncrement: tickIncrement,
16787         tickStep: tickStep,
16788         transpose: transpose,
16789         variance: variance,
16790         zip: zip,
16791         axisTop: axisTop,
16792         axisRight: axisRight,
16793         axisBottom: axisBottom,
16794         axisLeft: axisLeft,
16795         brush: brush,
16796         brushX: brushX,
16797         brushY: brushY,
16798         brushSelection: brushSelection,
16799         chord: chord,
16800         ribbon: ribbon,
16801         nest: nest,
16802         set: set$2,
16803         map: map$1,
16804         keys: keys,
16805         values: values,
16806         entries: entries,
16807         color: color,
16808         rgb: rgb,
16809         hsl: hsl,
16810         lab: lab,
16811         hcl: hcl,
16812         cubehelix: cubehelix,
16813         dispatch: dispatch,
16814         drag: drag,
16815         dragDisable: dragDisable,
16816         dragEnable: yesdrag,
16817         dsvFormat: dsv,
16818         csvParse: csvParse,
16819         csvParseRows: csvParseRows,
16820         csvFormat: csvFormat,
16821         csvFormatRows: csvFormatRows,
16822         tsvParse: tsvParse,
16823         tsvParseRows: tsvParseRows,
16824         tsvFormat: tsvFormat,
16825         tsvFormatRows: tsvFormatRows,
16826         easeLinear: linear$1,
16827         easeQuad: quadInOut,
16828         easeQuadIn: quadIn,
16829         easeQuadOut: quadOut,
16830         easeQuadInOut: quadInOut,
16831         easeCubic: cubicInOut,
16832         easeCubicIn: cubicIn,
16833         easeCubicOut: cubicOut,
16834         easeCubicInOut: cubicInOut,
16835         easePoly: polyInOut,
16836         easePolyIn: polyIn,
16837         easePolyOut: polyOut,
16838         easePolyInOut: polyInOut,
16839         easeSin: sinInOut,
16840         easeSinIn: sinIn,
16841         easeSinOut: sinOut,
16842         easeSinInOut: sinInOut,
16843         easeExp: expInOut,
16844         easeExpIn: expIn,
16845         easeExpOut: expOut,
16846         easeExpInOut: expInOut,
16847         easeCircle: circleInOut,
16848         easeCircleIn: circleIn,
16849         easeCircleOut: circleOut,
16850         easeCircleInOut: circleInOut,
16851         easeBounce: bounceOut,
16852         easeBounceIn: bounceIn,
16853         easeBounceOut: bounceOut,
16854         easeBounceInOut: bounceInOut,
16855         easeBack: backInOut,
16856         easeBackIn: backIn,
16857         easeBackOut: backOut,
16858         easeBackInOut: backInOut,
16859         easeElastic: elasticOut,
16860         easeElasticIn: elasticIn,
16861         easeElasticOut: elasticOut,
16862         easeElasticInOut: elasticInOut,
16863         forceCenter: center$1,
16864         forceCollide: collide,
16865         forceLink: link,
16866         forceManyBody: manyBody,
16867         forceRadial: radial,
16868         forceSimulation: simulation,
16869         forceX: x$2,
16870         forceY: y$2,
16871         formatDefaultLocale: defaultLocale,
16872         get format () { return format; },
16873         get formatPrefix () { return formatPrefix; },
16874         formatLocale: formatLocale,
16875         formatSpecifier: formatSpecifier,
16876         precisionFixed: precisionFixed,
16877         precisionPrefix: precisionPrefix,
16878         precisionRound: precisionRound,
16879         geoArea: d3_geoArea,
16880         geoBounds: d3_geoBounds,
16881         geoCentroid: d3_geoCentroid,
16882         geoCircle: circle,
16883         geoClipAntimeridian: clipAntimeridian,
16884         geoClipCircle: clipCircle,
16885         geoClipExtent: extent$1,
16886         geoClipRectangle: clipRectangle,
16887         geoContains: contains,
16888         geoDistance: distance,
16889         geoGraticule: graticule,
16890         geoGraticule10: graticule10,
16891         geoInterpolate: interpolate$1,
16892         geoLength: d3_geoLength,
16893         geoPath: d3_geoPath,
16894         geoAlbers: albers,
16895         geoAlbersUsa: albersUsa,
16896         geoAzimuthalEqualArea: azimuthalEqualArea,
16897         geoAzimuthalEqualAreaRaw: azimuthalEqualAreaRaw,
16898         geoAzimuthalEquidistant: azimuthalEquidistant,
16899         geoAzimuthalEquidistantRaw: azimuthalEquidistantRaw,
16900         geoConicConformal: conicConformal,
16901         geoConicConformalRaw: conicConformalRaw,
16902         geoConicEqualArea: conicEqualArea,
16903         geoConicEqualAreaRaw: conicEqualAreaRaw,
16904         geoConicEquidistant: conicEquidistant,
16905         geoConicEquidistantRaw: conicEquidistantRaw,
16906         geoEquirectangular: equirectangular,
16907         geoEquirectangularRaw: equirectangularRaw,
16908         geoGnomonic: gnomonic,
16909         geoGnomonicRaw: gnomonicRaw,
16910         geoIdentity: d3_geoIdentity,
16911         geoProjection: projection,
16912         geoProjectionMutator: projectionMutator,
16913         geoMercator: mercator,
16914         geoMercatorRaw: mercatorRaw,
16915         geoNaturalEarth1: naturalEarth1,
16916         geoNaturalEarth1Raw: naturalEarth1Raw,
16917         geoOrthographic: orthographic,
16918         geoOrthographicRaw: orthographicRaw,
16919         geoStereographic: stereographic,
16920         geoStereographicRaw: stereographicRaw,
16921         geoTransverseMercator: transverseMercator,
16922         geoTransverseMercatorRaw: transverseMercatorRaw,
16923         geoRotation: rotation,
16924         geoStream: d3_geoStream,
16925         geoTransform: d3_geoTransform,
16926         cluster: cluster,
16927         hierarchy: hierarchy,
16928         pack: index$1,
16929         packSiblings: siblings,
16930         packEnclose: enclose,
16931         partition: partition,
16932         stratify: stratify,
16933         tree: tree,
16934         treemap: index$2,
16935         treemapBinary: binary,
16936         treemapDice: treemapDice,
16937         treemapSlice: treemapSlice,
16938         treemapSliceDice: sliceDice,
16939         treemapSquarify: squarify,
16940         treemapResquarify: resquarify,
16941         interpolate: d3_interpolate,
16942         interpolateArray: array$1,
16943         interpolateBasis: basis$1,
16944         interpolateBasisClosed: basisClosed,
16945         interpolateDate: date,
16946         interpolateNumber: d3_interpolateNumber,
16947         interpolateObject: object,
16948         interpolateRound: interpolateRound,
16949         interpolateString: interpolateString,
16950         interpolateTransformCss: interpolateTransformCss,
16951         interpolateTransformSvg: interpolateTransformSvg,
16952         interpolateZoom: interpolateZoom,
16953         interpolateRgb: d3_interpolateRgb,
16954         interpolateRgbBasis: rgbBasis,
16955         interpolateRgbBasisClosed: rgbBasisClosed,
16956         interpolateHsl: hsl$2,
16957         interpolateHslLong: hslLong,
16958         interpolateLab: lab$1,
16959         interpolateHcl: hcl$2,
16960         interpolateHclLong: hclLong,
16961         interpolateCubehelix: cubehelix$2,
16962         interpolateCubehelixLong: cubehelixLong,
16963         quantize: d3_quantize,
16964         path: path,
16965         polygonArea: d3_polygonArea,
16966         polygonCentroid: d3_polygonCentroid,
16967         polygonHull: d3_polygonHull,
16968         polygonContains: contains$1,
16969         polygonLength: length$1,
16970         quadtree: quadtree,
16971         queue: queue,
16972         randomUniform: uniform,
16973         randomNormal: normal,
16974         randomLogNormal: logNormal,
16975         randomBates: bates,
16976         randomIrwinHall: irwinHall,
16977         randomExponential: exponential$1,
16978         request: d3_request,
16979         html: html,
16980         json: d3_json,
16981         text: d3_text,
16982         xml: d3_xml,
16983         csv: csv$1,
16984         tsv: tsv$1,
16985         scaleBand: band,
16986         scalePoint: point$1,
16987         scaleIdentity: identity$5,
16988         scaleLinear: linear$2,
16989         scaleLog: log$1,
16990         scaleOrdinal: ordinal,
16991         scaleImplicit: implicit,
16992         scalePow: pow$1,
16993         scaleSqrt: sqrt$1,
16994         scaleQuantile: quantile$$1,
16995         scaleQuantize: quantize,
16996         scaleThreshold: threshold$1,
16997         scaleTime: time,
16998         scaleUtc: utcTime,
16999         schemeCategory10: category10,
17000         schemeCategory20b: category20b,
17001         schemeCategory20c: category20c,
17002         schemeCategory20: category20,
17003         interpolateCubehelixDefault: cubehelix$3,
17004         interpolateRainbow: rainbow$1,
17005         interpolateWarm: warm,
17006         interpolateCool: cool,
17007         interpolateViridis: viridis,
17008         interpolateMagma: magma,
17009         interpolateInferno: inferno,
17010         interpolatePlasma: plasma,
17011         scaleSequential: sequential,
17012         creator: creator,
17013         local: local,
17014         matcher: matcher$1,
17015         mouse: d3_mouse,
17016         namespace: namespace,
17017         namespaces: namespaces,
17018         clientPoint: point,
17019         select: d3_select,
17020         selectAll: d3_selectAll,
17021         selection: selection,
17022         selector: selector,
17023         selectorAll: selectorAll,
17024         style: styleValue,
17025         touch: touch,
17026         touches: d3_touches,
17027         window: defaultView,
17028         get event () { return event; },
17029         customEvent: customEvent,
17030         arc: arc,
17031         area: area,
17032         line: line,
17033         pie: pie,
17034         areaRadial: areaRadial,
17035         radialArea: areaRadial,
17036         lineRadial: lineRadial$1,
17037         radialLine: lineRadial$1,
17038         pointRadial: pointRadial,
17039         linkHorizontal: linkHorizontal,
17040         linkVertical: linkVertical,
17041         linkRadial: linkRadial,
17042         symbol: symbol,
17043         symbols: symbols,
17044         symbolCircle: circle$2,
17045         symbolCross: cross$2,
17046         symbolDiamond: diamond,
17047         symbolSquare: square,
17048         symbolStar: star,
17049         symbolTriangle: triangle,
17050         symbolWye: wye,
17051         curveBasisClosed: basisClosed$1,
17052         curveBasisOpen: basisOpen,
17053         curveBasis: basis$2,
17054         curveBundle: bundle,
17055         curveCardinalClosed: cardinalClosed,
17056         curveCardinalOpen: cardinalOpen,
17057         curveCardinal: cardinal,
17058         curveCatmullRomClosed: catmullRomClosed,
17059         curveCatmullRomOpen: catmullRomOpen,
17060         curveCatmullRom: catmullRom,
17061         curveLinearClosed: linearClosed,
17062         curveLinear: curveLinear,
17063         curveMonotoneX: monotoneX,
17064         curveMonotoneY: monotoneY,
17065         curveNatural: natural,
17066         curveStep: step,
17067         curveStepAfter: stepAfter,
17068         curveStepBefore: stepBefore,
17069         stack: stack,
17070         stackOffsetExpand: expand,
17071         stackOffsetDiverging: diverging,
17072         stackOffsetNone: none$1,
17073         stackOffsetSilhouette: silhouette,
17074         stackOffsetWiggle: wiggle,
17075         stackOrderAscending: ascending$1,
17076         stackOrderDescending: descending$1,
17077         stackOrderInsideOut: insideOut,
17078         stackOrderNone: none$2,
17079         stackOrderReverse: reverse,
17080         timeInterval: newInterval,
17081         timeMillisecond: millisecond,
17082         timeMilliseconds: milliseconds,
17083         utcMillisecond: millisecond,
17084         utcMilliseconds: milliseconds,
17085         timeSecond: second,
17086         timeSeconds: seconds,
17087         utcSecond: second,
17088         utcSeconds: seconds,
17089         timeMinute: minute,
17090         timeMinutes: minutes,
17091         timeHour: hour,
17092         timeHours: hours,
17093         timeDay: day,
17094         timeDays: days,
17095         timeWeek: sunday,
17096         timeWeeks: sundays,
17097         timeSunday: sunday,
17098         timeSundays: sundays,
17099         timeMonday: monday,
17100         timeMondays: mondays,
17101         timeTuesday: tuesday,
17102         timeTuesdays: tuesdays,
17103         timeWednesday: wednesday,
17104         timeWednesdays: wednesdays,
17105         timeThursday: thursday,
17106         timeThursdays: thursdays,
17107         timeFriday: friday,
17108         timeFridays: fridays,
17109         timeSaturday: saturday,
17110         timeSaturdays: saturdays,
17111         timeMonth: month,
17112         timeMonths: months,
17113         timeYear: year,
17114         timeYears: years,
17115         utcMinute: utcMinute,
17116         utcMinutes: utcMinutes,
17117         utcHour: utcHour,
17118         utcHours: utcHours,
17119         utcDay: utcDay,
17120         utcDays: utcDays,
17121         utcWeek: utcSunday,
17122         utcWeeks: utcSundays,
17123         utcSunday: utcSunday,
17124         utcSundays: utcSundays,
17125         utcMonday: utcMonday,
17126         utcMondays: utcMondays,
17127         utcTuesday: utcTuesday,
17128         utcTuesdays: utcTuesdays,
17129         utcWednesday: utcWednesday,
17130         utcWednesdays: utcWednesdays,
17131         utcThursday: utcThursday,
17132         utcThursdays: utcThursdays,
17133         utcFriday: utcFriday,
17134         utcFridays: utcFridays,
17135         utcSaturday: utcSaturday,
17136         utcSaturdays: utcSaturdays,
17137         utcMonth: utcMonth,
17138         utcMonths: utcMonths,
17139         utcYear: utcYear,
17140         utcYears: utcYears,
17141         timeFormatDefaultLocale: defaultLocale$1,
17142         get timeFormat () { return timeFormat; },
17143         get timeParse () { return timeParse; },
17144         get utcFormat () { return utcFormat; },
17145         get utcParse () { return utcParse; },
17146         timeFormatLocale: formatLocale$1,
17147         isoFormat: formatIso,
17148         isoParse: parseIso,
17149         now: now,
17150         timer: timer,
17151         timerFlush: timerFlush,
17152         timeout: d3_timeout,
17153         interval: interval$1,
17154         transition: transition,
17155         active: active,
17156         interrupt: interrupt,
17157         voronoi: voronoi,
17158         zoom: d3_zoom,
17159         zoomTransform: transform,
17160         zoomIdentity: identity$7
17161 });
17162
17163 function actionAddEntity(way) {
17164     return function(graph) {
17165         return graph.replace(way);
17166     };
17167 }
17168
17169 /**
17170  * Removes all key-value entries from the list cache.
17171  *
17172  * @private
17173  * @name clear
17174  * @memberOf ListCache
17175  */
17176 function listCacheClear() {
17177   this.__data__ = [];
17178   this.size = 0;
17179 }
17180
17181 /**
17182  * Performs a
17183  * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
17184  * comparison between two values to determine if they are equivalent.
17185  *
17186  * @static
17187  * @memberOf _
17188  * @since 4.0.0
17189  * @category Lang
17190  * @param {*} value The value to compare.
17191  * @param {*} other The other value to compare.
17192  * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
17193  * @example
17194  *
17195  * var object = { 'a': 1 };
17196  * var other = { 'a': 1 };
17197  *
17198  * _.eq(object, object);
17199  * // => true
17200  *
17201  * _.eq(object, other);
17202  * // => false
17203  *
17204  * _.eq('a', 'a');
17205  * // => true
17206  *
17207  * _.eq('a', Object('a'));
17208  * // => false
17209  *
17210  * _.eq(NaN, NaN);
17211  * // => true
17212  */
17213 function eq(value, other) {
17214   return value === other || (value !== value && other !== other);
17215 }
17216
17217 /**
17218  * Gets the index at which the `key` is found in `array` of key-value pairs.
17219  *
17220  * @private
17221  * @param {Array} array The array to inspect.
17222  * @param {*} key The key to search for.
17223  * @returns {number} Returns the index of the matched value, else `-1`.
17224  */
17225 function assocIndexOf(array, key) {
17226   var length = array.length;
17227   while (length--) {
17228     if (eq(array[length][0], key)) {
17229       return length;
17230     }
17231   }
17232   return -1;
17233 }
17234
17235 /** Used for built-in method references. */
17236 var arrayProto = Array.prototype;
17237
17238 /** Built-in value references. */
17239 var splice = arrayProto.splice;
17240
17241 /**
17242  * Removes `key` and its value from the list cache.
17243  *
17244  * @private
17245  * @name delete
17246  * @memberOf ListCache
17247  * @param {string} key The key of the value to remove.
17248  * @returns {boolean} Returns `true` if the entry was removed, else `false`.
17249  */
17250 function listCacheDelete(key) {
17251   var data = this.__data__,
17252       index = assocIndexOf(data, key);
17253
17254   if (index < 0) {
17255     return false;
17256   }
17257   var lastIndex = data.length - 1;
17258   if (index == lastIndex) {
17259     data.pop();
17260   } else {
17261     splice.call(data, index, 1);
17262   }
17263   --this.size;
17264   return true;
17265 }
17266
17267 /**
17268  * Gets the list cache value for `key`.
17269  *
17270  * @private
17271  * @name get
17272  * @memberOf ListCache
17273  * @param {string} key The key of the value to get.
17274  * @returns {*} Returns the entry value.
17275  */
17276 function listCacheGet(key) {
17277   var data = this.__data__,
17278       index = assocIndexOf(data, key);
17279
17280   return index < 0 ? undefined : data[index][1];
17281 }
17282
17283 /**
17284  * Checks if a list cache value for `key` exists.
17285  *
17286  * @private
17287  * @name has
17288  * @memberOf ListCache
17289  * @param {string} key The key of the entry to check.
17290  * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
17291  */
17292 function listCacheHas(key) {
17293   return assocIndexOf(this.__data__, key) > -1;
17294 }
17295
17296 /**
17297  * Sets the list cache `key` to `value`.
17298  *
17299  * @private
17300  * @name set
17301  * @memberOf ListCache
17302  * @param {string} key The key of the value to set.
17303  * @param {*} value The value to set.
17304  * @returns {Object} Returns the list cache instance.
17305  */
17306 function listCacheSet(key, value) {
17307   var data = this.__data__,
17308       index = assocIndexOf(data, key);
17309
17310   if (index < 0) {
17311     ++this.size;
17312     data.push([key, value]);
17313   } else {
17314     data[index][1] = value;
17315   }
17316   return this;
17317 }
17318
17319 /**
17320  * Creates an list cache object.
17321  *
17322  * @private
17323  * @constructor
17324  * @param {Array} [entries] The key-value pairs to cache.
17325  */
17326 function ListCache(entries) {
17327   var index = -1,
17328       length = entries == null ? 0 : entries.length;
17329
17330   this.clear();
17331   while (++index < length) {
17332     var entry = entries[index];
17333     this.set(entry[0], entry[1]);
17334   }
17335 }
17336
17337 // Add methods to `ListCache`.
17338 ListCache.prototype.clear = listCacheClear;
17339 ListCache.prototype['delete'] = listCacheDelete;
17340 ListCache.prototype.get = listCacheGet;
17341 ListCache.prototype.has = listCacheHas;
17342 ListCache.prototype.set = listCacheSet;
17343
17344 /**
17345  * Removes all key-value entries from the stack.
17346  *
17347  * @private
17348  * @name clear
17349  * @memberOf Stack
17350  */
17351 function stackClear() {
17352   this.__data__ = new ListCache;
17353   this.size = 0;
17354 }
17355
17356 /**
17357  * Removes `key` and its value from the stack.
17358  *
17359  * @private
17360  * @name delete
17361  * @memberOf Stack
17362  * @param {string} key The key of the value to remove.
17363  * @returns {boolean} Returns `true` if the entry was removed, else `false`.
17364  */
17365 function stackDelete(key) {
17366   var data = this.__data__,
17367       result = data['delete'](key);
17368
17369   this.size = data.size;
17370   return result;
17371 }
17372
17373 /**
17374  * Gets the stack value for `key`.
17375  *
17376  * @private
17377  * @name get
17378  * @memberOf Stack
17379  * @param {string} key The key of the value to get.
17380  * @returns {*} Returns the entry value.
17381  */
17382 function stackGet(key) {
17383   return this.__data__.get(key);
17384 }
17385
17386 /**
17387  * Checks if a stack value for `key` exists.
17388  *
17389  * @private
17390  * @name has
17391  * @memberOf Stack
17392  * @param {string} key The key of the entry to check.
17393  * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
17394  */
17395 function stackHas(key) {
17396   return this.__data__.has(key);
17397 }
17398
17399 /** Detect free variable `global` from Node.js. */
17400 var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
17401
17402 /** Detect free variable `self`. */
17403 var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
17404
17405 /** Used as a reference to the global object. */
17406 var root$2 = freeGlobal || freeSelf || Function('return this')();
17407
17408 /** Built-in value references. */
17409 var Symbol = root$2.Symbol;
17410
17411 /** Used for built-in method references. */
17412 var objectProto = Object.prototype;
17413
17414 /** Used to check objects for own properties. */
17415 var hasOwnProperty = objectProto.hasOwnProperty;
17416
17417 /**
17418  * Used to resolve the
17419  * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
17420  * of values.
17421  */
17422 var nativeObjectToString = objectProto.toString;
17423
17424 /** Built-in value references. */
17425 var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
17426
17427 /**
17428  * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
17429  *
17430  * @private
17431  * @param {*} value The value to query.
17432  * @returns {string} Returns the raw `toStringTag`.
17433  */
17434 function getRawTag(value) {
17435   var isOwn = hasOwnProperty.call(value, symToStringTag),
17436       tag = value[symToStringTag];
17437
17438   try {
17439     value[symToStringTag] = undefined;
17440     var unmasked = true;
17441   } catch (e) {}
17442
17443   var result = nativeObjectToString.call(value);
17444   if (unmasked) {
17445     if (isOwn) {
17446       value[symToStringTag] = tag;
17447     } else {
17448       delete value[symToStringTag];
17449     }
17450   }
17451   return result;
17452 }
17453
17454 /** Used for built-in method references. */
17455 var objectProto$1 = Object.prototype;
17456
17457 /**
17458  * Used to resolve the
17459  * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
17460  * of values.
17461  */
17462 var nativeObjectToString$1 = objectProto$1.toString;
17463
17464 /**
17465  * Converts `value` to a string using `Object.prototype.toString`.
17466  *
17467  * @private
17468  * @param {*} value The value to convert.
17469  * @returns {string} Returns the converted string.
17470  */
17471 function objectToString(value) {
17472   return nativeObjectToString$1.call(value);
17473 }
17474
17475 /** `Object#toString` result references. */
17476 var nullTag = '[object Null]';
17477 var undefinedTag = '[object Undefined]';
17478
17479 /** Built-in value references. */
17480 var symToStringTag$1 = Symbol ? Symbol.toStringTag : undefined;
17481
17482 /**
17483  * The base implementation of `getTag` without fallbacks for buggy environments.
17484  *
17485  * @private
17486  * @param {*} value The value to query.
17487  * @returns {string} Returns the `toStringTag`.
17488  */
17489 function baseGetTag(value) {
17490   if (value == null) {
17491     return value === undefined ? undefinedTag : nullTag;
17492   }
17493   return (symToStringTag$1 && symToStringTag$1 in Object(value))
17494     ? getRawTag(value)
17495     : objectToString(value);
17496 }
17497
17498 /**
17499  * Checks if `value` is the
17500  * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
17501  * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
17502  *
17503  * @static
17504  * @memberOf _
17505  * @since 0.1.0
17506  * @category Lang
17507  * @param {*} value The value to check.
17508  * @returns {boolean} Returns `true` if `value` is an object, else `false`.
17509  * @example
17510  *
17511  * _.isObject({});
17512  * // => true
17513  *
17514  * _.isObject([1, 2, 3]);
17515  * // => true
17516  *
17517  * _.isObject(_.noop);
17518  * // => true
17519  *
17520  * _.isObject(null);
17521  * // => false
17522  */
17523 function isObject(value) {
17524   var type = typeof value;
17525   return value != null && (type == 'object' || type == 'function');
17526 }
17527
17528 /** `Object#toString` result references. */
17529 var asyncTag = '[object AsyncFunction]';
17530 var funcTag = '[object Function]';
17531 var genTag = '[object GeneratorFunction]';
17532 var proxyTag = '[object Proxy]';
17533
17534 /**
17535  * Checks if `value` is classified as a `Function` object.
17536  *
17537  * @static
17538  * @memberOf _
17539  * @since 0.1.0
17540  * @category Lang
17541  * @param {*} value The value to check.
17542  * @returns {boolean} Returns `true` if `value` is a function, else `false`.
17543  * @example
17544  *
17545  * _.isFunction(_);
17546  * // => true
17547  *
17548  * _.isFunction(/abc/);
17549  * // => false
17550  */
17551 function isFunction(value) {
17552   if (!isObject(value)) {
17553     return false;
17554   }
17555   // The use of `Object#toString` avoids issues with the `typeof` operator
17556   // in Safari 9 which returns 'object' for typed arrays and other constructors.
17557   var tag = baseGetTag(value);
17558   return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
17559 }
17560
17561 /** Used to detect overreaching core-js shims. */
17562 var coreJsData = root$2['__core-js_shared__'];
17563
17564 /** Used to detect methods masquerading as native. */
17565 var maskSrcKey = (function() {
17566   var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
17567   return uid ? ('Symbol(src)_1.' + uid) : '';
17568 }());
17569
17570 /**
17571  * Checks if `func` has its source masked.
17572  *
17573  * @private
17574  * @param {Function} func The function to check.
17575  * @returns {boolean} Returns `true` if `func` is masked, else `false`.
17576  */
17577 function isMasked(func) {
17578   return !!maskSrcKey && (maskSrcKey in func);
17579 }
17580
17581 /** Used for built-in method references. */
17582 var funcProto = Function.prototype;
17583
17584 /** Used to resolve the decompiled source of functions. */
17585 var funcToString = funcProto.toString;
17586
17587 /**
17588  * Converts `func` to its source code.
17589  *
17590  * @private
17591  * @param {Function} func The function to convert.
17592  * @returns {string} Returns the source code.
17593  */
17594 function toSource(func) {
17595   if (func != null) {
17596     try {
17597       return funcToString.call(func);
17598     } catch (e) {}
17599     try {
17600       return (func + '');
17601     } catch (e) {}
17602   }
17603   return '';
17604 }
17605
17606 /**
17607  * Used to match `RegExp`
17608  * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
17609  */
17610 var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
17611
17612 /** Used to detect host constructors (Safari). */
17613 var reIsHostCtor = /^\[object .+?Constructor\]$/;
17614
17615 /** Used for built-in method references. */
17616 var funcProto$1 = Function.prototype;
17617 var objectProto$2 = Object.prototype;
17618
17619 /** Used to resolve the decompiled source of functions. */
17620 var funcToString$1 = funcProto$1.toString;
17621
17622 /** Used to check objects for own properties. */
17623 var hasOwnProperty$1 = objectProto$2.hasOwnProperty;
17624
17625 /** Used to detect if a method is native. */
17626 var reIsNative = RegExp('^' +
17627   funcToString$1.call(hasOwnProperty$1).replace(reRegExpChar, '\\$&')
17628   .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
17629 );
17630
17631 /**
17632  * The base implementation of `_.isNative` without bad shim checks.
17633  *
17634  * @private
17635  * @param {*} value The value to check.
17636  * @returns {boolean} Returns `true` if `value` is a native function,
17637  *  else `false`.
17638  */
17639 function baseIsNative(value) {
17640   if (!isObject(value) || isMasked(value)) {
17641     return false;
17642   }
17643   var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
17644   return pattern.test(toSource(value));
17645 }
17646
17647 /**
17648  * Gets the value at `key` of `object`.
17649  *
17650  * @private
17651  * @param {Object} [object] The object to query.
17652  * @param {string} key The key of the property to get.
17653  * @returns {*} Returns the property value.
17654  */
17655 function getValue(object, key) {
17656   return object == null ? undefined : object[key];
17657 }
17658
17659 /**
17660  * Gets the native function at `key` of `object`.
17661  *
17662  * @private
17663  * @param {Object} object The object to query.
17664  * @param {string} key The key of the method to get.
17665  * @returns {*} Returns the function if it's native, else `undefined`.
17666  */
17667 function getNative(object, key) {
17668   var value = getValue(object, key);
17669   return baseIsNative(value) ? value : undefined;
17670 }
17671
17672 /* Built-in method references that are verified to be native. */
17673 var Map$1 = getNative(root$2, 'Map');
17674
17675 /* Built-in method references that are verified to be native. */
17676 var nativeCreate = getNative(Object, 'create');
17677
17678 /**
17679  * Removes all key-value entries from the hash.
17680  *
17681  * @private
17682  * @name clear
17683  * @memberOf Hash
17684  */
17685 function hashClear() {
17686   this.__data__ = nativeCreate ? nativeCreate(null) : {};
17687   this.size = 0;
17688 }
17689
17690 /**
17691  * Removes `key` and its value from the hash.
17692  *
17693  * @private
17694  * @name delete
17695  * @memberOf Hash
17696  * @param {Object} hash The hash to modify.
17697  * @param {string} key The key of the value to remove.
17698  * @returns {boolean} Returns `true` if the entry was removed, else `false`.
17699  */
17700 function hashDelete(key) {
17701   var result = this.has(key) && delete this.__data__[key];
17702   this.size -= result ? 1 : 0;
17703   return result;
17704 }
17705
17706 /** Used to stand-in for `undefined` hash values. */
17707 var HASH_UNDEFINED = '__lodash_hash_undefined__';
17708
17709 /** Used for built-in method references. */
17710 var objectProto$3 = Object.prototype;
17711
17712 /** Used to check objects for own properties. */
17713 var hasOwnProperty$2 = objectProto$3.hasOwnProperty;
17714
17715 /**
17716  * Gets the hash value for `key`.
17717  *
17718  * @private
17719  * @name get
17720  * @memberOf Hash
17721  * @param {string} key The key of the value to get.
17722  * @returns {*} Returns the entry value.
17723  */
17724 function hashGet(key) {
17725   var data = this.__data__;
17726   if (nativeCreate) {
17727     var result = data[key];
17728     return result === HASH_UNDEFINED ? undefined : result;
17729   }
17730   return hasOwnProperty$2.call(data, key) ? data[key] : undefined;
17731 }
17732
17733 /** Used for built-in method references. */
17734 var objectProto$4 = Object.prototype;
17735
17736 /** Used to check objects for own properties. */
17737 var hasOwnProperty$3 = objectProto$4.hasOwnProperty;
17738
17739 /**
17740  * Checks if a hash value for `key` exists.
17741  *
17742  * @private
17743  * @name has
17744  * @memberOf Hash
17745  * @param {string} key The key of the entry to check.
17746  * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
17747  */
17748 function hashHas(key) {
17749   var data = this.__data__;
17750   return nativeCreate ? (data[key] !== undefined) : hasOwnProperty$3.call(data, key);
17751 }
17752
17753 /** Used to stand-in for `undefined` hash values. */
17754 var HASH_UNDEFINED$1 = '__lodash_hash_undefined__';
17755
17756 /**
17757  * Sets the hash `key` to `value`.
17758  *
17759  * @private
17760  * @name set
17761  * @memberOf Hash
17762  * @param {string} key The key of the value to set.
17763  * @param {*} value The value to set.
17764  * @returns {Object} Returns the hash instance.
17765  */
17766 function hashSet(key, value) {
17767   var data = this.__data__;
17768   this.size += this.has(key) ? 0 : 1;
17769   data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED$1 : value;
17770   return this;
17771 }
17772
17773 /**
17774  * Creates a hash object.
17775  *
17776  * @private
17777  * @constructor
17778  * @param {Array} [entries] The key-value pairs to cache.
17779  */
17780 function Hash(entries) {
17781   var index = -1,
17782       length = entries == null ? 0 : entries.length;
17783
17784   this.clear();
17785   while (++index < length) {
17786     var entry = entries[index];
17787     this.set(entry[0], entry[1]);
17788   }
17789 }
17790
17791 // Add methods to `Hash`.
17792 Hash.prototype.clear = hashClear;
17793 Hash.prototype['delete'] = hashDelete;
17794 Hash.prototype.get = hashGet;
17795 Hash.prototype.has = hashHas;
17796 Hash.prototype.set = hashSet;
17797
17798 /**
17799  * Removes all key-value entries from the map.
17800  *
17801  * @private
17802  * @name clear
17803  * @memberOf MapCache
17804  */
17805 function mapCacheClear() {
17806   this.size = 0;
17807   this.__data__ = {
17808     'hash': new Hash,
17809     'map': new (Map$1 || ListCache),
17810     'string': new Hash
17811   };
17812 }
17813
17814 /**
17815  * Checks if `value` is suitable for use as unique object key.
17816  *
17817  * @private
17818  * @param {*} value The value to check.
17819  * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
17820  */
17821 function isKeyable(value) {
17822   var type = typeof value;
17823   return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
17824     ? (value !== '__proto__')
17825     : (value === null);
17826 }
17827
17828 /**
17829  * Gets the data for `map`.
17830  *
17831  * @private
17832  * @param {Object} map The map to query.
17833  * @param {string} key The reference key.
17834  * @returns {*} Returns the map data.
17835  */
17836 function getMapData(map, key) {
17837   var data = map.__data__;
17838   return isKeyable(key)
17839     ? data[typeof key == 'string' ? 'string' : 'hash']
17840     : data.map;
17841 }
17842
17843 /**
17844  * Removes `key` and its value from the map.
17845  *
17846  * @private
17847  * @name delete
17848  * @memberOf MapCache
17849  * @param {string} key The key of the value to remove.
17850  * @returns {boolean} Returns `true` if the entry was removed, else `false`.
17851  */
17852 function mapCacheDelete(key) {
17853   var result = getMapData(this, key)['delete'](key);
17854   this.size -= result ? 1 : 0;
17855   return result;
17856 }
17857
17858 /**
17859  * Gets the map value for `key`.
17860  *
17861  * @private
17862  * @name get
17863  * @memberOf MapCache
17864  * @param {string} key The key of the value to get.
17865  * @returns {*} Returns the entry value.
17866  */
17867 function mapCacheGet(key) {
17868   return getMapData(this, key).get(key);
17869 }
17870
17871 /**
17872  * Checks if a map value for `key` exists.
17873  *
17874  * @private
17875  * @name has
17876  * @memberOf MapCache
17877  * @param {string} key The key of the entry to check.
17878  * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
17879  */
17880 function mapCacheHas(key) {
17881   return getMapData(this, key).has(key);
17882 }
17883
17884 /**
17885  * Sets the map `key` to `value`.
17886  *
17887  * @private
17888  * @name set
17889  * @memberOf MapCache
17890  * @param {string} key The key of the value to set.
17891  * @param {*} value The value to set.
17892  * @returns {Object} Returns the map cache instance.
17893  */
17894 function mapCacheSet(key, value) {
17895   var data = getMapData(this, key),
17896       size = data.size;
17897
17898   data.set(key, value);
17899   this.size += data.size == size ? 0 : 1;
17900   return this;
17901 }
17902
17903 /**
17904  * Creates a map cache object to store key-value pairs.
17905  *
17906  * @private
17907  * @constructor
17908  * @param {Array} [entries] The key-value pairs to cache.
17909  */
17910 function MapCache(entries) {
17911   var index = -1,
17912       length = entries == null ? 0 : entries.length;
17913
17914   this.clear();
17915   while (++index < length) {
17916     var entry = entries[index];
17917     this.set(entry[0], entry[1]);
17918   }
17919 }
17920
17921 // Add methods to `MapCache`.
17922 MapCache.prototype.clear = mapCacheClear;
17923 MapCache.prototype['delete'] = mapCacheDelete;
17924 MapCache.prototype.get = mapCacheGet;
17925 MapCache.prototype.has = mapCacheHas;
17926 MapCache.prototype.set = mapCacheSet;
17927
17928 /** Used as the size to enable large array optimizations. */
17929 var LARGE_ARRAY_SIZE = 200;
17930
17931 /**
17932  * Sets the stack `key` to `value`.
17933  *
17934  * @private
17935  * @name set
17936  * @memberOf Stack
17937  * @param {string} key The key of the value to set.
17938  * @param {*} value The value to set.
17939  * @returns {Object} Returns the stack cache instance.
17940  */
17941 function stackSet(key, value) {
17942   var data = this.__data__;
17943   if (data instanceof ListCache) {
17944     var pairs = data.__data__;
17945     if (!Map$1 || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
17946       pairs.push([key, value]);
17947       this.size = ++data.size;
17948       return this;
17949     }
17950     data = this.__data__ = new MapCache(pairs);
17951   }
17952   data.set(key, value);
17953   this.size = data.size;
17954   return this;
17955 }
17956
17957 /**
17958  * Creates a stack cache object to store key-value pairs.
17959  *
17960  * @private
17961  * @constructor
17962  * @param {Array} [entries] The key-value pairs to cache.
17963  */
17964 function Stack(entries) {
17965   var data = this.__data__ = new ListCache(entries);
17966   this.size = data.size;
17967 }
17968
17969 // Add methods to `Stack`.
17970 Stack.prototype.clear = stackClear;
17971 Stack.prototype['delete'] = stackDelete;
17972 Stack.prototype.get = stackGet;
17973 Stack.prototype.has = stackHas;
17974 Stack.prototype.set = stackSet;
17975
17976 /**
17977  * A specialized version of `_.forEach` for arrays without support for
17978  * iteratee shorthands.
17979  *
17980  * @private
17981  * @param {Array} [array] The array to iterate over.
17982  * @param {Function} iteratee The function invoked per iteration.
17983  * @returns {Array} Returns `array`.
17984  */
17985 function arrayEach(array, iteratee) {
17986   var index = -1,
17987       length = array == null ? 0 : array.length;
17988
17989   while (++index < length) {
17990     if (iteratee(array[index], index, array) === false) {
17991       break;
17992     }
17993   }
17994   return array;
17995 }
17996
17997 var defineProperty = (function() {
17998   try {
17999     var func = getNative(Object, 'defineProperty');
18000     func({}, '', {});
18001     return func;
18002   } catch (e) {}
18003 }());
18004
18005 /**
18006  * The base implementation of `assignValue` and `assignMergeValue` without
18007  * value checks.
18008  *
18009  * @private
18010  * @param {Object} object The object to modify.
18011  * @param {string} key The key of the property to assign.
18012  * @param {*} value The value to assign.
18013  */
18014 function baseAssignValue(object, key, value) {
18015   if (key == '__proto__' && defineProperty) {
18016     defineProperty(object, key, {
18017       'configurable': true,
18018       'enumerable': true,
18019       'value': value,
18020       'writable': true
18021     });
18022   } else {
18023     object[key] = value;
18024   }
18025 }
18026
18027 /** Used for built-in method references. */
18028 var objectProto$5 = Object.prototype;
18029
18030 /** Used to check objects for own properties. */
18031 var hasOwnProperty$4 = objectProto$5.hasOwnProperty;
18032
18033 /**
18034  * Assigns `value` to `key` of `object` if the existing value is not equivalent
18035  * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
18036  * for equality comparisons.
18037  *
18038  * @private
18039  * @param {Object} object The object to modify.
18040  * @param {string} key The key of the property to assign.
18041  * @param {*} value The value to assign.
18042  */
18043 function assignValue(object, key, value) {
18044   var objValue = object[key];
18045   if (!(hasOwnProperty$4.call(object, key) && eq(objValue, value)) ||
18046       (value === undefined && !(key in object))) {
18047     baseAssignValue(object, key, value);
18048   }
18049 }
18050
18051 /**
18052  * Copies properties of `source` to `object`.
18053  *
18054  * @private
18055  * @param {Object} source The object to copy properties from.
18056  * @param {Array} props The property identifiers to copy.
18057  * @param {Object} [object={}] The object to copy properties to.
18058  * @param {Function} [customizer] The function to customize copied values.
18059  * @returns {Object} Returns `object`.
18060  */
18061 function copyObject(source, props, object, customizer) {
18062   var isNew = !object;
18063   object || (object = {});
18064
18065   var index = -1,
18066       length = props.length;
18067
18068   while (++index < length) {
18069     var key = props[index];
18070
18071     var newValue = customizer
18072       ? customizer(object[key], source[key], key, object, source)
18073       : undefined;
18074
18075     if (newValue === undefined) {
18076       newValue = source[key];
18077     }
18078     if (isNew) {
18079       baseAssignValue(object, key, newValue);
18080     } else {
18081       assignValue(object, key, newValue);
18082     }
18083   }
18084   return object;
18085 }
18086
18087 /**
18088  * The base implementation of `_.times` without support for iteratee shorthands
18089  * or max array length checks.
18090  *
18091  * @private
18092  * @param {number} n The number of times to invoke `iteratee`.
18093  * @param {Function} iteratee The function invoked per iteration.
18094  * @returns {Array} Returns the array of results.
18095  */
18096 function baseTimes(n, iteratee) {
18097   var index = -1,
18098       result = Array(n);
18099
18100   while (++index < n) {
18101     result[index] = iteratee(index);
18102   }
18103   return result;
18104 }
18105
18106 /**
18107  * Checks if `value` is object-like. A value is object-like if it's not `null`
18108  * and has a `typeof` result of "object".
18109  *
18110  * @static
18111  * @memberOf _
18112  * @since 4.0.0
18113  * @category Lang
18114  * @param {*} value The value to check.
18115  * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
18116  * @example
18117  *
18118  * _.isObjectLike({});
18119  * // => true
18120  *
18121  * _.isObjectLike([1, 2, 3]);
18122  * // => true
18123  *
18124  * _.isObjectLike(_.noop);
18125  * // => false
18126  *
18127  * _.isObjectLike(null);
18128  * // => false
18129  */
18130 function isObjectLike(value) {
18131   return value != null && typeof value == 'object';
18132 }
18133
18134 /** `Object#toString` result references. */
18135 var argsTag = '[object Arguments]';
18136
18137 /**
18138  * The base implementation of `_.isArguments`.
18139  *
18140  * @private
18141  * @param {*} value The value to check.
18142  * @returns {boolean} Returns `true` if `value` is an `arguments` object,
18143  */
18144 function baseIsArguments(value) {
18145   return isObjectLike(value) && baseGetTag(value) == argsTag;
18146 }
18147
18148 /** Used for built-in method references. */
18149 var objectProto$6 = Object.prototype;
18150
18151 /** Used to check objects for own properties. */
18152 var hasOwnProperty$5 = objectProto$6.hasOwnProperty;
18153
18154 /** Built-in value references. */
18155 var propertyIsEnumerable = objectProto$6.propertyIsEnumerable;
18156
18157 /**
18158  * Checks if `value` is likely an `arguments` object.
18159  *
18160  * @static
18161  * @memberOf _
18162  * @since 0.1.0
18163  * @category Lang
18164  * @param {*} value The value to check.
18165  * @returns {boolean} Returns `true` if `value` is an `arguments` object,
18166  *  else `false`.
18167  * @example
18168  *
18169  * _.isArguments(function() { return arguments; }());
18170  * // => true
18171  *
18172  * _.isArguments([1, 2, 3]);
18173  * // => false
18174  */
18175 var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
18176   return isObjectLike(value) && hasOwnProperty$5.call(value, 'callee') &&
18177     !propertyIsEnumerable.call(value, 'callee');
18178 };
18179
18180 /**
18181  * Checks if `value` is classified as an `Array` object.
18182  *
18183  * @static
18184  * @memberOf _
18185  * @since 0.1.0
18186  * @category Lang
18187  * @param {*} value The value to check.
18188  * @returns {boolean} Returns `true` if `value` is an array, else `false`.
18189  * @example
18190  *
18191  * _.isArray([1, 2, 3]);
18192  * // => true
18193  *
18194  * _.isArray(document.body.children);
18195  * // => false
18196  *
18197  * _.isArray('abc');
18198  * // => false
18199  *
18200  * _.isArray(_.noop);
18201  * // => false
18202  */
18203 var isArray = Array.isArray;
18204
18205 /**
18206  * This method returns `false`.
18207  *
18208  * @static
18209  * @memberOf _
18210  * @since 4.13.0
18211  * @category Util
18212  * @returns {boolean} Returns `false`.
18213  * @example
18214  *
18215  * _.times(2, _.stubFalse);
18216  * // => [false, false]
18217  */
18218 function stubFalse() {
18219   return false;
18220 }
18221
18222 /** Detect free variable `exports`. */
18223 var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
18224
18225 /** Detect free variable `module`. */
18226 var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
18227
18228 /** Detect the popular CommonJS extension `module.exports`. */
18229 var moduleExports = freeModule && freeModule.exports === freeExports;
18230
18231 /** Built-in value references. */
18232 var Buffer = moduleExports ? root$2.Buffer : undefined;
18233
18234 /* Built-in method references for those with the same name as other `lodash` methods. */
18235 var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;
18236
18237 /**
18238  * Checks if `value` is a buffer.
18239  *
18240  * @static
18241  * @memberOf _
18242  * @since 4.3.0
18243  * @category Lang
18244  * @param {*} value The value to check.
18245  * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
18246  * @example
18247  *
18248  * _.isBuffer(new Buffer(2));
18249  * // => true
18250  *
18251  * _.isBuffer(new Uint8Array(2));
18252  * // => false
18253  */
18254 var isBuffer = nativeIsBuffer || stubFalse;
18255
18256 /** Used as references for various `Number` constants. */
18257 var MAX_SAFE_INTEGER = 9007199254740991;
18258
18259 /** Used to detect unsigned integer values. */
18260 var reIsUint = /^(?:0|[1-9]\d*)$/;
18261
18262 /**
18263  * Checks if `value` is a valid array-like index.
18264  *
18265  * @private
18266  * @param {*} value The value to check.
18267  * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
18268  * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
18269  */
18270 function isIndex(value, length) {
18271   length = length == null ? MAX_SAFE_INTEGER : length;
18272   return !!length &&
18273     (typeof value == 'number' || reIsUint.test(value)) &&
18274     (value > -1 && value % 1 == 0 && value < length);
18275 }
18276
18277 /** Used as references for various `Number` constants. */
18278 var MAX_SAFE_INTEGER$1 = 9007199254740991;
18279
18280 /**
18281  * Checks if `value` is a valid array-like length.
18282  *
18283  * **Note:** This method is loosely based on
18284  * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
18285  *
18286  * @static
18287  * @memberOf _
18288  * @since 4.0.0
18289  * @category Lang
18290  * @param {*} value The value to check.
18291  * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
18292  * @example
18293  *
18294  * _.isLength(3);
18295  * // => true
18296  *
18297  * _.isLength(Number.MIN_VALUE);
18298  * // => false
18299  *
18300  * _.isLength(Infinity);
18301  * // => false
18302  *
18303  * _.isLength('3');
18304  * // => false
18305  */
18306 function isLength(value) {
18307   return typeof value == 'number' &&
18308     value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$1;
18309 }
18310
18311 /** `Object#toString` result references. */
18312 var argsTag$1 = '[object Arguments]';
18313 var arrayTag = '[object Array]';
18314 var boolTag = '[object Boolean]';
18315 var dateTag = '[object Date]';
18316 var errorTag = '[object Error]';
18317 var funcTag$1 = '[object Function]';
18318 var mapTag = '[object Map]';
18319 var numberTag = '[object Number]';
18320 var objectTag = '[object Object]';
18321 var regexpTag = '[object RegExp]';
18322 var setTag = '[object Set]';
18323 var stringTag = '[object String]';
18324 var weakMapTag = '[object WeakMap]';
18325
18326 var arrayBufferTag = '[object ArrayBuffer]';
18327 var dataViewTag = '[object DataView]';
18328 var float32Tag = '[object Float32Array]';
18329 var float64Tag = '[object Float64Array]';
18330 var int8Tag = '[object Int8Array]';
18331 var int16Tag = '[object Int16Array]';
18332 var int32Tag = '[object Int32Array]';
18333 var uint8Tag = '[object Uint8Array]';
18334 var uint8ClampedTag = '[object Uint8ClampedArray]';
18335 var uint16Tag = '[object Uint16Array]';
18336 var uint32Tag = '[object Uint32Array]';
18337
18338 /** Used to identify `toStringTag` values of typed arrays. */
18339 var typedArrayTags = {};
18340 typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
18341 typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
18342 typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
18343 typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
18344 typedArrayTags[uint32Tag] = true;
18345 typedArrayTags[argsTag$1] = typedArrayTags[arrayTag] =
18346 typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
18347 typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
18348 typedArrayTags[errorTag] = typedArrayTags[funcTag$1] =
18349 typedArrayTags[mapTag] = typedArrayTags[numberTag] =
18350 typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
18351 typedArrayTags[setTag] = typedArrayTags[stringTag] =
18352 typedArrayTags[weakMapTag] = false;
18353
18354 /**
18355  * The base implementation of `_.isTypedArray` without Node.js optimizations.
18356  *
18357  * @private
18358  * @param {*} value The value to check.
18359  * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
18360  */
18361 function baseIsTypedArray(value) {
18362   return isObjectLike(value) &&
18363     isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
18364 }
18365
18366 /**
18367  * The base implementation of `_.unary` without support for storing metadata.
18368  *
18369  * @private
18370  * @param {Function} func The function to cap arguments for.
18371  * @returns {Function} Returns the new capped function.
18372  */
18373 function baseUnary(func) {
18374   return function(value) {
18375     return func(value);
18376   };
18377 }
18378
18379 /** Detect free variable `exports`. */
18380 var freeExports$1 = typeof exports == 'object' && exports && !exports.nodeType && exports;
18381
18382 /** Detect free variable `module`. */
18383 var freeModule$1 = freeExports$1 && typeof module == 'object' && module && !module.nodeType && module;
18384
18385 /** Detect the popular CommonJS extension `module.exports`. */
18386 var moduleExports$1 = freeModule$1 && freeModule$1.exports === freeExports$1;
18387
18388 /** Detect free variable `process` from Node.js. */
18389 var freeProcess = moduleExports$1 && freeGlobal.process;
18390
18391 /** Used to access faster Node.js helpers. */
18392 var nodeUtil = (function() {
18393   try {
18394     return freeProcess && freeProcess.binding && freeProcess.binding('util');
18395   } catch (e) {}
18396 }());
18397
18398 /* Node.js helper references. */
18399 var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
18400
18401 /**
18402  * Checks if `value` is classified as a typed array.
18403  *
18404  * @static
18405  * @memberOf _
18406  * @since 3.0.0
18407  * @category Lang
18408  * @param {*} value The value to check.
18409  * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
18410  * @example
18411  *
18412  * _.isTypedArray(new Uint8Array);
18413  * // => true
18414  *
18415  * _.isTypedArray([]);
18416  * // => false
18417  */
18418 var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
18419
18420 /** Used for built-in method references. */
18421 var objectProto$7 = Object.prototype;
18422
18423 /** Used to check objects for own properties. */
18424 var hasOwnProperty$6 = objectProto$7.hasOwnProperty;
18425
18426 /**
18427  * Creates an array of the enumerable property names of the array-like `value`.
18428  *
18429  * @private
18430  * @param {*} value The value to query.
18431  * @param {boolean} inherited Specify returning inherited property names.
18432  * @returns {Array} Returns the array of property names.
18433  */
18434 function arrayLikeKeys(value, inherited) {
18435   var isArr = isArray(value),
18436       isArg = !isArr && isArguments(value),
18437       isBuff = !isArr && !isArg && isBuffer(value),
18438       isType = !isArr && !isArg && !isBuff && isTypedArray(value),
18439       skipIndexes = isArr || isArg || isBuff || isType,
18440       result = skipIndexes ? baseTimes(value.length, String) : [],
18441       length = result.length;
18442
18443   for (var key in value) {
18444     if ((inherited || hasOwnProperty$6.call(value, key)) &&
18445         !(skipIndexes && (
18446            // Safari 9 has enumerable `arguments.length` in strict mode.
18447            key == 'length' ||
18448            // Node.js 0.10 has enumerable non-index properties on buffers.
18449            (isBuff && (key == 'offset' || key == 'parent')) ||
18450            // PhantomJS 2 has enumerable non-index properties on typed arrays.
18451            (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
18452            // Skip index properties.
18453            isIndex(key, length)
18454         ))) {
18455       result.push(key);
18456     }
18457   }
18458   return result;
18459 }
18460
18461 /** Used for built-in method references. */
18462 var objectProto$8 = Object.prototype;
18463
18464 /**
18465  * Checks if `value` is likely a prototype object.
18466  *
18467  * @private
18468  * @param {*} value The value to check.
18469  * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
18470  */
18471 function isPrototype(value) {
18472   var Ctor = value && value.constructor,
18473       proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$8;
18474
18475   return value === proto;
18476 }
18477
18478 /**
18479  * Creates a unary function that invokes `func` with its argument transformed.
18480  *
18481  * @private
18482  * @param {Function} func The function to wrap.
18483  * @param {Function} transform The argument transform.
18484  * @returns {Function} Returns the new function.
18485  */
18486 function overArg(func, transform) {
18487   return function(arg) {
18488     return func(transform(arg));
18489   };
18490 }
18491
18492 /* Built-in method references for those with the same name as other `lodash` methods. */
18493 var nativeKeys = overArg(Object.keys, Object);
18494
18495 /** Used for built-in method references. */
18496 var objectProto$9 = Object.prototype;
18497
18498 /** Used to check objects for own properties. */
18499 var hasOwnProperty$7 = objectProto$9.hasOwnProperty;
18500
18501 /**
18502  * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
18503  *
18504  * @private
18505  * @param {Object} object The object to query.
18506  * @returns {Array} Returns the array of property names.
18507  */
18508 function baseKeys(object) {
18509   if (!isPrototype(object)) {
18510     return nativeKeys(object);
18511   }
18512   var result = [];
18513   for (var key in Object(object)) {
18514     if (hasOwnProperty$7.call(object, key) && key != 'constructor') {
18515       result.push(key);
18516     }
18517   }
18518   return result;
18519 }
18520
18521 /**
18522  * Checks if `value` is array-like. A value is considered array-like if it's
18523  * not a function and has a `value.length` that's an integer greater than or
18524  * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
18525  *
18526  * @static
18527  * @memberOf _
18528  * @since 4.0.0
18529  * @category Lang
18530  * @param {*} value The value to check.
18531  * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
18532  * @example
18533  *
18534  * _.isArrayLike([1, 2, 3]);
18535  * // => true
18536  *
18537  * _.isArrayLike(document.body.children);
18538  * // => true
18539  *
18540  * _.isArrayLike('abc');
18541  * // => true
18542  *
18543  * _.isArrayLike(_.noop);
18544  * // => false
18545  */
18546 function isArrayLike(value) {
18547   return value != null && isLength(value.length) && !isFunction(value);
18548 }
18549
18550 /**
18551  * Creates an array of the own enumerable property names of `object`.
18552  *
18553  * **Note:** Non-object values are coerced to objects. See the
18554  * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
18555  * for more details.
18556  *
18557  * @static
18558  * @since 0.1.0
18559  * @memberOf _
18560  * @category Object
18561  * @param {Object} object The object to query.
18562  * @returns {Array} Returns the array of property names.
18563  * @example
18564  *
18565  * function Foo() {
18566  *   this.a = 1;
18567  *   this.b = 2;
18568  * }
18569  *
18570  * Foo.prototype.c = 3;
18571  *
18572  * _.keys(new Foo);
18573  * // => ['a', 'b'] (iteration order is not guaranteed)
18574  *
18575  * _.keys('hi');
18576  * // => ['0', '1']
18577  */
18578 function keys$1(object) {
18579   return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
18580 }
18581
18582 /**
18583  * The base implementation of `_.assign` without support for multiple sources
18584  * or `customizer` functions.
18585  *
18586  * @private
18587  * @param {Object} object The destination object.
18588  * @param {Object} source The source object.
18589  * @returns {Object} Returns `object`.
18590  */
18591 function baseAssign(object, source) {
18592   return object && copyObject(source, keys$1(source), object);
18593 }
18594
18595 /**
18596  * This function is like
18597  * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
18598  * except that it includes inherited enumerable properties.
18599  *
18600  * @private
18601  * @param {Object} object The object to query.
18602  * @returns {Array} Returns the array of property names.
18603  */
18604 function nativeKeysIn(object) {
18605   var result = [];
18606   if (object != null) {
18607     for (var key in Object(object)) {
18608       result.push(key);
18609     }
18610   }
18611   return result;
18612 }
18613
18614 /** Used for built-in method references. */
18615 var objectProto$10 = Object.prototype;
18616
18617 /** Used to check objects for own properties. */
18618 var hasOwnProperty$8 = objectProto$10.hasOwnProperty;
18619
18620 /**
18621  * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
18622  *
18623  * @private
18624  * @param {Object} object The object to query.
18625  * @returns {Array} Returns the array of property names.
18626  */
18627 function baseKeysIn(object) {
18628   if (!isObject(object)) {
18629     return nativeKeysIn(object);
18630   }
18631   var isProto = isPrototype(object),
18632       result = [];
18633
18634   for (var key in object) {
18635     if (!(key == 'constructor' && (isProto || !hasOwnProperty$8.call(object, key)))) {
18636       result.push(key);
18637     }
18638   }
18639   return result;
18640 }
18641
18642 /**
18643  * Creates an array of the own and inherited enumerable property names of `object`.
18644  *
18645  * **Note:** Non-object values are coerced to objects.
18646  *
18647  * @static
18648  * @memberOf _
18649  * @since 3.0.0
18650  * @category Object
18651  * @param {Object} object The object to query.
18652  * @returns {Array} Returns the array of property names.
18653  * @example
18654  *
18655  * function Foo() {
18656  *   this.a = 1;
18657  *   this.b = 2;
18658  * }
18659  *
18660  * Foo.prototype.c = 3;
18661  *
18662  * _.keysIn(new Foo);
18663  * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
18664  */
18665 function keysIn$1(object) {
18666   return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
18667 }
18668
18669 /**
18670  * The base implementation of `_.assignIn` without support for multiple sources
18671  * or `customizer` functions.
18672  *
18673  * @private
18674  * @param {Object} object The destination object.
18675  * @param {Object} source The source object.
18676  * @returns {Object} Returns `object`.
18677  */
18678 function baseAssignIn(object, source) {
18679   return object && copyObject(source, keysIn$1(source), object);
18680 }
18681
18682 /** Detect free variable `exports`. */
18683 var freeExports$2 = typeof exports == 'object' && exports && !exports.nodeType && exports;
18684
18685 /** Detect free variable `module`. */
18686 var freeModule$2 = freeExports$2 && typeof module == 'object' && module && !module.nodeType && module;
18687
18688 /** Detect the popular CommonJS extension `module.exports`. */
18689 var moduleExports$2 = freeModule$2 && freeModule$2.exports === freeExports$2;
18690
18691 /** Built-in value references. */
18692 var Buffer$1 = moduleExports$2 ? root$2.Buffer : undefined;
18693 var allocUnsafe = Buffer$1 ? Buffer$1.allocUnsafe : undefined;
18694
18695 /**
18696  * Creates a clone of  `buffer`.
18697  *
18698  * @private
18699  * @param {Buffer} buffer The buffer to clone.
18700  * @param {boolean} [isDeep] Specify a deep clone.
18701  * @returns {Buffer} Returns the cloned buffer.
18702  */
18703 function cloneBuffer(buffer, isDeep) {
18704   if (isDeep) {
18705     return buffer.slice();
18706   }
18707   var length = buffer.length,
18708       result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
18709
18710   buffer.copy(result);
18711   return result;
18712 }
18713
18714 /**
18715  * Copies the values of `source` to `array`.
18716  *
18717  * @private
18718  * @param {Array} source The array to copy values from.
18719  * @param {Array} [array=[]] The array to copy values to.
18720  * @returns {Array} Returns `array`.
18721  */
18722 function copyArray(source, array) {
18723   var index = -1,
18724       length = source.length;
18725
18726   array || (array = Array(length));
18727   while (++index < length) {
18728     array[index] = source[index];
18729   }
18730   return array;
18731 }
18732
18733 /**
18734  * A specialized version of `_.filter` for arrays without support for
18735  * iteratee shorthands.
18736  *
18737  * @private
18738  * @param {Array} [array] The array to iterate over.
18739  * @param {Function} predicate The function invoked per iteration.
18740  * @returns {Array} Returns the new filtered array.
18741  */
18742 function arrayFilter(array, predicate) {
18743   var index = -1,
18744       length = array == null ? 0 : array.length,
18745       resIndex = 0,
18746       result = [];
18747
18748   while (++index < length) {
18749     var value = array[index];
18750     if (predicate(value, index, array)) {
18751       result[resIndex++] = value;
18752     }
18753   }
18754   return result;
18755 }
18756
18757 /**
18758  * This method returns a new empty array.
18759  *
18760  * @static
18761  * @memberOf _
18762  * @since 4.13.0
18763  * @category Util
18764  * @returns {Array} Returns the new empty array.
18765  * @example
18766  *
18767  * var arrays = _.times(2, _.stubArray);
18768  *
18769  * console.log(arrays);
18770  * // => [[], []]
18771  *
18772  * console.log(arrays[0] === arrays[1]);
18773  * // => false
18774  */
18775 function stubArray() {
18776   return [];
18777 }
18778
18779 /** Used for built-in method references. */
18780 var objectProto$11 = Object.prototype;
18781
18782 /** Built-in value references. */
18783 var propertyIsEnumerable$1 = objectProto$11.propertyIsEnumerable;
18784
18785 /* Built-in method references for those with the same name as other `lodash` methods. */
18786 var nativeGetSymbols = Object.getOwnPropertySymbols;
18787
18788 /**
18789  * Creates an array of the own enumerable symbols of `object`.
18790  *
18791  * @private
18792  * @param {Object} object The object to query.
18793  * @returns {Array} Returns the array of symbols.
18794  */
18795 var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
18796   if (object == null) {
18797     return [];
18798   }
18799   object = Object(object);
18800   return arrayFilter(nativeGetSymbols(object), function(symbol) {
18801     return propertyIsEnumerable$1.call(object, symbol);
18802   });
18803 };
18804
18805 /**
18806  * Copies own symbols of `source` to `object`.
18807  *
18808  * @private
18809  * @param {Object} source The object to copy symbols from.
18810  * @param {Object} [object={}] The object to copy symbols to.
18811  * @returns {Object} Returns `object`.
18812  */
18813 function copySymbols(source, object) {
18814   return copyObject(source, getSymbols(source), object);
18815 }
18816
18817 /**
18818  * Appends the elements of `values` to `array`.
18819  *
18820  * @private
18821  * @param {Array} array The array to modify.
18822  * @param {Array} values The values to append.
18823  * @returns {Array} Returns `array`.
18824  */
18825 function arrayPush(array, values) {
18826   var index = -1,
18827       length = values.length,
18828       offset = array.length;
18829
18830   while (++index < length) {
18831     array[offset + index] = values[index];
18832   }
18833   return array;
18834 }
18835
18836 /** Built-in value references. */
18837 var getPrototype = overArg(Object.getPrototypeOf, Object);
18838
18839 /* Built-in method references for those with the same name as other `lodash` methods. */
18840 var nativeGetSymbols$1 = Object.getOwnPropertySymbols;
18841
18842 /**
18843  * Creates an array of the own and inherited enumerable symbols of `object`.
18844  *
18845  * @private
18846  * @param {Object} object The object to query.
18847  * @returns {Array} Returns the array of symbols.
18848  */
18849 var getSymbolsIn = !nativeGetSymbols$1 ? stubArray : function(object) {
18850   var result = [];
18851   while (object) {
18852     arrayPush(result, getSymbols(object));
18853     object = getPrototype(object);
18854   }
18855   return result;
18856 };
18857
18858 /**
18859  * Copies own and inherited symbols of `source` to `object`.
18860  *
18861  * @private
18862  * @param {Object} source The object to copy symbols from.
18863  * @param {Object} [object={}] The object to copy symbols to.
18864  * @returns {Object} Returns `object`.
18865  */
18866 function copySymbolsIn(source, object) {
18867   return copyObject(source, getSymbolsIn(source), object);
18868 }
18869
18870 /**
18871  * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
18872  * `keysFunc` and `symbolsFunc` to get the enumerable property names and
18873  * symbols of `object`.
18874  *
18875  * @private
18876  * @param {Object} object The object to query.
18877  * @param {Function} keysFunc The function to get the keys of `object`.
18878  * @param {Function} symbolsFunc The function to get the symbols of `object`.
18879  * @returns {Array} Returns the array of property names and symbols.
18880  */
18881 function baseGetAllKeys(object, keysFunc, symbolsFunc) {
18882   var result = keysFunc(object);
18883   return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
18884 }
18885
18886 /**
18887  * Creates an array of own enumerable property names and symbols of `object`.
18888  *
18889  * @private
18890  * @param {Object} object The object to query.
18891  * @returns {Array} Returns the array of property names and symbols.
18892  */
18893 function getAllKeys(object) {
18894   return baseGetAllKeys(object, keys$1, getSymbols);
18895 }
18896
18897 /**
18898  * Creates an array of own and inherited enumerable property names and
18899  * symbols of `object`.
18900  *
18901  * @private
18902  * @param {Object} object The object to query.
18903  * @returns {Array} Returns the array of property names and symbols.
18904  */
18905 function getAllKeysIn(object) {
18906   return baseGetAllKeys(object, keysIn$1, getSymbolsIn);
18907 }
18908
18909 /* Built-in method references that are verified to be native. */
18910 var DataView = getNative(root$2, 'DataView');
18911
18912 /* Built-in method references that are verified to be native. */
18913 var Promise = getNative(root$2, 'Promise');
18914
18915 /* Built-in method references that are verified to be native. */
18916 var Set$1 = getNative(root$2, 'Set');
18917
18918 /* Built-in method references that are verified to be native. */
18919 var WeakMap = getNative(root$2, 'WeakMap');
18920
18921 /** `Object#toString` result references. */
18922 var mapTag$1 = '[object Map]';
18923 var objectTag$1 = '[object Object]';
18924 var promiseTag = '[object Promise]';
18925 var setTag$1 = '[object Set]';
18926 var weakMapTag$1 = '[object WeakMap]';
18927
18928 var dataViewTag$1 = '[object DataView]';
18929
18930 /** Used to detect maps, sets, and weakmaps. */
18931 var dataViewCtorString = toSource(DataView);
18932 var mapCtorString = toSource(Map$1);
18933 var promiseCtorString = toSource(Promise);
18934 var setCtorString = toSource(Set$1);
18935 var weakMapCtorString = toSource(WeakMap);
18936
18937 /**
18938  * Gets the `toStringTag` of `value`.
18939  *
18940  * @private
18941  * @param {*} value The value to query.
18942  * @returns {string} Returns the `toStringTag`.
18943  */
18944 var getTag = baseGetTag;
18945
18946 // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
18947 if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag$1) ||
18948     (Map$1 && getTag(new Map$1) != mapTag$1) ||
18949     (Promise && getTag(Promise.resolve()) != promiseTag) ||
18950     (Set$1 && getTag(new Set$1) != setTag$1) ||
18951     (WeakMap && getTag(new WeakMap) != weakMapTag$1)) {
18952   getTag = function(value) {
18953     var result = baseGetTag(value),
18954         Ctor = result == objectTag$1 ? value.constructor : undefined,
18955         ctorString = Ctor ? toSource(Ctor) : '';
18956
18957     if (ctorString) {
18958       switch (ctorString) {
18959         case dataViewCtorString: return dataViewTag$1;
18960         case mapCtorString: return mapTag$1;
18961         case promiseCtorString: return promiseTag;
18962         case setCtorString: return setTag$1;
18963         case weakMapCtorString: return weakMapTag$1;
18964       }
18965     }
18966     return result;
18967   };
18968 }
18969
18970 var getTag$1 = getTag;
18971
18972 /** Used for built-in method references. */
18973 var objectProto$12 = Object.prototype;
18974
18975 /** Used to check objects for own properties. */
18976 var hasOwnProperty$9 = objectProto$12.hasOwnProperty;
18977
18978 /**
18979  * Initializes an array clone.
18980  *
18981  * @private
18982  * @param {Array} array The array to clone.
18983  * @returns {Array} Returns the initialized clone.
18984  */
18985 function initCloneArray(array) {
18986   var length = array.length,
18987       result = array.constructor(length);
18988
18989   // Add properties assigned by `RegExp#exec`.
18990   if (length && typeof array[0] == 'string' && hasOwnProperty$9.call(array, 'index')) {
18991     result.index = array.index;
18992     result.input = array.input;
18993   }
18994   return result;
18995 }
18996
18997 /** Built-in value references. */
18998 var Uint8Array = root$2.Uint8Array;
18999
19000 /**
19001  * Creates a clone of `arrayBuffer`.
19002  *
19003  * @private
19004  * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
19005  * @returns {ArrayBuffer} Returns the cloned array buffer.
19006  */
19007 function cloneArrayBuffer(arrayBuffer) {
19008   var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
19009   new Uint8Array(result).set(new Uint8Array(arrayBuffer));
19010   return result;
19011 }
19012
19013 /**
19014  * Creates a clone of `dataView`.
19015  *
19016  * @private
19017  * @param {Object} dataView The data view to clone.
19018  * @param {boolean} [isDeep] Specify a deep clone.
19019  * @returns {Object} Returns the cloned data view.
19020  */
19021 function cloneDataView(dataView, isDeep) {
19022   var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
19023   return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
19024 }
19025
19026 /**
19027  * Adds the key-value `pair` to `map`.
19028  *
19029  * @private
19030  * @param {Object} map The map to modify.
19031  * @param {Array} pair The key-value pair to add.
19032  * @returns {Object} Returns `map`.
19033  */
19034 function addMapEntry(map, pair) {
19035   // Don't return `map.set` because it's not chainable in IE 11.
19036   map.set(pair[0], pair[1]);
19037   return map;
19038 }
19039
19040 /**
19041  * A specialized version of `_.reduce` for arrays without support for
19042  * iteratee shorthands.
19043  *
19044  * @private
19045  * @param {Array} [array] The array to iterate over.
19046  * @param {Function} iteratee The function invoked per iteration.
19047  * @param {*} [accumulator] The initial value.
19048  * @param {boolean} [initAccum] Specify using the first element of `array` as
19049  *  the initial value.
19050  * @returns {*} Returns the accumulated value.
19051  */
19052 function arrayReduce(array, iteratee, accumulator, initAccum) {
19053   var index = -1,
19054       length = array == null ? 0 : array.length;
19055
19056   if (initAccum && length) {
19057     accumulator = array[++index];
19058   }
19059   while (++index < length) {
19060     accumulator = iteratee(accumulator, array[index], index, array);
19061   }
19062   return accumulator;
19063 }
19064
19065 /**
19066  * Converts `map` to its key-value pairs.
19067  *
19068  * @private
19069  * @param {Object} map The map to convert.
19070  * @returns {Array} Returns the key-value pairs.
19071  */
19072 function mapToArray(map) {
19073   var index = -1,
19074       result = Array(map.size);
19075
19076   map.forEach(function(value, key) {
19077     result[++index] = [key, value];
19078   });
19079   return result;
19080 }
19081
19082 /** Used to compose bitmasks for cloning. */
19083 var CLONE_DEEP_FLAG = 1;
19084
19085 /**
19086  * Creates a clone of `map`.
19087  *
19088  * @private
19089  * @param {Object} map The map to clone.
19090  * @param {Function} cloneFunc The function to clone values.
19091  * @param {boolean} [isDeep] Specify a deep clone.
19092  * @returns {Object} Returns the cloned map.
19093  */
19094 function cloneMap(map, isDeep, cloneFunc) {
19095   var array = isDeep ? cloneFunc(mapToArray(map), CLONE_DEEP_FLAG) : mapToArray(map);
19096   return arrayReduce(array, addMapEntry, new map.constructor);
19097 }
19098
19099 /** Used to match `RegExp` flags from their coerced string values. */
19100 var reFlags = /\w*$/;
19101
19102 /**
19103  * Creates a clone of `regexp`.
19104  *
19105  * @private
19106  * @param {Object} regexp The regexp to clone.
19107  * @returns {Object} Returns the cloned regexp.
19108  */
19109 function cloneRegExp(regexp) {
19110   var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
19111   result.lastIndex = regexp.lastIndex;
19112   return result;
19113 }
19114
19115 /**
19116  * Adds `value` to `set`.
19117  *
19118  * @private
19119  * @param {Object} set The set to modify.
19120  * @param {*} value The value to add.
19121  * @returns {Object} Returns `set`.
19122  */
19123 function addSetEntry(set, value) {
19124   // Don't return `set.add` because it's not chainable in IE 11.
19125   set.add(value);
19126   return set;
19127 }
19128
19129 /**
19130  * Converts `set` to an array of its values.
19131  *
19132  * @private
19133  * @param {Object} set The set to convert.
19134  * @returns {Array} Returns the values.
19135  */
19136 function setToArray(set) {
19137   var index = -1,
19138       result = Array(set.size);
19139
19140   set.forEach(function(value) {
19141     result[++index] = value;
19142   });
19143   return result;
19144 }
19145
19146 /** Used to compose bitmasks for cloning. */
19147 var CLONE_DEEP_FLAG$1 = 1;
19148
19149 /**
19150  * Creates a clone of `set`.
19151  *
19152  * @private
19153  * @param {Object} set The set to clone.
19154  * @param {Function} cloneFunc The function to clone values.
19155  * @param {boolean} [isDeep] Specify a deep clone.
19156  * @returns {Object} Returns the cloned set.
19157  */
19158 function cloneSet(set, isDeep, cloneFunc) {
19159   var array = isDeep ? cloneFunc(setToArray(set), CLONE_DEEP_FLAG$1) : setToArray(set);
19160   return arrayReduce(array, addSetEntry, new set.constructor);
19161 }
19162
19163 /** Used to convert symbols to primitives and strings. */
19164 var symbolProto = Symbol ? Symbol.prototype : undefined;
19165 var symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;
19166
19167 /**
19168  * Creates a clone of the `symbol` object.
19169  *
19170  * @private
19171  * @param {Object} symbol The symbol object to clone.
19172  * @returns {Object} Returns the cloned symbol object.
19173  */
19174 function cloneSymbol(symbol) {
19175   return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
19176 }
19177
19178 /**
19179  * Creates a clone of `typedArray`.
19180  *
19181  * @private
19182  * @param {Object} typedArray The typed array to clone.
19183  * @param {boolean} [isDeep] Specify a deep clone.
19184  * @returns {Object} Returns the cloned typed array.
19185  */
19186 function cloneTypedArray(typedArray, isDeep) {
19187   var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
19188   return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
19189 }
19190
19191 /** `Object#toString` result references. */
19192 var boolTag$1 = '[object Boolean]';
19193 var dateTag$1 = '[object Date]';
19194 var mapTag$2 = '[object Map]';
19195 var numberTag$1 = '[object Number]';
19196 var regexpTag$1 = '[object RegExp]';
19197 var setTag$2 = '[object Set]';
19198 var stringTag$1 = '[object String]';
19199 var symbolTag = '[object Symbol]';
19200
19201 var arrayBufferTag$1 = '[object ArrayBuffer]';
19202 var dataViewTag$2 = '[object DataView]';
19203 var float32Tag$1 = '[object Float32Array]';
19204 var float64Tag$1 = '[object Float64Array]';
19205 var int8Tag$1 = '[object Int8Array]';
19206 var int16Tag$1 = '[object Int16Array]';
19207 var int32Tag$1 = '[object Int32Array]';
19208 var uint8Tag$1 = '[object Uint8Array]';
19209 var uint8ClampedTag$1 = '[object Uint8ClampedArray]';
19210 var uint16Tag$1 = '[object Uint16Array]';
19211 var uint32Tag$1 = '[object Uint32Array]';
19212
19213 /**
19214  * Initializes an object clone based on its `toStringTag`.
19215  *
19216  * **Note:** This function only supports cloning values with tags of
19217  * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
19218  *
19219  * @private
19220  * @param {Object} object The object to clone.
19221  * @param {string} tag The `toStringTag` of the object to clone.
19222  * @param {Function} cloneFunc The function to clone values.
19223  * @param {boolean} [isDeep] Specify a deep clone.
19224  * @returns {Object} Returns the initialized clone.
19225  */
19226 function initCloneByTag(object, tag, cloneFunc, isDeep) {
19227   var Ctor = object.constructor;
19228   switch (tag) {
19229     case arrayBufferTag$1:
19230       return cloneArrayBuffer(object);
19231
19232     case boolTag$1:
19233     case dateTag$1:
19234       return new Ctor(+object);
19235
19236     case dataViewTag$2:
19237       return cloneDataView(object, isDeep);
19238
19239     case float32Tag$1: case float64Tag$1:
19240     case int8Tag$1: case int16Tag$1: case int32Tag$1:
19241     case uint8Tag$1: case uint8ClampedTag$1: case uint16Tag$1: case uint32Tag$1:
19242       return cloneTypedArray(object, isDeep);
19243
19244     case mapTag$2:
19245       return cloneMap(object, isDeep, cloneFunc);
19246
19247     case numberTag$1:
19248     case stringTag$1:
19249       return new Ctor(object);
19250
19251     case regexpTag$1:
19252       return cloneRegExp(object);
19253
19254     case setTag$2:
19255       return cloneSet(object, isDeep, cloneFunc);
19256
19257     case symbolTag:
19258       return cloneSymbol(object);
19259   }
19260 }
19261
19262 /** Built-in value references. */
19263 var objectCreate = Object.create;
19264
19265 /**
19266  * The base implementation of `_.create` without support for assigning
19267  * properties to the created object.
19268  *
19269  * @private
19270  * @param {Object} proto The object to inherit from.
19271  * @returns {Object} Returns the new object.
19272  */
19273 var baseCreate = (function() {
19274   function object() {}
19275   return function(proto) {
19276     if (!isObject(proto)) {
19277       return {};
19278     }
19279     if (objectCreate) {
19280       return objectCreate(proto);
19281     }
19282     object.prototype = proto;
19283     var result = new object;
19284     object.prototype = undefined;
19285     return result;
19286   };
19287 }());
19288
19289 /**
19290  * Initializes an object clone.
19291  *
19292  * @private
19293  * @param {Object} object The object to clone.
19294  * @returns {Object} Returns the initialized clone.
19295  */
19296 function initCloneObject(object) {
19297   return (typeof object.constructor == 'function' && !isPrototype(object))
19298     ? baseCreate(getPrototype(object))
19299     : {};
19300 }
19301
19302 /** Used to compose bitmasks for cloning. */
19303 var CLONE_DEEP_FLAG$2 = 1;
19304 var CLONE_FLAT_FLAG = 2;
19305 var CLONE_SYMBOLS_FLAG = 4;
19306
19307 /** `Object#toString` result references. */
19308 var argsTag$2 = '[object Arguments]';
19309 var arrayTag$1 = '[object Array]';
19310 var boolTag$2 = '[object Boolean]';
19311 var dateTag$2 = '[object Date]';
19312 var errorTag$1 = '[object Error]';
19313 var funcTag$2 = '[object Function]';
19314 var genTag$1 = '[object GeneratorFunction]';
19315 var mapTag$3 = '[object Map]';
19316 var numberTag$2 = '[object Number]';
19317 var objectTag$2 = '[object Object]';
19318 var regexpTag$2 = '[object RegExp]';
19319 var setTag$3 = '[object Set]';
19320 var stringTag$2 = '[object String]';
19321 var symbolTag$1 = '[object Symbol]';
19322 var weakMapTag$2 = '[object WeakMap]';
19323
19324 var arrayBufferTag$2 = '[object ArrayBuffer]';
19325 var dataViewTag$3 = '[object DataView]';
19326 var float32Tag$2 = '[object Float32Array]';
19327 var float64Tag$2 = '[object Float64Array]';
19328 var int8Tag$2 = '[object Int8Array]';
19329 var int16Tag$2 = '[object Int16Array]';
19330 var int32Tag$2 = '[object Int32Array]';
19331 var uint8Tag$2 = '[object Uint8Array]';
19332 var uint8ClampedTag$2 = '[object Uint8ClampedArray]';
19333 var uint16Tag$2 = '[object Uint16Array]';
19334 var uint32Tag$2 = '[object Uint32Array]';
19335
19336 /** Used to identify `toStringTag` values supported by `_.clone`. */
19337 var cloneableTags = {};
19338 cloneableTags[argsTag$2] = cloneableTags[arrayTag$1] =
19339 cloneableTags[arrayBufferTag$2] = cloneableTags[dataViewTag$3] =
19340 cloneableTags[boolTag$2] = cloneableTags[dateTag$2] =
19341 cloneableTags[float32Tag$2] = cloneableTags[float64Tag$2] =
19342 cloneableTags[int8Tag$2] = cloneableTags[int16Tag$2] =
19343 cloneableTags[int32Tag$2] = cloneableTags[mapTag$3] =
19344 cloneableTags[numberTag$2] = cloneableTags[objectTag$2] =
19345 cloneableTags[regexpTag$2] = cloneableTags[setTag$3] =
19346 cloneableTags[stringTag$2] = cloneableTags[symbolTag$1] =
19347 cloneableTags[uint8Tag$2] = cloneableTags[uint8ClampedTag$2] =
19348 cloneableTags[uint16Tag$2] = cloneableTags[uint32Tag$2] = true;
19349 cloneableTags[errorTag$1] = cloneableTags[funcTag$2] =
19350 cloneableTags[weakMapTag$2] = false;
19351
19352 /**
19353  * The base implementation of `_.clone` and `_.cloneDeep` which tracks
19354  * traversed objects.
19355  *
19356  * @private
19357  * @param {*} value The value to clone.
19358  * @param {boolean} bitmask The bitmask flags.
19359  *  1 - Deep clone
19360  *  2 - Flatten inherited properties
19361  *  4 - Clone symbols
19362  * @param {Function} [customizer] The function to customize cloning.
19363  * @param {string} [key] The key of `value`.
19364  * @param {Object} [object] The parent object of `value`.
19365  * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
19366  * @returns {*} Returns the cloned value.
19367  */
19368 function baseClone(value, bitmask, customizer, key, object, stack) {
19369   var result,
19370       isDeep = bitmask & CLONE_DEEP_FLAG$2,
19371       isFlat = bitmask & CLONE_FLAT_FLAG,
19372       isFull = bitmask & CLONE_SYMBOLS_FLAG;
19373
19374   if (customizer) {
19375     result = object ? customizer(value, key, object, stack) : customizer(value);
19376   }
19377   if (result !== undefined) {
19378     return result;
19379   }
19380   if (!isObject(value)) {
19381     return value;
19382   }
19383   var isArr = isArray(value);
19384   if (isArr) {
19385     result = initCloneArray(value);
19386     if (!isDeep) {
19387       return copyArray(value, result);
19388     }
19389   } else {
19390     var tag = getTag$1(value),
19391         isFunc = tag == funcTag$2 || tag == genTag$1;
19392
19393     if (isBuffer(value)) {
19394       return cloneBuffer(value, isDeep);
19395     }
19396     if (tag == objectTag$2 || tag == argsTag$2 || (isFunc && !object)) {
19397       result = (isFlat || isFunc) ? {} : initCloneObject(value);
19398       if (!isDeep) {
19399         return isFlat
19400           ? copySymbolsIn(value, baseAssignIn(result, value))
19401           : copySymbols(value, baseAssign(result, value));
19402       }
19403     } else {
19404       if (!cloneableTags[tag]) {
19405         return object ? value : {};
19406       }
19407       result = initCloneByTag(value, tag, baseClone, isDeep);
19408     }
19409   }
19410   // Check for circular references and return its corresponding clone.
19411   stack || (stack = new Stack);
19412   var stacked = stack.get(value);
19413   if (stacked) {
19414     return stacked;
19415   }
19416   stack.set(value, result);
19417
19418   var keysFunc = isFull
19419     ? (isFlat ? getAllKeysIn : getAllKeys)
19420     : (isFlat ? keysIn : keys$1);
19421
19422   var props = isArr ? undefined : keysFunc(value);
19423   arrayEach(props || value, function(subValue, key) {
19424     if (props) {
19425       key = subValue;
19426       subValue = value[key];
19427     }
19428     // Recursively populate clone (susceptible to call stack limits).
19429     assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
19430   });
19431   return result;
19432 }
19433
19434 /** Used to compose bitmasks for cloning. */
19435 var CLONE_SYMBOLS_FLAG$1 = 4;
19436
19437 /**
19438  * Creates a shallow clone of `value`.
19439  *
19440  * **Note:** This method is loosely based on the
19441  * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
19442  * and supports cloning arrays, array buffers, booleans, date objects, maps,
19443  * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
19444  * arrays. The own enumerable properties of `arguments` objects are cloned
19445  * as plain objects. An empty object is returned for uncloneable values such
19446  * as error objects, functions, DOM nodes, and WeakMaps.
19447  *
19448  * @static
19449  * @memberOf _
19450  * @since 0.1.0
19451  * @category Lang
19452  * @param {*} value The value to clone.
19453  * @returns {*} Returns the cloned value.
19454  * @see _.cloneDeep
19455  * @example
19456  *
19457  * var objects = [{ 'a': 1 }, { 'b': 2 }];
19458  *
19459  * var shallow = _.clone(objects);
19460  * console.log(shallow[0] === objects[0]);
19461  * // => true
19462  */
19463 function clone(value) {
19464   return baseClone(value, CLONE_SYMBOLS_FLAG$1);
19465 }
19466
19467 /**
19468  * A specialized version of `baseAggregator` for arrays.
19469  *
19470  * @private
19471  * @param {Array} [array] The array to iterate over.
19472  * @param {Function} setter The function to set `accumulator` values.
19473  * @param {Function} iteratee The iteratee to transform keys.
19474  * @param {Object} accumulator The initial aggregated object.
19475  * @returns {Function} Returns `accumulator`.
19476  */
19477 function arrayAggregator(array, setter, iteratee, accumulator) {
19478   var index = -1,
19479       length = array == null ? 0 : array.length;
19480
19481   while (++index < length) {
19482     var value = array[index];
19483     setter(accumulator, value, iteratee(value), array);
19484   }
19485   return accumulator;
19486 }
19487
19488 /**
19489  * Creates a base function for methods like `_.forIn` and `_.forOwn`.
19490  *
19491  * @private
19492  * @param {boolean} [fromRight] Specify iterating from right to left.
19493  * @returns {Function} Returns the new base function.
19494  */
19495 function createBaseFor(fromRight) {
19496   return function(object, iteratee, keysFunc) {
19497     var index = -1,
19498         iterable = Object(object),
19499         props = keysFunc(object),
19500         length = props.length;
19501
19502     while (length--) {
19503       var key = props[fromRight ? length : ++index];
19504       if (iteratee(iterable[key], key, iterable) === false) {
19505         break;
19506       }
19507     }
19508     return object;
19509   };
19510 }
19511
19512 /**
19513  * The base implementation of `baseForOwn` which iterates over `object`
19514  * properties returned by `keysFunc` and invokes `iteratee` for each property.
19515  * Iteratee functions may exit iteration early by explicitly returning `false`.
19516  *
19517  * @private
19518  * @param {Object} object The object to iterate over.
19519  * @param {Function} iteratee The function invoked per iteration.
19520  * @param {Function} keysFunc The function to get the keys of `object`.
19521  * @returns {Object} Returns `object`.
19522  */
19523 var baseFor = createBaseFor();
19524
19525 /**
19526  * The base implementation of `_.forOwn` without support for iteratee shorthands.
19527  *
19528  * @private
19529  * @param {Object} object The object to iterate over.
19530  * @param {Function} iteratee The function invoked per iteration.
19531  * @returns {Object} Returns `object`.
19532  */
19533 function baseForOwn(object, iteratee) {
19534   return object && baseFor(object, iteratee, keys$1);
19535 }
19536
19537 /**
19538  * Creates a `baseEach` or `baseEachRight` function.
19539  *
19540  * @private
19541  * @param {Function} eachFunc The function to iterate over a collection.
19542  * @param {boolean} [fromRight] Specify iterating from right to left.
19543  * @returns {Function} Returns the new base function.
19544  */
19545 function createBaseEach(eachFunc, fromRight) {
19546   return function(collection, iteratee) {
19547     if (collection == null) {
19548       return collection;
19549     }
19550     if (!isArrayLike(collection)) {
19551       return eachFunc(collection, iteratee);
19552     }
19553     var length = collection.length,
19554         index = fromRight ? length : -1,
19555         iterable = Object(collection);
19556
19557     while ((fromRight ? index-- : ++index < length)) {
19558       if (iteratee(iterable[index], index, iterable) === false) {
19559         break;
19560       }
19561     }
19562     return collection;
19563   };
19564 }
19565
19566 /**
19567  * The base implementation of `_.forEach` without support for iteratee shorthands.
19568  *
19569  * @private
19570  * @param {Array|Object} collection The collection to iterate over.
19571  * @param {Function} iteratee The function invoked per iteration.
19572  * @returns {Array|Object} Returns `collection`.
19573  */
19574 var baseEach = createBaseEach(baseForOwn);
19575
19576 /**
19577  * Aggregates elements of `collection` on `accumulator` with keys transformed
19578  * by `iteratee` and values set by `setter`.
19579  *
19580  * @private
19581  * @param {Array|Object} collection The collection to iterate over.
19582  * @param {Function} setter The function to set `accumulator` values.
19583  * @param {Function} iteratee The iteratee to transform keys.
19584  * @param {Object} accumulator The initial aggregated object.
19585  * @returns {Function} Returns `accumulator`.
19586  */
19587 function baseAggregator(collection, setter, iteratee, accumulator) {
19588   baseEach(collection, function(value, key, collection) {
19589     setter(accumulator, value, iteratee(value), collection);
19590   });
19591   return accumulator;
19592 }
19593
19594 /** Used to stand-in for `undefined` hash values. */
19595 var HASH_UNDEFINED$2 = '__lodash_hash_undefined__';
19596
19597 /**
19598  * Adds `value` to the array cache.
19599  *
19600  * @private
19601  * @name add
19602  * @memberOf SetCache
19603  * @alias push
19604  * @param {*} value The value to cache.
19605  * @returns {Object} Returns the cache instance.
19606  */
19607 function setCacheAdd(value) {
19608   this.__data__.set(value, HASH_UNDEFINED$2);
19609   return this;
19610 }
19611
19612 /**
19613  * Checks if `value` is in the array cache.
19614  *
19615  * @private
19616  * @name has
19617  * @memberOf SetCache
19618  * @param {*} value The value to search for.
19619  * @returns {number} Returns `true` if `value` is found, else `false`.
19620  */
19621 function setCacheHas(value) {
19622   return this.__data__.has(value);
19623 }
19624
19625 /**
19626  *
19627  * Creates an array cache object to store unique values.
19628  *
19629  * @private
19630  * @constructor
19631  * @param {Array} [values] The values to cache.
19632  */
19633 function SetCache(values) {
19634   var index = -1,
19635       length = values == null ? 0 : values.length;
19636
19637   this.__data__ = new MapCache;
19638   while (++index < length) {
19639     this.add(values[index]);
19640   }
19641 }
19642
19643 // Add methods to `SetCache`.
19644 SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
19645 SetCache.prototype.has = setCacheHas;
19646
19647 /**
19648  * A specialized version of `_.some` for arrays without support for iteratee
19649  * shorthands.
19650  *
19651  * @private
19652  * @param {Array} [array] The array to iterate over.
19653  * @param {Function} predicate The function invoked per iteration.
19654  * @returns {boolean} Returns `true` if any element passes the predicate check,
19655  *  else `false`.
19656  */
19657 function arraySome(array, predicate) {
19658   var index = -1,
19659       length = array == null ? 0 : array.length;
19660
19661   while (++index < length) {
19662     if (predicate(array[index], index, array)) {
19663       return true;
19664     }
19665   }
19666   return false;
19667 }
19668
19669 /**
19670  * Checks if a `cache` value for `key` exists.
19671  *
19672  * @private
19673  * @param {Object} cache The cache to query.
19674  * @param {string} key The key of the entry to check.
19675  * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
19676  */
19677 function cacheHas(cache, key) {
19678   return cache.has(key);
19679 }
19680
19681 /** Used to compose bitmasks for value comparisons. */
19682 var COMPARE_PARTIAL_FLAG = 1;
19683 var COMPARE_UNORDERED_FLAG = 2;
19684
19685 /**
19686  * A specialized version of `baseIsEqualDeep` for arrays with support for
19687  * partial deep comparisons.
19688  *
19689  * @private
19690  * @param {Array} array The array to compare.
19691  * @param {Array} other The other array to compare.
19692  * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
19693  * @param {Function} customizer The function to customize comparisons.
19694  * @param {Function} equalFunc The function to determine equivalents of values.
19695  * @param {Object} stack Tracks traversed `array` and `other` objects.
19696  * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
19697  */
19698 function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
19699   var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
19700       arrLength = array.length,
19701       othLength = other.length;
19702
19703   if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
19704     return false;
19705   }
19706   // Assume cyclic values are equal.
19707   var stacked = stack.get(array);
19708   if (stacked && stack.get(other)) {
19709     return stacked == other;
19710   }
19711   var index = -1,
19712       result = true,
19713       seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
19714
19715   stack.set(array, other);
19716   stack.set(other, array);
19717
19718   // Ignore non-index properties.
19719   while (++index < arrLength) {
19720     var arrValue = array[index],
19721         othValue = other[index];
19722
19723     if (customizer) {
19724       var compared = isPartial
19725         ? customizer(othValue, arrValue, index, other, array, stack)
19726         : customizer(arrValue, othValue, index, array, other, stack);
19727     }
19728     if (compared !== undefined) {
19729       if (compared) {
19730         continue;
19731       }
19732       result = false;
19733       break;
19734     }
19735     // Recursively compare arrays (susceptible to call stack limits).
19736     if (seen) {
19737       if (!arraySome(other, function(othValue, othIndex) {
19738             if (!cacheHas(seen, othIndex) &&
19739                 (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
19740               return seen.push(othIndex);
19741             }
19742           })) {
19743         result = false;
19744         break;
19745       }
19746     } else if (!(
19747           arrValue === othValue ||
19748             equalFunc(arrValue, othValue, bitmask, customizer, stack)
19749         )) {
19750       result = false;
19751       break;
19752     }
19753   }
19754   stack['delete'](array);
19755   stack['delete'](other);
19756   return result;
19757 }
19758
19759 /** Used to compose bitmasks for value comparisons. */
19760 var COMPARE_PARTIAL_FLAG$1 = 1;
19761 var COMPARE_UNORDERED_FLAG$1 = 2;
19762
19763 /** `Object#toString` result references. */
19764 var boolTag$3 = '[object Boolean]';
19765 var dateTag$3 = '[object Date]';
19766 var errorTag$2 = '[object Error]';
19767 var mapTag$4 = '[object Map]';
19768 var numberTag$3 = '[object Number]';
19769 var regexpTag$3 = '[object RegExp]';
19770 var setTag$4 = '[object Set]';
19771 var stringTag$3 = '[object String]';
19772 var symbolTag$2 = '[object Symbol]';
19773
19774 var arrayBufferTag$3 = '[object ArrayBuffer]';
19775 var dataViewTag$4 = '[object DataView]';
19776
19777 /** Used to convert symbols to primitives and strings. */
19778 var symbolProto$1 = Symbol ? Symbol.prototype : undefined;
19779 var symbolValueOf$1 = symbolProto$1 ? symbolProto$1.valueOf : undefined;
19780
19781 /**
19782  * A specialized version of `baseIsEqualDeep` for comparing objects of
19783  * the same `toStringTag`.
19784  *
19785  * **Note:** This function only supports comparing values with tags of
19786  * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
19787  *
19788  * @private
19789  * @param {Object} object The object to compare.
19790  * @param {Object} other The other object to compare.
19791  * @param {string} tag The `toStringTag` of the objects to compare.
19792  * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
19793  * @param {Function} customizer The function to customize comparisons.
19794  * @param {Function} equalFunc The function to determine equivalents of values.
19795  * @param {Object} stack Tracks traversed `object` and `other` objects.
19796  * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
19797  */
19798 function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
19799   switch (tag) {
19800     case dataViewTag$4:
19801       if ((object.byteLength != other.byteLength) ||
19802           (object.byteOffset != other.byteOffset)) {
19803         return false;
19804       }
19805       object = object.buffer;
19806       other = other.buffer;
19807
19808     case arrayBufferTag$3:
19809       if ((object.byteLength != other.byteLength) ||
19810           !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
19811         return false;
19812       }
19813       return true;
19814
19815     case boolTag$3:
19816     case dateTag$3:
19817     case numberTag$3:
19818       // Coerce booleans to `1` or `0` and dates to milliseconds.
19819       // Invalid dates are coerced to `NaN`.
19820       return eq(+object, +other);
19821
19822     case errorTag$2:
19823       return object.name == other.name && object.message == other.message;
19824
19825     case regexpTag$3:
19826     case stringTag$3:
19827       // Coerce regexes to strings and treat strings, primitives and objects,
19828       // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
19829       // for more details.
19830       return object == (other + '');
19831
19832     case mapTag$4:
19833       var convert = mapToArray;
19834
19835     case setTag$4:
19836       var isPartial = bitmask & COMPARE_PARTIAL_FLAG$1;
19837       convert || (convert = setToArray);
19838
19839       if (object.size != other.size && !isPartial) {
19840         return false;
19841       }
19842       // Assume cyclic values are equal.
19843       var stacked = stack.get(object);
19844       if (stacked) {
19845         return stacked == other;
19846       }
19847       bitmask |= COMPARE_UNORDERED_FLAG$1;
19848
19849       // Recursively compare objects (susceptible to call stack limits).
19850       stack.set(object, other);
19851       var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
19852       stack['delete'](object);
19853       return result;
19854
19855     case symbolTag$2:
19856       if (symbolValueOf$1) {
19857         return symbolValueOf$1.call(object) == symbolValueOf$1.call(other);
19858       }
19859   }
19860   return false;
19861 }
19862
19863 /** Used to compose bitmasks for value comparisons. */
19864 var COMPARE_PARTIAL_FLAG$2 = 1;
19865
19866 /** Used for built-in method references. */
19867 var objectProto$13 = Object.prototype;
19868
19869 /** Used to check objects for own properties. */
19870 var hasOwnProperty$10 = objectProto$13.hasOwnProperty;
19871
19872 /**
19873  * A specialized version of `baseIsEqualDeep` for objects with support for
19874  * partial deep comparisons.
19875  *
19876  * @private
19877  * @param {Object} object The object to compare.
19878  * @param {Object} other The other object to compare.
19879  * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
19880  * @param {Function} customizer The function to customize comparisons.
19881  * @param {Function} equalFunc The function to determine equivalents of values.
19882  * @param {Object} stack Tracks traversed `object` and `other` objects.
19883  * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
19884  */
19885 function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
19886   var isPartial = bitmask & COMPARE_PARTIAL_FLAG$2,
19887       objProps = getAllKeys(object),
19888       objLength = objProps.length,
19889       othProps = getAllKeys(other),
19890       othLength = othProps.length;
19891
19892   if (objLength != othLength && !isPartial) {
19893     return false;
19894   }
19895   var index = objLength;
19896   while (index--) {
19897     var key = objProps[index];
19898     if (!(isPartial ? key in other : hasOwnProperty$10.call(other, key))) {
19899       return false;
19900     }
19901   }
19902   // Assume cyclic values are equal.
19903   var stacked = stack.get(object);
19904   if (stacked && stack.get(other)) {
19905     return stacked == other;
19906   }
19907   var result = true;
19908   stack.set(object, other);
19909   stack.set(other, object);
19910
19911   var skipCtor = isPartial;
19912   while (++index < objLength) {
19913     key = objProps[index];
19914     var objValue = object[key],
19915         othValue = other[key];
19916
19917     if (customizer) {
19918       var compared = isPartial
19919         ? customizer(othValue, objValue, key, other, object, stack)
19920         : customizer(objValue, othValue, key, object, other, stack);
19921     }
19922     // Recursively compare objects (susceptible to call stack limits).
19923     if (!(compared === undefined
19924           ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
19925           : compared
19926         )) {
19927       result = false;
19928       break;
19929     }
19930     skipCtor || (skipCtor = key == 'constructor');
19931   }
19932   if (result && !skipCtor) {
19933     var objCtor = object.constructor,
19934         othCtor = other.constructor;
19935
19936     // Non `Object` object instances with different constructors are not equal.
19937     if (objCtor != othCtor &&
19938         ('constructor' in object && 'constructor' in other) &&
19939         !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
19940           typeof othCtor == 'function' && othCtor instanceof othCtor)) {
19941       result = false;
19942     }
19943   }
19944   stack['delete'](object);
19945   stack['delete'](other);
19946   return result;
19947 }
19948
19949 /** Used to compose bitmasks for value comparisons. */
19950 var COMPARE_PARTIAL_FLAG$3 = 1;
19951
19952 /** `Object#toString` result references. */
19953 var argsTag$3 = '[object Arguments]';
19954 var arrayTag$2 = '[object Array]';
19955 var objectTag$3 = '[object Object]';
19956
19957 /** Used for built-in method references. */
19958 var objectProto$14 = Object.prototype;
19959
19960 /** Used to check objects for own properties. */
19961 var hasOwnProperty$11 = objectProto$14.hasOwnProperty;
19962
19963 /**
19964  * A specialized version of `baseIsEqual` for arrays and objects which performs
19965  * deep comparisons and tracks traversed objects enabling objects with circular
19966  * references to be compared.
19967  *
19968  * @private
19969  * @param {Object} object The object to compare.
19970  * @param {Object} other The other object to compare.
19971  * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
19972  * @param {Function} customizer The function to customize comparisons.
19973  * @param {Function} equalFunc The function to determine equivalents of values.
19974  * @param {Object} [stack] Tracks traversed `object` and `other` objects.
19975  * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
19976  */
19977 function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
19978   var objIsArr = isArray(object),
19979       othIsArr = isArray(other),
19980       objTag = objIsArr ? arrayTag$2 : getTag$1(object),
19981       othTag = othIsArr ? arrayTag$2 : getTag$1(other);
19982
19983   objTag = objTag == argsTag$3 ? objectTag$3 : objTag;
19984   othTag = othTag == argsTag$3 ? objectTag$3 : othTag;
19985
19986   var objIsObj = objTag == objectTag$3,
19987       othIsObj = othTag == objectTag$3,
19988       isSameTag = objTag == othTag;
19989
19990   if (isSameTag && isBuffer(object)) {
19991     if (!isBuffer(other)) {
19992       return false;
19993     }
19994     objIsArr = true;
19995     objIsObj = false;
19996   }
19997   if (isSameTag && !objIsObj) {
19998     stack || (stack = new Stack);
19999     return (objIsArr || isTypedArray(object))
20000       ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
20001       : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
20002   }
20003   if (!(bitmask & COMPARE_PARTIAL_FLAG$3)) {
20004     var objIsWrapped = objIsObj && hasOwnProperty$11.call(object, '__wrapped__'),
20005         othIsWrapped = othIsObj && hasOwnProperty$11.call(other, '__wrapped__');
20006
20007     if (objIsWrapped || othIsWrapped) {
20008       var objUnwrapped = objIsWrapped ? object.value() : object,
20009           othUnwrapped = othIsWrapped ? other.value() : other;
20010
20011       stack || (stack = new Stack);
20012       return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
20013     }
20014   }
20015   if (!isSameTag) {
20016     return false;
20017   }
20018   stack || (stack = new Stack);
20019   return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
20020 }
20021
20022 /**
20023  * The base implementation of `_.isEqual` which supports partial comparisons
20024  * and tracks traversed objects.
20025  *
20026  * @private
20027  * @param {*} value The value to compare.
20028  * @param {*} other The other value to compare.
20029  * @param {boolean} bitmask The bitmask flags.
20030  *  1 - Unordered comparison
20031  *  2 - Partial comparison
20032  * @param {Function} [customizer] The function to customize comparisons.
20033  * @param {Object} [stack] Tracks traversed `value` and `other` objects.
20034  * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
20035  */
20036 function baseIsEqual(value, other, bitmask, customizer, stack) {
20037   if (value === other) {
20038     return true;
20039   }
20040   if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
20041     return value !== value && other !== other;
20042   }
20043   return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
20044 }
20045
20046 /** Used to compose bitmasks for value comparisons. */
20047 var COMPARE_PARTIAL_FLAG$4 = 1;
20048 var COMPARE_UNORDERED_FLAG$2 = 2;
20049
20050 /**
20051  * The base implementation of `_.isMatch` without support for iteratee shorthands.
20052  *
20053  * @private
20054  * @param {Object} object The object to inspect.
20055  * @param {Object} source The object of property values to match.
20056  * @param {Array} matchData The property names, values, and compare flags to match.
20057  * @param {Function} [customizer] The function to customize comparisons.
20058  * @returns {boolean} Returns `true` if `object` is a match, else `false`.
20059  */
20060 function baseIsMatch(object, source, matchData, customizer) {
20061   var index = matchData.length,
20062       length = index,
20063       noCustomizer = !customizer;
20064
20065   if (object == null) {
20066     return !length;
20067   }
20068   object = Object(object);
20069   while (index--) {
20070     var data = matchData[index];
20071     if ((noCustomizer && data[2])
20072           ? data[1] !== object[data[0]]
20073           : !(data[0] in object)
20074         ) {
20075       return false;
20076     }
20077   }
20078   while (++index < length) {
20079     data = matchData[index];
20080     var key = data[0],
20081         objValue = object[key],
20082         srcValue = data[1];
20083
20084     if (noCustomizer && data[2]) {
20085       if (objValue === undefined && !(key in object)) {
20086         return false;
20087       }
20088     } else {
20089       var stack = new Stack;
20090       if (customizer) {
20091         var result = customizer(objValue, srcValue, key, object, source, stack);
20092       }
20093       if (!(result === undefined
20094             ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$4 | COMPARE_UNORDERED_FLAG$2, customizer, stack)
20095             : result
20096           )) {
20097         return false;
20098       }
20099     }
20100   }
20101   return true;
20102 }
20103
20104 /**
20105  * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
20106  *
20107  * @private
20108  * @param {*} value The value to check.
20109  * @returns {boolean} Returns `true` if `value` if suitable for strict
20110  *  equality comparisons, else `false`.
20111  */
20112 function isStrictComparable(value) {
20113   return value === value && !isObject(value);
20114 }
20115
20116 /**
20117  * Gets the property names, values, and compare flags of `object`.
20118  *
20119  * @private
20120  * @param {Object} object The object to query.
20121  * @returns {Array} Returns the match data of `object`.
20122  */
20123 function getMatchData(object) {
20124   var result = keys$1(object),
20125       length = result.length;
20126
20127   while (length--) {
20128     var key = result[length],
20129         value = object[key];
20130
20131     result[length] = [key, value, isStrictComparable(value)];
20132   }
20133   return result;
20134 }
20135
20136 /**
20137  * A specialized version of `matchesProperty` for source values suitable
20138  * for strict equality comparisons, i.e. `===`.
20139  *
20140  * @private
20141  * @param {string} key The key of the property to get.
20142  * @param {*} srcValue The value to match.
20143  * @returns {Function} Returns the new spec function.
20144  */
20145 function matchesStrictComparable(key, srcValue) {
20146   return function(object) {
20147     if (object == null) {
20148       return false;
20149     }
20150     return object[key] === srcValue &&
20151       (srcValue !== undefined || (key in Object(object)));
20152   };
20153 }
20154
20155 /**
20156  * The base implementation of `_.matches` which doesn't clone `source`.
20157  *
20158  * @private
20159  * @param {Object} source The object of property values to match.
20160  * @returns {Function} Returns the new spec function.
20161  */
20162 function baseMatches(source) {
20163   var matchData = getMatchData(source);
20164   if (matchData.length == 1 && matchData[0][2]) {
20165     return matchesStrictComparable(matchData[0][0], matchData[0][1]);
20166   }
20167   return function(object) {
20168     return object === source || baseIsMatch(object, source, matchData);
20169   };
20170 }
20171
20172 /** `Object#toString` result references. */
20173 var symbolTag$3 = '[object Symbol]';
20174
20175 /**
20176  * Checks if `value` is classified as a `Symbol` primitive or object.
20177  *
20178  * @static
20179  * @memberOf _
20180  * @since 4.0.0
20181  * @category Lang
20182  * @param {*} value The value to check.
20183  * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
20184  * @example
20185  *
20186  * _.isSymbol(Symbol.iterator);
20187  * // => true
20188  *
20189  * _.isSymbol('abc');
20190  * // => false
20191  */
20192 function isSymbol(value) {
20193   return typeof value == 'symbol' ||
20194     (isObjectLike(value) && baseGetTag(value) == symbolTag$3);
20195 }
20196
20197 /** Used to match property names within property paths. */
20198 var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/;
20199 var reIsPlainProp = /^\w*$/;
20200
20201 /**
20202  * Checks if `value` is a property name and not a property path.
20203  *
20204  * @private
20205  * @param {*} value The value to check.
20206  * @param {Object} [object] The object to query keys on.
20207  * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
20208  */
20209 function isKey(value, object) {
20210   if (isArray(value)) {
20211     return false;
20212   }
20213   var type = typeof value;
20214   if (type == 'number' || type == 'symbol' || type == 'boolean' ||
20215       value == null || isSymbol(value)) {
20216     return true;
20217   }
20218   return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
20219     (object != null && value in Object(object));
20220 }
20221
20222 /** Error message constants. */
20223 var FUNC_ERROR_TEXT = 'Expected a function';
20224
20225 /**
20226  * Creates a function that memoizes the result of `func`. If `resolver` is
20227  * provided, it determines the cache key for storing the result based on the
20228  * arguments provided to the memoized function. By default, the first argument
20229  * provided to the memoized function is used as the map cache key. The `func`
20230  * is invoked with the `this` binding of the memoized function.
20231  *
20232  * **Note:** The cache is exposed as the `cache` property on the memoized
20233  * function. Its creation may be customized by replacing the `_.memoize.Cache`
20234  * constructor with one whose instances implement the
20235  * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
20236  * method interface of `clear`, `delete`, `get`, `has`, and `set`.
20237  *
20238  * @static
20239  * @memberOf _
20240  * @since 0.1.0
20241  * @category Function
20242  * @param {Function} func The function to have its output memoized.
20243  * @param {Function} [resolver] The function to resolve the cache key.
20244  * @returns {Function} Returns the new memoized function.
20245  * @example
20246  *
20247  * var object = { 'a': 1, 'b': 2 };
20248  * var other = { 'c': 3, 'd': 4 };
20249  *
20250  * var values = _.memoize(_.values);
20251  * values(object);
20252  * // => [1, 2]
20253  *
20254  * values(other);
20255  * // => [3, 4]
20256  *
20257  * object.a = 2;
20258  * values(object);
20259  * // => [1, 2]
20260  *
20261  * // Modify the result cache.
20262  * values.cache.set(object, ['a', 'b']);
20263  * values(object);
20264  * // => ['a', 'b']
20265  *
20266  * // Replace `_.memoize.Cache`.
20267  * _.memoize.Cache = WeakMap;
20268  */
20269 function memoize(func, resolver) {
20270   if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
20271     throw new TypeError(FUNC_ERROR_TEXT);
20272   }
20273   var memoized = function() {
20274     var args = arguments,
20275         key = resolver ? resolver.apply(this, args) : args[0],
20276         cache = memoized.cache;
20277
20278     if (cache.has(key)) {
20279       return cache.get(key);
20280     }
20281     var result = func.apply(this, args);
20282     memoized.cache = cache.set(key, result) || cache;
20283     return result;
20284   };
20285   memoized.cache = new (memoize.Cache || MapCache);
20286   return memoized;
20287 }
20288
20289 // Expose `MapCache`.
20290 memoize.Cache = MapCache;
20291
20292 /** Used as the maximum memoize cache size. */
20293 var MAX_MEMOIZE_SIZE = 500;
20294
20295 /**
20296  * A specialized version of `_.memoize` which clears the memoized function's
20297  * cache when it exceeds `MAX_MEMOIZE_SIZE`.
20298  *
20299  * @private
20300  * @param {Function} func The function to have its output memoized.
20301  * @returns {Function} Returns the new memoized function.
20302  */
20303 function memoizeCapped(func) {
20304   var result = memoize(func, function(key) {
20305     if (cache.size === MAX_MEMOIZE_SIZE) {
20306       cache.clear();
20307     }
20308     return key;
20309   });
20310
20311   var cache = result.cache;
20312   return result;
20313 }
20314
20315 /** Used to match property names within property paths. */
20316 var reLeadingDot = /^\./;
20317 var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
20318
20319 /** Used to match backslashes in property paths. */
20320 var reEscapeChar = /\\(\\)?/g;
20321
20322 /**
20323  * Converts `string` to a property path array.
20324  *
20325  * @private
20326  * @param {string} string The string to convert.
20327  * @returns {Array} Returns the property path array.
20328  */
20329 var stringToPath = memoizeCapped(function(string) {
20330   var result = [];
20331   if (reLeadingDot.test(string)) {
20332     result.push('');
20333   }
20334   string.replace(rePropName, function(match, number, quote, string) {
20335     result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
20336   });
20337   return result;
20338 });
20339
20340 /**
20341  * A specialized version of `_.map` for arrays without support for iteratee
20342  * shorthands.
20343  *
20344  * @private
20345  * @param {Array} [array] The array to iterate over.
20346  * @param {Function} iteratee The function invoked per iteration.
20347  * @returns {Array} Returns the new mapped array.
20348  */
20349 function arrayMap(array, iteratee) {
20350   var index = -1,
20351       length = array == null ? 0 : array.length,
20352       result = Array(length);
20353
20354   while (++index < length) {
20355     result[index] = iteratee(array[index], index, array);
20356   }
20357   return result;
20358 }
20359
20360 /** Used as references for various `Number` constants. */
20361 var INFINITY = 1 / 0;
20362
20363 /** Used to convert symbols to primitives and strings. */
20364 var symbolProto$2 = Symbol ? Symbol.prototype : undefined;
20365 var symbolToString = symbolProto$2 ? symbolProto$2.toString : undefined;
20366
20367 /**
20368  * The base implementation of `_.toString` which doesn't convert nullish
20369  * values to empty strings.
20370  *
20371  * @private
20372  * @param {*} value The value to process.
20373  * @returns {string} Returns the string.
20374  */
20375 function baseToString(value) {
20376   // Exit early for strings to avoid a performance hit in some environments.
20377   if (typeof value == 'string') {
20378     return value;
20379   }
20380   if (isArray(value)) {
20381     // Recursively convert values (susceptible to call stack limits).
20382     return arrayMap(value, baseToString) + '';
20383   }
20384   if (isSymbol(value)) {
20385     return symbolToString ? symbolToString.call(value) : '';
20386   }
20387   var result = (value + '');
20388   return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
20389 }
20390
20391 /**
20392  * Converts `value` to a string. An empty string is returned for `null`
20393  * and `undefined` values. The sign of `-0` is preserved.
20394  *
20395  * @static
20396  * @memberOf _
20397  * @since 4.0.0
20398  * @category Lang
20399  * @param {*} value The value to convert.
20400  * @returns {string} Returns the converted string.
20401  * @example
20402  *
20403  * _.toString(null);
20404  * // => ''
20405  *
20406  * _.toString(-0);
20407  * // => '-0'
20408  *
20409  * _.toString([1, 2, 3]);
20410  * // => '1,2,3'
20411  */
20412 function toString(value) {
20413   return value == null ? '' : baseToString(value);
20414 }
20415
20416 /**
20417  * Casts `value` to a path array if it's not one.
20418  *
20419  * @private
20420  * @param {*} value The value to inspect.
20421  * @param {Object} [object] The object to query keys on.
20422  * @returns {Array} Returns the cast property path array.
20423  */
20424 function castPath(value, object) {
20425   if (isArray(value)) {
20426     return value;
20427   }
20428   return isKey(value, object) ? [value] : stringToPath(toString(value));
20429 }
20430
20431 /** Used as references for various `Number` constants. */
20432 var INFINITY$1 = 1 / 0;
20433
20434 /**
20435  * Converts `value` to a string key if it's not a string or symbol.
20436  *
20437  * @private
20438  * @param {*} value The value to inspect.
20439  * @returns {string|symbol} Returns the key.
20440  */
20441 function toKey(value) {
20442   if (typeof value == 'string' || isSymbol(value)) {
20443     return value;
20444   }
20445   var result = (value + '');
20446   return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result;
20447 }
20448
20449 /**
20450  * The base implementation of `_.get` without support for default values.
20451  *
20452  * @private
20453  * @param {Object} object The object to query.
20454  * @param {Array|string} path The path of the property to get.
20455  * @returns {*} Returns the resolved value.
20456  */
20457 function baseGet(object, path) {
20458   path = castPath(path, object);
20459
20460   var index = 0,
20461       length = path.length;
20462
20463   while (object != null && index < length) {
20464     object = object[toKey(path[index++])];
20465   }
20466   return (index && index == length) ? object : undefined;
20467 }
20468
20469 /**
20470  * Gets the value at `path` of `object`. If the resolved value is
20471  * `undefined`, the `defaultValue` is returned in its place.
20472  *
20473  * @static
20474  * @memberOf _
20475  * @since 3.7.0
20476  * @category Object
20477  * @param {Object} object The object to query.
20478  * @param {Array|string} path The path of the property to get.
20479  * @param {*} [defaultValue] The value returned for `undefined` resolved values.
20480  * @returns {*} Returns the resolved value.
20481  * @example
20482  *
20483  * var object = { 'a': [{ 'b': { 'c': 3 } }] };
20484  *
20485  * _.get(object, 'a[0].b.c');
20486  * // => 3
20487  *
20488  * _.get(object, ['a', '0', 'b', 'c']);
20489  * // => 3
20490  *
20491  * _.get(object, 'a.b.c', 'default');
20492  * // => 'default'
20493  */
20494 function get$2(object, path, defaultValue) {
20495   var result = object == null ? undefined : baseGet(object, path);
20496   return result === undefined ? defaultValue : result;
20497 }
20498
20499 /**
20500  * The base implementation of `_.hasIn` without support for deep paths.
20501  *
20502  * @private
20503  * @param {Object} [object] The object to query.
20504  * @param {Array|string} key The key to check.
20505  * @returns {boolean} Returns `true` if `key` exists, else `false`.
20506  */
20507 function baseHasIn(object, key) {
20508   return object != null && key in Object(object);
20509 }
20510
20511 /**
20512  * Checks if `path` exists on `object`.
20513  *
20514  * @private
20515  * @param {Object} object The object to query.
20516  * @param {Array|string} path The path to check.
20517  * @param {Function} hasFunc The function to check properties.
20518  * @returns {boolean} Returns `true` if `path` exists, else `false`.
20519  */
20520 function hasPath(object, path, hasFunc) {
20521   path = castPath(path, object);
20522
20523   var index = -1,
20524       length = path.length,
20525       result = false;
20526
20527   while (++index < length) {
20528     var key = toKey(path[index]);
20529     if (!(result = object != null && hasFunc(object, key))) {
20530       break;
20531     }
20532     object = object[key];
20533   }
20534   if (result || ++index != length) {
20535     return result;
20536   }
20537   length = object == null ? 0 : object.length;
20538   return !!length && isLength(length) && isIndex(key, length) &&
20539     (isArray(object) || isArguments(object));
20540 }
20541
20542 /**
20543  * Checks if `path` is a direct or inherited property of `object`.
20544  *
20545  * @static
20546  * @memberOf _
20547  * @since 4.0.0
20548  * @category Object
20549  * @param {Object} object The object to query.
20550  * @param {Array|string} path The path to check.
20551  * @returns {boolean} Returns `true` if `path` exists, else `false`.
20552  * @example
20553  *
20554  * var object = _.create({ 'a': _.create({ 'b': 2 }) });
20555  *
20556  * _.hasIn(object, 'a');
20557  * // => true
20558  *
20559  * _.hasIn(object, 'a.b');
20560  * // => true
20561  *
20562  * _.hasIn(object, ['a', 'b']);
20563  * // => true
20564  *
20565  * _.hasIn(object, 'b');
20566  * // => false
20567  */
20568 function hasIn(object, path) {
20569   return object != null && hasPath(object, path, baseHasIn);
20570 }
20571
20572 /** Used to compose bitmasks for value comparisons. */
20573 var COMPARE_PARTIAL_FLAG$5 = 1;
20574 var COMPARE_UNORDERED_FLAG$3 = 2;
20575
20576 /**
20577  * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
20578  *
20579  * @private
20580  * @param {string} path The path of the property to get.
20581  * @param {*} srcValue The value to match.
20582  * @returns {Function} Returns the new spec function.
20583  */
20584 function baseMatchesProperty(path, srcValue) {
20585   if (isKey(path) && isStrictComparable(srcValue)) {
20586     return matchesStrictComparable(toKey(path), srcValue);
20587   }
20588   return function(object) {
20589     var objValue = get$2(object, path);
20590     return (objValue === undefined && objValue === srcValue)
20591       ? hasIn(object, path)
20592       : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$5 | COMPARE_UNORDERED_FLAG$3);
20593   };
20594 }
20595
20596 /**
20597  * This method returns the first argument it receives.
20598  *
20599  * @static
20600  * @since 0.1.0
20601  * @memberOf _
20602  * @category Util
20603  * @param {*} value Any value.
20604  * @returns {*} Returns `value`.
20605  * @example
20606  *
20607  * var object = { 'a': 1 };
20608  *
20609  * console.log(_.identity(object) === object);
20610  * // => true
20611  */
20612 function identity$8(value) {
20613   return value;
20614 }
20615
20616 /**
20617  * The base implementation of `_.property` without support for deep paths.
20618  *
20619  * @private
20620  * @param {string} key The key of the property to get.
20621  * @returns {Function} Returns the new accessor function.
20622  */
20623 function baseProperty(key) {
20624   return function(object) {
20625     return object == null ? undefined : object[key];
20626   };
20627 }
20628
20629 /**
20630  * A specialized version of `baseProperty` which supports deep paths.
20631  *
20632  * @private
20633  * @param {Array|string} path The path of the property to get.
20634  * @returns {Function} Returns the new accessor function.
20635  */
20636 function basePropertyDeep(path) {
20637   return function(object) {
20638     return baseGet(object, path);
20639   };
20640 }
20641
20642 /**
20643  * Creates a function that returns the value at `path` of a given object.
20644  *
20645  * @static
20646  * @memberOf _
20647  * @since 2.4.0
20648  * @category Util
20649  * @param {Array|string} path The path of the property to get.
20650  * @returns {Function} Returns the new accessor function.
20651  * @example
20652  *
20653  * var objects = [
20654  *   { 'a': { 'b': 2 } },
20655  *   { 'a': { 'b': 1 } }
20656  * ];
20657  *
20658  * _.map(objects, _.property('a.b'));
20659  * // => [2, 1]
20660  *
20661  * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
20662  * // => [1, 2]
20663  */
20664 function property(path) {
20665   return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
20666 }
20667
20668 /**
20669  * The base implementation of `_.iteratee`.
20670  *
20671  * @private
20672  * @param {*} [value=_.identity] The value to convert to an iteratee.
20673  * @returns {Function} Returns the iteratee.
20674  */
20675 function baseIteratee(value) {
20676   // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
20677   // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
20678   if (typeof value == 'function') {
20679     return value;
20680   }
20681   if (value == null) {
20682     return identity$8;
20683   }
20684   if (typeof value == 'object') {
20685     return isArray(value)
20686       ? baseMatchesProperty(value[0], value[1])
20687       : baseMatches(value);
20688   }
20689   return property(value);
20690 }
20691
20692 /**
20693  * Creates a function like `_.groupBy`.
20694  *
20695  * @private
20696  * @param {Function} setter The function to set accumulator values.
20697  * @param {Function} [initializer] The accumulator object initializer.
20698  * @returns {Function} Returns the new aggregator function.
20699  */
20700 function createAggregator(setter, initializer) {
20701   return function(collection, iteratee) {
20702     var func = isArray(collection) ? arrayAggregator : baseAggregator,
20703         accumulator = initializer ? initializer() : {};
20704
20705     return func(collection, setter, baseIteratee(iteratee, 2), accumulator);
20706   };
20707 }
20708
20709 /** Used for built-in method references. */
20710 var objectProto$15 = Object.prototype;
20711
20712 /** Used to check objects for own properties. */
20713 var hasOwnProperty$12 = objectProto$15.hasOwnProperty;
20714
20715 /**
20716  * Creates an object composed of keys generated from the results of running
20717  * each element of `collection` thru `iteratee`. The order of grouped values
20718  * is determined by the order they occur in `collection`. The corresponding
20719  * value of each key is an array of elements responsible for generating the
20720  * key. The iteratee is invoked with one argument: (value).
20721  *
20722  * @static
20723  * @memberOf _
20724  * @since 0.1.0
20725  * @category Collection
20726  * @param {Array|Object} collection The collection to iterate over.
20727  * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
20728  * @returns {Object} Returns the composed aggregate object.
20729  * @example
20730  *
20731  * _.groupBy([6.1, 4.2, 6.3], Math.floor);
20732  * // => { '4': [4.2], '6': [6.1, 6.3] }
20733  *
20734  * // The `_.property` iteratee shorthand.
20735  * _.groupBy(['one', 'two', 'three'], 'length');
20736  * // => { '3': ['one', 'two'], '5': ['three'] }
20737  */
20738 var groupBy = createAggregator(function(result, value, key) {
20739   if (hasOwnProperty$12.call(result, key)) {
20740     result[key].push(value);
20741   } else {
20742     baseAssignValue(result, key, [value]);
20743   }
20744 });
20745
20746 /**
20747  * Gets the last element of `array`.
20748  *
20749  * @static
20750  * @memberOf _
20751  * @since 0.1.0
20752  * @category Array
20753  * @param {Array} array The array to query.
20754  * @returns {*} Returns the last element of `array`.
20755  * @example
20756  *
20757  * _.last([1, 2, 3]);
20758  * // => 3
20759  */
20760 function last(array) {
20761   var length = array == null ? 0 : array.length;
20762   return length ? array[length - 1] : undefined;
20763 }
20764
20765 /**
20766  * The base implementation of `_.slice` without an iteratee call guard.
20767  *
20768  * @private
20769  * @param {Array} array The array to slice.
20770  * @param {number} [start=0] The start position.
20771  * @param {number} [end=array.length] The end position.
20772  * @returns {Array} Returns the slice of `array`.
20773  */
20774 function baseSlice(array, start, end) {
20775   var index = -1,
20776       length = array.length;
20777
20778   if (start < 0) {
20779     start = -start > length ? 0 : (length + start);
20780   }
20781   end = end > length ? length : end;
20782   if (end < 0) {
20783     end += length;
20784   }
20785   length = start > end ? 0 : ((end - start) >>> 0);
20786   start >>>= 0;
20787
20788   var result = Array(length);
20789   while (++index < length) {
20790     result[index] = array[index + start];
20791   }
20792   return result;
20793 }
20794
20795 /**
20796  * Gets the parent value at `path` of `object`.
20797  *
20798  * @private
20799  * @param {Object} object The object to query.
20800  * @param {Array} path The path to get the parent value of.
20801  * @returns {*} Returns the parent value.
20802  */
20803 function parent(object, path) {
20804   return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
20805 }
20806
20807 /**
20808  * The base implementation of `_.unset`.
20809  *
20810  * @private
20811  * @param {Object} object The object to modify.
20812  * @param {Array|string} path The property path to unset.
20813  * @returns {boolean} Returns `true` if the property is deleted, else `false`.
20814  */
20815 function baseUnset(object, path) {
20816   path = castPath(path, object);
20817   object = parent(object, path);
20818   return object == null || delete object[toKey(last(path))];
20819 }
20820
20821 /** `Object#toString` result references. */
20822 var objectTag$4 = '[object Object]';
20823
20824 /** Used for built-in method references. */
20825 var funcProto$2 = Function.prototype;
20826 var objectProto$16 = Object.prototype;
20827
20828 /** Used to resolve the decompiled source of functions. */
20829 var funcToString$2 = funcProto$2.toString;
20830
20831 /** Used to check objects for own properties. */
20832 var hasOwnProperty$13 = objectProto$16.hasOwnProperty;
20833
20834 /** Used to infer the `Object` constructor. */
20835 var objectCtorString = funcToString$2.call(Object);
20836
20837 /**
20838  * Checks if `value` is a plain object, that is, an object created by the
20839  * `Object` constructor or one with a `[[Prototype]]` of `null`.
20840  *
20841  * @static
20842  * @memberOf _
20843  * @since 0.8.0
20844  * @category Lang
20845  * @param {*} value The value to check.
20846  * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
20847  * @example
20848  *
20849  * function Foo() {
20850  *   this.a = 1;
20851  * }
20852  *
20853  * _.isPlainObject(new Foo);
20854  * // => false
20855  *
20856  * _.isPlainObject([1, 2, 3]);
20857  * // => false
20858  *
20859  * _.isPlainObject({ 'x': 0, 'y': 0 });
20860  * // => true
20861  *
20862  * _.isPlainObject(Object.create(null));
20863  * // => true
20864  */
20865 function isPlainObject(value) {
20866   if (!isObjectLike(value) || baseGetTag(value) != objectTag$4) {
20867     return false;
20868   }
20869   var proto = getPrototype(value);
20870   if (proto === null) {
20871     return true;
20872   }
20873   var Ctor = hasOwnProperty$13.call(proto, 'constructor') && proto.constructor;
20874   return typeof Ctor == 'function' && Ctor instanceof Ctor &&
20875     funcToString$2.call(Ctor) == objectCtorString;
20876 }
20877
20878 /**
20879  * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
20880  * objects.
20881  *
20882  * @private
20883  * @param {*} value The value to inspect.
20884  * @param {string} key The key of the property to inspect.
20885  * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
20886  */
20887 function customOmitClone(value) {
20888   return isPlainObject(value) ? undefined : value;
20889 }
20890
20891 /** Built-in value references. */
20892 var spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;
20893
20894 /**
20895  * Checks if `value` is a flattenable `arguments` object or array.
20896  *
20897  * @private
20898  * @param {*} value The value to check.
20899  * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
20900  */
20901 function isFlattenable(value) {
20902   return isArray(value) || isArguments(value) ||
20903     !!(spreadableSymbol && value && value[spreadableSymbol]);
20904 }
20905
20906 /**
20907  * The base implementation of `_.flatten` with support for restricting flattening.
20908  *
20909  * @private
20910  * @param {Array} array The array to flatten.
20911  * @param {number} depth The maximum recursion depth.
20912  * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
20913  * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
20914  * @param {Array} [result=[]] The initial result value.
20915  * @returns {Array} Returns the new flattened array.
20916  */
20917 function baseFlatten(array, depth, predicate, isStrict, result) {
20918   var index = -1,
20919       length = array.length;
20920
20921   predicate || (predicate = isFlattenable);
20922   result || (result = []);
20923
20924   while (++index < length) {
20925     var value = array[index];
20926     if (depth > 0 && predicate(value)) {
20927       if (depth > 1) {
20928         // Recursively flatten arrays (susceptible to call stack limits).
20929         baseFlatten(value, depth - 1, predicate, isStrict, result);
20930       } else {
20931         arrayPush(result, value);
20932       }
20933     } else if (!isStrict) {
20934       result[result.length] = value;
20935     }
20936   }
20937   return result;
20938 }
20939
20940 /**
20941  * Flattens `array` a single level deep.
20942  *
20943  * @static
20944  * @memberOf _
20945  * @since 0.1.0
20946  * @category Array
20947  * @param {Array} array The array to flatten.
20948  * @returns {Array} Returns the new flattened array.
20949  * @example
20950  *
20951  * _.flatten([1, [2, [3, [4]], 5]]);
20952  * // => [1, 2, [3, [4]], 5]
20953  */
20954 function flatten(array) {
20955   var length = array == null ? 0 : array.length;
20956   return length ? baseFlatten(array, 1) : [];
20957 }
20958
20959 /**
20960  * A faster alternative to `Function#apply`, this function invokes `func`
20961  * with the `this` binding of `thisArg` and the arguments of `args`.
20962  *
20963  * @private
20964  * @param {Function} func The function to invoke.
20965  * @param {*} thisArg The `this` binding of `func`.
20966  * @param {Array} args The arguments to invoke `func` with.
20967  * @returns {*} Returns the result of `func`.
20968  */
20969 function apply(func, thisArg, args) {
20970   switch (args.length) {
20971     case 0: return func.call(thisArg);
20972     case 1: return func.call(thisArg, args[0]);
20973     case 2: return func.call(thisArg, args[0], args[1]);
20974     case 3: return func.call(thisArg, args[0], args[1], args[2]);
20975   }
20976   return func.apply(thisArg, args);
20977 }
20978
20979 /* Built-in method references for those with the same name as other `lodash` methods. */
20980 var nativeMax = Math.max;
20981
20982 /**
20983  * A specialized version of `baseRest` which transforms the rest array.
20984  *
20985  * @private
20986  * @param {Function} func The function to apply a rest parameter to.
20987  * @param {number} [start=func.length-1] The start position of the rest parameter.
20988  * @param {Function} transform The rest array transform.
20989  * @returns {Function} Returns the new function.
20990  */
20991 function overRest(func, start, transform) {
20992   start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
20993   return function() {
20994     var args = arguments,
20995         index = -1,
20996         length = nativeMax(args.length - start, 0),
20997         array = Array(length);
20998
20999     while (++index < length) {
21000       array[index] = args[start + index];
21001     }
21002     index = -1;
21003     var otherArgs = Array(start + 1);
21004     while (++index < start) {
21005       otherArgs[index] = args[index];
21006     }
21007     otherArgs[start] = transform(array);
21008     return apply(func, this, otherArgs);
21009   };
21010 }
21011
21012 /**
21013  * Creates a function that returns `value`.
21014  *
21015  * @static
21016  * @memberOf _
21017  * @since 2.4.0
21018  * @category Util
21019  * @param {*} value The value to return from the new function.
21020  * @returns {Function} Returns the new constant function.
21021  * @example
21022  *
21023  * var objects = _.times(2, _.constant({ 'a': 1 }));
21024  *
21025  * console.log(objects);
21026  * // => [{ 'a': 1 }, { 'a': 1 }]
21027  *
21028  * console.log(objects[0] === objects[1]);
21029  * // => true
21030  */
21031 function constant$13(value) {
21032   return function() {
21033     return value;
21034   };
21035 }
21036
21037 /**
21038  * The base implementation of `setToString` without support for hot loop shorting.
21039  *
21040  * @private
21041  * @param {Function} func The function to modify.
21042  * @param {Function} string The `toString` result.
21043  * @returns {Function} Returns `func`.
21044  */
21045 var baseSetToString = !defineProperty ? identity$8 : function(func, string) {
21046   return defineProperty(func, 'toString', {
21047     'configurable': true,
21048     'enumerable': false,
21049     'value': constant$13(string),
21050     'writable': true
21051   });
21052 };
21053
21054 /** Used to detect hot functions by number of calls within a span of milliseconds. */
21055 var HOT_COUNT = 800;
21056 var HOT_SPAN = 16;
21057
21058 /* Built-in method references for those with the same name as other `lodash` methods. */
21059 var nativeNow = Date.now;
21060
21061 /**
21062  * Creates a function that'll short out and invoke `identity` instead
21063  * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
21064  * milliseconds.
21065  *
21066  * @private
21067  * @param {Function} func The function to restrict.
21068  * @returns {Function} Returns the new shortable function.
21069  */
21070 function shortOut(func) {
21071   var count = 0,
21072       lastCalled = 0;
21073
21074   return function() {
21075     var stamp = nativeNow(),
21076         remaining = HOT_SPAN - (stamp - lastCalled);
21077
21078     lastCalled = stamp;
21079     if (remaining > 0) {
21080       if (++count >= HOT_COUNT) {
21081         return arguments[0];
21082       }
21083     } else {
21084       count = 0;
21085     }
21086     return func.apply(undefined, arguments);
21087   };
21088 }
21089
21090 /**
21091  * Sets the `toString` method of `func` to return `string`.
21092  *
21093  * @private
21094  * @param {Function} func The function to modify.
21095  * @param {Function} string The `toString` result.
21096  * @returns {Function} Returns `func`.
21097  */
21098 var setToString = shortOut(baseSetToString);
21099
21100 /**
21101  * A specialized version of `baseRest` which flattens the rest array.
21102  *
21103  * @private
21104  * @param {Function} func The function to apply a rest parameter to.
21105  * @returns {Function} Returns the new function.
21106  */
21107 function flatRest(func) {
21108   return setToString(overRest(func, undefined, flatten), func + '');
21109 }
21110
21111 /** Used to compose bitmasks for cloning. */
21112 var CLONE_DEEP_FLAG$3 = 1;
21113 var CLONE_FLAT_FLAG$1 = 2;
21114 var CLONE_SYMBOLS_FLAG$2 = 4;
21115
21116 /**
21117  * The opposite of `_.pick`; this method creates an object composed of the
21118  * own and inherited enumerable property paths of `object` that are not omitted.
21119  *
21120  * **Note:** This method is considerably slower than `_.pick`.
21121  *
21122  * @static
21123  * @since 0.1.0
21124  * @memberOf _
21125  * @category Object
21126  * @param {Object} object The source object.
21127  * @param {...(string|string[])} [paths] The property paths to omit.
21128  * @returns {Object} Returns the new object.
21129  * @example
21130  *
21131  * var object = { 'a': 1, 'b': '2', 'c': 3 };
21132  *
21133  * _.omit(object, ['a', 'c']);
21134  * // => { 'b': '2' }
21135  */
21136 var omit = flatRest(function(object, paths) {
21137   var result = {};
21138   if (object == null) {
21139     return result;
21140   }
21141   var isDeep = false;
21142   paths = arrayMap(paths, function(path) {
21143     path = castPath(path, object);
21144     isDeep || (isDeep = path.length > 1);
21145     return path;
21146   });
21147   copyObject(object, getAllKeysIn(object), result);
21148   if (isDeep) {
21149     result = baseClone(result, CLONE_DEEP_FLAG$3 | CLONE_FLAT_FLAG$1 | CLONE_SYMBOLS_FLAG$2, customOmitClone);
21150   }
21151   var length = paths.length;
21152   while (length--) {
21153     baseUnset(result, paths[length]);
21154   }
21155   return result;
21156 });
21157
21158 /**
21159  * Creates an array with all falsey values removed. The values `false`, `null`,
21160  * `0`, `""`, `undefined`, and `NaN` are falsey.
21161  *
21162  * @static
21163  * @memberOf _
21164  * @since 0.1.0
21165  * @category Array
21166  * @param {Array} array The array to compact.
21167  * @returns {Array} Returns the new array of filtered values.
21168  * @example
21169  *
21170  * _.compact([0, 1, false, 2, '', 3]);
21171  * // => [1, 2, 3]
21172  */
21173 function compact(array) {
21174   var index = -1,
21175       length = array == null ? 0 : array.length,
21176       resIndex = 0,
21177       result = [];
21178
21179   while (++index < length) {
21180     var value = array[index];
21181     if (value) {
21182       result[resIndex++] = value;
21183     }
21184   }
21185   return result;
21186 }
21187
21188 /**
21189  * The base implementation of `_.rest` which doesn't validate or coerce arguments.
21190  *
21191  * @private
21192  * @param {Function} func The function to apply a rest parameter to.
21193  * @param {number} [start=func.length-1] The start position of the rest parameter.
21194  * @returns {Function} Returns the new function.
21195  */
21196 function baseRest(func, start) {
21197   return setToString(overRest(func, start, identity$8), func + '');
21198 }
21199
21200 /**
21201  * Checks if the given arguments are from an iteratee call.
21202  *
21203  * @private
21204  * @param {*} value The potential iteratee value argument.
21205  * @param {*} index The potential iteratee index or key argument.
21206  * @param {*} object The potential iteratee object argument.
21207  * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
21208  *  else `false`.
21209  */
21210 function isIterateeCall(value, index, object) {
21211   if (!isObject(object)) {
21212     return false;
21213   }
21214   var type = typeof index;
21215   if (type == 'number'
21216         ? (isArrayLike(object) && isIndex(index, object.length))
21217         : (type == 'string' && index in object)
21218       ) {
21219     return eq(object[index], value);
21220   }
21221   return false;
21222 }
21223
21224 /**
21225  * Creates a function like `_.assign`.
21226  *
21227  * @private
21228  * @param {Function} assigner The function to assign values.
21229  * @returns {Function} Returns the new assigner function.
21230  */
21231 function createAssigner(assigner) {
21232   return baseRest(function(object, sources) {
21233     var index = -1,
21234         length = sources.length,
21235         customizer = length > 1 ? sources[length - 1] : undefined,
21236         guard = length > 2 ? sources[2] : undefined;
21237
21238     customizer = (assigner.length > 3 && typeof customizer == 'function')
21239       ? (length--, customizer)
21240       : undefined;
21241
21242     if (guard && isIterateeCall(sources[0], sources[1], guard)) {
21243       customizer = length < 3 ? undefined : customizer;
21244       length = 1;
21245     }
21246     object = Object(object);
21247     while (++index < length) {
21248       var source = sources[index];
21249       if (source) {
21250         assigner(object, source, index, customizer);
21251       }
21252     }
21253     return object;
21254   });
21255 }
21256
21257 /**
21258  * This method is like `_.assign` except that it iterates over own and
21259  * inherited source properties.
21260  *
21261  * **Note:** This method mutates `object`.
21262  *
21263  * @static
21264  * @memberOf _
21265  * @since 4.0.0
21266  * @alias extend
21267  * @category Object
21268  * @param {Object} object The destination object.
21269  * @param {...Object} [sources] The source objects.
21270  * @returns {Object} Returns `object`.
21271  * @see _.assign
21272  * @example
21273  *
21274  * function Foo() {
21275  *   this.a = 1;
21276  * }
21277  *
21278  * function Bar() {
21279  *   this.c = 3;
21280  * }
21281  *
21282  * Foo.prototype.b = 2;
21283  * Bar.prototype.d = 4;
21284  *
21285  * _.assignIn({ 'a': 0 }, new Foo, new Bar);
21286  * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
21287  */
21288 var assignIn = createAssigner(function(object, source) {
21289   copyObject(source, keysIn$1(source), object);
21290 });
21291
21292 /**
21293  * The base implementation of `_.filter` without support for iteratee shorthands.
21294  *
21295  * @private
21296  * @param {Array|Object} collection The collection to iterate over.
21297  * @param {Function} predicate The function invoked per iteration.
21298  * @returns {Array} Returns the new filtered array.
21299  */
21300 function baseFilter(collection, predicate) {
21301   var result = [];
21302   baseEach(collection, function(value, index, collection) {
21303     if (predicate(value, index, collection)) {
21304       result.push(value);
21305     }
21306   });
21307   return result;
21308 }
21309
21310 /**
21311  * Iterates over elements of `collection`, returning an array of all elements
21312  * `predicate` returns truthy for. The predicate is invoked with three
21313  * arguments: (value, index|key, collection).
21314  *
21315  * **Note:** Unlike `_.remove`, this method returns a new array.
21316  *
21317  * @static
21318  * @memberOf _
21319  * @since 0.1.0
21320  * @category Collection
21321  * @param {Array|Object} collection The collection to iterate over.
21322  * @param {Function} [predicate=_.identity] The function invoked per iteration.
21323  * @returns {Array} Returns the new filtered array.
21324  * @see _.reject
21325  * @example
21326  *
21327  * var users = [
21328  *   { 'user': 'barney', 'age': 36, 'active': true },
21329  *   { 'user': 'fred',   'age': 40, 'active': false }
21330  * ];
21331  *
21332  * _.filter(users, function(o) { return !o.active; });
21333  * // => objects for ['fred']
21334  *
21335  * // The `_.matches` iteratee shorthand.
21336  * _.filter(users, { 'age': 36, 'active': true });
21337  * // => objects for ['barney']
21338  *
21339  * // The `_.matchesProperty` iteratee shorthand.
21340  * _.filter(users, ['active', false]);
21341  * // => objects for ['fred']
21342  *
21343  * // The `_.property` iteratee shorthand.
21344  * _.filter(users, 'active');
21345  * // => objects for ['barney']
21346  */
21347 function filter(collection, predicate) {
21348   var func = isArray(collection) ? arrayFilter : baseFilter;
21349   return func(collection, baseIteratee(predicate, 3));
21350 }
21351
21352 /**
21353  * Creates a `_.find` or `_.findLast` function.
21354  *
21355  * @private
21356  * @param {Function} findIndexFunc The function to find the collection index.
21357  * @returns {Function} Returns the new find function.
21358  */
21359 function createFind(findIndexFunc) {
21360   return function(collection, predicate, fromIndex) {
21361     var iterable = Object(collection);
21362     if (!isArrayLike(collection)) {
21363       var iteratee = baseIteratee(predicate, 3);
21364       collection = keys$1(collection);
21365       predicate = function(key) { return iteratee(iterable[key], key, iterable); };
21366     }
21367     var index = findIndexFunc(collection, predicate, fromIndex);
21368     return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
21369   };
21370 }
21371
21372 /**
21373  * The base implementation of `_.findIndex` and `_.findLastIndex` without
21374  * support for iteratee shorthands.
21375  *
21376  * @private
21377  * @param {Array} array The array to inspect.
21378  * @param {Function} predicate The function invoked per iteration.
21379  * @param {number} fromIndex The index to search from.
21380  * @param {boolean} [fromRight] Specify iterating from right to left.
21381  * @returns {number} Returns the index of the matched value, else `-1`.
21382  */
21383 function baseFindIndex(array, predicate, fromIndex, fromRight) {
21384   var length = array.length,
21385       index = fromIndex + (fromRight ? 1 : -1);
21386
21387   while ((fromRight ? index-- : ++index < length)) {
21388     if (predicate(array[index], index, array)) {
21389       return index;
21390     }
21391   }
21392   return -1;
21393 }
21394
21395 /** Used as references for various `Number` constants. */
21396 var NAN = 0 / 0;
21397
21398 /** Used to match leading and trailing whitespace. */
21399 var reTrim = /^\s+|\s+$/g;
21400
21401 /** Used to detect bad signed hexadecimal string values. */
21402 var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
21403
21404 /** Used to detect binary string values. */
21405 var reIsBinary = /^0b[01]+$/i;
21406
21407 /** Used to detect octal string values. */
21408 var reIsOctal = /^0o[0-7]+$/i;
21409
21410 /** Built-in method references without a dependency on `root`. */
21411 var freeParseInt = parseInt;
21412
21413 /**
21414  * Converts `value` to a number.
21415  *
21416  * @static
21417  * @memberOf _
21418  * @since 4.0.0
21419  * @category Lang
21420  * @param {*} value The value to process.
21421  * @returns {number} Returns the number.
21422  * @example
21423  *
21424  * _.toNumber(3.2);
21425  * // => 3.2
21426  *
21427  * _.toNumber(Number.MIN_VALUE);
21428  * // => 5e-324
21429  *
21430  * _.toNumber(Infinity);
21431  * // => Infinity
21432  *
21433  * _.toNumber('3.2');
21434  * // => 3.2
21435  */
21436 function toNumber(value) {
21437   if (typeof value == 'number') {
21438     return value;
21439   }
21440   if (isSymbol(value)) {
21441     return NAN;
21442   }
21443   if (isObject(value)) {
21444     var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
21445     value = isObject(other) ? (other + '') : other;
21446   }
21447   if (typeof value != 'string') {
21448     return value === 0 ? value : +value;
21449   }
21450   value = value.replace(reTrim, '');
21451   var isBinary = reIsBinary.test(value);
21452   return (isBinary || reIsOctal.test(value))
21453     ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
21454     : (reIsBadHex.test(value) ? NAN : +value);
21455 }
21456
21457 /** Used as references for various `Number` constants. */
21458 var INFINITY$2 = 1 / 0;
21459 var MAX_INTEGER = 1.7976931348623157e+308;
21460
21461 /**
21462  * Converts `value` to a finite number.
21463  *
21464  * @static
21465  * @memberOf _
21466  * @since 4.12.0
21467  * @category Lang
21468  * @param {*} value The value to convert.
21469  * @returns {number} Returns the converted number.
21470  * @example
21471  *
21472  * _.toFinite(3.2);
21473  * // => 3.2
21474  *
21475  * _.toFinite(Number.MIN_VALUE);
21476  * // => 5e-324
21477  *
21478  * _.toFinite(Infinity);
21479  * // => 1.7976931348623157e+308
21480  *
21481  * _.toFinite('3.2');
21482  * // => 3.2
21483  */
21484 function toFinite(value) {
21485   if (!value) {
21486     return value === 0 ? value : 0;
21487   }
21488   value = toNumber(value);
21489   if (value === INFINITY$2 || value === -INFINITY$2) {
21490     var sign = (value < 0 ? -1 : 1);
21491     return sign * MAX_INTEGER;
21492   }
21493   return value === value ? value : 0;
21494 }
21495
21496 /**
21497  * Converts `value` to an integer.
21498  *
21499  * **Note:** This method is loosely based on
21500  * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
21501  *
21502  * @static
21503  * @memberOf _
21504  * @since 4.0.0
21505  * @category Lang
21506  * @param {*} value The value to convert.
21507  * @returns {number} Returns the converted integer.
21508  * @example
21509  *
21510  * _.toInteger(3.2);
21511  * // => 3
21512  *
21513  * _.toInteger(Number.MIN_VALUE);
21514  * // => 0
21515  *
21516  * _.toInteger(Infinity);
21517  * // => 1.7976931348623157e+308
21518  *
21519  * _.toInteger('3.2');
21520  * // => 3
21521  */
21522 function toInteger(value) {
21523   var result = toFinite(value),
21524       remainder = result % 1;
21525
21526   return result === result ? (remainder ? result - remainder : result) : 0;
21527 }
21528
21529 /* Built-in method references for those with the same name as other `lodash` methods. */
21530 var nativeMax$1 = Math.max;
21531
21532 /**
21533  * This method is like `_.find` except that it returns the index of the first
21534  * element `predicate` returns truthy for instead of the element itself.
21535  *
21536  * @static
21537  * @memberOf _
21538  * @since 1.1.0
21539  * @category Array
21540  * @param {Array} array The array to inspect.
21541  * @param {Function} [predicate=_.identity] The function invoked per iteration.
21542  * @param {number} [fromIndex=0] The index to search from.
21543  * @returns {number} Returns the index of the found element, else `-1`.
21544  * @example
21545  *
21546  * var users = [
21547  *   { 'user': 'barney',  'active': false },
21548  *   { 'user': 'fred',    'active': false },
21549  *   { 'user': 'pebbles', 'active': true }
21550  * ];
21551  *
21552  * _.findIndex(users, function(o) { return o.user == 'barney'; });
21553  * // => 0
21554  *
21555  * // The `_.matches` iteratee shorthand.
21556  * _.findIndex(users, { 'user': 'fred', 'active': false });
21557  * // => 1
21558  *
21559  * // The `_.matchesProperty` iteratee shorthand.
21560  * _.findIndex(users, ['active', false]);
21561  * // => 0
21562  *
21563  * // The `_.property` iteratee shorthand.
21564  * _.findIndex(users, 'active');
21565  * // => 2
21566  */
21567 function findIndex(array, predicate, fromIndex) {
21568   var length = array == null ? 0 : array.length;
21569   if (!length) {
21570     return -1;
21571   }
21572   var index = fromIndex == null ? 0 : toInteger(fromIndex);
21573   if (index < 0) {
21574     index = nativeMax$1(length + index, 0);
21575   }
21576   return baseFindIndex(array, baseIteratee(predicate, 3), index);
21577 }
21578
21579 /**
21580  * Iterates over elements of `collection`, returning the first element
21581  * `predicate` returns truthy for. The predicate is invoked with three
21582  * arguments: (value, index|key, collection).
21583  *
21584  * @static
21585  * @memberOf _
21586  * @since 0.1.0
21587  * @category Collection
21588  * @param {Array|Object} collection The collection to inspect.
21589  * @param {Function} [predicate=_.identity] The function invoked per iteration.
21590  * @param {number} [fromIndex=0] The index to search from.
21591  * @returns {*} Returns the matched element, else `undefined`.
21592  * @example
21593  *
21594  * var users = [
21595  *   { 'user': 'barney',  'age': 36, 'active': true },
21596  *   { 'user': 'fred',    'age': 40, 'active': false },
21597  *   { 'user': 'pebbles', 'age': 1,  'active': true }
21598  * ];
21599  *
21600  * _.find(users, function(o) { return o.age < 40; });
21601  * // => object for 'barney'
21602  *
21603  * // The `_.matches` iteratee shorthand.
21604  * _.find(users, { 'age': 1, 'active': true });
21605  * // => object for 'pebbles'
21606  *
21607  * // The `_.matchesProperty` iteratee shorthand.
21608  * _.find(users, ['active', false]);
21609  * // => object for 'fred'
21610  *
21611  * // The `_.property` iteratee shorthand.
21612  * _.find(users, 'active');
21613  * // => object for 'barney'
21614  */
21615 var find$1 = createFind(findIndex);
21616
21617 /**
21618  * The base implementation of `_.map` without support for iteratee shorthands.
21619  *
21620  * @private
21621  * @param {Array|Object} collection The collection to iterate over.
21622  * @param {Function} iteratee The function invoked per iteration.
21623  * @returns {Array} Returns the new mapped array.
21624  */
21625 function baseMap(collection, iteratee) {
21626   var index = -1,
21627       result = isArrayLike(collection) ? Array(collection.length) : [];
21628
21629   baseEach(collection, function(value, key, collection) {
21630     result[++index] = iteratee(value, key, collection);
21631   });
21632   return result;
21633 }
21634
21635 /**
21636  * Creates an array of values by running each element in `collection` thru
21637  * `iteratee`. The iteratee is invoked with three arguments:
21638  * (value, index|key, collection).
21639  *
21640  * Many lodash methods are guarded to work as iteratees for methods like
21641  * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
21642  *
21643  * The guarded methods are:
21644  * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
21645  * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
21646  * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
21647  * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
21648  *
21649  * @static
21650  * @memberOf _
21651  * @since 0.1.0
21652  * @category Collection
21653  * @param {Array|Object} collection The collection to iterate over.
21654  * @param {Function} [iteratee=_.identity] The function invoked per iteration.
21655  * @returns {Array} Returns the new mapped array.
21656  * @example
21657  *
21658  * function square(n) {
21659  *   return n * n;
21660  * }
21661  *
21662  * _.map([4, 8], square);
21663  * // => [16, 64]
21664  *
21665  * _.map({ 'a': 4, 'b': 8 }, square);
21666  * // => [16, 64] (iteration order is not guaranteed)
21667  *
21668  * var users = [
21669  *   { 'user': 'barney' },
21670  *   { 'user': 'fred' }
21671  * ];
21672  *
21673  * // The `_.property` iteratee shorthand.
21674  * _.map(users, 'user');
21675  * // => ['barney', 'fred']
21676  */
21677 function map$4(collection, iteratee) {
21678   var func = isArray(collection) ? arrayMap : baseMap;
21679   return func(collection, baseIteratee(iteratee, 3));
21680 }
21681
21682 /**
21683  * The base implementation of `_.values` and `_.valuesIn` which creates an
21684  * array of `object` property values corresponding to the property names
21685  * of `props`.
21686  *
21687  * @private
21688  * @param {Object} object The object to query.
21689  * @param {Array} props The property names to get values for.
21690  * @returns {Object} Returns the array of property values.
21691  */
21692 function baseValues(object, props) {
21693   return arrayMap(props, function(key) {
21694     return object[key];
21695   });
21696 }
21697
21698 /**
21699  * Creates an array of the own enumerable string keyed property values of `object`.
21700  *
21701  * **Note:** Non-object values are coerced to objects.
21702  *
21703  * @static
21704  * @since 0.1.0
21705  * @memberOf _
21706  * @category Object
21707  * @param {Object} object The object to query.
21708  * @returns {Array} Returns the array of property values.
21709  * @example
21710  *
21711  * function Foo() {
21712  *   this.a = 1;
21713  *   this.b = 2;
21714  * }
21715  *
21716  * Foo.prototype.c = 3;
21717  *
21718  * _.values(new Foo);
21719  * // => [1, 2] (iteration order is not guaranteed)
21720  *
21721  * _.values('hi');
21722  * // => ['h', 'i']
21723  */
21724 function values$1(object) {
21725   return object == null ? [] : baseValues(object, keys$1(object));
21726 }
21727
21728 /**
21729  * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
21730  * of key-value pairs for `object` corresponding to the property names of `props`.
21731  *
21732  * @private
21733  * @param {Object} object The object to query.
21734  * @param {Array} props The property names to get values for.
21735  * @returns {Object} Returns the key-value pairs.
21736  */
21737 function baseToPairs(object, props) {
21738   return arrayMap(props, function(key) {
21739     return [key, object[key]];
21740   });
21741 }
21742
21743 /**
21744  * Converts `set` to its value-value pairs.
21745  *
21746  * @private
21747  * @param {Object} set The set to convert.
21748  * @returns {Array} Returns the value-value pairs.
21749  */
21750 function setToPairs(set) {
21751   var index = -1,
21752       result = Array(set.size);
21753
21754   set.forEach(function(value) {
21755     result[++index] = [value, value];
21756   });
21757   return result;
21758 }
21759
21760 /** `Object#toString` result references. */
21761 var mapTag$5 = '[object Map]';
21762 var setTag$5 = '[object Set]';
21763
21764 /**
21765  * Creates a `_.toPairs` or `_.toPairsIn` function.
21766  *
21767  * @private
21768  * @param {Function} keysFunc The function to get the keys of a given object.
21769  * @returns {Function} Returns the new pairs function.
21770  */
21771 function createToPairs(keysFunc) {
21772   return function(object) {
21773     var tag = getTag$1(object);
21774     if (tag == mapTag$5) {
21775       return mapToArray(object);
21776     }
21777     if (tag == setTag$5) {
21778       return setToPairs(object);
21779     }
21780     return baseToPairs(object, keysFunc(object));
21781   };
21782 }
21783
21784 /**
21785  * Creates an array of own enumerable string keyed-value pairs for `object`
21786  * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
21787  * entries are returned.
21788  *
21789  * @static
21790  * @memberOf _
21791  * @since 4.0.0
21792  * @alias entries
21793  * @category Object
21794  * @param {Object} object The object to query.
21795  * @returns {Array} Returns the key-value pairs.
21796  * @example
21797  *
21798  * function Foo() {
21799  *   this.a = 1;
21800  *   this.b = 2;
21801  * }
21802  *
21803  * Foo.prototype.c = 3;
21804  *
21805  * _.toPairs(new Foo);
21806  * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
21807  */
21808 var toPairs = createToPairs(keys$1);
21809
21810 /**
21811  * The base implementation of `_.isNaN` without support for number objects.
21812  *
21813  * @private
21814  * @param {*} value The value to check.
21815  * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
21816  */
21817 function baseIsNaN(value) {
21818   return value !== value;
21819 }
21820
21821 /**
21822  * A specialized version of `_.indexOf` which performs strict equality
21823  * comparisons of values, i.e. `===`.
21824  *
21825  * @private
21826  * @param {Array} array The array to inspect.
21827  * @param {*} value The value to search for.
21828  * @param {number} fromIndex The index to search from.
21829  * @returns {number} Returns the index of the matched value, else `-1`.
21830  */
21831 function strictIndexOf(array, value, fromIndex) {
21832   var index = fromIndex - 1,
21833       length = array.length;
21834
21835   while (++index < length) {
21836     if (array[index] === value) {
21837       return index;
21838     }
21839   }
21840   return -1;
21841 }
21842
21843 /**
21844  * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
21845  *
21846  * @private
21847  * @param {Array} array The array to inspect.
21848  * @param {*} value The value to search for.
21849  * @param {number} fromIndex The index to search from.
21850  * @returns {number} Returns the index of the matched value, else `-1`.
21851  */
21852 function baseIndexOf(array, value, fromIndex) {
21853   return value === value
21854     ? strictIndexOf(array, value, fromIndex)
21855     : baseFindIndex(array, baseIsNaN, fromIndex);
21856 }
21857
21858 /**
21859  * A specialized version of `_.includes` for arrays without support for
21860  * specifying an index to search from.
21861  *
21862  * @private
21863  * @param {Array} [array] The array to inspect.
21864  * @param {*} target The value to search for.
21865  * @returns {boolean} Returns `true` if `target` is found, else `false`.
21866  */
21867 function arrayIncludes(array, value) {
21868   var length = array == null ? 0 : array.length;
21869   return !!length && baseIndexOf(array, value, 0) > -1;
21870 }
21871
21872 /**
21873  * This function is like `arrayIncludes` except that it accepts a comparator.
21874  *
21875  * @private
21876  * @param {Array} [array] The array to inspect.
21877  * @param {*} target The value to search for.
21878  * @param {Function} comparator The comparator invoked per element.
21879  * @returns {boolean} Returns `true` if `target` is found, else `false`.
21880  */
21881 function arrayIncludesWith(array, value, comparator) {
21882   var index = -1,
21883       length = array == null ? 0 : array.length;
21884
21885   while (++index < length) {
21886     if (comparator(value, array[index])) {
21887       return true;
21888     }
21889   }
21890   return false;
21891 }
21892
21893 /**
21894  * This method returns `undefined`.
21895  *
21896  * @static
21897  * @memberOf _
21898  * @since 2.3.0
21899  * @category Util
21900  * @example
21901  *
21902  * _.times(2, _.noop);
21903  * // => [undefined, undefined]
21904  */
21905 function noop$3() {
21906   // No operation performed.
21907 }
21908
21909 /** Used as references for various `Number` constants. */
21910 var INFINITY$3 = 1 / 0;
21911
21912 /**
21913  * Creates a set object of `values`.
21914  *
21915  * @private
21916  * @param {Array} values The values to add to the set.
21917  * @returns {Object} Returns the new set.
21918  */
21919 var createSet = !(Set$1 && (1 / setToArray(new Set$1([,-0]))[1]) == INFINITY$3) ? noop$3 : function(values) {
21920   return new Set$1(values);
21921 };
21922
21923 /** Used as the size to enable large array optimizations. */
21924 var LARGE_ARRAY_SIZE$1 = 200;
21925
21926 /**
21927  * The base implementation of `_.uniqBy` without support for iteratee shorthands.
21928  *
21929  * @private
21930  * @param {Array} array The array to inspect.
21931  * @param {Function} [iteratee] The iteratee invoked per element.
21932  * @param {Function} [comparator] The comparator invoked per element.
21933  * @returns {Array} Returns the new duplicate free array.
21934  */
21935 function baseUniq(array, iteratee, comparator) {
21936   var index = -1,
21937       includes = arrayIncludes,
21938       length = array.length,
21939       isCommon = true,
21940       result = [],
21941       seen = result;
21942
21943   if (comparator) {
21944     isCommon = false;
21945     includes = arrayIncludesWith;
21946   }
21947   else if (length >= LARGE_ARRAY_SIZE$1) {
21948     var set = iteratee ? null : createSet(array);
21949     if (set) {
21950       return setToArray(set);
21951     }
21952     isCommon = false;
21953     includes = cacheHas;
21954     seen = new SetCache;
21955   }
21956   else {
21957     seen = iteratee ? [] : result;
21958   }
21959   outer:
21960   while (++index < length) {
21961     var value = array[index],
21962         computed = iteratee ? iteratee(value) : value;
21963
21964     value = (comparator || value !== 0) ? value : 0;
21965     if (isCommon && computed === computed) {
21966       var seenIndex = seen.length;
21967       while (seenIndex--) {
21968         if (seen[seenIndex] === computed) {
21969           continue outer;
21970         }
21971       }
21972       if (iteratee) {
21973         seen.push(computed);
21974       }
21975       result.push(value);
21976     }
21977     else if (!includes(seen, computed, comparator)) {
21978       if (seen !== result) {
21979         seen.push(computed);
21980       }
21981       result.push(value);
21982     }
21983   }
21984   return result;
21985 }
21986
21987 /**
21988  * This method is like `_.isArrayLike` except that it also checks if `value`
21989  * is an object.
21990  *
21991  * @static
21992  * @memberOf _
21993  * @since 4.0.0
21994  * @category Lang
21995  * @param {*} value The value to check.
21996  * @returns {boolean} Returns `true` if `value` is an array-like object,
21997  *  else `false`.
21998  * @example
21999  *
22000  * _.isArrayLikeObject([1, 2, 3]);
22001  * // => true
22002  *
22003  * _.isArrayLikeObject(document.body.children);
22004  * // => true
22005  *
22006  * _.isArrayLikeObject('abc');
22007  * // => false
22008  *
22009  * _.isArrayLikeObject(_.noop);
22010  * // => false
22011  */
22012 function isArrayLikeObject(value) {
22013   return isObjectLike(value) && isArrayLike(value);
22014 }
22015
22016 /**
22017  * Creates an array of unique values, in order, from all given arrays using
22018  * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
22019  * for equality comparisons.
22020  *
22021  * @static
22022  * @memberOf _
22023  * @since 0.1.0
22024  * @category Array
22025  * @param {...Array} [arrays] The arrays to inspect.
22026  * @returns {Array} Returns the new array of combined values.
22027  * @example
22028  *
22029  * _.union([2], [1, 2]);
22030  * // => [2, 1]
22031  */
22032 var union = baseRest(function(arrays) {
22033   return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
22034 });
22035
22036 /** Used as the size to enable large array optimizations. */
22037 var LARGE_ARRAY_SIZE$2 = 200;
22038
22039 /**
22040  * The base implementation of methods like `_.difference` without support
22041  * for excluding multiple arrays or iteratee shorthands.
22042  *
22043  * @private
22044  * @param {Array} array The array to inspect.
22045  * @param {Array} values The values to exclude.
22046  * @param {Function} [iteratee] The iteratee invoked per element.
22047  * @param {Function} [comparator] The comparator invoked per element.
22048  * @returns {Array} Returns the new array of filtered values.
22049  */
22050 function baseDifference(array, values, iteratee, comparator) {
22051   var index = -1,
22052       includes = arrayIncludes,
22053       isCommon = true,
22054       length = array.length,
22055       result = [],
22056       valuesLength = values.length;
22057
22058   if (!length) {
22059     return result;
22060   }
22061   if (iteratee) {
22062     values = arrayMap(values, baseUnary(iteratee));
22063   }
22064   if (comparator) {
22065     includes = arrayIncludesWith;
22066     isCommon = false;
22067   }
22068   else if (values.length >= LARGE_ARRAY_SIZE$2) {
22069     includes = cacheHas;
22070     isCommon = false;
22071     values = new SetCache(values);
22072   }
22073   outer:
22074   while (++index < length) {
22075     var value = array[index],
22076         computed = iteratee == null ? value : iteratee(value);
22077
22078     value = (comparator || value !== 0) ? value : 0;
22079     if (isCommon && computed === computed) {
22080       var valuesIndex = valuesLength;
22081       while (valuesIndex--) {
22082         if (values[valuesIndex] === computed) {
22083           continue outer;
22084         }
22085       }
22086       result.push(value);
22087     }
22088     else if (!includes(values, computed, comparator)) {
22089       result.push(value);
22090     }
22091   }
22092   return result;
22093 }
22094
22095 /**
22096  * Creates an array excluding all given values using
22097  * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
22098  * for equality comparisons.
22099  *
22100  * **Note:** Unlike `_.pull`, this method returns a new array.
22101  *
22102  * @static
22103  * @memberOf _
22104  * @since 0.1.0
22105  * @category Array
22106  * @param {Array} array The array to inspect.
22107  * @param {...*} [values] The values to exclude.
22108  * @returns {Array} Returns the new array of filtered values.
22109  * @see _.difference, _.xor
22110  * @example
22111  *
22112  * _.without([2, 1, 2, 3], 1, 2);
22113  * // => [3]
22114  */
22115 var without = baseRest(function(array, values) {
22116   return isArrayLikeObject(array)
22117     ? baseDifference(array, values)
22118     : [];
22119 });
22120
22121 function osmIsInterestingTag(key) {
22122     return key !== 'attribution' &&
22123         key !== 'created_by' &&
22124         key !== 'source' &&
22125         key !== 'odbl' &&
22126         key.indexOf('tiger:') !== 0;
22127
22128 }
22129
22130
22131 var osmOneWayTags = {
22132     'aerialway': {
22133         'chair_lift': true,
22134         'mixed_lift': true,
22135         't-bar': true,
22136         'j-bar': true,
22137         'platter': true,
22138         'rope_tow': true,
22139         'magic_carpet': true,
22140         'yes': true
22141     },
22142     'highway': {
22143         'motorway': true,
22144         'motorway_link': true
22145     },
22146     'junction': {
22147         'circular': true,
22148         'roundabout': true
22149     },
22150     'man_made': {
22151         'piste:halfpipe': true
22152     },
22153     'piste:type': {
22154         'downhill': true,
22155         'sled': true,
22156         'yes': true
22157     },
22158     'waterway': {
22159         'canal': true,
22160         'ditch': true,
22161         'drain': true,
22162         'river': true,
22163         'stream': true
22164     }
22165 };
22166
22167
22168 var osmPavedTags = {
22169     'surface': {
22170         'paved': true,
22171         'asphalt': true,
22172         'concrete': true,
22173         'concrete:lanes': true,
22174         'concrete:plates': true
22175     },
22176     'tracktype': {
22177         'grade1': true
22178     }
22179 };
22180
22181 var wikipedia = [
22182     [
22183         "Abkhazian",
22184         "Аҧсшәа",
22185         "ab"
22186     ],
22187     [
22188         "Achinese",
22189         "Acèh",
22190         "ace"
22191     ],
22192     [
22193         "Adyghe",
22194         "адыгабзэ",
22195         "ady"
22196     ],
22197     [
22198         "Afrikaans",
22199         "Afrikaans",
22200         "af"
22201     ],
22202     [
22203         "Akan",
22204         "Akan",
22205         "ak"
22206     ],
22207     [
22208         "Alemannisch",
22209         "Alemannisch",
22210         "als"
22211     ],
22212     [
22213         "Amharic",
22214         "አማርኛ",
22215         "am"
22216     ],
22217     [
22218         "Aragonese",
22219         "aragonés",
22220         "an"
22221     ],
22222     [
22223         "Old English",
22224         "Ænglisc",
22225         "ang"
22226     ],
22227     [
22228         "Arabic",
22229         "العربية",
22230         "ar"
22231     ],
22232     [
22233         "Aramaic",
22234         "ܐܪܡܝܐ",
22235         "arc"
22236     ],
22237     [
22238         "Egyptian Arabic",
22239         "مصرى",
22240         "arz"
22241     ],
22242     [
22243         "Assamese",
22244         "অসমীয়া",
22245         "as"
22246     ],
22247     [
22248         "Asturian",
22249         "asturianu",
22250         "ast"
22251     ],
22252     [
22253         "Avaric",
22254         "авар",
22255         "av"
22256     ],
22257     [
22258         "Aymara",
22259         "Aymar aru",
22260         "ay"
22261     ],
22262     [
22263         "Azerbaijani",
22264         "azərbaycanca",
22265         "az"
22266     ],
22267     [
22268         "تۆرکجه",
22269         "تۆرکجه",
22270         "azb"
22271     ],
22272     [
22273         "Bashkir",
22274         "башҡортса",
22275         "ba"
22276     ],
22277     [
22278         "Bavarian",
22279         "Boarisch",
22280         "bar"
22281     ],
22282     [
22283         "Samogitian",
22284         "žemaitėška",
22285         "bat-smg"
22286     ],
22287     [
22288         "Bikol Central",
22289         "Bikol Central",
22290         "bcl"
22291     ],
22292     [
22293         "Belarusian",
22294         "беларуская",
22295         "be"
22296     ],
22297     [
22298         "беларуская (тарашкевіца)‎",
22299         "беларуская (тарашкевіца)‎",
22300         "be-x-old"
22301     ],
22302     [
22303         "Bulgarian",
22304         "български",
22305         "bg"
22306     ],
22307     [
22308         "भोजपुरी",
22309         "भोजपुरी",
22310         "bh"
22311     ],
22312     [
22313         "Bislama",
22314         "Bislama",
22315         "bi"
22316     ],
22317     [
22318         "Banjar",
22319         "Bahasa Banjar",
22320         "bjn"
22321     ],
22322     [
22323         "Bambara",
22324         "bamanankan",
22325         "bm"
22326     ],
22327     [
22328         "Bangla",
22329         "বাংলা",
22330         "bn"
22331     ],
22332     [
22333         "Tibetan",
22334         "བོད་ཡིག",
22335         "bo"
22336     ],
22337     [
22338         "Bishnupriya",
22339         "বিষ্ণুপ্রিয়া মণিপুরী",
22340         "bpy"
22341     ],
22342     [
22343         "Breton",
22344         "brezhoneg",
22345         "br"
22346     ],
22347     [
22348         "Bosnian",
22349         "bosanski",
22350         "bs"
22351     ],
22352     [
22353         "Buginese",
22354         "ᨅᨔ ᨕᨘᨁᨗ",
22355         "bug"
22356     ],
22357     [
22358         "буряад",
22359         "буряад",
22360         "bxr"
22361     ],
22362     [
22363         "Catalan",
22364         "català",
22365         "ca"
22366     ],
22367     [
22368         "Chavacano de Zamboanga",
22369         "Chavacano de Zamboanga",
22370         "cbk-zam"
22371     ],
22372     [
22373         "Min Dong Chinese",
22374         "Mìng-dĕ̤ng-ngṳ̄",
22375         "cdo"
22376     ],
22377     [
22378         "Chechen",
22379         "нохчийн",
22380         "ce"
22381     ],
22382     [
22383         "Cebuano",
22384         "Cebuano",
22385         "ceb"
22386     ],
22387     [
22388         "Chamorro",
22389         "Chamoru",
22390         "ch"
22391     ],
22392     [
22393         "Cherokee",
22394         "ᏣᎳᎩ",
22395         "chr"
22396     ],
22397     [
22398         "Cheyenne",
22399         "Tsetsêhestâhese",
22400         "chy"
22401     ],
22402     [
22403         "Central Kurdish",
22404         "کوردیی ناوەندی",
22405         "ckb"
22406     ],
22407     [
22408         "Corsican",
22409         "corsu",
22410         "co"
22411     ],
22412     [
22413         "Cree",
22414         "Nēhiyawēwin / ᓀᐦᐃᔭᐍᐏᐣ",
22415         "cr"
22416     ],
22417     [
22418         "Crimean Turkish",
22419         "qırımtatarca",
22420         "crh"
22421     ],
22422     [
22423         "Czech",
22424         "čeština",
22425         "cs"
22426     ],
22427     [
22428         "Kashubian",
22429         "kaszëbsczi",
22430         "csb"
22431     ],
22432     [
22433         "Church Slavic",
22434         "словѣньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ",
22435         "cu"
22436     ],
22437     [
22438         "Chuvash",
22439         "Чӑвашла",
22440         "cv"
22441     ],
22442     [
22443         "Welsh",
22444         "Cymraeg",
22445         "cy"
22446     ],
22447     [
22448         "Danish",
22449         "dansk",
22450         "da"
22451     ],
22452     [
22453         "German",
22454         "Deutsch",
22455         "de"
22456     ],
22457     [
22458         "Zazaki",
22459         "Zazaki",
22460         "diq"
22461     ],
22462     [
22463         "Lower Sorbian",
22464         "dolnoserbski",
22465         "dsb"
22466     ],
22467     [
22468         "Divehi",
22469         "ދިވެހިބަސް",
22470         "dv"
22471     ],
22472     [
22473         "Dzongkha",
22474         "ཇོང་ཁ",
22475         "dz"
22476     ],
22477     [
22478         "Ewe",
22479         "eʋegbe",
22480         "ee"
22481     ],
22482     [
22483         "Greek",
22484         "Ελληνικά",
22485         "el"
22486     ],
22487     [
22488         "Emiliano-Romagnolo",
22489         "emiliàn e rumagnòl",
22490         "eml"
22491     ],
22492     [
22493         "English",
22494         "English",
22495         "en"
22496     ],
22497     [
22498         "Esperanto",
22499         "Esperanto",
22500         "eo"
22501     ],
22502     [
22503         "Spanish",
22504         "español",
22505         "es"
22506     ],
22507     [
22508         "Estonian",
22509         "eesti",
22510         "et"
22511     ],
22512     [
22513         "Basque",
22514         "euskara",
22515         "eu"
22516     ],
22517     [
22518         "Extremaduran",
22519         "estremeñu",
22520         "ext"
22521     ],
22522     [
22523         "Persian",
22524         "فارسی",
22525         "fa"
22526     ],
22527     [
22528         "Fulah",
22529         "Fulfulde",
22530         "ff"
22531     ],
22532     [
22533         "Finnish",
22534         "suomi",
22535         "fi"
22536     ],
22537     [
22538         "Võro",
22539         "Võro",
22540         "fiu-vro"
22541     ],
22542     [
22543         "Fijian",
22544         "Na Vosa Vakaviti",
22545         "fj"
22546     ],
22547     [
22548         "Faroese",
22549         "føroyskt",
22550         "fo"
22551     ],
22552     [
22553         "French",
22554         "français",
22555         "fr"
22556     ],
22557     [
22558         "Arpitan",
22559         "arpetan",
22560         "frp"
22561     ],
22562     [
22563         "Northern Frisian",
22564         "Nordfriisk",
22565         "frr"
22566     ],
22567     [
22568         "Friulian",
22569         "furlan",
22570         "fur"
22571     ],
22572     [
22573         "Western Frisian",
22574         "Frysk",
22575         "fy"
22576     ],
22577     [
22578         "Irish",
22579         "Gaeilge",
22580         "ga"
22581     ],
22582     [
22583         "Gagauz",
22584         "Gagauz",
22585         "gag"
22586     ],
22587     [
22588         "Gan Chinese",
22589         "贛語",
22590         "gan"
22591     ],
22592     [
22593         "Scottish Gaelic",
22594         "Gàidhlig",
22595         "gd"
22596     ],
22597     [
22598         "Galician",
22599         "galego",
22600         "gl"
22601     ],
22602     [
22603         "Gilaki",
22604         "گیلکی",
22605         "glk"
22606     ],
22607     [
22608         "Guarani",
22609         "Avañe'ẽ",
22610         "gn"
22611     ],
22612     [
22613         "Goan Konkani",
22614         "गोंयची कोंकणी / Gõychi Konknni",
22615         "gom"
22616     ],
22617     [
22618         "Gothic",
22619         "𐌲𐌿𐍄𐌹𐍃𐌺",
22620         "got"
22621     ],
22622     [
22623         "Gujarati",
22624         "ગુજરાતી",
22625         "gu"
22626     ],
22627     [
22628         "Manx",
22629         "Gaelg",
22630         "gv"
22631     ],
22632     [
22633         "Hausa",
22634         "Hausa",
22635         "ha"
22636     ],
22637     [
22638         "Hakka Chinese",
22639         "客家語/Hak-kâ-ngî",
22640         "hak"
22641     ],
22642     [
22643         "Hawaiian",
22644         "Hawaiʻi",
22645         "haw"
22646     ],
22647     [
22648         "Hebrew",
22649         "עברית",
22650         "he"
22651     ],
22652     [
22653         "Hindi",
22654         "हिन्दी",
22655         "hi"
22656     ],
22657     [
22658         "Fiji Hindi",
22659         "Fiji Hindi",
22660         "hif"
22661     ],
22662     [
22663         "Croatian",
22664         "hrvatski",
22665         "hr"
22666     ],
22667     [
22668         "Upper Sorbian",
22669         "hornjoserbsce",
22670         "hsb"
22671     ],
22672     [
22673         "Haitian Creole",
22674         "Kreyòl ayisyen",
22675         "ht"
22676     ],
22677     [
22678         "Hungarian",
22679         "magyar",
22680         "hu"
22681     ],
22682     [
22683         "Armenian",
22684         "Հայերեն",
22685         "hy"
22686     ],
22687     [
22688         "Interlingua",
22689         "interlingua",
22690         "ia"
22691     ],
22692     [
22693         "Indonesian",
22694         "Bahasa Indonesia",
22695         "id"
22696     ],
22697     [
22698         "Interlingue",
22699         "Interlingue",
22700         "ie"
22701     ],
22702     [
22703         "Igbo",
22704         "Igbo",
22705         "ig"
22706     ],
22707     [
22708         "Inupiaq",
22709         "Iñupiak",
22710         "ik"
22711     ],
22712     [
22713         "Iloko",
22714         "Ilokano",
22715         "ilo"
22716     ],
22717     [
22718         "Ido",
22719         "Ido",
22720         "io"
22721     ],
22722     [
22723         "Icelandic",
22724         "íslenska",
22725         "is"
22726     ],
22727     [
22728         "Italian",
22729         "italiano",
22730         "it"
22731     ],
22732     [
22733         "Inuktitut",
22734         "ᐃᓄᒃᑎᑐᑦ/inuktitut",
22735         "iu"
22736     ],
22737     [
22738         "Japanese",
22739         "日本語",
22740         "ja"
22741     ],
22742     [
22743         "Jamaican Creole English",
22744         "Patois",
22745         "jam"
22746     ],
22747     [
22748         "Lojban",
22749         "la .lojban.",
22750         "jbo"
22751     ],
22752     [
22753         "Javanese",
22754         "Basa Jawa",
22755         "jv"
22756     ],
22757     [
22758         "Georgian",
22759         "ქართული",
22760         "ka"
22761     ],
22762     [
22763         "Kara-Kalpak",
22764         "Qaraqalpaqsha",
22765         "kaa"
22766     ],
22767     [
22768         "Kabyle",
22769         "Taqbaylit",
22770         "kab"
22771     ],
22772     [
22773         "Kabardian",
22774         "Адыгэбзэ",
22775         "kbd"
22776     ],
22777     [
22778         "Kongo",
22779         "Kongo",
22780         "kg"
22781     ],
22782     [
22783         "Kikuyu",
22784         "Gĩkũyũ",
22785         "ki"
22786     ],
22787     [
22788         "Kazakh",
22789         "қазақша",
22790         "kk"
22791     ],
22792     [
22793         "Kalaallisut",
22794         "kalaallisut",
22795         "kl"
22796     ],
22797     [
22798         "Khmer",
22799         "ភាសាខ្មែរ",
22800         "km"
22801     ],
22802     [
22803         "Kannada",
22804         "ಕನ್ನಡ",
22805         "kn"
22806     ],
22807     [
22808         "Korean",
22809         "한국어",
22810         "ko"
22811     ],
22812     [
22813         "Komi-Permyak",
22814         "Перем Коми",
22815         "koi"
22816     ],
22817     [
22818         "Karachay-Balkar",
22819         "къарачай-малкъар",
22820         "krc"
22821     ],
22822     [
22823         "Kashmiri",
22824         "कॉशुर / کٲشُر",
22825         "ks"
22826     ],
22827     [
22828         "Colognian",
22829         "Ripoarisch",
22830         "ksh"
22831     ],
22832     [
22833         "Kurdish",
22834         "Kurdî",
22835         "ku"
22836     ],
22837     [
22838         "Komi",
22839         "коми",
22840         "kv"
22841     ],
22842     [
22843         "Cornish",
22844         "kernowek",
22845         "kw"
22846     ],
22847     [
22848         "Kyrgyz",
22849         "Кыргызча",
22850         "ky"
22851     ],
22852     [
22853         "Latin",
22854         "Latina",
22855         "la"
22856     ],
22857     [
22858         "Ladino",
22859         "Ladino",
22860         "lad"
22861     ],
22862     [
22863         "Luxembourgish",
22864         "Lëtzebuergesch",
22865         "lb"
22866     ],
22867     [
22868         "лакку",
22869         "лакку",
22870         "lbe"
22871     ],
22872     [
22873         "Lezghian",
22874         "лезги",
22875         "lez"
22876     ],
22877     [
22878         "Ganda",
22879         "Luganda",
22880         "lg"
22881     ],
22882     [
22883         "Limburgish",
22884         "Limburgs",
22885         "li"
22886     ],
22887     [
22888         "Ligurian",
22889         "Ligure",
22890         "lij"
22891     ],
22892     [
22893         "Lombard",
22894         "lumbaart",
22895         "lmo"
22896     ],
22897     [
22898         "Lingala",
22899         "lingála",
22900         "ln"
22901     ],
22902     [
22903         "Lao",
22904         "ລາວ",
22905         "lo"
22906     ],
22907     [
22908         "Northern Luri",
22909         "لۊری شومالی",
22910         "lrc"
22911     ],
22912     [
22913         "Lithuanian",
22914         "lietuvių",
22915         "lt"
22916     ],
22917     [
22918         "Latgalian",
22919         "latgaļu",
22920         "ltg"
22921     ],
22922     [
22923         "Latvian",
22924         "latviešu",
22925         "lv"
22926     ],
22927     [
22928         "Maithili",
22929         "मैथिली",
22930         "mai"
22931     ],
22932     [
22933         "Basa Banyumasan",
22934         "Basa Banyumasan",
22935         "map-bms"
22936     ],
22937     [
22938         "Moksha",
22939         "мокшень",
22940         "mdf"
22941     ],
22942     [
22943         "Malagasy",
22944         "Malagasy",
22945         "mg"
22946     ],
22947     [
22948         "Eastern Mari",
22949         "олык марий",
22950         "mhr"
22951     ],
22952     [
22953         "Maori",
22954         "Māori",
22955         "mi"
22956     ],
22957     [
22958         "Minangkabau",
22959         "Baso Minangkabau",
22960         "min"
22961     ],
22962     [
22963         "Macedonian",
22964         "македонски",
22965         "mk"
22966     ],
22967     [
22968         "Malayalam",
22969         "മലയാളം",
22970         "ml"
22971     ],
22972     [
22973         "Mongolian",
22974         "монгол",
22975         "mn"
22976     ],
22977     [
22978         "Marathi",
22979         "मराठी",
22980         "mr"
22981     ],
22982     [
22983         "Western Mari",
22984         "кырык мары",
22985         "mrj"
22986     ],
22987     [
22988         "Malay",
22989         "Bahasa Melayu",
22990         "ms"
22991     ],
22992     [
22993         "Maltese",
22994         "Malti",
22995         "mt"
22996     ],
22997     [
22998         "Mirandese",
22999         "Mirandés",
23000         "mwl"
23001     ],
23002     [
23003         "Burmese",
23004         "မြန်မာဘာသာ",
23005         "my"
23006     ],
23007     [
23008         "Erzya",
23009         "эрзянь",
23010         "myv"
23011     ],
23012     [
23013         "Mazanderani",
23014         "مازِرونی",
23015         "mzn"
23016     ],
23017     [
23018         "Nauru",
23019         "Dorerin Naoero",
23020         "na"
23021     ],
23022     [
23023         "Nāhuatl",
23024         "Nāhuatl",
23025         "nah"
23026     ],
23027     [
23028         "Neapolitan",
23029         "Napulitano",
23030         "nap"
23031     ],
23032     [
23033         "Low German",
23034         "Plattdüütsch",
23035         "nds"
23036     ],
23037     [
23038         "Low Saxon",
23039         "Nedersaksies",
23040         "nds-nl"
23041     ],
23042     [
23043         "Nepali",
23044         "नेपाली",
23045         "ne"
23046     ],
23047     [
23048         "Newari",
23049         "नेपाल भाषा",
23050         "new"
23051     ],
23052     [
23053         "Dutch",
23054         "Nederlands",
23055         "nl"
23056     ],
23057     [
23058         "Norwegian Nynorsk",
23059         "norsk nynorsk",
23060         "nn"
23061     ],
23062     [
23063         "Norwegian",
23064         "norsk bokmål",
23065         "no"
23066     ],
23067     [
23068         "Novial",
23069         "Novial",
23070         "nov"
23071     ],
23072     [
23073         "Nouormand",
23074         "Nouormand",
23075         "nrm"
23076     ],
23077     [
23078         "Northern Sotho",
23079         "Sesotho sa Leboa",
23080         "nso"
23081     ],
23082     [
23083         "Navajo",
23084         "Diné bizaad",
23085         "nv"
23086     ],
23087     [
23088         "Nyanja",
23089         "Chi-Chewa",
23090         "ny"
23091     ],
23092     [
23093         "Occitan",
23094         "occitan",
23095         "oc"
23096     ],
23097     [
23098         "Livvi-Karelian",
23099         "Livvinkarjala",
23100         "olo"
23101     ],
23102     [
23103         "Oromo",
23104         "Oromoo",
23105         "om"
23106     ],
23107     [
23108         "Odia",
23109         "ଓଡ଼ିଆ",
23110         "or"
23111     ],
23112     [
23113         "Ossetic",
23114         "Ирон",
23115         "os"
23116     ],
23117     [
23118         "Punjabi",
23119         "ਪੰਜਾਬੀ",
23120         "pa"
23121     ],
23122     [
23123         "Pangasinan",
23124         "Pangasinan",
23125         "pag"
23126     ],
23127     [
23128         "Pampanga",
23129         "Kapampangan",
23130         "pam"
23131     ],
23132     [
23133         "Papiamento",
23134         "Papiamentu",
23135         "pap"
23136     ],
23137     [
23138         "Picard",
23139         "Picard",
23140         "pcd"
23141     ],
23142     [
23143         "Pennsylvania German",
23144         "Deitsch",
23145         "pdc"
23146     ],
23147     [
23148         "Palatine German",
23149         "Pälzisch",
23150         "pfl"
23151     ],
23152     [
23153         "Pali",
23154         "पालि",
23155         "pi"
23156     ],
23157     [
23158         "Norfuk / Pitkern",
23159         "Norfuk / Pitkern",
23160         "pih"
23161     ],
23162     [
23163         "Polish",
23164         "polski",
23165         "pl"
23166     ],
23167     [
23168         "Piedmontese",
23169         "Piemontèis",
23170         "pms"
23171     ],
23172     [
23173         "Western Punjabi",
23174         "پنجابی",
23175         "pnb"
23176     ],
23177     [
23178         "Pontic",
23179         "Ποντιακά",
23180         "pnt"
23181     ],
23182     [
23183         "Pashto",
23184         "پښتو",
23185         "ps"
23186     ],
23187     [
23188         "Portuguese",
23189         "português",
23190         "pt"
23191     ],
23192     [
23193         "Quechua",
23194         "Runa Simi",
23195         "qu"
23196     ],
23197     [
23198         "Romansh",
23199         "rumantsch",
23200         "rm"
23201     ],
23202     [
23203         "Romani",
23204         "Romani",
23205         "rmy"
23206     ],
23207     [
23208         "Rundi",
23209         "Kirundi",
23210         "rn"
23211     ],
23212     [
23213         "Romanian",
23214         "română",
23215         "ro"
23216     ],
23217     [
23218         "Aromanian",
23219         "armãneashti",
23220         "roa-rup"
23221     ],
23222     [
23223         "tarandíne",
23224         "tarandíne",
23225         "roa-tara"
23226     ],
23227     [
23228         "Russian",
23229         "русский",
23230         "ru"
23231     ],
23232     [
23233         "Rusyn",
23234         "русиньскый",
23235         "rue"
23236     ],
23237     [
23238         "Kinyarwanda",
23239         "Kinyarwanda",
23240         "rw"
23241     ],
23242     [
23243         "Sanskrit",
23244         "संस्कृतम्",
23245         "sa"
23246     ],
23247     [
23248         "Sakha",
23249         "саха тыла",
23250         "sah"
23251     ],
23252     [
23253         "Sardinian",
23254         "sardu",
23255         "sc"
23256     ],
23257     [
23258         "Sicilian",
23259         "sicilianu",
23260         "scn"
23261     ],
23262     [
23263         "Scots",
23264         "Scots",
23265         "sco"
23266     ],
23267     [
23268         "Sindhi",
23269         "سنڌي",
23270         "sd"
23271     ],
23272     [
23273         "Northern Sami",
23274         "sámegiella",
23275         "se"
23276     ],
23277     [
23278         "Sango",
23279         "Sängö",
23280         "sg"
23281     ],
23282     [
23283         "Serbo-Croatian",
23284         "srpskohrvatski / српскохрватски",
23285         "sh"
23286     ],
23287     [
23288         "Sinhala",
23289         "සිංහල",
23290         "si"
23291     ],
23292     [
23293         "Simple English",
23294         "Simple English",
23295         "simple"
23296     ],
23297     [
23298         "Slovak",
23299         "slovenčina",
23300         "sk"
23301     ],
23302     [
23303         "Slovenian",
23304         "slovenščina",
23305         "sl"
23306     ],
23307     [
23308         "Samoan",
23309         "Gagana Samoa",
23310         "sm"
23311     ],
23312     [
23313         "Shona",
23314         "chiShona",
23315         "sn"
23316     ],
23317     [
23318         "Somali",
23319         "Soomaaliga",
23320         "so"
23321     ],
23322     [
23323         "Albanian",
23324         "shqip",
23325         "sq"
23326     ],
23327     [
23328         "Serbian",
23329         "српски / srpski",
23330         "sr"
23331     ],
23332     [
23333         "Sranan Tongo",
23334         "Sranantongo",
23335         "srn"
23336     ],
23337     [
23338         "Swati",
23339         "SiSwati",
23340         "ss"
23341     ],
23342     [
23343         "Southern Sotho",
23344         "Sesotho",
23345         "st"
23346     ],
23347     [
23348         "Saterland Frisian",
23349         "Seeltersk",
23350         "stq"
23351     ],
23352     [
23353         "Sundanese",
23354         "Basa Sunda",
23355         "su"
23356     ],
23357     [
23358         "Swedish",
23359         "svenska",
23360         "sv"
23361     ],
23362     [
23363         "Swahili",
23364         "Kiswahili",
23365         "sw"
23366     ],
23367     [
23368         "Silesian",
23369         "ślůnski",
23370         "szl"
23371     ],
23372     [
23373         "Tamil",
23374         "தமிழ்",
23375         "ta"
23376     ],
23377     [
23378         "Tulu",
23379         "ತುಳು",
23380         "tcy"
23381     ],
23382     [
23383         "Telugu",
23384         "తెలుగు",
23385         "te"
23386     ],
23387     [
23388         "Tetum",
23389         "tetun",
23390         "tet"
23391     ],
23392     [
23393         "Tajik",
23394         "тоҷикӣ",
23395         "tg"
23396     ],
23397     [
23398         "Thai",
23399         "ไทย",
23400         "th"
23401     ],
23402     [
23403         "Tigrinya",
23404         "ትግርኛ",
23405         "ti"
23406     ],
23407     [
23408         "Turkmen",
23409         "Türkmençe",
23410         "tk"
23411     ],
23412     [
23413         "Tagalog",
23414         "Tagalog",
23415         "tl"
23416     ],
23417     [
23418         "Tswana",
23419         "Setswana",
23420         "tn"
23421     ],
23422     [
23423         "Tongan",
23424         "lea faka-Tonga",
23425         "to"
23426     ],
23427     [
23428         "Tok Pisin",
23429         "Tok Pisin",
23430         "tpi"
23431     ],
23432     [
23433         "Turkish",
23434         "Türkçe",
23435         "tr"
23436     ],
23437     [
23438         "Tsonga",
23439         "Xitsonga",
23440         "ts"
23441     ],
23442     [
23443         "Tatar",
23444         "татарча/tatarça",
23445         "tt"
23446     ],
23447     [
23448         "Tumbuka",
23449         "chiTumbuka",
23450         "tum"
23451     ],
23452     [
23453         "Twi",
23454         "Twi",
23455         "tw"
23456     ],
23457     [
23458         "Tahitian",
23459         "reo tahiti",
23460         "ty"
23461     ],
23462     [
23463         "Tuvinian",
23464         "тыва дыл",
23465         "tyv"
23466     ],
23467     [
23468         "Udmurt",
23469         "удмурт",
23470         "udm"
23471     ],
23472     [
23473         "Uyghur",
23474         "ئۇيغۇرچە / Uyghurche",
23475         "ug"
23476     ],
23477     [
23478         "Ukrainian",
23479         "українська",
23480         "uk"
23481     ],
23482     [
23483         "Urdu",
23484         "اردو",
23485         "ur"
23486     ],
23487     [
23488         "Uzbek",
23489         "oʻzbekcha/ўзбекча",
23490         "uz"
23491     ],
23492     [
23493         "Venda",
23494         "Tshivenda",
23495         "ve"
23496     ],
23497     [
23498         "Venetian",
23499         "vèneto",
23500         "vec"
23501     ],
23502     [
23503         "Veps",
23504         "vepsän kel’",
23505         "vep"
23506     ],
23507     [
23508         "Vietnamese",
23509         "Tiếng Việt",
23510         "vi"
23511     ],
23512     [
23513         "West Flemish",
23514         "West-Vlams",
23515         "vls"
23516     ],
23517     [
23518         "Volapük",
23519         "Volapük",
23520         "vo"
23521     ],
23522     [
23523         "Walloon",
23524         "walon",
23525         "wa"
23526     ],
23527     [
23528         "Waray",
23529         "Winaray",
23530         "war"
23531     ],
23532     [
23533         "Wolof",
23534         "Wolof",
23535         "wo"
23536     ],
23537     [
23538         "Wu Chinese",
23539         "吴语",
23540         "wuu"
23541     ],
23542     [
23543         "Kalmyk",
23544         "хальмг",
23545         "xal"
23546     ],
23547     [
23548         "Xhosa",
23549         "isiXhosa",
23550         "xh"
23551     ],
23552     [
23553         "Mingrelian",
23554         "მარგალური",
23555         "xmf"
23556     ],
23557     [
23558         "Yiddish",
23559         "ייִדיש",
23560         "yi"
23561     ],
23562     [
23563         "Yoruba",
23564         "Yorùbá",
23565         "yo"
23566     ],
23567     [
23568         "Zhuang",
23569         "Vahcuengh",
23570         "za"
23571     ],
23572     [
23573         "Zeelandic",
23574         "Zeêuws",
23575         "zea"
23576     ],
23577     [
23578         "Chinese",
23579         "中文",
23580         "zh"
23581     ],
23582     [
23583         "Classical Chinese",
23584         "文言",
23585         "zh-classical"
23586     ],
23587     [
23588         "Chinese (Min Nan)",
23589         "Bân-lâm-gú",
23590         "zh-min-nan"
23591     ],
23592     [
23593         "Cantonese",
23594         "粵語",
23595         "zh-yue"
23596     ],
23597     [
23598         "Zulu",
23599         "isiZulu",
23600         "zu"
23601     ]
23602 ];
23603
23604 var wikipedia$1 = Object.freeze({
23605         default: wikipedia
23606 });
23607
23608 var require$$6 = ( wikipedia$1 && wikipedia ) || wikipedia$1;
23609
23610 var wikipedia$2 = require$$6;
23611
23612 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}}};
23613 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}}};
23614 var man_made = {"windmill":{"De Hoop":{"count":57}}};
23615 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}}};
23616 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}}};
23617 var dataSuggestions = {
23618         amenity: amenity,
23619         leisure: leisure,
23620         man_made: man_made,
23621         shop: shop,
23622         tourism: tourism
23623 };
23624
23625 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"]]}];
23626
23627 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"}}];
23628
23629 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"];
23630
23631 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},"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}};
23632
23633 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"};
23634
23635 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"}]}]}];
23636
23637 var type$2 = "FeatureCollection";
23638 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]]]}}];
23639 var dataImperial = {
23640         type: type$2,
23641         features: features
23642 };
23643
23644 var type$3 = "FeatureCollection";
23645 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]]]}}];
23646 var dataDriveLeft = {
23647         type: type$3,
23648         features: features$1
23649 };
23650
23651 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":"closed","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}/{z}, {x}, {y} for Z/X/Y tile scheme\n   - {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. 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"}}},"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/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/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":""},"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"},"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"}}};
23652
23653 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,iVBORw0KGgoAAAANSUhEUgAAAMgAAAB0CAYAAADAUH2QAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAActpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+QWRvYmUgSW1hZ2VSZWFkeTwveG1wOkNyZWF0b3JUb29sPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KKS7NPQAAQABJREFUeAHtXQd8VFX2PjOTXkgICSRBIKH3DipFQEBB7H3tvfe197q49ooV1866u4oiFqwIWOhN6b0FSO9tZt7/+27eGV/iIAkk6P53zu/3ze3t3HNue/e9EQlRiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ48P+TA67/xmZZlvWbertcLuu/sS2hOv+5OfAbQfszVddWBK0jTac9WFWpJKooAXtIeYKxKuRXHw6owNUnbpPHccwMbhSmCkFT3ayD1llN+pECCuGwq59f/ULKQlaFqL4cqCtk9U3XqPFsxVAloOm0ax2dptqd9XDOHPRX5VCTSqIwfiFlcbIvZA/GgWCCFixek/g5FIMK4QFUMVgvoq5b/V0lJSWuuLg4RDHkVA6nQqhdTZ1JaPoA4w4pSg0T/+y/DnlhVS30G/uvSekPURBHQ1UpqAiqDGrfkxlQEqTR+qsC0FQlUAWg2wmNo34ajwxnWIj+ZBxQeUH/sK8CBH/KT5MqigpYoNCmtNgNZZlsmIJuVQb1oxnmiGP8q6qqaLrBKHd1dbUrPDxcYMJLBHY/oMLuNL0IppugnYqh4VQItRvzQIxKKDNE9eQAZIb9zT4T2Llk6ABQXrbAPxcm/T2ws/8anQ6YgtjKYQQdrTCCDtOpGOG2P00qRxgUIgINN24Iv9ZVR3ma6geryYvpyExVCprUIKepdjJUlcM5m6iiaDmIFqI/ggN1lOMu1OF8oDXAfs8BpgL3QEZymkpJnAKGspqG2FDkTKWgAKtdTSpAAJgRorxebyQUIgyEIEMMj8vKykoCWuzcuTMBZhzieqKjo6tTUlLKW7Vqlde3b98dHo+HCqBKQOUgqupA/WkyrioKzQDA+JCSgCF/BHFAJf9povz3gRP2UI+18B+FuNspZzDNbLOHuA32Dkhgg1PWI4HdOFUEp3KoskQgGwMIezQUIwoC74ZyMPeY9evXZ3z//fc9gN7ffvtth7Vr1ybZ8atHjhxZ1q5du5KYmJjSqKioyk6dOm3u3bv3bDCo2ufzUeirUH4lFKaCgLsSUFPtVBxVIKZhZwSA9L7GZjjyD1H9OEC54WD1V4DKwX5i31B2SBy82H+dgKeBk4FGJxbYJORQDiqGUzlopwZQMSKB6PLy8hgqBuxh+fn5rT/88MNDp06dOvzjjz/uynjHHntsARQia9CgQbsyMzPzWrZsWQYlInMo1GSULpFoUvjLbdBeCYWhYtCvDMpSZtvppj+hM4zOKMyHnWNml5CSgBMHkCg7IBgWZWUR0AtgX9DtJPYT5YZ92gtpNiBNo+5HmkRB2EBUWGcJmgqnYkRBMeKhGPRzr1q1qus777xz1IMPPng43HGXXHLJzmOOOWZt//79c9LT072WJbEbNqxPhAI1W7p0afz27dujKyurwyorK6UCELfbn9gsvhqaVtGmbZviDu3b56alpe1G2p2RkZHZyLMEKMdMVe52u0ugKHSTsaowOruo4jmVxBtSEnDqABHkxyyVYLZBkYuBFoAqg7MWHBxVhsegj75GmjCYVKZGoboaud+Z/o5y6IwRhUJiKioq4qAcgucZqU888cQp99xzD6fRMJjrLrzwwmVt2pA3kgL0BpJeeen5hEsvv8rdrl2GPPPM09K3Ty+pKC+RysoqqaqskPy8PFm9aqUs/PEHueOOr5mWZB05fnzhkWPHbh84cOA6KNuq2NjYLPhHYFaJhlkMRaGCkg9UYo5GBGeeWkxGu0JKAqYcYNLZvT7FckVAatR9Y6MqiK0cFDCdMWiyDCoHFSMKI3gclkex2De4P//888OuuOKKKzdu3Jhy+eWXb/3Xv95LuvLKK3di090N7WyHwSEGaQyVuuJpWqUlJYK9iCRlDJCqqFjxWF5JCvdIUmeX9D/cLReFW/JUdamVvXOba9mSxa4333w78YYbbkhE2h5HHnnkyOOPP34lzPlYqq2BXzhOyqIwo0TYJwKqJByVqCS1KKQktdjRlA6w2iyzsmEuREFHA1z+cknuJA5iHOC2AMvsgEZVEJ2e7Lz3z0BjVCF0RKabjaJycK/RDLMG7XGPPvromTfffPNfunXrVvHRRx99GQ9KS2s9YtfO7VbLVqnuar8la7cVysJ1edacDUXy065yWbZktsvzn1vM5sDMuie/KJKQjB0EZDkKRcaHyZCW0XJEZoIc2jlJurdtZjWL8MrObRutTz/93HX9X28y7U1t1ar6pptvXnzqqad+e9BBB61GfbBKqyzCUqwQdi69SgGOSFQSdozuR9ghnEkatROQZ4jqcICyBD77YB6MoJ/sYC5/OQCT2AdUDtIViPsC4jbq8ooZN5qCoHKsOBVDlYNmQDkwczTDzBGNpU3za6655vpJkyYNv+qqqzb/7W9/WwLdyCwqLOw2YfyY8Bff+Lfke5tZr3y7Qd5cW+ySSiw9I1DNKI94IiLEt22FtJ75uMRsXinWIAwsI67EPJMoPijJLkQtrcJPGeSZ6ZpHyB0DU+SUQ9tQWaQgZ6f14YcfWZdceplh8uDBg8uuvfbaL88444yvUNccKEkplKQA9mJAlYTTvCoJFcXYQ0oCTjQxOZTkFBT1BsBlcV26H31xDz0RH9bGHbwaRUFYMdRPlUMVRJUjxlaOWMwgKRdffPGt2Iz3nThx4spbb711G9L1BVKKsHQ6ZsIYa33fa1zbPW3R2ipJjYuSGKzWKv0uyfH6YWLQiIRs528V+QwnexvniPSEkoy7BqxrJm7LL/EulzRDlHAMMFleS8oLMOhU+OSMPnFy6zGdpFdGkmTt2GY9P+kl/0MPPcgZTrC8W4u6vNu2bduVWHJVRERE5MO7CKCScBPvnEmoIJxFqCwhamIOcOAFr/0w26GoswHKCwc4LpH/ibAlMJtEOZhvYykIBc252Y3AJjwa+4xoKEcCZo4YzBxJ55133l1vv/123yeffPKX6667jkI4AIjelltlPT5trTx12WUuOekM6dDjMPF6S6XYXSkuyGp4dJ64wyvEb0VKSX4HqbQSxJ+/TfxfviCy/BOR4ReL1WccxBbK4ALvwrDlASJgbxUeJpHRcbIua7fISw/K3165Xa4573iJDRNr5syZvlGjRqEKEjZs2LAiLPsmH3LIIT9hJqnATJIHfyoJl1ycRQizxFKTHQd7iJqYA1COPR7dUoFQPKcOLrkanfZbQewKctaggqiicJ/BmSMeypFA+/XXX3/TU089NeLhiRNX33LrrRQ8Kod79qqt/sOm/ewWq0haffWWRHTOkOhBfcVlbZHIuC3ijtyEuSBHvJXVUlWyVQrWXAMki79ki/jWYfDYMBvZBCc2LrxVolTFjpb41m2lRfYy2bTqa+l57v3y7p0XSq+O6YKn8t5bbrnF/+abb0YkJib6YE7G8fKXdZTEOZNw5qCihJZawdneJL62nFEZdFBSxWjSmXy/FASVZnpVCioJwaUVT5/iMIs0xywSAcU4Fwpy5o033rj57488koM5sz/CXe8snmadtegBV9e4WGkZWykrpmyWaJzCtjslU/yVkVJdEillO8OkaK1fchZWSvncFUj2K7ladhJXcob4V2Gp5ceeut+JIu0HmZnE5fdKeHW5VO22JLPNPGlmzZZd22IkvihF1q7bbDK5+aZb5OSTTpLEFonVL0x6wY+ZjXWXGTNmPHvEEUd8aytJLrycexJuFAMzCUaufe4gm3/koRNwmg0oR0SDxh4d/6hy2TAn2fWgoGv7tb37zFNn/o1hZ8X2mdBANk6XVlQOHudyIxWH/UYiTqwivvnmmxGjR4++d/y4cfn/ef/9dbga0g/hYW8s/I913opTXIfFjxAfsnHHhEnuD1mya1aBtD81U3KX5cnG94vFyuYzvnKJ6YwDq979xd38dHE1aytWVLz4wmOk2h0upavnScU7N4h0HYMDwZuhnokS5a+SiqoIObLTSunRcar4/blSVu6T8iqfbJpVJrOfWo58a2j8IeMkrXuad9rHn7iKCgs8LVq0qPjiiy8e7tmz52IoOa+y6J6E+xHnpl33I/We3h1CIfVVLqQhb/2Ir6OnXfOGGciHgxmyqd+DNDv+XuvpaFMwPlDGWPdAWH3z1dYhvipRIA8No+nki10X+sFqBnBjd8ZviH2fFcQunAynUugsQuXg0or7jviioqJ0jMSPz507t+WWLVvm4eFfT4THvr34I+vsn493jY4/Sqo81eJx+8RXUCFZs7Jk3csbEYXUTFoNL5LUQ5HgoPPFFTtcvFYX8foSpRrjS7XXJ1VeL2BJJewFc96Tqk8fFxl5ucQMOV3KKsJlfOdfZFCvG6XKl4kNfjyGfb943R6c6fpl3mtbpGxmuGTe00zSKvpL8xVx8tzL2PjXHOl6xo4du+ODDz54AC9lbcMdsUI8J6GScD+ix786i1SjM/Y64im/EJfpAgT/g+BoB7QC4gD2CRUxC9iI+NthGkLcfVIUpDMC5qwn/NKQaQZAMxZgHJa7C9gMbEF8I5DB0iPcEMIQ7VfhV/9gJuPCn/sJwwO4+XCrO4BTGbPq4FJ2LbACcTj4NIicdYHdbO6ZgdO/QRkiMhm+r2Qai8RkLMG8OJtEonFcYnmee+65k6AcrSZPnrwGytEGfrFzNi70QzncYxKPFJ8Hq5X8Mslekiu/PLYawSS3dD2nlbQdliVRLS6GSE+Q6or22H9HQzm8EHIoFHw96BO3m/CJCw8KEwZNkNy1cyVy5gtSljZQevVvLQO6ThbL3xnporFWgXrgNMyLGcQV5pYep7aW6e8tFdfsHGl+foZcdurNcu31V8rjzz3hfvH5F31ffvll+rPPPnvcbbfd9jIOGGKhIFQMXV6x87TdbnRArRESYbWInQUPSpIKxmC4TwBGAl2A5kAwykPapQiYDvDEZgcjwW+Pm1aGOwlxA88GYM9A2GnAeKAHkAwEo0J4rkL8r2D+B+XqSVEgLyZCuJ4wjYLzbIAKRrlwEgfQSchjMUwYLlwbsjrBfiWAI0jzfgeMWjQBrk8Rz5QH81q4+wBUIA7GVFyCeXMJ/ADyLQMQ1aLfyUBL2DfB/Bj+fJ4Co36KjDQB2icFYWHIQQVEFYXKEYHZIwazh3vhwoV93njjjaNYUmJSc45ScZtyt8s5C25xD2k+XHwV1ZKzJEtWPrVavKV+SR4YJ5kj0mT+49sl4+BESW5/t5RmjxC3NxocqRJ/WDUUCjOHL0yq/X6Ylnhw9Iun4OLCS1Phic3Ff8TFUJI5Iu/9Ww47pa1ERRVJSUUL9Eo1OhPnAKyM24VnJpZEJkTI0Oc7y1eXb5ENGVMxdCfLK6NflEnPPO8P84T5n3vmOc+LL744Zvz48T/hGv1CzCJUkkrkQOVgW7nccfLAZA+/WgReBYQKdvLjZmBErUg1DuZHkJSnSbCPsnEn0j8N+8Po6EpnvvALShoHJvN5ADgX4GzhpGDlJiDCwTZuQ/p/wX4nyl0Pu1M52X6mp8KfD+yJZiJgMdLzuJbCPhHgakOJMzD5p+2mEjjpDDhYRjCi0jwKUDlJw4AOAJWf7cgBIBQm76B9hLA9Ehu4L8SGqHDQpKIRfI+DG93of/zjHyesWbOGdl+428Op1PXkkldkk3uxuNe7ZPET82T5Qys538iQu7vK6Lt6S/dxGZI6qEzyVpwirqIJEuOJkrjoaomNcktsZLjERIQBbonBjBEV7sbDc9pdEhkWLjuqwsTbpoe0PgYy4P9cCtZPw+PvZHCdCysXFMQedsgi1NiLB4rNOyZI10tiJfOhjvLGxlfkxXmv4ZTY7bnz9jt9GZmZVVgWhr388svHIQXrzw7l6RyVg21lu518gLM2QRh0BEyH/QOEfgKMsGNxNiEoYHatAnykgNCPYRqPs8y9wHzk1QXCxpGY9QhKjrIPQYTFwBUAlUPzq2+5bOfpwHLkeTLK5WhMPydxdiVxANH8aeoyyYQj3UvwewogLxmmisH2KmA1S1maSpzRSM78OZuTeBxPXimxrzYCzG8ZQL7tM9VtaH0zcgoG82BlwsvKyihAMm/evJ7PP//8kOHDh1O7LQusmLtzmfXMxvtkwHeZMue6WVLwY4n0vbaDHPviIOk8sqXExUH4w0olrSsWwcty8OC8WuKiXFCAcImlYkApiGhbOaKhHNFQEr8rSsLCXDI+dZ1cPnCqnH72BlZBvnjVL0V5FWY55YMoUBr8mPiMqQoDtrY7/CBwc530WdRdbt/xqCzfvlrw8lX4pEnPmw54/fXX+3333Xd9MXu4MIuwYzmFUzDZZrbdAJ1PngQIblUOCuh84ASAxVNw2KGaB/0oKAoVMMZh3oxHMB7r1AuYjfx77klJHGUPRNxvgbYA0zIPzY95s870Y5ksn3btW43HejAt2/5v5H2hPRMwvZLaNY3TZJwCpLsU5iWAlsWBhjysxTe4SRU1RuCX8Ug06+ZNt5PWwJEJ/AiQV7+exsDRUNKG1TsdGqoMVAZrpcPxBJozRuSUKVPGwXRdc+01m7DrdH0672t55vMXXPKEyIJnF0r6uGQZ+8pA6X7MQZLQIlzCvOESac2SCPexktLuRdk8e5K4K4olPiYSyoHZIwLKYVAze1BJqBy4YygdErbLcd1elqFdLpXk2EmS3KZCxl/XTrJX75aNSwu48IdioPfR9T5YsDoDYKKC3mq/RCRFSt87u8mOF/KkZOcaeXv9fygQnjGjx7hP/8vpOIwrF2zWR8OPoy8HALZRZxHywskPODkiBJRjPJxzgHSAQsa42qEUFHXTj3xUXtJN/jIO60Oim8rJfFKAGSjnIFtJmM4Q/Lgv4OzCkfSfAOvMNEzr7G9VCPpp+bQb1sDUcrWOTjeCa5GGOT3px7TMbywwESDRT+vLOAxXwGoUVWekYPkyDknD1CTfufzDskQmA5uAl+DeBH8Y+3YCqJ2FvOpNbKATplOx9+Dyyp2bm5uO5x6DcN8qd+iQoWG9Dx7ieemRZ9gIppGeN3aS9sNTJTbODcXw4QTLgyVSoYRbw7CXOE5ateGSEXNpznZJa30Q5mEfhNwtXgh1tc+FLQQXTDiN8oVLq9id0rP1gxIR8RNOqgbjuNiFJ+8+6TIiWT57arMsmrZdWvdvIR48Nuc5E3YrYtgEuwVQWXzVliT1aiFLZZX0XNZTHkl+ynXm9pOld+sukWeffXbpP6f8Mxob9l6rV69u36VLl2WYRSIxm5BvKlTIKcAPp3L0gf+HAPnD5QQFlEReEEzPtHOAhcAugMS1c09gOIDxxRAFSIWb+XCpQaXjkmUCOt+5CTV8hv+1QAfAWTachpifCukO2LMB5t8SaGXbGYfkjHs+ynrdVkLuJ7ROWmZNippf9WP6qwEOMGw3y2W7SbRrPOOBH9ZXFUT96muiSkYZ2CaC/YEqN3xzrgWyk/aFyBgFG8l82HEunFp1gxl/3HHHrUxKSkot99W09aCOB0nalSmS2i0BQzA21zhNCsfSKJIK4l6AB4PTJczTUlqlkYciu1cvlu4DDhFfVLgZ+asxBXjAS7fLgyUVzrHCoiQl5gdw/FvJzh4tlWX5UpiLh4mlPinOr5bkLpGy6cdSmfP6RmnWOkYiEsLFg3ezwrA598SHi4vvaWFWspBneItI6XpbFymcWISHjTny5ZbvqCCeQQMHeVokJ1etXLkyAq/99oWC/GIriC4PlAc0eYTCEYyjN5cj7wDkiY7esBoBocn4/wHuQ/yf6VGXkEc7+HHfcDPA+BQqFWrOYnQfhXinIg9uoj2w8xVhKgvLPwsgMa2TNB/uS+4A5gL5AAW1BcDN8DXAEYBTOS5A3lQO5yYdUfZKlA2ipmNrt4OJWTaFhG1i+TrjwdpwQh1RxYDiUju03IZnhhT7oiBGGOzSaCfCIDiYQMIj5s+fz3Wf9OnTx4dXZhMWL1gsaWGtXanXpUlKl3hx48qI2wOh9IRJuAv3pTxfiOV9ASP7AOzwKySqeZIM/csVsmDaGzL6lHNxEsXjXb9Y7kjMEnikXVomJTnZkrdtq2zPmiWFW/BO5vQFUl2u+ziW/istnrLzV4fDltAjWpL7JEl8hwSJzoiX+E7Ncfi/RVpuaCtT0j6zzik+1YX3UsKuvPKKqvvvuz9iwYIFPS644II4TB4c4VRBdASkcJEPJArgfUAPwDl6s6MIxrsHHXc/TEMUOlh0JGUcHhtvhnkLwmbDnAqwryiwWo52POPwKFY37VyWsQ86AySNT7sqB9flw5GGe0Ql5seZhAcJnyDPG2E+CpDORty37XqyDg0l5k2wLmwrZ8y3gB+A7QAHEfKUsyLrXbOM+FWp4FV/Ql33pY5BC2iQgoBB7MS68OAGbBiemrPhcT/88EOHc845p/LHH3+MP+WUU8gQK9+b78qMa4MVNWYO8CHM7QUKoCRLsMT5u1jV4yU23A8/zMN4XaRLv4Pl+ymTpDw3S9J7DZDCggLJ3pUlm9askJXzZssP7z7jaExzyTykVNK7pUmztGjc3wqX6BYRUCqRmc+vlexfKuTIv/eQ6JRIKS3ySklulZTihm/e+mLZ8F4WllrsH1S8fzOpSqiS+AURsrDrh65V+XdKSvyAMFyJZ+fJL7/80gb3tlJSU1MLsJzkYMD2sn0q2NyUl4JHHeDHkZ/EOEoUTvJ7MuLdb/OS4WbU10g0GQYwjKP1dNivg/05hjmI4RS6/gBH+88B5k8FyQRYL1UIWGvRy3ZddbRmPiSmYZl8+PkYyuUSLw/2gHLArnEZXymYn4bRZDh5RboNeTxcY/3NbxZ8qDy6NGo0Qf9NSfX0aJCC2HmSiQo2mptC5uPatWsXP8nTavPWLR5c+kt9Y8rbMufn+a5XHnparBwskdLxTgcuIbolEYLZBU+0/you73Ac4YZheYXnGsgWe2/p2KOvKWr9ou8lDJuFH7/8WD6a9Dfjx5/Ow4+U9H4TJL3LdklKf00i4wfjti/2JtAw7kO4Kfdjlup+dGv57pf18LOkeacEicET9OYoA3tzaYNnIV3O90lpXpUUbsPDysU5UrKoSCq/wmy/G8oV/p0MP2OAp3u37myrf9asWc3x5mM6FGQ9Hhw6FUSVhPFIFwFcb+tMQz92NHmEnOUWgGQ20zXW2r+2EHKpZAQE7udhPwexuPxRoWd5VAbmezJABVFBZfkkdde4fv1l3WqRXSbjc29h2gK/exmJbhDL3RNp24OFM09VjrOQzzuMhDxZb4Y568h8WJYXcPrD+zekZar5mwiN4cFKNoRMA5BATTbcgxE1DBLj2rZtW/KyZcsSTj/z9IpPPvw4LLlDury0kstjnNvt9iJRllSWn4v3yIfixCpJosMSJS6SuwA83UY/R0ZFYV8ShiHMkrbd+sg/7r/epOVP254DZOgJ50lq1/4S2SJNqtxx4op6UzyeQlyNj4DQV+Lho2WUgadVmJ4kpXuiSb9qRpY0795cLPhxL+NF/2PYxj4kTKIPipCw1nESP6ClpBzZTtb+bZGkVqbL3Wf+VZLyIuWMM89wH3XUUd5PP/00YtOmTamHHnqoG8ssM7ojc1UOmhXodK79jzeF/ioUdFK4GOd9dHyuHa/aFhKG75EQJxxpuEafBlBBnIKjwjEM8biGN7MdTG7iSRpe4/r190rEZ110KUOBZZsYn/mbmwHwM/2MeEZRf03eIBuVmMsnzlrvIE/KHPOn//6Q8kHN/clrj2kbqiDOjAzz4IG2YucMysnJSYbhPuWkU8o7dO4Yty53k/wQMc2KlRauwq2LpEXBA1KefwKObSOEjxNdrip0DM6W3HiWgRPi0vwc+fnLmfLl609J1vqVzFJGnHCmDD/uDGnVsSfeHEyQMgz/xXhjsKJyFx72fY08emF49ppeJaeoauC++PGkPRqv37Y/OkU2TM+WojMrJa5dHJTJb+JwCYZFOxTLJ9VUGKSLbBsnSUNbS35VmaTcNtrq3a2vKx7HbZ27djEKgg9McBPJ/ZYHSkKBVwXhsoRPtw+FX1eAxDAlwx843qUH4lLg60sqSN/YCZgXm0r+axkdYO+IfH+BSdpWY5hwjUsvpqWwc4/CB47cY3yKdJuAWjMEwhiXZeyPcjAtlaME0GUVp6P9yRNZHThqqIIElAJVVLsKihuf5DFPLfE8hEwJyy0r4nNMV3O84pc1D9cPBx4qsQlQCBdffgoDcLIUHo27VmXyy/yv5LvXn5Bda5ea1h884VSZ+8m/pMfBI6TPYUdKQTFeoCqvxOyDg19cN8EVRahFLuJGcfRDL9Y8LSfnoRuIgwpGeiR9ULJRkOy1RRLVJs4swSgJNeBMAgmggiCRF9dQojDTFNy/SbKPL3N17NUNihvubp+ZaYSnsLCQa3LoRi3lIB+UuB8gMT4FjEQBJY84undGXckbrv3pXx9iWm6me9uRWZ6mpZ1NZj92AlRBlsFOJTkIYLizjsyP9csAnge4byLT0UOyAODp1loIcWAZhnDmz1G/oYLN+CzvC6TdiHy4rDS8hN/+krZJzf3NL2j6hiqIZuLsIH5EmpX0YP9BAeIIaUaf3SU4wcNquNmwlrLt02wpzyuS2MTWRnglKoIRJWv1Eln52VuyasYUk/fQ0y+Xw085X+Lx1wZUkNmfTpWuhx2FC4lQJI7+FGYszX1+LKvwZqFYZZCWcAg57ltBDrCANhLBfQdX8HHt4k2+O5fkScshqbjPhQuL6CIus3AR2M6PEsN8ETUlCtdbk2Vzzo+yBYcEaQcluWPj40x7oSBcxpi2YVnJL0Cy3c4OopCSlD+0azgVYzI9GoE0T2alQtiODgghL4vmw+Ta9gaAgs56O4ltoKCyntyvDLEBwxy5rkP6ObB/BnyD/KigzLuhR7xaz5+YHkRlaaiSmYRBfpTHagaJsv9erHBDiY3WhjOtul18zdZ42Arir0Y/oGsiO5uJRcp2rOJBllh4HbYsP1uWT3tNpl53lFGOLqNPlvOemy7jLr9LWmR0wU3eVBl/6W2yfNZnsm3zJqmGzlVAsqsgxVW+aihLMzwJPwy9/z0UpRLgUgl3fbFkqzLKAxMPAcPxpDx9XIrsmIFNODbkfvPQkQriUA7Yzb4EebuaRYmrLa73ZHXFO+5mr+uKisBGCeT3+8kvwnxZnibgpDSno46dcZmPgoKioJ/anabTn/ZgpP4pdqC674d7LUDl4J6E+TqJSmJmBphcxhFUGvYhl2CXA9OAn6EYtwLRHP1h1ndQZT2UP9tgbyrSMpok/31REGdFalWOa3MGlpSUGX93RQYeXFwlkRlbTJp8vNhUXV4qOasWyvePXCLL3njQ+I+88Tk5/KqHJK3nYPMxkvzCInxnwSVt+3BJj7fzl8yXskov3vvgux9+KEjNbd6qsmOlvHwi/JLgFw3FwN8hWHlQAigiFcaLGQUPA1v04dYBL5hvL4MUYOaAqHAmopLUALMHwunv5+aoMyxLT8ZN4iSTrubbcpC0yEhGC0oQHLY5Jmjgr56MoyDvFfRTu9N0+tP+e2S0GRF4CsWRvhD2Y4CNAJWE+aoiqBLBy/hT6An2H8PYTs48VKoMYCKwEPn2Qb76vAVeeyWtsx4e7DVBAyJo3s62NCB5/aKSKQ0lVkgrZUwoBhfmzIcMle3bd5jKh/GjhWuPFFf3XRLRY4uU/LBUNsU8K3lfvcFo0mbs2dLzmPOlVbuO4sO7HUXYZ0TipCkcyyCrAs8kWneUWJxY/TTtHckcMh5vHcbjjUC8m25mEcwmVbF4cn4ilGkUPsBbAX8fBL4U11hWS7OkaVAUXlPBfa72NcusgvVFEte7hVESnnQZ5cA7IpQGLq+gd3hC7xJPK3jM8eGuF2uJzUNVTf/im8C8RIdTXp+2V/nAZSXkp+ZY1iQK/sOiAmmCR2mwL/Pk8s2uLTSwZqSnkqxGnQYg7EHgAoB7HyVnXZhW07PvqChOZWHcbsAs5Dcc+S6DaQZD+JH21iYV5prYjfO7tzIbpRRlyv5kBl5hwQ/ZwpqcU7nk5+eZfGOjIHHFLaS48FQ8sWbI5oBydLzw79Ll9JskslWGlOJCYBk+IVoBKS3HKRVPqorKkBVenR18+lWyc+UC2bJuJZTAhXC8NgtUAJX4ikkVTqEq/UlS7k2Xoso02VWcKT+tOVw2bTgDG/pyKS9G30ZHSEzPWNk9d7dUFOL6u8eDvQivq+CgACe2OHSHsnBm8WMZ5ZIydx9MNztxIdL0qx8KYtqD14WL0Qi21Qk2TKlILXswKVQcSRoTKvRm/6flOpQkH/Yr4c9N/p3ADwD3FM66sH1sE2cYM8jBJKmyYMNolmnNYL6F7uY+h0qjgq8mvA4YHZAyzbDfgCaRiSRWzikkZKovOTmZx3myY0cWwv2S1hybaG+u7P5snhTOQKLoBLHK8yXzmsmS3HsI5nA8qCsrw7sdrAY211gWUUjDIaQsAM/cJbnbQGYpa376RuIyepnZgw/6qvC/OlVuP77PW4Yn4zuxv9gtJdnb8R2sXeLO3ikrsgpkW/Im8fHUC1NF1dYy8Rfia40vrZAYPDT0JEaJJzlaXIlYfcTjdhiOmf2Ru8RXPlR2l2LPmjxfEvi1RlQsOzvbKAhmEGxOarXbhPPHpm1qcZjkE5vDaehNgHlwxFdewrpfRN5TOb60cwkIuK0krDusLu5HHiIg4J1h9gMOBjjD9ABaACoPFH7nDAGnWaZx2UVFOxN4DWAc+v2RRN42GSlDGlKAKgbT0M4OMbAFSKZ++JHr6ScfE18ZZOFVfPnQfDoVsSKx/4OC+NxhUl6Jp94Y/S28DMXkHLnxYhWeqANYbvE9dTeWTeHJbaTNsGNl+b+fldbDjpe4Nl2kpCBPinZvk9wNKyR33VLJmYO9ZBWX3L8SuVa0DusGjH2uxHhxmW9UV0nxnFyDX2OilzvhMuPAdhLWaaNER+JWR3WZjOwXbzWLi3ZZfq8fX5Mnn3wZGRnZMLnGpwARbLdT0H+Gm2QUqsYa+OUo/CQEdUXAp5EtqBcVgXUKkLoRRmFmOJ9Sr4GdeI8REcZFZX9gPHAWwFMV5lO3HSqMJyHsNYA8+KNI+a5mk9RjfxQkoBy2wAhu72ZzI5uXs8uTm5fvXzR3Nhi6Ba/TjpRd/c6X8K2LpfrzpyR3yde4HNhSovAuhzt6A66IcGUWBSVJwwzCY+CWEFJ8HK4co3xEoqQPPVG2Qgk2zv1KEnbtkE3fT5fd35m+DTAlvOcYXGXpKlZSW6mOiBcrFk/RXfGSmr5SUto/I6U728i6G36QuHGpknw0PuJQgL1MEW7/biuVyjX5Uj5lpcmrWcLdIoUR0vWKI1yxEOnCghLfP6e8GzVixIhcvFZPBeH+Q5ciygPtpEUI5j6Fyx4VMAoV45PXJwArwC+GN3TkpYAzTy0L1lq0xwdwtnLwOQas5jDBzCpIzTS8C7YL9s8IhD8C83VgNFB3JlEF6YZ4PNUqRxzSnupUE/pf/NtQBSEjlBlq596DAmB17NhxF65iFMycObMF/h3KGj1mjIy94F75MrIP7ky1kyL7FnLpzHfEfdpSXDMvxU1e9DpmFD+eS7ndxRjioBS46e3ydUaWHVFYN7zUVHM4tPpdHqbUEHsqYeQ5Etm+n7hTMsUXjQ/E4Yl8OWYiC3sZs1+GLOwoP1hi/adJ+EFfSXivdClbkYMFAvJMx81iLL3CsdCoxh2t6uIiKf3lSNm+LF/aZn0gL056Xg4eNFDwPrppL/68Zzv+OqEAG3QKKdvrnEF4/EmBWQlzPsKGA6ogsJolFs2zEP53xOO1FD40Y5y9EuLyIiSXaBzt653Ojh94doG0ag+M/PAjKwkqDfPeBr/TYOdsmAoEawfWzvjsTM0zExiB9tF+oEiVtUnLqzuF1rewgHIgAYXDKAheVc3p3LnzFmYye/b3VqtWqXL7DVfBlSAJ5RUS2wnXPY5iqE/yluOjbt4O2FNkAm2A9nD3wca7I/87TazohbgWcodkzT9elr99KtLU7EXDUztI6ml3S8Yd06TF0VdLVM9R4k9qI5V4f728CkfBFRW4HYxBHBt4lx8m/hh3w6ox2OB3kNj+1eLfUiXlOTjxwmXFqgocGXux1MM1e1+z7uJrNUYSxp4vWw65Tfp2dkvv3n18uMVrOoL/L4JKlOPErhozCEd/ChlBXlCIOMKT3q4xav0yjHG7ArfbIfwaiqaxvWobCGccKgePVrsAzahUMH83nebCeIjP/hkKpNt2LvUCBD8z88Dk0ot/W8e7X7mIMM+OFEyJKTfOOphBJJDpgbEckDIbpCBkJtpOhtFUuw9XS7x4NZUCUNq9e3ezVvngo2mukqICq3c7DDQtwmQjnmM0S10tMQN5JB8tOz/LkrK8UvF68LwCH3mrwseqq2B6cau3GrcxdiwLl+8ebiff34+vsi9HFv1xkREr4+qd2yW6+3BxtepgTrxK8H5IWRlOq7AZ5zEvpiAAzQLwUSAsbPDNLW8U8k7GpcSa5lYWVmEfhFMr1MSLZ39ef6FU5XfHA5wwScLeR/I91sln3SH9+/ernj17NjfU/gEDBnDNXo0/3OFI7pxBlB/0I00BNgKcnckTJeX1fRDCc22BpPDyRacw26Q94EYcLouoHCOQCWemt5gZ/Ew62vdEzNOONxJxZgN8nzwWflQCLS8wCsOP6y8qhy790u28A3HgZp+TygBzIGNcqJJt/hFGk5atndaQhqliqEkB8WJUpeD4hg4dugR/ruldumi+Z+nyX6wkvJ/xKF57FRy3xuK7PZ72XSWibwvxbSyWPHw9sRq8rcLxbRWWRl4cuRZnV8rK99bLDzfMl7y5G6XlCLcMfKi3DL67l3Q9jw94KyRn0WdSXFIqZZgxKrBMKucpFZdVwfoJChAWjhMsz26xEmv6vDIfT94hunrdpBoDsrcyBQcDbinB7HVI1xhXbEy0bN26reqll16KuPDCCzdi+bgZhbOtbGfdGYS8oNBSwIphvwtQUqFiRzI96XXEfQRIpBADHL1pKowb4ckA15UzAT7MORbujwFE3fNTbYSzHlSsMUjzJcCyhwAL4DeAYUwPmLrZ+TFToxxwX4G4PD5kuFNGtC1rELcI8XQWUX9EP2CkitGkZTsbX9+WsUJOcJTk64TcaVtYiqzBl9LXMrPp0z81o+sxg1vjYDMMr8S2F3c8PuMzFm7QzvfXS9luXDqMwLeu0A85y/Nl/p0LZNNb+HB123DpeXdP6X5VL0mCgvlx5Jo0IB6vzSZI8UdPSGnWRinHrQc+OOT76kGJ/Y99T1hMHp517BB/LJfOnIXKjYLwFi+kCDNYuDRHXj78TcIwvH573eh2iOWuXrx0qcl4woQJ3HwX4Vu9VRgI2E4z+cA07YPJeASFErJj3nngTEIBMkIHk0R+q5LcBDuvcTwNnAAMAHoBBwNnAC8zHLgVIBk+wzwamEoPlMPyavUh3fDnVfpRiPIpwJlM68sl3o8IewroD5jlFuLDamaV7jCfRxxCSQWRbsMPmF/YgZxdSc44NT5N/6t1adKSajG3PiWRmYingkFTO64ayyx2RBH+4mwmTHn44b+51q1bJ11aJ8idQxJwhb29xOWfKJ5e6yXiMHzobUul5PyYJRXFXtyV2iorb1ss3q1VknZupvS4b7AkDm5plKes3I/nJbiv2zxaOl2XzqylcuFHeBCIW8FG5vbEK/QblMAdha/DYz/iDY8wN3z9JZhBUHNMPGYW8eMBeAqWdvjnHjn34FSre9tE+XnlusppH34Y0759+8KRI0cuQZFeLK94alMFUOjZbicfzCkR/FRYLoad6SiETKNEnrPC5BVHimuAD4AFABXxJ+AdgOlbAYzHcqhsBN3HQZD/A+DvUMyexJQJt9nAw+Rx7XSAAsz4VBJVFPpdC3DJthRxvwa+gp11XQxw9iCxjtoWupkP0/Ik73WAxHr9UeSsW5PVocEKYteEzFPhCCgIRlcKkHXiiSd+j1F3G+yed6e8x3DrgtEZuDcagevsY3AB9xaJPqIzvPHU7J0s2fDkYtn50lrTG+3u7Sstj8vESTy+7A7F4BIK/xKCPUoYNtoFWKKNw5vLJ4v1w7t4MI8+xUfjcLRj8qr9Az/TxXifHV9N4TLO60FzByWJf2MR7oTxLRLc1cLSLgX7kdX4h6oeHWPlyP6pLn4WaPLkV8OAcPxN3I/NmzffhqfplXb76s4g5IPygqO63oXi0+qxAAWfSkIBIy9I7FwKLNPRXxtAP5L606Sf9pMKBdPwWcSFAIn7FhRtyo6C+yUgBuBeQfOE1dhZFtMzT84ohwOjgR6A1tNwDm4lxtd8rkc5WSiPysr6kbT+Na4D86tlKk+apFRlfEMzJ2MIVpIgA/miNi70VnhxHLrr9NNP/xh+cs/dd7qXLFliZbaKlzeOSpOCPJ8kbRkqhdb94hlzNqaCMqleiA84DGkurZ85VKJ6J+MkC8dFldhXQI7471Lcn1RiJVHh3S15ZQPQpSfU9Aj/QKcoB+KBflUlockrUYZ94B1a6MNGvRpvBVfj1V5JicWTiKKansWdL+gGPjmEAosq5Jlj2/Gf3qSyyscRH88+RhZD2efAXolPnFLYcCxmZg+dQbT9lE5TIsJ1E81NMionIwHOEBQwChV5pYpC/qvgBfKCHzud/s7+YRqmpT/xMDAJIJn9BISWMwjreAawA6CSsJ+YTuunedOteWqd6Me8GYfEcLaVfqS7kD/fCmQ52oaakOC/Wmbw0MbxbdIynB1Q7+qCOayUKglNZWQV/iqAgmSdddZZX1944YWctt333f+AH1dCrLMO7yiXDU6UtTjw6rB5t/jmLrJ7Ilfc3B8051EtpBHdVYWlEZWDqMDmvsoql9LKfpKTm4xbjh1EjrwOk/0qfFzy8xqFQEFGBvC1FAnDSRlnFko/LlJ6i7DPKMBeB19atHC8S3IVoyCss9pHRMgOPNp49ZiB1uH9WjKofNeunYW0XHLJxd/gyyab7dmDMwJnDyoPBUrbz7bTXovAI+4PeMxaCnC0vwjYClDYqCisCIVP86LbCebLMMZh/kzDtOuBY5EnP37AEykYNcoJk7MXhXcO4nCT/RGgSkihZ34E82ZZ9GM4QTvLqVsmGIl3pUX+gnwfZHmwM20wUp6oqfHUDJamPn7Mj6T50tQ81TQRGvuHDN9XYiXJaDKXdnYkhYdfI8RHTqKL8PfLb+OYtPuHUz+IeP3NI32XXXqJ+55Tero+v+M9Wf/qOeZ7mFuOu19c2xZK5ZcfSXZijDQ/Pk34QWo3TqVgmF7D/Vq8p14gZYVjsDTCu+i4dW51G4OTeuxVv8V+sm1vkUzMLJWQ4dI8PP7ejbXbNrwDvBnmdvGvnIFqkZabXxcuIVo3zpLWvdvLuvQN5juFnXvhu1Y+vz87Nyfv2GOPTce/TO3ALPgtElTiGLsYJkdmKgjbyXazzYqgnQSB4smW2RfAPhl2ziSXAWcB3QEKX31pNSK+DPBrgXwLkHyvNXMxI4RRSTh7UaiPh/14mFcDo4CG9jeYY46tn0Z+2XsqE3G0HWrCqxY1tNxaieGItj24BFRi+0mcJam0TUL7lTE7ArUiU2gSXP+ywvFYaiVhNol89dVXT8Mfd54LP3wZZLYMHz7MPfHhB+X2277G15b+Im069pOtu7eK619n4VZguURf0kdi8a1eN/YBEGMzCTBrtydLCrdeLyW7u+JeVTn2FShqKwT+jUvxwP0w3CQ6Bi+ZrsBd1X+gKAfFdoQoYsZptxE1wyXIjYVizd4p7U/vLxvKFkn/mHEyNK6jfP/jLOl7yOCqnOzdMm3atAh8X/gZPD3/CU/Oi7A5h9YJZ5USQDfqVBIqCz+RQ0XZI4FP5DNnE47OWA2aDywMhZVCC82WDKAFoJ1NZcwFtgHcw4BZMhvpWTbTm4eHtO+JEIczjh4cMA3vWh0OHAyAKeYLjjw6Zr+x/pwh2c4tAGf+2cAslMk2By0TeSLYnICBweYuF/nBtjoHDNbjR8TbofHhbhAh3TAkSAM4AKtisAzmzRXLV8ifJ3emPnA3GrEx+0yoECtLBlNJWFlqOJUEC31phqfOzbGxjbvpppuufeyxxyDF4l24aJG7f79+7qUbcqXvW+twclQqXZLiZPW2NbjYeLZhbeTVfSTqkFZ4Eo6TK7ABrQbKpWjT1VJdeBBKgWziNq/gjzxl+mPYrM9F1ja1Q/93RVF4kCjNsByLxNINX5CXzH/hzivKmFciaU+uk6zH8T8kbU6U6aPvtzokpbkKiwrzr7ryKg/+ZLTZK6+8Mv2iiy56D8pRCuXgPoLX2DmLsDM4i1DQCTOboH5OgYB3cLL5xRmFaQMEf/KtGUCTfcJ8ixHPKATshhCPvA48v7C9f9dgmiDlsQwwxvQV+40KQuFjmTQDhPQMp+Qxzm8I4Qjae/vrG+83BfzBHmT4PhOZhoaTcRxNyXQVGgoRhYmK48Z/oU/mN6Xef//9jgP6969es3at9OnY0b3mIo+c9sZKWby1WDq27iy5F70m+a9cIJXPLsXLJf0kHJ/iwUqeax90UTSeiGNvgT2DVBXgRayZ+PLt3cjeQRNux1dtx0JVUSz3ImazjrTVcOf1wf58AT5QlyCbpEDOTr3VenDM9a62zVuy3gVfzPiiCsrR6uqrr/4FyvEx/HhfiorBdlBQKThGIWBqmwMjNPz2SraQkWcsk4JHosAzbyribwhxtY8Yr5Zi/SZyEA+mscvjYMZyWWfWH0z8LQWpG/t2j4S8kMQMlDqyB4vbIKWumwHyJ69Y96C0L3wJmlEQzz0WGiRuUC+boexEKgMbQhOSbJYLsVhq8Y88o3fs2NH+/PPPvwP//ZeOsOp58+aHDRo00JVXUiWPf7RK/jYLx+vJsdLJ96HsfPnv+L4uJqLru0hYP0TH931dVnPxbrtCrI24ePr9C7is/T3GwDbYrF9bowj/vhkHleNwYfsGKBFWKnhvvebKiSXJeJ89CX+nsKbNa9iGvC2xz7aSddnLJTU5Bc9SKgvwRzle/C118kknnbQVf/rzJE7htmL2K8LsV4ANejH2IFx+UEmoIBRSMxCgY35XeBCvXmTzkH2h/aEzEodntdcrr/pEcpTH6M4ym6S8+tTpzxpHmbNf9bM1nEpCqJJEQfhicP2dSpIIJYnCH9J0vvTSS2/+/PPPWyMe/jRzuvuYoyeYkefTBVvl/A93yO6wZcjlaun0Ynsp2L5Zsi/vJHIIluf4pyiZkYED00eRFHTMXVhJH4plUxLGRMjr9++I4O/X8HI74p+GDy5Ykoac8eqbbKhA+C5LLhjjkdTSWfLmFU/KxqqdvsLi4uI7br/dheskCXhuswv7pSfw5cQNqHcp6p2PUrisonLoBp2KQaUwitIUwou8Q/Qn4oBO8/tVpXvvvVfTO0dBfW+bph9KEo5/jy06/PDDf4aidFmxYkXylCnvSnhElL9Ht66uPh3TXBcdnCYd8CWRj7GyyWv/lZTNghwuwPvszfDm3y+4KjL1Y3H3mSDRJz4g7syBWElF4itulXiHPUziU9pJcuF6iZn3gZS37i3+5AwpLijHFscvA1tFyePHpcutx+FqfGG1PPfWS1b/AQNKr736msipU6fGnXzyydufAbVu3Xod/gSoAidwVA7dkFM5uASiYnBpYpQkpBzgxP8ANcoMQj45llrOmUQ37Wbjbs8kkfimVMv77rvv3Iceeuhwps3s0Mn73DNPu8eOGeWGwkhOSbF8s+FHmfHzLPn0xX/JztlrBfOERB1zi+zoeTQKw9SA72A1w3MOPg2vwJuJfrwLImuX408FLjHru8yrp8ixB/eVw7vGydCeafjEqRkLvJMmTZIrr7yS7TYeV1111ZKJEydOxr/ZbsfMUY6Zg6dVnDm496ByEDpz0DQX/WCGKMSBhnEASsL3FyKAGCAeSAT4b6NtAX5VsB+U4zCY44ET3nvvvRfwN20crbnOtk46+VQv9ii+0uJibmStZatX4N82a8Jq4oyw0v/6sTXg4fmW3DjTkiu+suSab4w97Z7Z1sUvL7EuvO1Jk9fAYaOt7Tt3MRtctfJ6ly1bXnnXXXdzH8FZwMLbjz5MGh8h/FzgOCjvETB5UbAn0B5IB1oACUAcEAXwmnijDSqoR4j+1zgAAdqTkrRBWCegN5RkCECBPCorK+sKjOCf4P9EOGIb4e7dv5/vueef8553xtlmWQOl8eMUzLrqsvNN+Atvf2xt3V1i7S6osnbmV1rZxV6rhM+UbUJ+Rglu+usNvhkzvqi49LLLOQuYtDRxSrVs8eLF9yL6icDRqMsomAMB3mbNBOoqRzT8QsrxvybMaG+TjIYQJm68nUst3bhzycUTLj4ZjcGoHY+9O/0i1q5d22X69OkjZsyYMRhIgV+A7r//fv+wYUMlOyfXevjB+2Txsl9ck1+ZJEeOO8rlxotRZaX4bm9JiZVfUIiPWldaeCBpPfzww6wDYQjvqFRjr7EMm/HvRo0atQiehTip4nssupzSJRWPqLnn4HKKikYl1SUWlSxEfzIONOV+sEkUhPwLoiQUVh4BE1QS7kuiIKN8qBgDQaV/BD6A3fqnn37qgf9Z74Wn2R2+nzMnJS8/n8rWYEpPS/OOGTt22yGHHLIMH11YhLcd1yATbr59UM5yKCdPqOoqhm7IqRgG6ACeWoXof5ADTaYg5KVDSTiDEDqzGGWAW2eUSChKDJ5c81iYysC4MVj6JOHjD6nbt29vjSVW6u7du1vgT3oS8D8ksYjLY+RwmHgR0G1Bwapx+lSOmaIIFwx34w3ALT169NjYtWvXrciL+xyzwYZiVEIxqBTcj3C20BlDZw2zrIN/YObgCAVqUl6hvBDtIwf+K2cQbautJKogajoVRZWFswoVhbNKFBoNXTHKwrhMR2Uysw8Uh3HCgTB8UNoFBfED1XigV4kr9yr8OhP4oUh82akCSsS9SF2l4OxAOBVDlQPVME+iz0H4UwAVjXX5/05cSv7ZBoS6dWIfxQGLgaPQTzzYYX816jJ4n5YuqFC9ya44K+0Ehd65vufoToGmEJfbyy0qAJWGSkGEYbZAUJj52wEognagM18/4lhIx1u05usjiF8FRWPeVAI1aWeZdRVD66TKomWsRtzJAJWPdQ/RH88B9hXlYyvQqErhbJoKgNOvSez2EoXCRVAx1a6mLq1oUiE4UtOuoFvhghIwnak/lAAHubxyZPEbXRRuQjfWZmllu512VQIyupZiUKnhZ4j1buxRSfMOmX9+DhwwBVFWQOBUIWhS4J1utasiOE0No8l6K3T0oKnCrqYqi9PUMKcZUJZgymDXmXUJ0Z+PAxzBOPA1CR1wBdFWOBTFqSSsjyqA0wymHJqVmrWWWvCkAtRVGo2jyvG7iqEZh8z/XQ78YQpClnP5AkOVIpgSaHgws26vqfCbrJl9EKhiBMxgM0bdjEPu/10OUPD+FGQrS91Zo65isK7OOqudykAKZjpnEoYbd0gxDL9CP3vhgArYXqIduGBbUVigKkswJWF43bo7lYP23yCkFGRbiBrCgbpC1pC0BySuQ2FYnirL75WtisFXdVVpfi9+KCzEgT1ygEeoTUIQbM4A3IBTSCnYKqy08xVMPtgx5cMeOIVwpOOrodxEk/QESfOh6Qw3kfhjK5SJD7uWra+Zmnjw1oMBLrdIWicm0TCto7MdNbF/jc82aDjDTBpa4M882b5apyx2fKYh1aqfM01NsPndY1tNBjXlKH80PwYFXnO182Uc5uXsh1o8dJavfeJIywHH2U+BvnOkq5uf8pKvCCBagFdaB9ZTee/kpbaDJsF8mZ5xg7XD8NgOD8ZbZ3nI4g8mu6INrkXddHBrY4PmFSQ+GRiUNC5MFabfxKtbXl133QTBwuH3e3Wod9l1ywrmDla+M97v1cUZj/Zgcevr58xL06ipYXDvrS/3yJs91U/z3lt43bo40+3NvsfO3FvCPYWTEdB2jgZ9EWckwKsdbDy1mDMCP23Dz6RBov4AAAufSURBVLTwn1Ivtv3fgpvx2FEdYJwCLIDfV3CnwX4yoEeyzIdPUDci/GOYhhAPzpolFexj4TkB4Gdt1gAfIGwt/LVu7eF3AtAd4NP1b4GPEacccYbCPhyYBjf/DWog7IcBfIpOYvm8aMlP2cxDeB/YD7f9P2E5sLMd/ErJOQD/RFO/Rki+sE7HA4cCzAfvGMs/EWcnwlrCfhpQt61bEP4h/AOEuPyMEOOxrCNgjAFaAfz4wwyEfQHTEMJZlzMAjvq8PUAiDzcjHt+JgWFG6FT4/QXABwJMnfj0lfHOB3hN5x3E4+d1KOxnAYnAi0AycC7APvuS4TDZVvJlMPBvuNfDzTYPAXhhlLKnvJyF8MUIJ69HALwnxzJY5jKEzYPJdvJqyZkAHyRrO3gFKRdx3kV4a9iHAky3FGgLrEbYboTB+BMsuVERMxLAfBXYE52JgFg7kN955fsWbDSZcK3t/5TtPtV21zU+tcPNd2lpJyHSM3Ujwn1HTWit/OtGu9VOP9UOONF2v1I3ou2+yQ5/0hH+H0c5g2z/BQ6/4fDb4oiv1q/svI5RjzrmN3Y4hYZtVB6nwE6BDEbPMy4JgYcGiwA/zZdCxnh8qY1UBlDZ6HcaPUAUeA5e9NO2UQjpPg8gvWy7zYfe4P7a+FrWSNufQhyMLrPDXw4WCL+77HC+sxOM1tnhGQj8K8AvQFL+3gLa2GGGd7Q3hMw6siEJ9hYXWmpGNcQjsz4AegMTgR+B+wCOZhz5OXqTOBJzxFBKtS1LbDPdNt+ESQHk9XiOahx5SX6Ajef9K46iVwPsuHOAdkBH4FmAHXkRDCpeAXADwDqNAzKAlwASR0PSqhpDOKqTqGQ/AyyffJsJkDSc9uNQRj+0hxfo2tIDRDvLZns/A5j+EeBtIBPgTKbCzBGQNAV4F+CISeH9BSAhGzMSsq1Ukn8DHHFnAI8B+OSLHAFMBK5AnJmoC+NovozHfqEA6+wFq5mxaG4FNgEUKtaTdE2NYUb89rCvB861/e6xzU62OZumoz9T4KwCNtAfRDfpZmANEAOwHV8DJOXlFbB/B3CQegC4wDa1b76AexLANkQCmwASy6LcuADOViw3C2Cd/DT/dIROOhogPe6sHNx/Mb6W9U+YfJNPX3f91vYfw/iwP2u7TafAzldfydQAwa2zz5123GkwKVgBgpuv/3KqJQ0JBDgs8OdrwjuAAqA5g2AuB0gUcLrZKQGCex7Apch3AOkfDIR5i3FZ1m22+wPbbWaqQAYOC8IftuNcaqfhzFq3rVRO5n+pHZdKV4vg/6gd9ioDYL/Jdt9YK2JNGNdWFChDsM+043I2GWnbuRwmXcJIMEuB1YDWRWeGq+HXDegPjAG4ZOWMqf2zAXYqNxWN+QR4CTvrobw2igT3OIBkZmGYVHrSfXb6SNhN3rabb7Ma0P2nJlTUCCjMuwHS9awwTI6KNO+g5x6IjO1qx/vEjkPGKu2CRZcAZIgRIpjDAI3HPN4HDrbzUUX91HbrX53xVVrtwEzYuZRYYcehUu0ElDTvz+1wKhTDqVQjgUqgGmgOqJDyX6HCgRIb2vkRcLNsUw87v//ATdJyaM8BzAwAM6AssCtfJthpo+BnBA7mmQDpLTvspRqnxe/rbgJoLgA4m7MvnDx8DW7SKOBjIB84BiA9AKj9OkfaOSY0+M8cO14agnMdUbSNH9jhrRBGPpL4x0IceDTOhXYcHSzVn3Fp5z7QtINmY5IZARozQ0deXtueaZucmkmcBkkdagz5J0yuIdn5nNavBPKAHQDpoBpDFsKsBKhgK4EcgMQ1B4Wam1Z21CD4cQTm9ExQQZiHUSiYOt2z7TwK5eivoxAFkaOpxqGbAl0KcOq2AM4sswESlwTMdwXymYl8psDOmY6DQTuAxLy4bGTb1gCFiGdGbJYNNzvWuGHVNItgrwDY1tVANkBi+Rpf426nH8iE1Vilp22yPJIZsWGWAT6A5e0E+LoxiWndxlZTHq3nA0cDDwNfAqShwDCgGmBbSWxXBsAlzJMAw9jHnHFPBjYCJPZBElAELAdIiYBRIJjkZRrAcCpuDyALuAR8mg6TpG1eCjv7hEtFysE24L+HHB3OzqTgkPqyBTCpCDS/BUjaefRrYXx+nVLpLgaUyUwaIPgbwVIzEAAL/DiKbwVIzOd4Y7OsuXXiJagb4TryPkM/uMfaad7QOE4TYUPt8M/s+Afb7jyYHHm52U0BOHpyZiG6aR6wc9RXfnC24shOofgNwb/uUkhHba7XA4R4HQGWTTKKAnMdwNktsLSBXRXCpIXbDJYwTwKUuJTKZASYy9UT5vNaIOwZQGDWdfifbce/z06v/A+k1bh2uPL6daTjzMwZl/ygErF8zrhc6nFAo2LUIvgZWajl2QgOw5RGyKduFqws6myWWRmwlwO7AG6WOCWygW0AjmjsOHibI7gBcJM2md+azWUc7EWIcztM5svRnqNM4G8AkJajFwt8DEYX4GmACslRaznCObX/BDvTDYb9LZiTga7APXDz+JLrc1XWTbCT1N0BcRgeZYN/Yvkm7DqimZEafnMR7xP4TwBIa4Ey+FPQvoJ9HPAG7BNhciS/C+A3gEfBpKK2ACgUd8NkONvKUf5l5MGBgkqix7sfwp8j+kT4kUecYTnqco9DoeL/sXOpwtmLsxxn5K0A+4CzU12ybA8ORpypI4EpiKuD00q4qXCcHV4DlJg3+2UTPVAe3wZl/gPpBml65SX3KMpLysHPiD8FZgZA2gE32/oR7GcANwF3AM0BzjCs2x0Ip+yQP+TTK0jDZTeMP8FRLir0u4SK6qjYBnYSR3Ljx4SwtwNImwAPQAbT/3KA9Ijt3tMRLwWeHcg0OvJR8OsS17TaUYzL/YCOrs64VCyGv2d7Hm+7n3VGctgpnIz/kO13Ld0kuEc74n1X42v828F/riNMrbNg4R5ljHrUMQvgjrHzDswi8OO+4dU6cenkAHSbo9xBdpzZdh5MRxieO+K57fBkhHEZSOrtCL+rxst6346ne8xzbP8XbH/t+y9s/5G2v+5tbO+A8ZYd/rTtc5ntHm+7OQtzNdDTdgcz2thpAjJGd2NQLSY1RobMAy0wmgyTa8kxQA48KAhO/7Hwz67j3xl+FOi58F+P+Bm2m6MGRzjOFBw1diP8R5iGHPlyBOUozdF4HTAd8bjcYeezcFjNhnc83O2APIAP1VbAZL2HwGgNfG2n6w97B6AcYPkEBWMlwlcjfh/Yudbmg67tMJkHyzoc4GywHv7cDJtRHybTHg30ArwAj7i/gcl0bWEMAqoBjopaFnn0PdwBQlx41YyUsB+GgEMAziKbAdZ9E0xDCE+GZTSgdQmkrYlR+xfxWX/GZyFfaVkwKYTDANZ5E9zaJvJnMLAQ/msc8UfAjzzgQ2GuANi2DKAuLznDs68HIKwjQF7y2RgHwFEA+/JrgPwiX8kbgrLAwZEz7HdIQ/d/D5FRwWpbX3/EY0ftNyEfj2bitKsfTZYF1Kov/Zxx6trrhtdNr/HVH2agHhqmZt281P/3TOaredeNx7KChe8pft306tb4atbXX+OpWTe9+quJ8Fq83lt8TXcgzFpC0dgF2g2lYHA0otYb+h1/Moowlwsd8WoS/vpbKz/1RnyWxTZx9KVp8oEZIMTRMjROIC9Heh/qC2cgbiC9bdH6aV4mvkZy5BPIm2HwZ50MP2Aq77UsDWNUJ9XKwxlAu7MsOH/TZmeZzj6om4/Tbedp9ovq78inFk/hrzyo6699oe3TeJqlmnvkJfI2y2dEVNlhnnXpd/lTN3LIHeJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAiAMhDoQ4EOJAY3Hg/wB3cRq/m/+84QAAAABJRU5ErkJggg=="},{"id":"maaamet.ee-orto","name":"Estonia Ortho (Maaamet)","type":"tms","template":"http://kaart.maakaart.ee/orto/{zoom}/{x}/{y}.jpeg","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_R065_N47_20160929T102022","name":"imagico.de: Cental Alps in late September 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R065_N47_20160929T102022&z={zoom}&x={x}&y={-y}","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-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_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-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":"https://{switch:wmts3,wmts4}.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,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAMAAAD04JH5AAABGlBMVEX///+y4OQAAAAKCgrL6ezI6exHs8AdorE/sL0FBQX+/v78/v4RERH5/PzS7fC64+chpLLt+Pm95Og+Pj4mprQYGBgAkaLM6u3D5+oAlabc8fMVn671+/wAjp/Y7/EmJiY4ODg4rbsgICBgYGBLtcHk5OT29vYyMjJqamoNnKtISEhYu8aamppMTEzy+vpycnLg8/S/5emjo6NSUlJfvsgsLCzs7Oxsw81NtsKsrKyu3uPo9vd+ytODzdXk9PaEhISBgYFVVVWe193P7O95yNGPj4/x8fGk2uB7e3vd3d3Hx8cuqbfW1tZnwctRuMOxsbG7u7vQ0NB2dnYAl6dzxs+14eWW1NtRUVGZ1dxwxc6r3eKx3+ON0NiR0tk4C4avAAAG00lEQVR4XtzY5Y4qSxQF4JVqV9zdXcfd3Y/Lve//GrcDdTPQyjDnNMl8PyBAUnuxa1c3Ae8S3l9fP/+KFVG24rm4IZfraFiBRCqX+jyRiscD8F1yUp5K5Xbhs36K1qcJ4ofwVzVuChCFr4a0/swmJOCn/dxnk/g6/FSKmwOkovBTMGUJ0FLgI8EmgAYfRa0BMvBTxzIDcRF+2s1ZjuE3+KplDvBZw58la5rbklfzLUjlDuAim8Ub7ekJlmXP8n04qc7fjEpwFF4v3d2Vtk/fEKJ/xrETHKfDiThJQOvfwUmilBGCBiETXHhKQkmWTUwZETQ4OMjFUxPx3BacfGsFo1Qw87hw/cQrllPgQD5v5eLxXOvBubmnreiMxRIoHK1PcTpcpNMynOUz0TmZf+AtzSXmsFwfy3oUonOCQe+1ZLr/r7g8lpTORE0yP+Clz5kDsAkZy/lhCSDw8HLIJUxYTsNyHoSoSfDOc62hJcDyQ9ARombB0FsCUFz2jwUIRvvwELLpgILlbNlsgedaWesQ6ljSlXUIH+FJtxzDIZYUEoLmY3gFTyFTC1hWwbIeMuYRgDc5z81PwB6Wppla0PqKRZxx7Ez9NN5Bb80maJ1jMTrHsrT93CHe5UwQopSQOcCiQmfclN7HO2XXhYwgBIVMRkzgDbKHw/xwT8MfsHe6zvOdgzw+posCVmsgYbU+MVitJsFqvXSxMkexQrkJ3BpPG1iFcXutdwHct9e+V7AyzxWs1oBgta4ZrNRLhBljhS7IRoREsDI3ZADckmv4bKfSUNWNyhhjBoZKEbefIjG13Lu4hA+eGMJE1tYiDJEaMRia5RiRCmvf2zFCfDiUR6TwTAewwkhHwIvKFHcwUTshDSxNUWR4e5mduVqEFNtSbAcU0CUDLEDLmmuFdC45SnJpBR6+q3XMOJbU4tzGn0h1eEiedx63O1u7M7X6XCA8EQjn4S7WxCy5wpg79ARXXEfk+WqV58Xqb1B7RvnRVDiQhLNuQ2We3K+E9bJaHtzA0Y8SX92eqor7tP0BWt49gVyLkUJFevb4RdRo9Ai5gIOrEi0/k0Ax6s8K6LBVV9VbbBKPAFpsALlHdmBrSOtT1dJvAHpgNO+rAjvH5B64JEeuAeQa6QJolGFrnd+eU+UB0Aa8CuRhZ6MNQ6Po3oExuZk83sNGurRtIo6wFxiZhEf2O3A97UPNNUCkAEONjGHjVDQH4A8wtAYIKLC6ZI5hqElNtwD30/nblGwDfOHNAaod5MPWAFlY1WMDGFAhdZcAJ6oGw4391aBjDVBdOADaZUxbUHEO8EIP4LW06TmDNIDtFsDODj2BTVJzDFCIYULtwc6+NcA6+tYASdgqTFugqUWnAGM6e8fkFnaurEP4LxC2HMM0bD2RI1qmax+gzkyjbZIebGXpdehVSQfSAfMOyLAXoc0vMpu2AXpk+n6Dfm51zpsa8AjDKDxffwgHdWmDfsOIXYAx7dAx6cJBVjRdinUYtPmbkQ5Hz/QnV5dcWANsMg16EtpwlKA3Q1r/F801+j9COBzIw0WTfrk2ubcEKDKXMFyqMbhI8CJNUOXFX6DkfDgQNgQCyRBcRabzXY+VzQEG9A7YkG7gpr8virxBFB+GeKUd6mwike7DQ72sTta/ldrzf9HskCYMWKM5XIR2z3/+/HI1xFLqtemEX9boazrwm9NnhX78gR2XN1wVIgr+qqONoqtGW8bHdh0ruCoXZfxV3d6Jq7WKjI+tSRhXUlnBX7XTHLi7/q89u1txFIbiAH6EzZV0xd6shNJHKM1VIFoBd6BXuYshn+//GluWma5qN1od4sD09wDJnyTnHEF45OXl5eXp/nw6IkIQPsAn2BX+8nZxWf7E9oUx7MYwlMJaieZUa005b+Yuhg2zyV+WsRzWqbgW76iYt9jR2OSOmXUJ3qj4h9ITTMuNTTos28FynosuWsG0liU9rIDFzlz08T1MqY1NeixbXguSij5dwRTEkgGDYaGd0GKAlzAhux/A+jsouRjiCMLSdhxgDwsdHwQgXz0APAhAYl4BEDYK8DPqI8SjMlzRC9WCMkztIADLPrMRkTmjyA4PYLlmQSuGopvAmt+BsY1Y0zAUSlj1h9EBZib4GMeh/U/GeXnj3TUQ4XIfx5rrA8yDrWH2hpmkhv85OqneSRcolPbjg4Q2MFuKSXtTnCGwv+pwvwLFiNSlqnyWw1PS8K/c3EvV5UqIy0jVI68QVe7VgK8hJjQOkEFMTCq16R1cxwGa9FsFMFtfAfGjAC3EVI6rAMOmr1A2EFfpVI/DEBnqDyMC0f3ojuMCNlArJ6VSUjqJYRs1MUpd92dY4Q9//EnbIq9ZogAAAABJRU5ErkJggg=="},{"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":"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,iVBORw0KGgoAAAANSUhEUgAAAMgAAAA2CAYAAACCwNb3AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAcppVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGFpbnQuTkVUIHYzLjMwPC94bXA6Q3JlYXRvclRvb2w+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgofPyfmAABAAElEQVR4AeW9B4AURfY/Xt3TEzdHYMk5I7KICKILhwE8DCe7eieiomRByRmGjKCAIHhgjl+PNUc4UVZEggKSdsmwsMuyOU0O3f3/vJqZZcPMgnfeHf5/BbMz3V3hVdVL9erVa6HNhEciCxS7VtBJKvsDJlWUxCjFa8tdk+6oD/zU1ZOMhyttYXYmK1EhMlbgfnudQWgd161y8+jRnhDZgt6+ZdIkY0nU71N/ijlFyjBneAMNTX/3lSZH8k51u1RR0i3KFHZTvrUy9qy13NWvVbtebkWJ0agq0yusdH9+zv5u0Ym4YgfCw0wHY6Lj93zw5Iw8fz2C2WymjxKo91q/U8xmwGOugufhDUuaFpcV9XJ53T0kSUo+VFooJIaHxSXGxifbnE4lwWASL5cUHRA1YmmEVn/Crsjfx2gjD26f+dzFQJu16wzcv4ZvAWU1AXhUVRWGvrSwvdNj73uxorhNpGTofryiSDIJGm2HpOZ9y1wOKdxoYnar9ezlyuKzbSITbSqTf0mMitvfuVW7febBwyp5mykpEtuxQ2aCUIMOhEaTH/qkQHEOEgShHE801wDg9ZNFELwiY4lhXmFWxbqPVzIgFquGWARoYCJ6zRsz/YS9eLmLqYUCE6SanVDQcZHZFK/S0RQZ0a998p2bhz+zK3XLFk16WppcM2+tK3+bzab9dXqx4lmuoH7G6yc8BHQ8+euXPUq3sNiI/sm33vniX54MVr/AUlNFlp4uY+LFQatn/i2nrDDV7XGnWEQlslRRmFslcFSmEUQmW0DSCtEDkkYjaMIjQP4K00sSixAEZnSzypjwyB/ijNEv7pix8jvKVpv46F49qQY8dzw3+eFiS8UTZV5H3wqmGB3AFpfHwzSihsn4ZjYrANMIzOtVWUSEwACHiH9hBItXsbUMiz5q0Bs3Z8x68U3gG8Etms1mhs81EW31+Xj2/15u8ePJQ0MdLucjFtndzY4JLGcKk71eJogiU1VUSeMjAEhZVpnBIIh6I3IoLAxwxSoahju5kTrjBze37v76xuHjj9M4ABaCqQoeSRZZnKLX6ZnL24CJAo29L+HndZcCsAUAAzKoJgNTLe5wfivPUgdqS14ev2cTvOF2o1b02uwNGQawdhIxcEzxMlmnZS7Fq6/9POS1v02rIKN+CVTmRP0BMK7QFq9f9TJFr2Gq7KlbPzghZhP/0+XUF+c/0Hn248suM1eHMsDE3G7MiwAABUUEshHXlAVZNRjCNRgS0Dv+qEx1uj2YTgFI62Iuqk9kkTkO75A4Z+WQ3gvHfZPcptPYDY88fSGllkQI2jcqj7aIWAmeboDnEuAplQGLB/3i8DBFgzyyCiIBxmvDIjWEWVoUdCqKrLhloKnMLCB2C+ik0F7SO8yl7d1yxrBpf14zd/6Xk5Z8CGRk1RE/KCy4mboltYpZ3WoeN/Orw7tm54tyhMXtBAFgFDAk6LpK40NEIAJ+ozFSQ2oApgMPMbser0Izb0MZG7IC6CaS4J5qObFv8i2Lx5n3zNu4mIgjNRVtod8EC8ZTcDMvuqUyD2c/CrCOPsSKrrdPADb/N6bPrQHsXoFh1pCSImqTEItISuL38Ac4RdOH/tII1voncJYjYAyIO0uU8dqSv01JEWWR1w9YatVN17x+jLEqY9xFQvZqyYeMKk1wj/mjVu68fPrjLE9lhzK73Su4vV5R0CjAP8J9AKZKQF2S9JJTVQQXUNCFqaLfdI+eUz4BhVBEofIlDoey11Yw6LvMX44OXD+vawbUJSKSahDU/AkuCrygcVP7LRy7cmfB6Y+PeiwdSh12r+hRILUFFXjI4ZH97eFbAxgg4RRmg5Sja9As2uDwiETAohe6sNPpzVbtHQ8VZ6cPWDZpM4idIz4RSU0grlz5iCNdNn/9bpOOsx//6ainbPlppyXCYnd60EMZRKFidDSB8aE2MRoamx8eECvzKIpI8ND4YCwlEWJGVETF63B7TtnKxJ/txYtuXTx+16a8/SYiDhAK56KiqoCSiFOAygHSH+OjchkAWAXZi5HHyISUIIFhJlGPAaREncVFrQ/q5GPgyxMo9tu+r1a/jyHVrRMzRjdbTRu2MdNbOa3Abge5qSAMkRaGErQoTO5vSxy7feWADCAXj+w+4ayIyL6UvWfEO2vbE5EQ4gWpVWBmM2+uzYxhG391l00rsNkUjax4UQ1xDvpw6glSNuQtVEhcAcQrSBr0Ldda6f3eljdyyJrZu8+rqoFU2QBSVq8kQBxzvtjS+Lv9Px077i7vU2FzeCTONJgWCE9S6zfBQ51DGXw4zmslUaPKDrd7l62g73tvvfVPah+wUBbQXSCBewV+Xu/fYAHgCYpXlURje8HA+sY32U0wpw5sRZ2qJ/072F9PtVWPfnv9yaNGaVFc6b1o/OwigzLW5XC4RfB+dIS4YNBEtykLvmX6gMNx1SFoZtykjJhcHRiJ+4xiDTt5/uR7lDc9jasRVF31RDih3r746XVnRPdYq9XhAa8lFSWkFYeLs2rw0PxcQazqVft+Q0hLQEqJWR2ub0rO9Rr13OS36AmQ0pfhyl/BDyP7cu/WLT9WXI4CIC6wE60XyB0KYYn7EQw0NvTxDeeVSmv/ghILDsJ0zOlxHbQW9U1Z9sxMypMCY8CVfpCAv84TAQiAsQT0irHGMKlnWMLOlHY9222d9+LnGF0xMJjXeTeqgZelObB5s2fYaytuyLWVLbVUWsHSBHDF0HMBJIdAgaKmyiIYhEbVajRQHkRonRwhqlVe5yfK6Zhbdp/3WJL/+tKSxygDIUEgI36T2iU//PKSBy54LROY3eEFonGJEchT+5sQELCAW3lFgoVggiYlKqqCZTDRVfAEBGfIqpdtDvdhW3HavS/MHoacih8GXigA213PTZ+RLTj7QP11oz19KMLw4wcWBjLDarIKHhLG0A5kiJlQRblE0Yii1upwsNPlhdOe/eSN6AxI2dB6aPB+/c/ukjLrRSdVrSS1l6K8rWIbzPxm6soX9hNEWFQxsznkZPzPgL5Kw+lZmTzHpYL853NVF1mDvNDdSaIETdBPyIwgJphMrLFoLHeJ4gmnwJwGr9zIpnrbX3TbgZIYI6gdwSog8QrVRJPnsLELxbljcPkWkKBK6hJCULn9F08ty3ZZAI8kAJEJ7+okugkVX1Z1oqa9IYpFSYZLxbLnrB4EHmEQOhaqzuhsu4X0GBkaJBkT6iQiEp0gSYXWCnZe0ax87cSJz57s0AFrelriMJYBK+XML9+L2fLj19MrXDbAI0qygppqQRTQr/AE+CFqWmjDWEPJdKlYkc/qYTvQKkrHE15rtBPGDqjaCqmstesg4GA6BCEJHouWxR7OPDwCt1Zf9wTCRRwZDmVFig8Ll9rronZ1btd95Oa/jT5BnRq1aZQ26XKSbE5Pp8s/VjKnu4dvfqHdj2cPDmQON1iqJjRxQGUgztwjIrG8fVKLme2bdP/IPGRIMXV4h6pKmzetGCiez1ybrdrai2ReCWGy53q3W2aXHRW9xr2zoc3GR8efMUP6ZkA4E4H0mDd6WKantAMQ2wOWGxQejp/YTGBaQXNrRMN9PVp0WnRrcv+daZ07WwmeV7Zvb7Dn3C99ThfmLdxrKejqcblBJCwokcCiAQOf4AGDaPRO+ktpKP5a/4ULNSn4kQFt4fDpQ8PKtUoscwIeFfDUIg5k4wnEoej1Ok0PU/zOlo2bzRvcJeXQsN69+R7H6q1bY7cf3fH40aILz+W4HbQmA20HrwmcRayElatMqHwQFfsIhNokkiUqp8/1kgJSA7JY6qCPltvEN5n15eRlq34CgKS7D/lrkmrub/Zt6AUsQfUC/5/u3W+v/1LZpbuLNaThk/SAhTRIIh3aq8hi1/D40sE33d5zyb3Dz1fLJvQHp8X11nFbNqTsPPLz6WPW0nDsitCOSR10AoSwP4leu8Sky2X5t6HcmQw/cVCdHtU93eXlZlsxlEhGHV4Rmy3Jxrivds3f+OddKLeOCvvaU0cOHFiA35/Qp8u8EVuOqRWpqkcmGIMyZEgGsczlZOWSnbj2ayBUhaX6YL9YVDiwFGZrvi4LNbywNGNRpmkhmf6xZ8HGh/egkvfxQaL+q5PvvrsU36v/vHZ2sT3/3FslDrsCI1ZQgqXRYW4vc0ieHpM/fb2pCAEKoSzTfhN2d1RYKtB5iPI6I0vN/ZcStc23m2A4iQsPl26LarL7js59uhFxEAijNm3SHkg6RcThXfPrjugR61bcAAoH+MHVgf8S2GjmGkat1iTLLvdtFtlDa6ughekmdhOUOKhVLWOT5hBxtDA/biCu72+Q97vJpFTjxrTx+S1ik9ZqDUZSF4Lit695US2DmeNs8eVmNDbG2BKukt29fOZNpR5nV5j98TS4moaMqEKR2jJ95Z9vuYsQGnsUZh2pRfhJ1dNuvTho3QS+1zPqnqFPddSGV0Ifk3xlqUTNhA5AiiisyGG/cdimpY3wVGHpTF51eFsYiLkP9AcMTjWDUrXiGAQY6BVNG63JPbB///H0KNVcAx5mVvlYSV8+u+ztFrqwnxnUMN/WSLWK/D99kkWQKwXFcPLsmTaiVhCiI8LDWJTRqDcYjRLp+DDaY59FhewTvFho1ZrSupX+nncg/kCrEKeiIHU0xSm3xbecuXPu+r7rh43JIqlh3mGWuBsIdswnvb2+Z/rnW07+cPEILfBY8ujRQTnUFfiC4uCVx/+1X1fALHDbmnOFiMvwugAAYiIAKRrbHs0aNfyccjzOWriBhJhLv8AHc7jlFt9eUKwx8uNGfPtBqWaBqVkvYQd251miKbwjPfnm4Bd8YByCc+glEYxegCG2ZpGqKzzwag0G1jKu4Wvmu/5S2NmcqktPM7uxzggUUQm2byaud9Gzib0HV0YbIzYzgx5snv7XTT6kZF6HRjWWlFfcHMhx+Kefm5TarTGcJEMxP5IeOokl6iP+uWHgYyUshUnp5hrwMLNgVoA7vI/Nw+K+MWFfHAyAxq9O4p3ARnIxNkTPFeVqxJYxCa8PiG258e5mXV9INias6qgJ/6CjIfJiQ/jTKFBtZOw0wJ6GvTj/ZNSp8ve5QdDjQ7wLi9Bw7W3RTffendy32yfPLnmOWiDCOHDKJzWIWw1dM3fZtuO//LLbXZJ41mUnNypGUoW+r+uETmKfkLqLPn0RD4W4DXFIrA5JItRJWhp94EDTsJiKOwbegVUvYwsWLKjTz/TULXzCW7VsfSFaZ6gAvRHL5WzdP7ZcRPGGaaihKlR63MStGXszmyOuxW4Dt5ZDwsIBVGVNM1HPGic2+YiKduqUGhTp6VkCK/IhocC2x3DvHp+ptDY8PpgE1QmI7R7XjVSWUqGlvJlghHWa1jscPfjtGn+wZlc1ko5l2yy/0IPkdj5CqJEJF60GlnFYPFpxN8QSRkbl/hTBYVHVaK2O9WzV8SZp9+z1L9eubMOOHeGf/rqtTwerdVShtvLBLNkmwRUFLEmEiST4RNau47dck+kSSp7CtDqpoSxYbghLmLdtzpoXd6ISkhqtBg5UzP3TSIdlE7as63X7kgmvHnaWdK2wV3r0hjCtEXtP5b+lwesk78nLeczicQFryD2i/kRbfY3j24dERtTBicZ8d1pph1mPncL1TbASkYcBV5+q187VL1XQFNtt8NPgyUPqzKtb3msDoy2KYlfA7+JVvRzNE0hbjBT1l4Y9dv+B1x6fxNJTU0OCnsJSlAwstVtFJOWcLy30YIqx5Q3vD/ytqpegpiswYbvi1f5QcM4VeJZVVuAppi6AcOpwhECmQHHsi9OtgOdEtcf+n6n4TmftW7TzZlcUsSK53KtIZDEOUrOqeuxeWSorq9BLJAYzs4tE9mYGLXb5BIzv35+sEbSj+M9Rb6+92XQua062UDmk2GmHSijC2hp60whlri0BLr9hwItFkBRpNIpNmWFr1+ZtR30wfm4OVZICuzwGWD2QtpnDdf+auQt2HP3VfMyONZfMPEbRoDqAFxoRmiClIL5Y/P51+kfr8cCRgSboCr7UBhXrDzwUWYndEvvl1+mReG6vnSdwHdh1LrDZ5YjYKKY4XXpy3KudYMORnGDMsaIp6pz/4eG9+9s7ZW9DqHtggcH1fWCgQlt8UcawrP5CSyIu0EzovQ7zArPKzIyVll7OpU6YwsM0vt29uv3FxolUqZfYPbFN+37lhwlrC0g6/0WIL/RO8GIN1zYirttl5MnIMAfN2TkrSyU7p+xwZju8biZEROrDMa5ByANbRbIUGxnGEqIidFImTI1UI9QWcep7mzpl5meHaXUaTaw+qqilLuGSefgT+/D43j+vmzv0QkHeO0edZQb4FcENglwgqOS/lrA5S3tbCqzUUhuN0ZNgjHp69/yXNtPOQDJMt61iBip+T1p15JurO2deOPvmpwWnejJs5EgaiXQSER1VI/SRLNotlnOsCeKL9a9B9x8sVW3M4JKtMYq+tWsoTABnAIoI3suy0/TrmaMDANn7PTfztZbPelcNVJ+aJbBBbbq+ZxO9hyEGHGguCIUAqWUlXK8z7uT7SKijwFYebyfsBcLj75VFUrX6AQtOF8CZk6kH+G1zCtxSMqrlqPXTj9w3J9/pjck5+LzV6w6DixgEGCRILajgOgDlmpliJOPeQC1hBqNY7oF/F19ehaQUDbwzWaFUOYg299Y+8EQ51kA1PHKpPtzjI7/m0w25D/T7y7LOTIgig5RaXZoFGobjI9xOw+Ni476Q0jYt7X+5KO+xtnOHJ+tVsVO54hG14DqwbFX8qjMU9l024ecoKfyDLycu+XDjkR+/e/3Dd77b7yi+UXV7PXzjhtTKkLAHWrzyzRUBAIbdGikcA9CM6bcP7N570rqHxx5DLhFOa0JR1kY1fbRPavRbOnHCP7N+eeECc2NmvF6dRivCIQ6dVaRWkdGsbXiDtU927vViGvsHRiGDS5orrV2HvzBWWHLwdHO/uyt/PLWvCEgZidUC+lRN9fCDTrNKfodFLuzwFufM26+q6T0FwROQFv5svi+fmiW8P3H+SzXu13NBKizt5oczqYeH89N6fI4g7eJFibWIiLOSKTUF/yDh66ndx6CxX0P8a2Z9Gas/C7jkd4lvarPmnYTnLVc2gnJ7SDVohKL3hNcerj/00wzUM+vdkn1kLq9S1fx1cwJh6ZnuT9Iz51Rvr77f0i/ZJ5df0Mk3K9hdhTM9VQKbGlZUWimKuZ1RTHC2jWKlj7SfOfzEt//8buT+RZt79F487h8XvZa0vLJyGdwc2g55btafiIZASVho4D9O2TRmOkfTsPgpe+etfzmLveWXGmUkNUiXVB9at7j1iaLzmw/biwZUum1ctQNBCm7sBxhNRrGLLvJs15btR77+2JQd26hp4kpXLCl057pNosYne59o2dLZc9HYo8xjaa14sLdHDpNBEje5Kqr3nNveYeayKaQp3E9uNVwF9e9+VyumEvGc2x4jhtbHcVQCxwBo4VqU5fN2/i7/vNbJFVUSI6FmUxXhjsysLvtBai+hU2aojNXA8f0kWKnN+mDKwPNUrDexrpFhemK9OnY6fvzyubI8puJQmIA9iBCsmPxVXV52Xq2Y2X3+qIOHFm1OB+1K5hSzAslB+FQjEQFa8trVCwvBOiQpSZZK3A6rip1VLHHsilZnitPpJZOXlUZodBcahkcVV7isF42SvvsFe2nDS56SH/ssHL9+97wND/35hZn5Lpd7YokHqijWAzjAQ6ZhLqQDfJATBawMWPPBWwfre0HRRhtNYpKo294uvuXITyeZswG5iMETMy5jrTHaJwFSVkwcvzc3a/UFwaNDx2F4kDRwV1YVDXbT4U6UHNVk7UvTV81sKwguNipZyzbtJ6K+5smqMVr/44sG+oi9Ea6y+y0uaDb1SGLghuR0ueTtpefu67vw6S3PjJjxWFrTpo5giOD3SbuqND2wGZ1PSefqVK+Yhk22l+fysxN1MArZCDTMLzOCITpNOv86KBV3iV6vnjLqEnLQQumbCSiexJl3pFXcMO/Jg2Cof1Khc+BuHYODPy9QTFQqvR4x2162ZfDKaU9/PX3VBjPWI34JSTK7Cj8y+KG6DH/R0F+kR4pGYmfovU6vM7XWhh3pG9vs2ZQuPTpmLX+rx/dz1t15YNHrT+2a/3LPnOf/0aR1XEIXtOKcuOkF85dTVjzTPizhTzeYYs4nhIdpZQ3cjqHPYQwhJEio0F4VllmgDxCHGGnSa1vrwktuDEscn7X0rTuIOAh4UqkweOAYGd5H317Vsvu8kd8eqix66YLHphPdMihE1Higk5hMBm1yWMLJGxu2uHHbjOcnEXGQmwkrgwfvdUMcVXMQetRrZenYqPFXTRRoBIoXi5HQFELFyKcJ29vyT47C1FWbF2U++eoLf4KG4+Vckk42htorCA0NVrU+xDHpjB3JggUOFxQILtowuZGilrU2RIZC1Ppa+k3PiGlSAb3W8EGEXgeEAlaFSIS/tHdHG9zlXhc7UJn3Um/z6A9mbX8rjtRHFFNRX9B1VYgqq25LDqZGNtaHsWbayAV7zBsWna16xAdKYljNsEzfJtT/jZpPa+jpw7ZsCB+1aUXU5tEzv9+Wn991yRsr/tpEY32yzGnvbmFeg42GGDMaBmNIGCY0wRBxLjLC9O7tbZL/bv7LcBxJZQIAxiBnqOl+C9WdK6eN3Z15ZM1Z1a7HVr8Hbj4i7II43SSL7SJjWfuoRi+Pnbpi0mAQBhEWierNo7lzXQDl/K1e6cB//1dQ3KoJRrUsgyZM0D8//JljtywY8yFTHEMVl0Im0KDuJlQJ7ygdlsLRwV/chS0rsj3b+5jHru/TqtuS54ePLSS1hBAh4xq5NQfMLwTyLGXw5MOGNqFi0OQbXnj3gpmaAmMeNOfvcRN94IAM7nD723n7P55nEYVmIF5iuJxwgrVBzyBJ1AKrRS4yeh4q2Lat/4DlExd8N/PFTWAuJEWwxk2tcqEPVkfte1JnQ/SeyPCoWdtmrNxBD8nsa2gUA3WHU54HxMGwMNQ+vH6i2KTUIjRt1VkzPm08d0qj/Hc1bGjD16v0eeL1F5rm5l+68bylNAq2W2+rqDhvUmzMkXfGzj1LAFID5AZQBIL3D4A6/r2Xmu8/dXTzLxW5d5ZhrQFB5KFVlwdrDZPJKNxgiM7u1qrjqE2PPvvtF9Oe4wiAatQAEvQyjx5ThrPHp1/44O/cq9d/VBJ5rvsU3i9OZesZ69C8zYKi07ahZ9RyrQYjgEMM1cioZjf8RKKVVFE+VVEinjLpJ1hP7XtyyJqZyx59dvmKNB8iCECE3+T+X+ay+4REzeaqrgIAgUszA/uXmHFVXdf4g3N9c1qa+5aF4xYVOYteddnh9EgUUE8FEDOURVIdHs95wZnocAovd5r72JN3rZw5b9v0FVuhfgIJmcbcGQ4oQdYntauW9izeNInfhIhO7TQOHJ1vyCk7zp83rP1403155cUDxywa3T+3olS4ALNsg2MHNL0WjKqINoXtjo+I/eT9cfO2+yvVvDFiSg5+04enbP/3u+PmCeQ/FNdIJ6ePNnOzMj26Z83MUd9m7nvxlGw3wFTn1SFCCYIS0FxoEnRGlhzXbMP8KSun9REErmunpJhZRiYWhiCCOV+81XjfsV83HXCX3lMhO5fzpmLO0SSHYoE8y/X1pxNUS7P0xoipWXesmjolX/C8YLU5vHBO1F6tE9gE1GgkEBPU0CPuUlOmbFuSPWfEiLSXFi3d8vT81/k6JCUFC9WUoAvVK+PgEyFwhvSLqCtP6v7CBhi0AoPBRyB+4VM32+90hzNBMxPhgPhaz3kj0341Vtwpk886HW6qJ3FdDJIY/otKfrlVzteKPa2Vl77pYR71TZQhZtqOmc9hd8PMGKmlCzL4WfZQ1VFPObcpyuqME2a+CB7DXl7+4PS3lq3K8dpb5sOTEvv/IEuYfoG6uR4Hy1UdQEND94YVheNaz3jkwI3N2i77cLz5Y2pk5OZVD2c7Cg98+8yq09UaVbPNbzqzcWMLDu289vy0O3LKC6fvK7pwW7EDm4+QGhKOCUOzwqLIIPUNS8xp3bTF8DefmJaxdeoq7tJ+6nJSldS4dcnEB9L3fPfqKa89FuCzSFjEuF/zH2EfpNqg8J8+dUj8dtrzq29bMrHPLjX/QdnhcsMnTcdtXQHWXbscroHSeEqIICmywysf1ZS3ys8/8doN80c80alhm7n/N272D+aMjGtSu7Bg5LUFaYbf4mAgCzaKoePVI0Fo7ZCZWQ/UoVrw3Td37lyDs5uZ798dXe8YVrb/i1/O6rzNNR4VuyOqtj5JQrWhT3QYEschVTmnsoLl6G2Dmjosg25fOuHNbm1vnL4+bUQRqvcHhPAFafBBceWvBDEjcGpKT+eesVu3f7Pup0vHHz1vh/OGLHi02PsENKBHURuF8C4NdAa3Tqu7iGNblXbVo4nQSD1OluR9NHDZM1+2a9Pur0qlO8dl83zUY8EoS5Sg2WbXas7FR0brC4sKaQvjxkXzRtxazjwdc3G4B34/Xh1UCjc6gnMBmg7RcayhKfr5V2asmUuLcFprkJvJZh/hKrTo+ipj55oTtuJHi5028liwa416k12mg2Z/3ARjBk4ICWzn3HVDsbj8PEuqHFJpteE0G05Q1Yu2vj5jt500H5hbBLnIalOKdK5biy4ey+i9ZPwbKd37TFnx50fKSK0Adwpp0OC+v/UtvfkIKwzno5hJbwiVk86zh1xMX8sM+c/1UGsc/4Gf/JTh8rS0oj8tnX2zq+LCz7kaWzOsKMBEmO5qjfmf4ywahggHanJUm5RjcT+e/2vZ0LQX5y/b8syi5fWYzBkRCK9j+N+X3PfuZ+9vOuCqaICzwrIRZ3dcGHEEsdA2NUWwhobIH2D23ZwQ3XDv3U8MvZwmwMSINPOnbYk/HdjXqMBe8UR5acXrI/9y34jPM/akZJ069tkptXJhCaQCKyghxzjf1o0b1wocbMCJsOTSubUia2g0MhgKDndq1PaZd0ZN/6HtzLVVUiMg1R57ZdmT2zJ+WHPEUxkBdUzWI96RCwEt3NiCbaLXm3IJGNi2ySzzR0sgDuKafPd3r3nTvbctfvrVXTrvk16ckQC3plOG9bDsK72l/ShIHg04midPsUn5gvxE5U9bBz+wes7oTyYv/QxmMOCvr50rpa7tF5kkmUarKbBUuAut5eepVBbcN6pKQxUCN1ZaTXlwZoHKegC9wQFDL6iryvl/kJ9XpaKYUlt1OZj+zOIVuE3qMsfNDEhZ8q74bvSygtQNK2/OKTq/e6+jqKUKtRwqH/yPr96On1AomomKmETek4IlvKTo7LIBSyfe36lt14dfSht5nqtcteKqSbM+fitu/5nDz+/KPfn4ORu5/Ekeg06rcXghNySdlGyIq+zStO2Et0bOfNvfF/b6CL5sIS4ij+17F1ml6PPs6i1bjF9+uyNxDWIv4brfk68+f1tW7pkxFcw5yCZqoitxZsapk5heo9HpoB800Ohko1b/U1xY5GvfTF/1Nvdf8G3wMPNobsVQEOol8suff1z//cXjw3Os5RSSB3suGhGxq3CQQW+41ZhwuXPrlp9tYh8wMzZ2zGj4j5iAuLRW4ESyc95LT93/wsyzZ8oLlx2zlUp04g4UIiGCC+fj9fXPhwiQ97QtBX09izkaOMtzP+23ZMKyH+eun1O9nbr1hK6elAjEWRDOuu2Vq1aNJrcnhrquEEhmKgqnMxxxHGqL1CULDuzLExO8xsT1JY0Gu9RqKxQhAqkBDBmNUrBeSx8/PX+Hqnaas3jsO2c05UMLrdhEhusRtttCBpWoDgLGByYQHOpgGqXYavV+77T1unyo8vi9G+c/+Pm4RV8hL8frQBlp+6+73vmV2Qd5Ky0eHRzRPJD2cFoTm4RHiV0iGnwx4OYBo6b3vyefCsICpUlvlKcyn4WLryM3wcIFWzPLcbnEyWlpJFUuBCp/7ampO/F7J4VsuVSc0+d0fk4UNnLcjQzhUuPwuLJ2DRofWfXw6LOB/HQQ6tTly8RNgf2M3bl6zpD3f9y2+bTqaqg6XF69Ros4UAhvBXWsdUQ06xjd5I3RUyY8PURIslOwL5TjMAXq+6N9A354CkLb6i9oPp2yYvnYd9ftMJ469topT0WnChvWajh1CM5MQRSumqCjE4LpcAZdPldRouaHu2YPWD65+/ezVt9D7eDDibFmRVfwveZ9UCcQy4v16A0RCfFpc99rN+eBRw5hDwuWspqRJ+HcVMps8NaSVSdgDaWK1a4ePADTqnoN2KmEJ2rwlAG8IC+B/ohLhxypd6+c9vhlofiVw+4KCYGvEL0E0SYhRYOXrnkXIfywPBF0Gq/gOe4p0dsvyV8O37hkztvj5i7j6igObFEJKctaZvLCUcQAlcopexDkFYsKfYKla6M2z7w1bvYbW9kL1Z0HuQVqxpa3m2XmZD3icrvuenH+iKRchxXAwUQ873FNpNZ4IiI8Ymuflh2/Nj/wRDY1snRI2iV8VW250kXASY4lM23KELMmg2V4A/FwZ3y7JerggT2vZpZeHHrJSctv0aMXtBqXjHPbBkg1Y3Rej2YdR78yYsqXX05dzhehOCTDiQqZ/9CJ1C10wEseAi8Pm7gXBNN10Mpp888qebNPq07ovbKMdSGc2eDeU4PHBu82XK/BVrSqHdFDvpdzB6csfebrjDkvDiYi4RuLaWm+gldh9tDO4KSlyCYj9tJFIYEKBbNiIZPE1Wevl/ZzrglZqS70Gu6nAAIMgK5DJVov+ImbbZ2+6s2ZH723M/zEnjVnbaX35mNdCkqDFVDEfirWZVdJxGiwwajVCpJ8wVIu7C45v/S+tXNLPnt2ySZS6UhqSVhky3YEFHTKLm3DiEjWJTzhq3v63jZy0m0PkhjVpGAR73MD2UxqqHD3qqkrth3NmHpCtotONyxcZP3wi9IyWthLlrZRrvIhRaXFnsHPT3uvS8sb5q18cFjulPdevivfXlnx3sgZVd6aHP4DzJNxwHeufNn2j+P2Hz847ssdX0/K9FTGMI9X1mKMPThgROuNZmGRrH1kwlsjn3jq6bREBAhIYVLquC2qz3fHzKv7/82fzQe4SgGCIcI3j3tn9btJF86vPucoH5Jjo/Nh/LQnnWa/Kpl4oJoBaXSy0+k6oi0e9Kflk5d9N2v1bLawPxA4gYsNEIB/WRx8BGmaaVnghprsUOA++z9MnLjRPhlxVjz4yDn8vO/B9eb7z5fkrTzqKGvr4dFL+Lhdk7SFMqiBe6ByprhArbRY/566aUlm+ui5PHayZCcvKZwN6KpPqOjQoOmU9AmLXtvOXqwuNThnfnjtopt7zB/x+iHZ1km1Yv0lYi1AthOSjdxNhoYPo4x4rBVOh/qrYtX+Klsfz6soSRu6fuHQTs27Hs7c/dkbty8a34BpNf+AC8HppOg4I4hMLrNaYnCm//Z/7PzqT5dke2yx3Y44DdgSod10FQxBpxe6aSPzOzdpNeb9MXM/+3bGmurw+dQqEO/143Ly+2BPBklF9KvzwjTtxkcnn0Gt9963zjywSenltSfcFZ0RmhQaCc7ngC1x/K2nWTLjgtnoSysq5FOKOCv15cXb08fO+56fB4I6gRMOJLfqT5heLwxhdrfPalilEtQsRZIJxAbrSbUNT0gWEo1XJeaaVdV/RW4kFLIUah77aIL5U+T+9J4XZs44W3pp9gmPLRJ+fDIPrH0NahckLTRYrbdQcUsnLpx5B5vj7chrWmokGSJv0IfvfvCuB//ybG8ejUKE1PA7D/qkBiLNLd1bcHJWtgciTIbfuUarBdVp+cFlrhH4OoKR4T+gClIgEgrn6DmkFphckvC1Z89Xz0Ak3pVsfup5l1dYVuq1shOWQkhthZXhAIsVh16YCxJJ0DgwjIicx3TwKGZNEDmxbUTCG08O/NuzPIxLQGrAJR4iUDZ/9UbDvYcyE7cKwhGuMlw3fln1T+41P0V/MsF2Aojw2UTzdpTtAheKMZfUklUnZWc4XHMowNtVTcKQJPD706o5TguLz7+4CvUkY8eML2midXAf8SKuFlA4GLHxe+BBFAe4POCvH6QTWEHpcWCHifAWwsGrqhyqh/xJiUyqbv0uPwJrIOCsRAzlqykrnpvx7aa/h/34y+JKg3fCaUsZ9tkgTXhc4/qbBJFI4ADu0zpnixFznhqH3C+Kt7boOPnHBS/3JeIgvcvvPOgl58GHNiy6CQh9ZJ+tYFa2rVLVyFxs6UAc9XaTBpPy4DyYTo/gecdLCuT91twX+yG85gHzq1MHt+/doYGsec5jd2RX2KzYDoEQQCER0TjC4F/SQGeUmkv6gt7h8R8MaNejz46560YQcXD4xqXSbj93bhyx6flbv96/98KhoouPUtevHrSBcv0xkx8RZEIE6sH3s9b9/b6eKR1vj2i4tQGiTMLED74U+nRfoNeQJBKcEr3FXluPxzYvuxf3udyINYSDrZGtKpCz5jesRGBeAuYVgbK9tEaulbDBR3ewu5kt2Oz5WK6cZF7PGRUfGKpPJUo6B2EN6g/RQq36fuMlEQcxSFK7nrtjdMWBRa9O7JnU9s52hqhTEtatiLZIx06v2jZUUcnpdLIKr2Pq6t1bjNJrY2f/RLBwCrxMLue+g0p9lk1YvDv35FzspmMIFbdGo4H7Awb3NyZEH8f+oFa9VF4h2yLkpZ3mjtCuTHtyIaqZad7/xaIjew/0PF5woV3bqPi2JoMp+uDFcwd6tOhwqVF82+/XwCrGFyxwCUjBgqO6S/zN5vGL/3n2wNxcyBpJ8ZJ9+o8RtKHa+BVlZdXLaKplrfoZQARSu1Y+ODIXDwYNXTt39LGCi38/4ayEoiSA3YS25BCG4AAWy4HX65niy3/DJY+Ugqg2dh8NEImEwCNAi0PCDO/jqAs3LfqRytd89Bh9V6XUVMmTnu6Om/vUykK5YhpzQJSEiP9VVeZf/QFpi60Cj5ksdBlm8f/GzPkW6+aOt+CIRo7WOu5SZbkKAvDFC6vbA94qtCB4bOJMupY1+Xrnz0MkMpvBzYRczjkn+duLi5KPFWW/ftBa3M1ps9ELnOigAm1b/MuJFonQlcVyq022GGUziETIWvK62dyTnzTbiYp3Hq9W+6nA79TOukH9BgjffHxUzsjwwXf/i/OSzxbmvH7IXdLN5bLDumXQGplG4hQSKPdH+b6dAxpiqup04grWVqld9M6MdPVDWF0e2bRid/7JA9vKBU+j+iIrUq1YGsAM5mVFtoqe606f1k9s29Z1oPjiL6JWNxjnu9HOlaYCUPjuCMyBRfqlcgRg4CnoKoQTSqAcvjnqFLuslZIWR0mrPbiGn799bFApCIRgUOg4BNQ6gnV86npzznfOzOWl2LCGeZdi/gStm/qJMkIRwv5UOiz9xfSsoiri6L/kmYV78k/sP+Io6+a0O0lqgJiuvgBEnVdNBBAAE+FnJJ9V7AtwqOUNKjRwxqgoWMa6Ba0AxyMpvhJO4nuf3vJKy9uXPrNx36XT+4+6Ld1cDic24TUKLO6snP37QRsCKBH4DgpP/TeDDnh9RTIQ+A7Pqcmrf8gIUStxh0QgQpsJg/TvjZ55tH+rzilttOEUdoFiYoXsCp1hg64NhwRP84O7PmtJ1eKkOL0bCqWCF+N3cfANbkEsUdUnURlirPRdK9G9K5+YGICCcx2wEwWvuVbpmpdU5Fo+NUv5rzbDTEvShLYS0ieYVwxo1nF+NNR4jA9FwgiZoKpifBAFWfX2kGit8bfNS7tn5Z5/42d7QXebDS7nElRaQf23pEaw1olIMAmiy2b37NPkPX7nc5Oj/zlj9QMDVky596aFY17D+ZGPEsKj9uBo6fksp4PdGRkTVVZp61rutQ/YdvCH4Rc1Xi2kBkUFR9xYbI5gbZpoDGdt9XFlpCemJA1RM5gvnkCw9q/lHhkayKx8LXmr5yGWdfWEajHdsF7z/QEwibWI6j4EngEkAPm9GnUAkzGXWq0olCgLRw9Cz6DvcuSrgWtn1n/jIiL55Gnzqd6Lxj11TnG9objJgy5Inb4GCBAKuCbZ7I4WuHWiS2xjZ0nZRTCbGlX7cgf+whAFWwA5rnamW4G3dwUe+79rVuB/gREd5GCcVGrlDnH57BtrIg7lZ3+Bl/bE4Kg1SYE6c4Ib8C9XI+OMph3fzVo7EqJDxKfGVIBA6Fplo5j2wwmLFicvHH3zAcVzD/kB4m7QJQNwVCPDYKSJ0PaUbl3y9LifL5zYcAaWDZCMb61BC7n/UIK8hfFWoy2ptLh2qMr9nec9+eH3M18YetO8kbkXZfsbZxi8hUsraFfU/ZOlXEch9UsU7E86ET9Kg/NdoqD14ugu0+lYG0OEvY0xcdrWGS9spAHM8KuJQUEn9KtHvvsWoSJzgHMUl5f+Zo3SAGdnpKBNX7kJZRV7RuRgSvfKnY5bj7jKWuG1TGQjD56gDDSTTCwtuX+DA2zzeUw4hfas0xCIBIPE2J55G97qPPexRVleN+LKIpJ5ED8ljkHQsophPTx2+TwflUK7dT+PhYH8fE8wGDSAugIuPjDdc/z4TwTq49INbR+6kCsdt+b1KhDgz1pXePqgo/HWSayBq7KI38g01yEifzfUlCQzmKeZdUxq8Xz+ecs9l9xWKFLBw/7AmwTzIbGLzkpRPF5e9MQZOqiEN3lh3khqhGrE39a//4VFJIX613vwcpZMV9mDPcwjd/6y+JU3zy17W4h0CevaGcLcsUadsViUNSWykwMk0EsYdVpjpM4gtdSFFSXrY1endElu5ScOAqoO0lSH1IAOh8LBqsKQrOWke1rKTL6yQXXs6tUylpnB270hvmkPFUwJ3Cfo+Pluko6psHCNBHs231OoBFMCG1PcuE+vcKvx0eMcP0OM0MTwSPKgbUNlOnXqFLR+PFLJ2Q6zjoA08lcM71oEstXgplS+eiKmHkhNo+Id0UAYVINRCJ7AYwQVOnyUwdSL5zD7+h489793N1/nhFIp4IAqXoCqIKx9rbHh1yoYOliA1ePlpx3gbhSy0YwFCzjTS+7Z+xDOGkFQQqUMabOjakgLRegddLocHA0rKQVnmkPW/7s/ICLBTGjheerOclb26zZ/REG3xq0HvTt6zjPPvP/KsovFF+9xOO39LtrKowvwuq4GEVHaaJ3xAhag27u167ADgZqtXJmCWY9t2nTVoA2t4hsJ53LLKaYT73zwDgmKBpRr0uop/OU3Ph37KkSS7hu1M+UF8fQLa7ag+AVkBFfAe5FdjspThbknqH2OoDAaYY7hN11XHaLlMuQtK8a7MbIunee21fqhSUGBDHbSZb+gMdI5bh6lBvdqJgKQqsZ5f/h7mjgRNUhqdlxbcKYc0Ef7H9fpB6S6KEPquF3ODrtV1cgPstHaCERZs4Xf5wqijS8HaHyoldq10k0ZDKe5MTI+Cw/9a7La2fg1H0r8eqh7ivvzrZ9CXcqPxsE0eudMnXqxVgbfUtQ4nUmQaNr4CAVqCFr9f+amv0kdPCDcR9zOxPILzgN9Fo5b+OLfRprR4uv+D2+8hP/1/dlFXzgaPApHgzdvR8zVa5ggMOpDfJVIfAkDEGxGcVuwwD3/QllRO2oiA//qTT7kUO5fY47+Je9kJ4prC4wOKqi45QRrw0amiNIR9/3Z+slYM8P+hYBXwBKjCJp8BISYtTDcwr2/LTL9WL9pOIPX0ys6MelnRylhVFDMpeawtmHxiD/buXFzdhDXdHio3exHT4OIbyLswK06ayJflEcBUditjd9/86XmyHPCvHChYPbRGy5/j+QbjFvatBf3HbFpSq2kVeM100GrhkkWBILJbEMv2uHnXkIQbGCIvz+zT8L5IWgIcAIJQhzUDM708mPPyISQo//jxBEVG4rQl+WLeCPREVfpgi6zHzvdc+GYBzft3+9XdfxAwhpBrhHUB4aIkGSloOO35i1b6F7QlEKMGinCqM+MxFtNMSoSDUCwzBhEDb1yGd9/mfX16wlkwIC+H3KMkn0RDuFt40q1aBTivMSyA3NRowkgO2IPSyxSMh4fktTTTg8dbtchAZEKMflB4eEVgPhLsHgqtpT2oOsQC2OeFfDyvkIjuJXhveWc/fqe1P5LiyGN1+Vx4A3gVVb1MFF/hHbBOcrVLoFrwAnTiOi9iDXz8ZKcAZTli0Z5dQipZtGMwGXQcQk8DHwjEx+L4akTynASMAcEi0f0ysa6CTdpa14pl12RedkXOlCO1PT0oPNFhEzP9/16qElhZWUsFSUtJljC6l2maPQOj/tQ0MqCFfpP3wMCYSgkuHm5PMecFW3Ouys+XP/JhsNweFz9wJpZt9C5FRioPP5QqcqYj19OTF236HacXPxoy77PJhB8FBCsNpxAcD64bz4x/TT0+CxCALDsegZc9FwQnBG7Dx2ZSXWZM83YK6r5imIsxoWAtyflKagsm0NvJSIVhK6DJVotR2v1LCoi6rvAc63eeDYacaZI+wqVyIXEA4vKZUvpPWiXv9MwxbebXh3hBP/7OJS/vrK0W7a17EZy90WTQeEB4cCipLJYU1jhpEcmFKJtni9WF5YR53vJVV29ww8gHVByIMig02mfSrewsQwX9Jrj489KX8Kg2K4+AiJuHbqbV4r4c/WHkybeGJVNBAKLatCS/CZWdQVwIMipLHiUKkn/cbZUm6nRfG2ryNTT82MXztxXqgMsGFZOYHSzVvLXy8K1xmNBB7BW/v/aJV75RWtMLXRLuQTvCD/mKG2zszRn0vZLp3d//vN35xtPf+hAzLSH9yZNf/jA97/sOrszNzPjsOj4S5bbRtybZYQIXk3uB/Qca4vPyfqFQGBBCYTyYDYlJ4KeHyvNm4wACGlw0nf73TxwHI8jEqlogagvrN/ipz/YZy1qDsswArkER0i+GFQUbQNZ8uD1YB9SO5RwqOknHU0TEL86tvue+v6Cm5GpxXvBa2/xp+emrKC7GT5rHRblgMcHk8r3i/DsRE72y/mw+kGK0JH2oNXiPrR6iUVrTfs7C4IbUhlUythNbTvsivEiGJ8iY0svODrzPuKN58dsxS0HrJg0F8V8rj90pJc8Hoh4fYyKcKsKLpMGr3XnumRQkKh5X6q2hovQGX7G62qIf3CcDWSp/o3BgTu6W71QUTT2kb8v/RNbf8ZlDph6q83XnjXpjmkfvdn3YvHleRVWKxlTeJ+r13Xlt8pM0JQVJu64rgiEAKSRIFcJkDh2lkTFipfFWxAFPdNRHnEJGzdlzHtznuLpccphDS9wO1wqkDkSHq28cyGCNgTeDdGzWYdPuujCIUA9eD1l8ImikDv08tgSBKc4XHD2H7eteHbtpC2bunLQzKR9MPXVzN2xaX9fPLinedSBXZb8h+AsSJEx6hlw+LDptaxpZOzHLzz41AU/ArHnJy/PbKIPzwVq0e5CSKIlkCrsDnVXSc7UWxaPfRMB9rp8rZ7WgzgU+mQiEMbjr6xKgTXwp1/txX1w9loOtuinMaJe005iks7EmkQlfkb3Elhn1JMirfjr2OxYbfg38KCj29Co6iaaH6ynJBzgUg+V5i0euOzZdUu3v98AjIT7x2UQ8UI1RTYO1/gPXupx7+qZY6DQPKa4oL4GMUbUbcV3J8Jg3BpLQW7grhR8ttAIuiTh5brnnFZ2MPvkt/esnTV75idvtOA10Pig9LKdWxIeXDd37PeHf9px1mM3IrQSef8FrRIMEuSoSs2Z3jage999QsKUh74v0sj9/ZPsE4c++K6rvxLUAnSqKtAHNAR6fRwhntZk95qt6z5eyBHPNznBYKe+yX0Wj3t3t6XgERy2h5EodJA2ag97SWAlBrGLFg6zsnwEQZmsOrjdRGh17bJdlZGF8GeiDSdIFDJ2BE2+ejxq5+hEcUCnXt3XPzzmMLn3kAcDIRJUyJe/Ljo/RnDBxwPSM2gluEnrJqhM2JKWhFZaE4LySWdtslxA+Y1MbOiU1FZn8R4hsIqQxEF5dZAsbq9L7B3bpHj+hKmtB8e1rSQVJC09jcfRunet+bb9+ad+wJtwZRy58xlwqGCtBM4KR2xVjQg3io0UbWUDY9SvFYr7V6siu6IlSR+nDbuxyF7RDIH/WuYqTlYJB0BIWcxfcCmLccI5VlXzQPOuOz6ZuHgAmuPz1WbWsENnPNYbcN4YAx3axwwMT4HTK+LDG9gNYhh6JByrVBWLgak6k6jpeEaxhyEQBqQ2XpRbj68aYrZ4FBxd7W2Ie3Wv+eWR9XC9WiPyP76EqkEUzwmYSxlc0Y2gbCAIrBC7dJSX9Wpxw7SKrN1Dsf+ih0U3pGMftYfAU4KMwADH7IUaqGbd+MEwLCaYFXtyOIUGwgDKhiYOIDUoWPHow8J07WKTniPiYCkpEsyRfPFvhpWsSXzT5zuWFIw5rpRCm9AGNTtSdyAR0Bp6ixNLODSlwXv2WmMzqzUXuXQ+H/sEeG0zAtGERiIaKwT/9iZGRunaxCetJOJIgUqEfhDHl+mo6efPmnfetuTpr/KY6x7EbHaj/qAGEOLcdGbVYoOEZ/bIU17r7UzS3q7DNuM5sk/jKAOFMgUDASvD3i7WUqGIg/pXJ01oI0FdklvGN3qlqOTSSxWynWRJyCDpdJ6Dv+DJ6ZIP0wuftNquPoMiTQI24nEaAJoBnVkOKQRADKrX69a20UWpXTp1WkaOstedilVnoH6nGyAOHj5m7aOjL7dNaDw8zmAir28EsRHoBfNBk9/KIUka8F2EUBUgRohD60Ss8viE+wi2TmHUR3vl4FQuptPoeoc12IVXyfFFP/zKuOpC8JDE2/z4xLOtYxqtZGFGrKvx7okQsFAb9AgfmmewdpFWPTiAgLe9QBUFZ8TpwtCTT8QBu78b9kJdB130j+8+vWAV1ZlRzfuAog3SvQG9+o7qKoWDAas6vAKOjpEETaS/gGphmwPrx7gITo/HbXN5ELDBQ9cUGIHGDnSNmAzBJUfQiunm+jNEtMK3U1ZtaC6a9oMh6DDmQdyIr9TgU5ugmmt0FCgaY0MbrwwLKgoJIeClMqH5KbYAEB9b9SThxUM3JDWf/WrahPMpYB7/zxAIDSNHBizYP528bEvzsKhHm0RGwZKIE/kCYixhgK4Mdc1f4DqE7JQP465qwFZD4QyfASAi+LniCQ8z6nuExf3ytznDSWVgZp/J+Eo7/veZfDn9uRm3GhJ2MYNWh/pdYHFX8tQEhV8RYoIYiJY4TIAP9uvQRQAPqaZuvL5Y110fc/yhB1MHU0V+eHid/mswkRTJfOdf82IiYnonavRWnP/Q0viEgolapdcSEHFiCOk95siPw3S4Jq5OY3ctKZAL39Q9nih8Kv24qUWnv7ZkRhvsckRt9RIJ5UebPnhovgBHfeeXiHEAaCjTqhIRYdI1lcI2fPTMUjKGiBlgHv9PEQgNHsMxTbJqHZy/6d1bGnV4uEtYvJsjJikx8CMkXfa3DgrnzlizwHwKIw/eCI5VYKzRpO0Z1vC9d+ZvvnW00JMfDQVCVk0+hwWEEEDS2X+bNLCPMXGXZNDrQV2kTnnAmTlQ/rzX/EXw4AMKIjzBG4NVWYwIN+l6hifu6nfL0BvHd+5v9UeBqQ0PmEiGl8Zn54y1x/u17NI7OSKxGOs8Hb3MFdVymLiZ+JqhCZ6RKqNxJsIjKQ5tjd5hSBKpSqWjnfEUcPHXnpp8pkNis16djNEWhcQ3TmOhLCFvgK6CNxLiLuBH23yeiS68cE7VNDCaNLfFNH5u37xNT/NimEj6Js85qMkYJ+43r0IK/RE+ONgGONEDwE79AAP9DYmHxAenTB8/9x+De/yp9Y2aqNcaSHpZi4BgOJkHDz+qlN7XwieBVDBZDwLAAl3l31joYmowqWgfSEPSWaZhhk4RH2bSdtZFHu+X2PovGbPXDiMzKl+U1wqPEwCXiIaIZDDOZOxesLFfL0P83Jb6CNiltDgKJotQc0gl8xAsvE0IDz3ZwgELfQgeIswqeOh99/QuEQlPSAAABIhJREFUFsyoAkfPCKNR294YVXp7fPMZ+82b+q0fPNhFxJFeT5BvGh8iko+enp85avioNnfEtni1rSlaNtL4oDmMD8AhPBE8/jHwQhVD9wkWvlikBSP/0D16FoAdY4l+0FILwRAUkC7qQi9pgWCQwmFhdHvy+dj43aoywMUJlm+mLs964JYBHfuaEr6J0Rs1IBS8AjAAB/PBgTkhIwSNCW8X3/Sb5g/w0Dhy/Ab8ZMgQFaz66DRmn+jGx3sltkj5asrzpAaT2yn4k09JEBpMfXh/UZiYTO95I/L9IyVSHARYLYxljpWWtR/OYBhIkhDX2gfiTjQBlP+BF8ztLlhynwJtPISXlTYrAc7RC0KxJ4BxwbTjBaY+nkeoh3HSG4ACWMFiP8EEjpSEo9haSfy2QXjMa/+cvhrvg0PCglzdsYMW8yhUfyIiwYcT+rBXV7e5XHBxWrGjckiB19moDIo03j7na5eYGSIucpgIDqIfHWChPUo8o32DCKCpzqtURmr1P7eNa7y13w09XqWX0RAE1dupH6KaMWsnf7y53dEzJ54stVTcU+yyd7Tg2Hk52saaH21DDmCjlCtHBEd1PKLxo6SH6Zhgx3hFYDx1GJFoBbYGrbbEIGnOmzTaIxjLHexSwacZG9OtICggKf76U0q1uRq4fGqKxVU5qcRh718seCNssJB7uOEW40FjQ/yN4OBCAL9xBoT/xj0sZFgcjOp6D7sUExa5Jykq+s2vJj33FW8GTNNvog40y4R2sx59tMLjbo8KsJFDS8s/TsILtIkzhWPBujV3zf/9gNnHxlkdNabeDpkJMVkGymVwQvlaVfVvrF3Y8UxxTle9TroJQVs6ny4rEpITmnaxed0Son+Q/0/5wdLLZzvFNihzOpyHGsfEH+/cqtORVUOfOB1oLKXahAbuXcM3TL8p2HDzwfJFXp7p9Y82984pyE02GAwdL1sqWoAgjE1jEjva3E5IDXQeEF22lJ0oV7zWznFJlYUVJXtjImMPtWrY6Ai8B3zcGA0TF+aS8xqAqJ6FTMAChQfyw0TPiIArKgpvvVRe3DbMaOyxJ/+idHN847Y2xRtd5nLIThAzaSi01xRvCNOEa3Xlh8vyT/dq0EK+WFr4c+voBLsqSQdbN2ha1LB9m7Pm3oO5N261dgkPq4gjcJ/PFbm0+4O6jXn77cQzuYdvvVxZ1DnCFHbDibKimBtiGrSGq3i0TfaQBiCGSTpvZtGlY4mRMSoOph/DnsnJxlHxh3t0v/EwXi1e9RoPf1AMPzUHWgStX/n5B/9VTSz+Kz2pTSi16/i6pCSy4OJFURerEfo06+po6YvuVzubCMIQM6pZhmpnuJbrq8Hy3oULMVZvEcLBMBaeoBMfad4Nv4IkmG1TOiOuGbl6X4MUC1JD1S2CCQTLXV2qblb7cV5VDR/s+sp4/vIlpfDSZaEczxJMBrVHpy7iw7feE2q8AjVwxpDCUsiQQkhahzgCGembq6wb0wVYyTlTq/6M4Nh98agRb9RV7JUaoX2zcIXM2dXzVP2GhE8dx1/5QZI7aJv/H+y6kJy2/hwbAAAAAElFTkSuQmCC"},{"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,iVBORw0KGgoAAAANSUhEUgAAAMgAAAA2CAYAAACCwNb3AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAcppVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGFpbnQuTkVUIHYzLjMwPC94bXA6Q3JlYXRvclRvb2w+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgofPyfmAABAAElEQVR4AeW9B4AURfY/Xt3TEzdHYMk5I7KICKILhwE8DCe7eieiomRByRmGjKCAIHhgjl+PNUc4UVZEggKSdsmwsMuyOU0O3f3/vJqZZcPMgnfeHf5/BbMz3V3hVdVL9erVa6HNhEciCxS7VtBJKvsDJlWUxCjFa8tdk+6oD/zU1ZOMhyttYXYmK1EhMlbgfnudQWgd161y8+jRnhDZgt6+ZdIkY0nU71N/ijlFyjBneAMNTX/3lSZH8k51u1RR0i3KFHZTvrUy9qy13NWvVbtebkWJ0agq0yusdH9+zv5u0Ym4YgfCw0wHY6Lj93zw5Iw8fz2C2WymjxKo91q/U8xmwGOugufhDUuaFpcV9XJ53T0kSUo+VFooJIaHxSXGxifbnE4lwWASL5cUHRA1YmmEVn/Crsjfx2gjD26f+dzFQJu16wzcv4ZvAWU1AXhUVRWGvrSwvdNj73uxorhNpGTofryiSDIJGm2HpOZ9y1wOKdxoYnar9ezlyuKzbSITbSqTf0mMitvfuVW7febBwyp5mykpEtuxQ2aCUIMOhEaTH/qkQHEOEgShHE801wDg9ZNFELwiY4lhXmFWxbqPVzIgFquGWARoYCJ6zRsz/YS9eLmLqYUCE6SanVDQcZHZFK/S0RQZ0a998p2bhz+zK3XLFk16WppcM2+tK3+bzab9dXqx4lmuoH7G6yc8BHQ8+euXPUq3sNiI/sm33vniX54MVr/AUlNFlp4uY+LFQatn/i2nrDDV7XGnWEQlslRRmFslcFSmEUQmW0DSCtEDkkYjaMIjQP4K00sSixAEZnSzypjwyB/ijNEv7pix8jvKVpv46F49qQY8dzw3+eFiS8UTZV5H3wqmGB3AFpfHwzSihsn4ZjYrANMIzOtVWUSEwACHiH9hBItXsbUMiz5q0Bs3Z8x68U3gG8Etms1mhs81EW31+Xj2/15u8ePJQ0MdLucjFtndzY4JLGcKk71eJogiU1VUSeMjAEhZVpnBIIh6I3IoLAxwxSoahju5kTrjBze37v76xuHjj9M4ABaCqQoeSRZZnKLX6ZnL24CJAo29L+HndZcCsAUAAzKoJgNTLe5wfivPUgdqS14ev2cTvOF2o1b02uwNGQawdhIxcEzxMlmnZS7Fq6/9POS1v02rIKN+CVTmRP0BMK7QFq9f9TJFr2Gq7KlbPzghZhP/0+XUF+c/0Hn248suM1eHMsDE3G7MiwAABUUEshHXlAVZNRjCNRgS0Dv+qEx1uj2YTgFI62Iuqk9kkTkO75A4Z+WQ3gvHfZPcptPYDY88fSGllkQI2jcqj7aIWAmeboDnEuAplQGLB/3i8DBFgzyyCiIBxmvDIjWEWVoUdCqKrLhloKnMLCB2C+ik0F7SO8yl7d1yxrBpf14zd/6Xk5Z8CGRk1RE/KCy4mboltYpZ3WoeN/Orw7tm54tyhMXtBAFgFDAk6LpK40NEIAJ+ozFSQ2oApgMPMbser0Izb0MZG7IC6CaS4J5qObFv8i2Lx5n3zNu4mIgjNRVtod8EC8ZTcDMvuqUyD2c/CrCOPsSKrrdPADb/N6bPrQHsXoFh1pCSImqTEItISuL38Ac4RdOH/tII1voncJYjYAyIO0uU8dqSv01JEWWR1w9YatVN17x+jLEqY9xFQvZqyYeMKk1wj/mjVu68fPrjLE9lhzK73Su4vV5R0CjAP8J9AKZKQF2S9JJTVQQXUNCFqaLfdI+eUz4BhVBEofIlDoey11Yw6LvMX44OXD+vawbUJSKSahDU/AkuCrygcVP7LRy7cmfB6Y+PeiwdSh12r+hRILUFFXjI4ZH97eFbAxgg4RRmg5Sja9As2uDwiETAohe6sNPpzVbtHQ8VZ6cPWDZpM4idIz4RSU0grlz5iCNdNn/9bpOOsx//6ainbPlppyXCYnd60EMZRKFidDSB8aE2MRoamx8eECvzKIpI8ND4YCwlEWJGVETF63B7TtnKxJ/txYtuXTx+16a8/SYiDhAK56KiqoCSiFOAygHSH+OjchkAWAXZi5HHyISUIIFhJlGPAaREncVFrQ/q5GPgyxMo9tu+r1a/jyHVrRMzRjdbTRu2MdNbOa3Abge5qSAMkRaGErQoTO5vSxy7feWADCAXj+w+4ayIyL6UvWfEO2vbE5EQ4gWpVWBmM2+uzYxhG391l00rsNkUjax4UQ1xDvpw6glSNuQtVEhcAcQrSBr0Ldda6f3eljdyyJrZu8+rqoFU2QBSVq8kQBxzvtjS+Lv9Px077i7vU2FzeCTONJgWCE9S6zfBQ51DGXw4zmslUaPKDrd7l62g73tvvfVPah+wUBbQXSCBewV+Xu/fYAHgCYpXlURje8HA+sY32U0wpw5sRZ2qJ/072F9PtVWPfnv9yaNGaVFc6b1o/OwigzLW5XC4RfB+dIS4YNBEtykLvmX6gMNx1SFoZtykjJhcHRiJ+4xiDTt5/uR7lDc9jasRVF31RDih3r746XVnRPdYq9XhAa8lFSWkFYeLs2rw0PxcQazqVft+Q0hLQEqJWR2ub0rO9Rr13OS36AmQ0pfhyl/BDyP7cu/WLT9WXI4CIC6wE60XyB0KYYn7EQw0NvTxDeeVSmv/ghILDsJ0zOlxHbQW9U1Z9sxMypMCY8CVfpCAv84TAQiAsQT0irHGMKlnWMLOlHY9222d9+LnGF0xMJjXeTeqgZelObB5s2fYaytuyLWVLbVUWsHSBHDF0HMBJIdAgaKmyiIYhEbVajRQHkRonRwhqlVe5yfK6Zhbdp/3WJL/+tKSxygDIUEgI36T2iU//PKSBy54LROY3eEFonGJEchT+5sQELCAW3lFgoVggiYlKqqCZTDRVfAEBGfIqpdtDvdhW3HavS/MHoacih8GXigA213PTZ+RLTj7QP11oz19KMLw4wcWBjLDarIKHhLG0A5kiJlQRblE0Yii1upwsNPlhdOe/eSN6AxI2dB6aPB+/c/ukjLrRSdVrSS1l6K8rWIbzPxm6soX9hNEWFQxsznkZPzPgL5Kw+lZmTzHpYL853NVF1mDvNDdSaIETdBPyIwgJphMrLFoLHeJ4gmnwJwGr9zIpnrbX3TbgZIYI6gdwSog8QrVRJPnsLELxbljcPkWkKBK6hJCULn9F08ty3ZZAI8kAJEJ7+okugkVX1Z1oqa9IYpFSYZLxbLnrB4EHmEQOhaqzuhsu4X0GBkaJBkT6iQiEp0gSYXWCnZe0ax87cSJz57s0AFrelriMJYBK+XML9+L2fLj19MrXDbAI0qygppqQRTQr/AE+CFqWmjDWEPJdKlYkc/qYTvQKkrHE15rtBPGDqjaCqmstesg4GA6BCEJHouWxR7OPDwCt1Zf9wTCRRwZDmVFig8Ll9rronZ1btd95Oa/jT5BnRq1aZQ26XKSbE5Pp8s/VjKnu4dvfqHdj2cPDmQON1iqJjRxQGUgztwjIrG8fVKLme2bdP/IPGRIMXV4h6pKmzetGCiez1ybrdrai2ReCWGy53q3W2aXHRW9xr2zoc3GR8efMUP6ZkA4E4H0mDd6WKantAMQ2wOWGxQejp/YTGBaQXNrRMN9PVp0WnRrcv+daZ07WwmeV7Zvb7Dn3C99ThfmLdxrKejqcblBJCwokcCiAQOf4AGDaPRO+ktpKP5a/4ULNSn4kQFt4fDpQ8PKtUoscwIeFfDUIg5k4wnEoej1Ok0PU/zOlo2bzRvcJeXQsN69+R7H6q1bY7cf3fH40aILz+W4HbQmA20HrwmcRayElatMqHwQFfsIhNokkiUqp8/1kgJSA7JY6qCPltvEN5n15eRlq34CgKS7D/lrkmrub/Zt6AUsQfUC/5/u3W+v/1LZpbuLNaThk/SAhTRIIh3aq8hi1/D40sE33d5zyb3Dz1fLJvQHp8X11nFbNqTsPPLz6WPW0nDsitCOSR10AoSwP4leu8Sky2X5t6HcmQw/cVCdHtU93eXlZlsxlEhGHV4Rmy3Jxrivds3f+OddKLeOCvvaU0cOHFiA35/Qp8u8EVuOqRWpqkcmGIMyZEgGsczlZOWSnbj2ayBUhaX6YL9YVDiwFGZrvi4LNbywNGNRpmkhmf6xZ8HGh/egkvfxQaL+q5PvvrsU36v/vHZ2sT3/3FslDrsCI1ZQgqXRYW4vc0ieHpM/fb2pCAEKoSzTfhN2d1RYKtB5iPI6I0vN/ZcStc23m2A4iQsPl26LarL7js59uhFxEAijNm3SHkg6RcThXfPrjugR61bcAAoH+MHVgf8S2GjmGkat1iTLLvdtFtlDa6ughekmdhOUOKhVLWOT5hBxtDA/biCu72+Q97vJpFTjxrTx+S1ik9ZqDUZSF4Lit695US2DmeNs8eVmNDbG2BKukt29fOZNpR5nV5j98TS4moaMqEKR2jJ95Z9vuYsQGnsUZh2pRfhJ1dNuvTho3QS+1zPqnqFPddSGV0Ifk3xlqUTNhA5AiiisyGG/cdimpY3wVGHpTF51eFsYiLkP9AcMTjWDUrXiGAQY6BVNG63JPbB///H0KNVcAx5mVvlYSV8+u+ztFrqwnxnUMN/WSLWK/D99kkWQKwXFcPLsmTaiVhCiI8LDWJTRqDcYjRLp+DDaY59FhewTvFho1ZrSupX+nncg/kCrEKeiIHU0xSm3xbecuXPu+r7rh43JIqlh3mGWuBsIdswnvb2+Z/rnW07+cPEILfBY8ujRQTnUFfiC4uCVx/+1X1fALHDbmnOFiMvwugAAYiIAKRrbHs0aNfyccjzOWriBhJhLv8AHc7jlFt9eUKwx8uNGfPtBqWaBqVkvYQd251miKbwjPfnm4Bd8YByCc+glEYxegCG2ZpGqKzzwag0G1jKu4Wvmu/5S2NmcqktPM7uxzggUUQm2byaud9Gzib0HV0YbIzYzgx5snv7XTT6kZF6HRjWWlFfcHMhx+Kefm5TarTGcJEMxP5IeOokl6iP+uWHgYyUshUnp5hrwMLNgVoA7vI/Nw+K+MWFfHAyAxq9O4p3ARnIxNkTPFeVqxJYxCa8PiG258e5mXV9INias6qgJ/6CjIfJiQ/jTKFBtZOw0wJ6GvTj/ZNSp8ve5QdDjQ7wLi9Bw7W3RTffendy32yfPLnmOWiDCOHDKJzWIWw1dM3fZtuO//LLbXZJ41mUnNypGUoW+r+uETmKfkLqLPn0RD4W4DXFIrA5JItRJWhp94EDTsJiKOwbegVUvYwsWLKjTz/TULXzCW7VsfSFaZ6gAvRHL5WzdP7ZcRPGGaaihKlR63MStGXszmyOuxW4Dt5ZDwsIBVGVNM1HPGic2+YiKduqUGhTp6VkCK/IhocC2x3DvHp+ptDY8PpgE1QmI7R7XjVSWUqGlvJlghHWa1jscPfjtGn+wZlc1ko5l2yy/0IPkdj5CqJEJF60GlnFYPFpxN8QSRkbl/hTBYVHVaK2O9WzV8SZp9+z1L9eubMOOHeGf/rqtTwerdVShtvLBLNkmwRUFLEmEiST4RNau47dck+kSSp7CtDqpoSxYbghLmLdtzpoXd6ISkhqtBg5UzP3TSIdlE7as63X7kgmvHnaWdK2wV3r0hjCtEXtP5b+lwesk78nLeczicQFryD2i/kRbfY3j24dERtTBicZ8d1pph1mPncL1TbASkYcBV5+q187VL1XQFNtt8NPgyUPqzKtb3msDoy2KYlfA7+JVvRzNE0hbjBT1l4Y9dv+B1x6fxNJTU0OCnsJSlAwstVtFJOWcLy30YIqx5Q3vD/ytqpegpiswYbvi1f5QcM4VeJZVVuAppi6AcOpwhECmQHHsi9OtgOdEtcf+n6n4TmftW7TzZlcUsSK53KtIZDEOUrOqeuxeWSorq9BLJAYzs4tE9mYGLXb5BIzv35+sEbSj+M9Rb6+92XQua062UDmk2GmHSijC2hp60whlri0BLr9hwItFkBRpNIpNmWFr1+ZtR30wfm4OVZICuzwGWD2QtpnDdf+auQt2HP3VfMyONZfMPEbRoDqAFxoRmiClIL5Y/P51+kfr8cCRgSboCr7UBhXrDzwUWYndEvvl1+mReG6vnSdwHdh1LrDZ5YjYKKY4XXpy3KudYMORnGDMsaIp6pz/4eG9+9s7ZW9DqHtggcH1fWCgQlt8UcawrP5CSyIu0EzovQ7zArPKzIyVll7OpU6YwsM0vt29uv3FxolUqZfYPbFN+37lhwlrC0g6/0WIL/RO8GIN1zYirttl5MnIMAfN2TkrSyU7p+xwZju8biZEROrDMa5ByANbRbIUGxnGEqIidFImTI1UI9QWcep7mzpl5meHaXUaTaw+qqilLuGSefgT+/D43j+vmzv0QkHeO0edZQb4FcENglwgqOS/lrA5S3tbCqzUUhuN0ZNgjHp69/yXNtPOQDJMt61iBip+T1p15JurO2deOPvmpwWnejJs5EgaiXQSER1VI/SRLNotlnOsCeKL9a9B9x8sVW3M4JKtMYq+tWsoTABnAIoI3suy0/TrmaMDANn7PTfztZbPelcNVJ+aJbBBbbq+ZxO9hyEGHGguCIUAqWUlXK8z7uT7SKijwFYebyfsBcLj75VFUrX6AQtOF8CZk6kH+G1zCtxSMqrlqPXTj9w3J9/pjck5+LzV6w6DixgEGCRILajgOgDlmpliJOPeQC1hBqNY7oF/F19ehaQUDbwzWaFUOYg299Y+8EQ51kA1PHKpPtzjI7/m0w25D/T7y7LOTIgig5RaXZoFGobjI9xOw+Ni476Q0jYt7X+5KO+xtnOHJ+tVsVO54hG14DqwbFX8qjMU9l024ecoKfyDLycu+XDjkR+/e/3Dd77b7yi+UXV7PXzjhtTKkLAHWrzyzRUBAIbdGikcA9CM6bcP7N570rqHxx5DLhFOa0JR1kY1fbRPavRbOnHCP7N+eeECc2NmvF6dRivCIQ6dVaRWkdGsbXiDtU927vViGvsHRiGDS5orrV2HvzBWWHLwdHO/uyt/PLWvCEgZidUC+lRN9fCDTrNKfodFLuzwFufM26+q6T0FwROQFv5svi+fmiW8P3H+SzXu13NBKizt5oczqYeH89N6fI4g7eJFibWIiLOSKTUF/yDh66ndx6CxX0P8a2Z9Gas/C7jkd4lvarPmnYTnLVc2gnJ7SDVohKL3hNcerj/00wzUM+vdkn1kLq9S1fx1cwJh6ZnuT9Iz51Rvr77f0i/ZJ5df0Mk3K9hdhTM9VQKbGlZUWimKuZ1RTHC2jWKlj7SfOfzEt//8buT+RZt79F487h8XvZa0vLJyGdwc2g55btafiIZASVho4D9O2TRmOkfTsPgpe+etfzmLveWXGmUkNUiXVB9at7j1iaLzmw/biwZUum1ctQNBCm7sBxhNRrGLLvJs15btR77+2JQd26hp4kpXLCl057pNosYne59o2dLZc9HYo8xjaa14sLdHDpNBEje5Kqr3nNveYeayKaQp3E9uNVwF9e9+VyumEvGc2x4jhtbHcVQCxwBo4VqU5fN2/i7/vNbJFVUSI6FmUxXhjsysLvtBai+hU2aojNXA8f0kWKnN+mDKwPNUrDexrpFhemK9OnY6fvzyubI8puJQmIA9iBCsmPxVXV52Xq2Y2X3+qIOHFm1OB+1K5hSzAslB+FQjEQFa8trVCwvBOiQpSZZK3A6rip1VLHHsilZnitPpJZOXlUZodBcahkcVV7isF42SvvsFe2nDS56SH/ssHL9+97wND/35hZn5Lpd7YokHqijWAzjAQ6ZhLqQDfJATBawMWPPBWwfre0HRRhtNYpKo294uvuXITyeZswG5iMETMy5jrTHaJwFSVkwcvzc3a/UFwaNDx2F4kDRwV1YVDXbT4U6UHNVk7UvTV81sKwguNipZyzbtJ6K+5smqMVr/44sG+oi9Ea6y+y0uaDb1SGLghuR0ueTtpefu67vw6S3PjJjxWFrTpo5giOD3SbuqND2wGZ1PSefqVK+Yhk22l+fysxN1MArZCDTMLzOCITpNOv86KBV3iV6vnjLqEnLQQumbCSiexJl3pFXcMO/Jg2Cof1Khc+BuHYODPy9QTFQqvR4x2162ZfDKaU9/PX3VBjPWI34JSTK7Cj8y+KG6DH/R0F+kR4pGYmfovU6vM7XWhh3pG9vs2ZQuPTpmLX+rx/dz1t15YNHrT+2a/3LPnOf/0aR1XEIXtOKcuOkF85dTVjzTPizhTzeYYs4nhIdpZQ3cjqHPYQwhJEio0F4VllmgDxCHGGnSa1vrwktuDEscn7X0rTuIOAh4UqkweOAYGd5H317Vsvu8kd8eqix66YLHphPdMihE1Higk5hMBm1yWMLJGxu2uHHbjOcnEXGQmwkrgwfvdUMcVXMQetRrZenYqPFXTRRoBIoXi5HQFELFyKcJ29vyT47C1FWbF2U++eoLf4KG4+Vckk42htorCA0NVrU+xDHpjB3JggUOFxQILtowuZGilrU2RIZC1Ppa+k3PiGlSAb3W8EGEXgeEAlaFSIS/tHdHG9zlXhc7UJn3Um/z6A9mbX8rjtRHFFNRX9B1VYgqq25LDqZGNtaHsWbayAV7zBsWna16xAdKYljNsEzfJtT/jZpPa+jpw7ZsCB+1aUXU5tEzv9+Wn991yRsr/tpEY32yzGnvbmFeg42GGDMaBmNIGCY0wRBxLjLC9O7tbZL/bv7LcBxJZQIAxiBnqOl+C9WdK6eN3Z15ZM1Z1a7HVr8Hbj4i7II43SSL7SJjWfuoRi+Pnbpi0mAQBhEWierNo7lzXQDl/K1e6cB//1dQ3KoJRrUsgyZM0D8//JljtywY8yFTHEMVl0Im0KDuJlQJ7ygdlsLRwV/chS0rsj3b+5jHru/TqtuS54ePLSS1hBAh4xq5NQfMLwTyLGXw5MOGNqFi0OQbXnj3gpmaAmMeNOfvcRN94IAM7nD723n7P55nEYVmIF5iuJxwgrVBzyBJ1AKrRS4yeh4q2Lat/4DlExd8N/PFTWAuJEWwxk2tcqEPVkfte1JnQ/SeyPCoWdtmrNxBD8nsa2gUA3WHU54HxMGwMNQ+vH6i2KTUIjRt1VkzPm08d0qj/Hc1bGjD16v0eeL1F5rm5l+68bylNAq2W2+rqDhvUmzMkXfGzj1LAFID5AZQBIL3D4A6/r2Xmu8/dXTzLxW5d5ZhrQFB5KFVlwdrDZPJKNxgiM7u1qrjqE2PPvvtF9Oe4wiAatQAEvQyjx5ThrPHp1/44O/cq9d/VBJ5rvsU3i9OZesZ69C8zYKi07ahZ9RyrQYjgEMM1cioZjf8RKKVVFE+VVEinjLpJ1hP7XtyyJqZyx59dvmKNB8iCECE3+T+X+ay+4REzeaqrgIAgUszA/uXmHFVXdf4g3N9c1qa+5aF4xYVOYteddnh9EgUUE8FEDOURVIdHs95wZnocAovd5r72JN3rZw5b9v0FVuhfgIJmcbcGQ4oQdYntauW9izeNInfhIhO7TQOHJ1vyCk7zp83rP1403155cUDxywa3T+3olS4ALNsg2MHNL0WjKqINoXtjo+I/eT9cfO2+yvVvDFiSg5+04enbP/3u+PmCeQ/FNdIJ6ePNnOzMj26Z83MUd9m7nvxlGw3wFTn1SFCCYIS0FxoEnRGlhzXbMP8KSun9REErmunpJhZRiYWhiCCOV+81XjfsV83HXCX3lMhO5fzpmLO0SSHYoE8y/X1pxNUS7P0xoipWXesmjolX/C8YLU5vHBO1F6tE9gE1GgkEBPU0CPuUlOmbFuSPWfEiLSXFi3d8vT81/k6JCUFC9WUoAvVK+PgEyFwhvSLqCtP6v7CBhi0AoPBRyB+4VM32+90hzNBMxPhgPhaz3kj0341Vtwpk886HW6qJ3FdDJIY/otKfrlVzteKPa2Vl77pYR71TZQhZtqOmc9hd8PMGKmlCzL4WfZQ1VFPObcpyuqME2a+CB7DXl7+4PS3lq3K8dpb5sOTEvv/IEuYfoG6uR4Hy1UdQEND94YVheNaz3jkwI3N2i77cLz5Y2pk5OZVD2c7Cg98+8yq09UaVbPNbzqzcWMLDu289vy0O3LKC6fvK7pwW7EDm4+QGhKOCUOzwqLIIPUNS8xp3bTF8DefmJaxdeoq7tJ+6nJSldS4dcnEB9L3fPfqKa89FuCzSFjEuF/zH2EfpNqg8J8+dUj8dtrzq29bMrHPLjX/QdnhcsMnTcdtXQHWXbscroHSeEqIICmywysf1ZS3ys8/8doN80c80alhm7n/N272D+aMjGtSu7Bg5LUFaYbf4mAgCzaKoePVI0Fo7ZCZWQ/UoVrw3Td37lyDs5uZ798dXe8YVrb/i1/O6rzNNR4VuyOqtj5JQrWhT3QYEschVTmnsoLl6G2Dmjosg25fOuHNbm1vnL4+bUQRqvcHhPAFafBBceWvBDEjcGpKT+eesVu3f7Pup0vHHz1vh/OGLHi02PsENKBHURuF8C4NdAa3Tqu7iGNblXbVo4nQSD1OluR9NHDZM1+2a9Pur0qlO8dl83zUY8EoS5Sg2WbXas7FR0brC4sKaQvjxkXzRtxazjwdc3G4B34/Xh1UCjc6gnMBmg7RcayhKfr5V2asmUuLcFprkJvJZh/hKrTo+ipj55oTtuJHi5028liwa416k12mg2Z/3ARjBk4ICWzn3HVDsbj8PEuqHFJpteE0G05Q1Yu2vj5jt500H5hbBLnIalOKdK5biy4ey+i9ZPwbKd37TFnx50fKSK0Adwpp0OC+v/UtvfkIKwzno5hJbwiVk86zh1xMX8sM+c/1UGsc/4Gf/JTh8rS0oj8tnX2zq+LCz7kaWzOsKMBEmO5qjfmf4ywahggHanJUm5RjcT+e/2vZ0LQX5y/b8syi5fWYzBkRCK9j+N+X3PfuZ+9vOuCqaICzwrIRZ3dcGHEEsdA2NUWwhobIH2D23ZwQ3XDv3U8MvZwmwMSINPOnbYk/HdjXqMBe8UR5acXrI/9y34jPM/akZJ069tkptXJhCaQCKyghxzjf1o0b1wocbMCJsOTSubUia2g0MhgKDndq1PaZd0ZN/6HtzLVVUiMg1R57ZdmT2zJ+WHPEUxkBdUzWI96RCwEt3NiCbaLXm3IJGNi2ySzzR0sgDuKafPd3r3nTvbctfvrVXTrvk16ckQC3plOG9bDsK72l/ShIHg04midPsUn5gvxE5U9bBz+wes7oTyYv/QxmMOCvr50rpa7tF5kkmUarKbBUuAut5eepVBbcN6pKQxUCN1ZaTXlwZoHKegC9wQFDL6iryvl/kJ9XpaKYUlt1OZj+zOIVuE3qMsfNDEhZ8q74bvSygtQNK2/OKTq/e6+jqKUKtRwqH/yPr96On1AomomKmETek4IlvKTo7LIBSyfe36lt14dfSht5nqtcteKqSbM+fitu/5nDz+/KPfn4ORu5/Ekeg06rcXghNySdlGyIq+zStO2Et0bOfNvfF/b6CL5sIS4ij+17F1ml6PPs6i1bjF9+uyNxDWIv4brfk68+f1tW7pkxFcw5yCZqoitxZsapk5heo9HpoB800Ohko1b/U1xY5GvfTF/1Nvdf8G3wMPNobsVQEOol8suff1z//cXjw3Os5RSSB3suGhGxq3CQQW+41ZhwuXPrlp9tYh8wMzZ2zGj4j5iAuLRW4ESyc95LT93/wsyzZ8oLlx2zlUp04g4UIiGCC+fj9fXPhwiQ97QtBX09izkaOMtzP+23ZMKyH+eun1O9nbr1hK6elAjEWRDOuu2Vq1aNJrcnhrquEEhmKgqnMxxxHGqL1CULDuzLExO8xsT1JY0Gu9RqKxQhAqkBDBmNUrBeSx8/PX+Hqnaas3jsO2c05UMLrdhEhusRtttCBpWoDgLGByYQHOpgGqXYavV+77T1unyo8vi9G+c/+Pm4RV8hL8frQBlp+6+73vmV2Qd5Ky0eHRzRPJD2cFoTm4RHiV0iGnwx4OYBo6b3vyefCsICpUlvlKcyn4WLryM3wcIFWzPLcbnEyWlpJFUuBCp/7ampO/F7J4VsuVSc0+d0fk4UNnLcjQzhUuPwuLJ2DRofWfXw6LOB/HQQ6tTly8RNgf2M3bl6zpD3f9y2+bTqaqg6XF69Ros4UAhvBXWsdUQ06xjd5I3RUyY8PURIslOwL5TjMAXq+6N9A354CkLb6i9oPp2yYvnYd9ftMJ469topT0WnChvWajh1CM5MQRSumqCjE4LpcAZdPldRouaHu2YPWD65+/ezVt9D7eDDibFmRVfwveZ9UCcQy4v16A0RCfFpc99rN+eBRw5hDwuWspqRJ+HcVMps8NaSVSdgDaWK1a4ePADTqnoN2KmEJ2rwlAG8IC+B/ohLhxypd6+c9vhlofiVw+4KCYGvEL0E0SYhRYOXrnkXIfywPBF0Gq/gOe4p0dsvyV8O37hkztvj5i7j6igObFEJKctaZvLCUcQAlcopexDkFYsKfYKla6M2z7w1bvYbW9kL1Z0HuQVqxpa3m2XmZD3icrvuenH+iKRchxXAwUQ873FNpNZ4IiI8Ymuflh2/Nj/wRDY1snRI2iV8VW250kXASY4lM23KELMmg2V4A/FwZ3y7JerggT2vZpZeHHrJSctv0aMXtBqXjHPbBkg1Y3Rej2YdR78yYsqXX05dzhehOCTDiQqZ/9CJ1C10wEseAi8Pm7gXBNN10Mpp888qebNPq07ovbKMdSGc2eDeU4PHBu82XK/BVrSqHdFDvpdzB6csfebrjDkvDiYi4RuLaWm+gldh9tDO4KSlyCYj9tJFIYEKBbNiIZPE1Wevl/ZzrglZqS70Gu6nAAIMgK5DJVov+ImbbZ2+6s2ZH723M/zEnjVnbaX35mNdCkqDFVDEfirWZVdJxGiwwajVCpJ8wVIu7C45v/S+tXNLPnt2ySZS6UhqSVhky3YEFHTKLm3DiEjWJTzhq3v63jZy0m0PkhjVpGAR73MD2UxqqHD3qqkrth3NmHpCtotONyxcZP3wi9IyWthLlrZRrvIhRaXFnsHPT3uvS8sb5q18cFjulPdevivfXlnx3sgZVd6aHP4DzJNxwHeufNn2j+P2Hz847ssdX0/K9FTGMI9X1mKMPThgROuNZmGRrH1kwlsjn3jq6bREBAhIYVLquC2qz3fHzKv7/82fzQe4SgGCIcI3j3tn9btJF86vPucoH5Jjo/Nh/LQnnWa/Kpl4oJoBaXSy0+k6oi0e9Kflk5d9N2v1bLawPxA4gYsNEIB/WRx8BGmaaVnghprsUOA++z9MnLjRPhlxVjz4yDn8vO/B9eb7z5fkrTzqKGvr4dFL+Lhdk7SFMqiBe6ByprhArbRY/566aUlm+ui5PHayZCcvKZwN6KpPqOjQoOmU9AmLXtvOXqwuNThnfnjtopt7zB/x+iHZ1km1Yv0lYi1AthOSjdxNhoYPo4x4rBVOh/qrYtX+Klsfz6soSRu6fuHQTs27Hs7c/dkbty8a34BpNf+AC8HppOg4I4hMLrNaYnCm//Z/7PzqT5dke2yx3Y44DdgSod10FQxBpxe6aSPzOzdpNeb9MXM/+3bGmurw+dQqEO/143Ly+2BPBklF9KvzwjTtxkcnn0Gt9963zjywSenltSfcFZ0RmhQaCc7ngC1x/K2nWTLjgtnoSysq5FOKOCv15cXb08fO+56fB4I6gRMOJLfqT5heLwxhdrfPalilEtQsRZIJxAbrSbUNT0gWEo1XJeaaVdV/RW4kFLIUah77aIL5U+T+9J4XZs44W3pp9gmPLRJ+fDIPrH0NahckLTRYrbdQcUsnLpx5B5vj7chrWmokGSJv0IfvfvCuB//ybG8ejUKE1PA7D/qkBiLNLd1bcHJWtgciTIbfuUarBdVp+cFlrhH4OoKR4T+gClIgEgrn6DmkFphckvC1Z89Xz0Ak3pVsfup5l1dYVuq1shOWQkhthZXhAIsVh16YCxJJ0DgwjIicx3TwKGZNEDmxbUTCG08O/NuzPIxLQGrAJR4iUDZ/9UbDvYcyE7cKwhGuMlw3fln1T+41P0V/MsF2Aojw2UTzdpTtAheKMZfUklUnZWc4XHMowNtVTcKQJPD706o5TguLz7+4CvUkY8eML2midXAf8SKuFlA4GLHxe+BBFAe4POCvH6QTWEHpcWCHifAWwsGrqhyqh/xJiUyqbv0uPwJrIOCsRAzlqykrnpvx7aa/h/34y+JKg3fCaUsZ9tkgTXhc4/qbBJFI4ADu0zpnixFznhqH3C+Kt7boOPnHBS/3JeIgvcvvPOgl58GHNiy6CQh9ZJ+tYFa2rVLVyFxs6UAc9XaTBpPy4DyYTo/gecdLCuT91twX+yG85gHzq1MHt+/doYGsec5jd2RX2KzYDoEQQCER0TjC4F/SQGeUmkv6gt7h8R8MaNejz46560YQcXD4xqXSbj93bhyx6flbv96/98KhoouPUtevHrSBcv0xkx8RZEIE6sH3s9b9/b6eKR1vj2i4tQGiTMLED74U+nRfoNeQJBKcEr3FXluPxzYvuxf3udyINYSDrZGtKpCz5jesRGBeAuYVgbK9tEaulbDBR3ewu5kt2Oz5WK6cZF7PGRUfGKpPJUo6B2EN6g/RQq36fuMlEQcxSFK7nrtjdMWBRa9O7JnU9s52hqhTEtatiLZIx06v2jZUUcnpdLIKr2Pq6t1bjNJrY2f/RLBwCrxMLue+g0p9lk1YvDv35FzspmMIFbdGo4H7Awb3NyZEH8f+oFa9VF4h2yLkpZ3mjtCuTHtyIaqZad7/xaIjew/0PF5woV3bqPi2JoMp+uDFcwd6tOhwqVF82+/XwCrGFyxwCUjBgqO6S/zN5vGL/3n2wNxcyBpJ8ZJ9+o8RtKHa+BVlZdXLaKplrfoZQARSu1Y+ODIXDwYNXTt39LGCi38/4ayEoiSA3YS25BCG4AAWy4HX65niy3/DJY+Ugqg2dh8NEImEwCNAi0PCDO/jqAs3LfqRytd89Bh9V6XUVMmTnu6Om/vUykK5YhpzQJSEiP9VVeZf/QFpi60Cj5ksdBlm8f/GzPkW6+aOt+CIRo7WOu5SZbkKAvDFC6vbA94qtCB4bOJMupY1+Xrnz0MkMpvBzYRczjkn+duLi5KPFWW/ftBa3M1ps9ELnOigAm1b/MuJFonQlcVyq022GGUziETIWvK62dyTnzTbiYp3Hq9W+6nA79TOukH9BgjffHxUzsjwwXf/i/OSzxbmvH7IXdLN5bLDumXQGplG4hQSKPdH+b6dAxpiqup04grWVqld9M6MdPVDWF0e2bRid/7JA9vKBU+j+iIrUq1YGsAM5mVFtoqe606f1k9s29Z1oPjiL6JWNxjnu9HOlaYCUPjuCMyBRfqlcgRg4CnoKoQTSqAcvjnqFLuslZIWR0mrPbiGn799bFApCIRgUOg4BNQ6gnV86npzznfOzOWl2LCGeZdi/gStm/qJMkIRwv5UOiz9xfSsoiri6L/kmYV78k/sP+Io6+a0O0lqgJiuvgBEnVdNBBAAE+FnJJ9V7AtwqOUNKjRwxqgoWMa6Ba0AxyMpvhJO4nuf3vJKy9uXPrNx36XT+4+6Ld1cDic24TUKLO6snP37QRsCKBH4DgpP/TeDDnh9RTIQ+A7Pqcmrf8gIUStxh0QgQpsJg/TvjZ55tH+rzilttOEUdoFiYoXsCp1hg64NhwRP84O7PmtJ1eKkOL0bCqWCF+N3cfANbkEsUdUnURlirPRdK9G9K5+YGICCcx2wEwWvuVbpmpdU5Fo+NUv5rzbDTEvShLYS0ieYVwxo1nF+NNR4jA9FwgiZoKpifBAFWfX2kGit8bfNS7tn5Z5/42d7QXebDS7nElRaQf23pEaw1olIMAmiy2b37NPkPX7nc5Oj/zlj9QMDVky596aFY17D+ZGPEsKj9uBo6fksp4PdGRkTVVZp61rutQ/YdvCH4Rc1Xi2kBkUFR9xYbI5gbZpoDGdt9XFlpCemJA1RM5gvnkCw9q/lHhkayKx8LXmr5yGWdfWEajHdsF7z/QEwibWI6j4EngEkAPm9GnUAkzGXWq0olCgLRw9Cz6DvcuSrgWtn1n/jIiL55Gnzqd6Lxj11TnG9objJgy5Inb4GCBAKuCbZ7I4WuHWiS2xjZ0nZRTCbGlX7cgf+whAFWwA5rnamW4G3dwUe+79rVuB/gREd5GCcVGrlDnH57BtrIg7lZ3+Bl/bE4Kg1SYE6c4Ib8C9XI+OMph3fzVo7EqJDxKfGVIBA6Fplo5j2wwmLFicvHH3zAcVzD/kB4m7QJQNwVCPDYKSJ0PaUbl3y9LifL5zYcAaWDZCMb61BC7n/UIK8hfFWoy2ptLh2qMr9nec9+eH3M18YetO8kbkXZfsbZxi8hUsraFfU/ZOlXEch9UsU7E86ET9Kg/NdoqD14ugu0+lYG0OEvY0xcdrWGS9spAHM8KuJQUEn9KtHvvsWoSJzgHMUl5f+Zo3SAGdnpKBNX7kJZRV7RuRgSvfKnY5bj7jKWuG1TGQjD56gDDSTTCwtuX+DA2zzeUw4hfas0xCIBIPE2J55G97qPPexRVleN+LKIpJ5ED8ljkHQsophPTx2+TwflUK7dT+PhYH8fE8wGDSAugIuPjDdc/z4TwTq49INbR+6kCsdt+b1KhDgz1pXePqgo/HWSayBq7KI38g01yEifzfUlCQzmKeZdUxq8Xz+ecs9l9xWKFLBw/7AmwTzIbGLzkpRPF5e9MQZOqiEN3lh3khqhGrE39a//4VFJIX613vwcpZMV9mDPcwjd/6y+JU3zy17W4h0CevaGcLcsUadsViUNSWykwMk0EsYdVpjpM4gtdSFFSXrY1endElu5ScOAqoO0lSH1IAOh8LBqsKQrOWke1rKTL6yQXXs6tUylpnB270hvmkPFUwJ3Cfo+Pluko6psHCNBHs231OoBFMCG1PcuE+vcKvx0eMcP0OM0MTwSPKgbUNlOnXqFLR+PFLJ2Q6zjoA08lcM71oEstXgplS+eiKmHkhNo+Id0UAYVINRCJ7AYwQVOnyUwdSL5zD7+h489793N1/nhFIp4IAqXoCqIKx9rbHh1yoYOliA1ePlpx3gbhSy0YwFCzjTS+7Z+xDOGkFQQqUMabOjakgLRegddLocHA0rKQVnmkPW/7s/ICLBTGjheerOclb26zZ/REG3xq0HvTt6zjPPvP/KsovFF+9xOO39LtrKowvwuq4GEVHaaJ3xAhag27u167ADgZqtXJmCWY9t2nTVoA2t4hsJ53LLKaYT73zwDgmKBpRr0uop/OU3Ph37KkSS7hu1M+UF8fQLa7ag+AVkBFfAe5FdjspThbknqH2OoDAaYY7hN11XHaLlMuQtK8a7MbIunee21fqhSUGBDHbSZb+gMdI5bh6lBvdqJgKQqsZ5f/h7mjgRNUhqdlxbcKYc0Ef7H9fpB6S6KEPquF3ODrtV1cgPstHaCERZs4Xf5wqijS8HaHyoldq10k0ZDKe5MTI+Cw/9a7La2fg1H0r8eqh7ivvzrZ9CXcqPxsE0eudMnXqxVgbfUtQ4nUmQaNr4CAVqCFr9f+amv0kdPCDcR9zOxPILzgN9Fo5b+OLfRprR4uv+D2+8hP/1/dlFXzgaPApHgzdvR8zVa5ggMOpDfJVIfAkDEGxGcVuwwD3/QllRO2oiA//qTT7kUO5fY47+Je9kJ4prC4wOKqi45QRrw0amiNIR9/3Z+slYM8P+hYBXwBKjCJp8BISYtTDcwr2/LTL9WL9pOIPX0ys6MelnRylhVFDMpeawtmHxiD/buXFzdhDXdHio3exHT4OIbyLswK06ayJflEcBUditjd9/86XmyHPCvHChYPbRGy5/j+QbjFvatBf3HbFpSq2kVeM100GrhkkWBILJbEMv2uHnXkIQbGCIvz+zT8L5IWgIcAIJQhzUDM708mPPyISQo//jxBEVG4rQl+WLeCPREVfpgi6zHzvdc+GYBzft3+9XdfxAwhpBrhHUB4aIkGSloOO35i1b6F7QlEKMGinCqM+MxFtNMSoSDUCwzBhEDb1yGd9/mfX16wlkwIC+H3KMkn0RDuFt40q1aBTivMSyA3NRowkgO2IPSyxSMh4fktTTTg8dbtchAZEKMflB4eEVgPhLsHgqtpT2oOsQC2OeFfDyvkIjuJXhveWc/fqe1P5LiyGN1+Vx4A3gVVb1MFF/hHbBOcrVLoFrwAnTiOi9iDXz8ZKcAZTli0Z5dQipZtGMwGXQcQk8DHwjEx+L4akTynASMAcEi0f0ysa6CTdpa14pl12RedkXOlCO1PT0oPNFhEzP9/16qElhZWUsFSUtJljC6l2maPQOj/tQ0MqCFfpP3wMCYSgkuHm5PMecFW3Ouys+XP/JhsNweFz9wJpZt9C5FRioPP5QqcqYj19OTF236HacXPxoy77PJhB8FBCsNpxAcD64bz4x/TT0+CxCALDsegZc9FwQnBG7Dx2ZSXWZM83YK6r5imIsxoWAtyflKagsm0NvJSIVhK6DJVotR2v1LCoi6rvAc63eeDYacaZI+wqVyIXEA4vKZUvpPWiXv9MwxbebXh3hBP/7OJS/vrK0W7a17EZy90WTQeEB4cCipLJYU1jhpEcmFKJtni9WF5YR53vJVV29ww8gHVByIMig02mfSrewsQwX9Jrj489KX8Kg2K4+AiJuHbqbV4r4c/WHkybeGJVNBAKLatCS/CZWdQVwIMipLHiUKkn/cbZUm6nRfG2ryNTT82MXztxXqgMsGFZOYHSzVvLXy8K1xmNBB7BW/v/aJV75RWtMLXRLuQTvCD/mKG2zszRn0vZLp3d//vN35xtPf+hAzLSH9yZNf/jA97/sOrszNzPjsOj4S5bbRtybZYQIXk3uB/Qca4vPyfqFQGBBCYTyYDYlJ4KeHyvNm4wACGlw0nf73TxwHI8jEqlogagvrN/ipz/YZy1qDsswArkER0i+GFQUbQNZ8uD1YB9SO5RwqOknHU0TEL86tvue+v6Cm5GpxXvBa2/xp+emrKC7GT5rHRblgMcHk8r3i/DsRE72y/mw+kGK0JH2oNXiPrR6iUVrTfs7C4IbUhlUythNbTvsivEiGJ8iY0svODrzPuKN58dsxS0HrJg0F8V8rj90pJc8Hoh4fYyKcKsKLpMGr3XnumRQkKh5X6q2hovQGX7G62qIf3CcDWSp/o3BgTu6W71QUTT2kb8v/RNbf8ZlDph6q83XnjXpjmkfvdn3YvHleRVWKxlTeJ+r13Xlt8pM0JQVJu64rgiEAKSRIFcJkDh2lkTFipfFWxAFPdNRHnEJGzdlzHtznuLpccphDS9wO1wqkDkSHq28cyGCNgTeDdGzWYdPuujCIUA9eD1l8ImikDv08tgSBKc4XHD2H7eteHbtpC2bunLQzKR9MPXVzN2xaX9fPLinedSBXZb8h+AsSJEx6hlw+LDptaxpZOzHLzz41AU/ArHnJy/PbKIPzwVq0e5CSKIlkCrsDnVXSc7UWxaPfRMB9rp8rZ7WgzgU+mQiEMbjr6xKgTXwp1/txX1w9loOtuinMaJe005iks7EmkQlfkb3Elhn1JMirfjr2OxYbfg38KCj29Co6iaaH6ynJBzgUg+V5i0euOzZdUu3v98AjIT7x2UQ8UI1RTYO1/gPXupx7+qZY6DQPKa4oL4GMUbUbcV3J8Jg3BpLQW7grhR8ttAIuiTh5brnnFZ2MPvkt/esnTV75idvtOA10Pig9LKdWxIeXDd37PeHf9px1mM3IrQSef8FrRIMEuSoSs2Z3jage999QsKUh74v0sj9/ZPsE4c++K6rvxLUAnSqKtAHNAR6fRwhntZk95qt6z5eyBHPNznBYKe+yX0Wj3t3t6XgERy2h5EodJA2ag97SWAlBrGLFg6zsnwEQZmsOrjdRGh17bJdlZGF8GeiDSdIFDJ2BE2+ejxq5+hEcUCnXt3XPzzmMLn3kAcDIRJUyJe/Ljo/RnDBxwPSM2gluEnrJqhM2JKWhFZaE4LySWdtslxA+Y1MbOiU1FZn8R4hsIqQxEF5dZAsbq9L7B3bpHj+hKmtB8e1rSQVJC09jcfRunet+bb9+ad+wJtwZRy58xlwqGCtBM4KR2xVjQg3io0UbWUDY9SvFYr7V6siu6IlSR+nDbuxyF7RDIH/WuYqTlYJB0BIWcxfcCmLccI5VlXzQPOuOz6ZuHgAmuPz1WbWsENnPNYbcN4YAx3axwwMT4HTK+LDG9gNYhh6JByrVBWLgak6k6jpeEaxhyEQBqQ2XpRbj68aYrZ4FBxd7W2Ie3Wv+eWR9XC9WiPyP76EqkEUzwmYSxlc0Y2gbCAIrBC7dJSX9Wpxw7SKrN1Dsf+ih0U3pGMftYfAU4KMwADH7IUaqGbd+MEwLCaYFXtyOIUGwgDKhiYOIDUoWPHow8J07WKTniPiYCkpEsyRfPFvhpWsSXzT5zuWFIw5rpRCm9AGNTtSdyAR0Bp6ixNLODSlwXv2WmMzqzUXuXQ+H/sEeG0zAtGERiIaKwT/9iZGRunaxCetJOJIgUqEfhDHl+mo6efPmnfetuTpr/KY6x7EbHaj/qAGEOLcdGbVYoOEZ/bIU17r7UzS3q7DNuM5sk/jKAOFMgUDASvD3i7WUqGIg/pXJ01oI0FdklvGN3qlqOTSSxWynWRJyCDpdJ6Dv+DJ6ZIP0wuftNquPoMiTQI24nEaAJoBnVkOKQRADKrX69a20UWpXTp1WkaOstedilVnoH6nGyAOHj5m7aOjL7dNaDw8zmAir28EsRHoBfNBk9/KIUka8F2EUBUgRohD60Ss8viE+wi2TmHUR3vl4FQuptPoeoc12IVXyfFFP/zKuOpC8JDE2/z4xLOtYxqtZGFGrKvx7okQsFAb9AgfmmewdpFWPTiAgLe9QBUFZ8TpwtCTT8QBu78b9kJdB130j+8+vWAV1ZlRzfuAog3SvQG9+o7qKoWDAas6vAKOjpEETaS/gGphmwPrx7gITo/HbXN5ELDBQ9cUGIHGDnSNmAzBJUfQiunm+jNEtMK3U1ZtaC6a9oMh6DDmQdyIr9TgU5ugmmt0FCgaY0MbrwwLKgoJIeClMqH5KbYAEB9b9SThxUM3JDWf/WrahPMpYB7/zxAIDSNHBizYP528bEvzsKhHm0RGwZKIE/kCYixhgK4Mdc1f4DqE7JQP465qwFZD4QyfASAi+LniCQ8z6nuExf3ytznDSWVgZp/J+Eo7/veZfDn9uRm3GhJ2MYNWh/pdYHFX8tQEhV8RYoIYiJY4TIAP9uvQRQAPqaZuvL5Y110fc/yhB1MHU0V+eHid/mswkRTJfOdf82IiYnonavRWnP/Q0viEgolapdcSEHFiCOk95siPw3S4Jq5OY3ctKZAL39Q9nih8Kv24qUWnv7ZkRhvsckRt9RIJ5UebPnhovgBHfeeXiHEAaCjTqhIRYdI1lcI2fPTMUjKGiBlgHv9PEQgNHsMxTbJqHZy/6d1bGnV4uEtYvJsjJikx8CMkXfa3DgrnzlizwHwKIw/eCI5VYKzRpO0Z1vC9d+ZvvnW00JMfDQVCVk0+hwWEEEDS2X+bNLCPMXGXZNDrQV2kTnnAmTlQ/rzX/EXw4AMKIjzBG4NVWYwIN+l6hifu6nfL0BvHd+5v9UeBqQ0PmEiGl8Zn54y1x/u17NI7OSKxGOs8Hb3MFdVymLiZ+JqhCZ6RKqNxJsIjKQ5tjd5hSBKpSqWjnfEUcPHXnpp8pkNis16djNEWhcQ3TmOhLCFvgK6CNxLiLuBH23yeiS68cE7VNDCaNLfFNH5u37xNT/NimEj6Js85qMkYJ+43r0IK/RE+ONgGONEDwE79AAP9DYmHxAenTB8/9x+De/yp9Y2aqNcaSHpZi4BgOJkHDz+qlN7XwieBVDBZDwLAAl3l31joYmowqWgfSEPSWaZhhk4RH2bSdtZFHu+X2PovGbPXDiMzKl+U1wqPEwCXiIaIZDDOZOxesLFfL0P83Jb6CNiltDgKJotQc0gl8xAsvE0IDz3ZwgELfQgeIswqeOh99/QuEQlPSAAABIhJREFUFsyoAkfPCKNR294YVXp7fPMZ+82b+q0fPNhFxJFeT5BvGh8iko+enp85avioNnfEtni1rSlaNtL4oDmMD8AhPBE8/jHwQhVD9wkWvlikBSP/0D16FoAdY4l+0FILwRAUkC7qQi9pgWCQwmFhdHvy+dj43aoywMUJlm+mLs964JYBHfuaEr6J0Rs1IBS8AjAAB/PBgTkhIwSNCW8X3/Sb5g/w0Dhy/Ab8ZMgQFaz66DRmn+jGx3sltkj5asrzpAaT2yn4k09JEBpMfXh/UZiYTO95I/L9IyVSHARYLYxljpWWtR/OYBhIkhDX2gfiTjQBlP+BF8ztLlhynwJtPISXlTYrAc7RC0KxJ4BxwbTjBaY+nkeoh3HSG4ACWMFiP8EEjpSEo9haSfy2QXjMa/+cvhrvg0PCglzdsYMW8yhUfyIiwYcT+rBXV7e5XHBxWrGjckiB19moDIo03j7na5eYGSIucpgIDqIfHWChPUo8o32DCKCpzqtURmr1P7eNa7y13w09XqWX0RAE1dupH6KaMWsnf7y53dEzJ54stVTcU+yyd7Tg2Hk52saaH21DDmCjlCtHBEd1PKLxo6SH6Zhgx3hFYDx1GJFoBbYGrbbEIGnOmzTaIxjLHexSwacZG9OtICggKf76U0q1uRq4fGqKxVU5qcRh718seCNssJB7uOEW40FjQ/yN4OBCAL9xBoT/xj0sZFgcjOp6D7sUExa5Jykq+s2vJj33FW8GTNNvog40y4R2sx59tMLjbo8KsJFDS8s/TsILtIkzhWPBujV3zf/9gNnHxlkdNabeDpkJMVkGymVwQvlaVfVvrF3Y8UxxTle9TroJQVs6ny4rEpITmnaxed0Son+Q/0/5wdLLZzvFNihzOpyHGsfEH+/cqtORVUOfOB1oLKXahAbuXcM3TL8p2HDzwfJFXp7p9Y82984pyE02GAwdL1sqWoAgjE1jEjva3E5IDXQeEF22lJ0oV7zWznFJlYUVJXtjImMPtWrY6Ai8B3zcGA0TF+aS8xqAqJ6FTMAChQfyw0TPiIArKgpvvVRe3DbMaOyxJ/+idHN847Y2xRtd5nLIThAzaSi01xRvCNOEa3Xlh8vyT/dq0EK+WFr4c+voBLsqSQdbN2ha1LB9m7Pm3oO5N261dgkPq4gjcJ/PFbm0+4O6jXn77cQzuYdvvVxZ1DnCFHbDibKimBtiGrSGq3i0TfaQBiCGSTpvZtGlY4mRMSoOph/DnsnJxlHxh3t0v/EwXi1e9RoPf1AMPzUHWgStX/n5B/9VTSz+Kz2pTSi16/i6pCSy4OJFURerEfo06+po6YvuVzubCMIQM6pZhmpnuJbrq8Hy3oULMVZvEcLBMBaeoBMfad4Nv4IkmG1TOiOuGbl6X4MUC1JD1S2CCQTLXV2qblb7cV5VDR/s+sp4/vIlpfDSZaEczxJMBrVHpy7iw7feE2q8AjVwxpDCUsiQQkhahzgCGembq6wb0wVYyTlTq/6M4Nh98agRb9RV7JUaoX2zcIXM2dXzVP2GhE8dx1/5QZI7aJv/H+y6kJy2/hwbAAAAAElFTkSuQmCC"},{"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"}];
23654
23655 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","address"],"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"],"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/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/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"},"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_yes","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"],"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"],"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"],"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"],"suggestion":true},"amenity/school/Amado Nervo":{"tags":{"name":"Amado Nervo","amenity":"school"},"name":"Amado Nervo","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"suggestion":true},"amenity/school/Benito Juarez":{"tags":{"name":"Benito Juarez","amenity":"school"},"name":"Benito Juarez","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Brown School":{"tags":{"name":"Brown School","amenity":"school"},"name":"Brown School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/CEM":{"tags":{"name":"CEM","amenity":"school"},"name":"CEM","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Center School":{"tags":{"name":"Center School","amenity":"school"},"name":"Center School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"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"],"suggestion":true},"amenity/school/Central School":{"tags":{"name":"Central School","amenity":"school"},"name":"Central School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"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"],"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"],"suggestion":true},"amenity/school/Cuauhtemoc":{"tags":{"name":"Cuauhtemoc","amenity":"school"},"name":"Cuauhtemoc","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Curso Comunitario":{"tags":{"name":"Curso Comunitario","amenity":"school"},"name":"Curso Comunitario","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Cursos Comunitarios":{"tags":{"name":"Cursos Comunitarios","amenity":"school"},"name":"Cursos Comunitarios","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/EPP":{"tags":{"name":"EPP","amenity":"school"},"name":"EPP","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Emiliano Zapata":{"tags":{"name":"Emiliano Zapata","amenity":"school"},"name":"Emiliano Zapata","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"suggestion":true},"amenity/school/Fairview School":{"tags":{"name":"Fairview School","amenity":"school"},"name":"Fairview School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"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"],"suggestion":true},"amenity/school/Francisco Villa":{"tags":{"name":"Francisco Villa","amenity":"school"},"name":"Francisco Villa","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"suggestion":true},"amenity/school/Franklin School":{"tags":{"name":"Franklin School","amenity":"school"},"name":"Franklin School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"suggestion":true},"amenity/school/Garfield School":{"tags":{"name":"Garfield School","amenity":"school"},"name":"Garfield School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"suggestion":true},"amenity/school/Government School":{"tags":{"name":"Government School","amenity":"school"},"name":"Government School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"suggestion":true},"amenity/school/Groupe Scolaire":{"tags":{"name":"Groupe Scolaire","amenity":"school"},"name":"Groupe Scolaire","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Guadalupe Victoria":{"tags":{"name":"Guadalupe Victoria","amenity":"school"},"name":"Guadalupe Victoria","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Highland School":{"tags":{"name":"Highland School","amenity":"school"},"name":"Highland School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"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"],"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"],"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"],"suggestion":true},"amenity/school/Ignacio Allende":{"tags":{"name":"Ignacio Allende","amenity":"school"},"name":"Ignacio Allende","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Ignacio Zaragoza":{"tags":{"name":"Ignacio Zaragoza","amenity":"school"},"name":"Ignacio Zaragoza","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"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"],"suggestion":true},"amenity/school/Jackson School":{"tags":{"name":"Jackson School","amenity":"school"},"name":"Jackson School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"suggestion":true},"amenity/school/Jefferson School":{"tags":{"name":"Jefferson School","amenity":"school"},"name":"Jefferson School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"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"],"suggestion":true},"amenity/school/Jose Vasconcelos":{"tags":{"name":"Jose Vasconcelos","amenity":"school"},"name":"Jose Vasconcelos","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"suggestion":true},"amenity/school/Juan Escutia":{"tags":{"name":"Juan Escutia","amenity":"school"},"name":"Juan Escutia","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Justo Sierra":{"tags":{"name":"Justo Sierra","amenity":"school"},"name":"Justo Sierra","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Kumon":{"tags":{"name":"Kumon","amenity":"school"},"name":"Kumon","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Lazaro Cardenas":{"tags":{"name":"Lazaro Cardenas","amenity":"school"},"name":"Lazaro Cardenas","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"suggestion":true},"amenity/school/Leona Vicario":{"tags":{"name":"Leona Vicario","amenity":"school"},"name":"Leona Vicario","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"suggestion":true},"amenity/school/Liberty School":{"tags":{"name":"Liberty School","amenity":"school"},"name":"Liberty School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"suggestion":true},"amenity/school/Lincoln School":{"tags":{"name":"Lincoln School","amenity":"school"},"name":"Lincoln School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"suggestion":true},"amenity/school/Longfellow School":{"tags":{"name":"Longfellow School","amenity":"school"},"name":"Longfellow School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"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"],"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"],"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"],"suggestion":true},"amenity/school/McKinley School":{"tags":{"name":"McKinley School","amenity":"school"},"name":"McKinley School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Miguel Hidalgo":{"tags":{"name":"Miguel Hidalgo","amenity":"school"},"name":"Miguel Hidalgo","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"suggestion":true},"amenity/school/Miller School":{"tags":{"name":"Miller School","amenity":"school"},"name":"Miller School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"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"],"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"],"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"],"suggestion":true},"amenity/school/Nicolas Bravo":{"tags":{"name":"Nicolas Bravo","amenity":"school"},"name":"Nicolas Bravo","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"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"],"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"],"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"],"suggestion":true},"amenity/school/Pedro Moreno":{"tags":{"name":"Pedro Moreno","amenity":"school"},"name":"Pedro Moreno","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Pestalozzischule":{"tags":{"name":"Pestalozzischule","amenity":"school"},"name":"Pestalozzischule","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"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"],"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"],"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"],"suggestion":true},"amenity/school/Primaria Comunitaria":{"tags":{"name":"Primaria Comunitaria","amenity":"school"},"name":"Primaria Comunitaria","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Ramon Corona":{"tags":{"name":"Ramon Corona","amenity":"school"},"name":"Ramon Corona","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"suggestion":true},"amenity/school/Riverside School":{"tags":{"name":"Riverside School","amenity":"school"},"name":"Riverside School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"suggestion":true},"amenity/school/Roosevelt School":{"tags":{"name":"Roosevelt School","amenity":"school"},"name":"Roosevelt School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/SD":{"tags":{"name":"SD","amenity":"school"},"name":"SD","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/SDN":{"tags":{"name":"SDN","amenity":"school"},"name":"SDN","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"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"],"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"],"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"],"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"],"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"],"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"],"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"],"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"],"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"],"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"],"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"],"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"],"suggestion":true},"amenity/school/Schillerschule":{"tags":{"name":"Schillerschule","amenity":"school"},"name":"Schillerschule","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"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"],"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"],"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"],"suggestion":true},"amenity/school/Smith School":{"tags":{"name":"Smith School","amenity":"school"},"name":"Smith School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"suggestion":true},"amenity/school/Sunnyside School":{"tags":{"name":"Sunnyside School","amenity":"school"},"name":"Sunnyside School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"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"],"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"],"suggestion":true},"amenity/school/Trinity School":{"tags":{"name":"Trinity School","amenity":"school"},"name":"Trinity School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/UNIDAD EDUCATIVA":{"tags":{"name":"UNIDAD EDUCATIVA","amenity":"school"},"name":"UNIDAD EDUCATIVA","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Union School":{"tags":{"name":"Union School","amenity":"school"},"name":"Union School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"suggestion":true},"amenity/school/Venustiano Carranza":{"tags":{"name":"Venustiano Carranza","amenity":"school"},"name":"Venustiano Carranza","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Vicente Guerrero":{"tags":{"name":"Vicente Guerrero","amenity":"school"},"name":"Vicente Guerrero","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Volkshochschule":{"tags":{"name":"Volkshochschule","amenity":"school"},"name":"Volkshochschule","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Volksschule":{"tags":{"name":"Volksschule","amenity":"school"},"name":"Volksschule","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"suggestion":true},"amenity/school/Washington School":{"tags":{"name":"Washington School","amenity":"school"},"name":"Washington School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"suggestion":true},"amenity/school/White School":{"tags":{"name":"White School","amenity":"school"},"name":"White School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"suggestion":true},"amenity/school/Wilson School":{"tags":{"name":"Wilson School","amenity":"school"},"name":"Wilson School","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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"],"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"],"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"],"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"],"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"],"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"],"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"],"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"],"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"],"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"],"suggestion":true},"amenity/school/Școala Generală":{"tags":{"name":"Școala Generală","amenity":"school"},"name":"Școala Generală","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Școală":{"tags":{"name":"Școală","amenity":"school"},"name":"Școală","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Вечерняя школа":{"tags":{"name":"Вечерняя школа","amenity":"school"},"name":"Вечерняя школа","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Гимназия №1":{"tags":{"name":"Гимназия №1","amenity":"school"},"name":"Гимназия №1","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Средняя школа №1":{"tags":{"name":"Средняя школа №1","amenity":"school"},"name":"Средняя школа №1","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Средняя школа №2":{"tags":{"name":"Средняя школа №2","amenity":"school"},"name":"Средняя школа №2","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Средняя школа №3":{"tags":{"name":"Средняя школа №3","amenity":"school"},"name":"Средняя школа №3","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа № 1":{"tags":{"name":"Школа № 1","amenity":"school"},"name":"Школа № 1","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа № 2":{"tags":{"name":"Школа № 2","amenity":"school"},"name":"Школа № 2","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа № 3":{"tags":{"name":"Школа № 3","amenity":"school"},"name":"Школа № 3","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа № 4":{"tags":{"name":"Школа № 4","amenity":"school"},"name":"Школа № 4","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа № 5":{"tags":{"name":"Школа № 5","amenity":"school"},"name":"Школа № 5","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №1":{"tags":{"name":"Школа №1","amenity":"school"},"name":"Школа №1","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №10":{"tags":{"name":"Школа №10","amenity":"school"},"name":"Школа №10","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №11":{"tags":{"name":"Школа №11","amenity":"school"},"name":"Школа №11","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №12":{"tags":{"name":"Школа №12","amenity":"school"},"name":"Школа №12","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №13":{"tags":{"name":"Школа №13","amenity":"school"},"name":"Школа №13","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №14":{"tags":{"name":"Школа №14","amenity":"school"},"name":"Школа №14","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №15":{"tags":{"name":"Школа №15","amenity":"school"},"name":"Школа №15","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №16":{"tags":{"name":"Школа №16","amenity":"school"},"name":"Школа №16","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №17":{"tags":{"name":"Школа №17","amenity":"school"},"name":"Школа №17","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №18":{"tags":{"name":"Школа №18","amenity":"school"},"name":"Школа №18","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №19":{"tags":{"name":"Школа №19","amenity":"school"},"name":"Школа №19","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №2":{"tags":{"name":"Школа №2","amenity":"school"},"name":"Школа №2","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №20":{"tags":{"name":"Школа №20","amenity":"school"},"name":"Школа №20","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №21":{"tags":{"name":"Школа №21","amenity":"school"},"name":"Школа №21","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №22":{"tags":{"name":"Школа №22","amenity":"school"},"name":"Школа №22","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №23":{"tags":{"name":"Школа №23","amenity":"school"},"name":"Школа №23","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №24":{"tags":{"name":"Школа №24","amenity":"school"},"name":"Школа №24","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №25":{"tags":{"name":"Школа №25","amenity":"school"},"name":"Школа №25","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №26":{"tags":{"name":"Школа №26","amenity":"school"},"name":"Школа №26","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №27":{"tags":{"name":"Школа №27","amenity":"school"},"name":"Школа №27","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №28":{"tags":{"name":"Школа №28","amenity":"school"},"name":"Школа №28","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №3":{"tags":{"name":"Школа №3","amenity":"school"},"name":"Школа №3","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №31":{"tags":{"name":"Школа №31","amenity":"school"},"name":"Школа №31","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №35":{"tags":{"name":"Школа №35","amenity":"school"},"name":"Школа №35","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №4":{"tags":{"name":"Школа №4","amenity":"school"},"name":"Школа №4","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №5":{"tags":{"name":"Школа №5","amenity":"school"},"name":"Школа №5","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №6":{"tags":{"name":"Школа №6","amenity":"school"},"name":"Школа №6","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №7":{"tags":{"name":"Школа №7","amenity":"school"},"name":"Школа №7","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №8":{"tags":{"name":"Школа №8","amenity":"school"},"name":"Школа №8","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/Школа №9":{"tags":{"name":"Школа №9","amenity":"school"},"name":"Школа №9","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/مدرسة":{"tags":{"name":"مدرسة","amenity":"school"},"name":"مدرسة","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/مدرسه":{"tags":{"name":"مدرسه","amenity":"school"},"name":"مدرسه","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/市立南中学校":{"tags":{"name":"市立南中学校","amenity":"school"},"name":"市立南中学校","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/市立南小学校":{"tags":{"name":"市立南小学校","amenity":"school"},"name":"市立南小学校","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"suggestion":true},"amenity/school/市立東中学校":{"tags":{"name":"市立東中学校","amenity":"school"},"name":"市立東中学校","icon":"school","geometry":["point","area"],"fields":["name","operator","address"],"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}};
23656
23657 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"]};
23658
23659 var categories = {"category-barrier":{"icon":"roadblock","geometry":"line","name":"Barrier Features","members":["barrier/fence","barrier/wall","barrier/ditch","barrier/gate","barrier/hedge","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"]}};
23660
23661 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"}}}};
23662
23663 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"];
23664 var all$1 = {
23665         all: all
23666 };
23667
23668 var all$2 = Object.freeze({
23669         all: all,
23670         default: all$1
23671 });
23672
23673 var Airport = ["airfield","airport","heliport","rocket"];
23674 var Dining = ["bakery","bar","beer","cafe","fast-food","ice-cream","restaurant"];
23675 var Education = ["college","school"];
23676 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"];
23677 var Health = ["dentist","doctor","hospital","pharmacy"];
23678 var Outdoors = ["campsite","cemetery","dog-park","garden","golf","park","picnic-site","playground","zoo"];
23679 var Transit = ["bus","ferry"];
23680 var streets = {
23681         Airport: Airport,
23682         Dining: Dining,
23683         Education: Education,
23684         General: General,
23685         Health: Health,
23686         Outdoors: Outdoors,
23687         Transit: Transit,
23688         "Mountain peak": ["mountain","volcano"],
23689         "Rail station": ["entrance","rail","rail-light","rail-metro"]
23690 };
23691
23692 var streets$1 = Object.freeze({
23693         Airport: Airport,
23694         Dining: Dining,
23695         Education: Education,
23696         General: General,
23697         Health: Health,
23698         Outdoors: Outdoors,
23699         Transit: Transit,
23700         default: streets
23701 });
23702
23703 var require$$0$1 = ( all$2 && all$1 ) || all$2;
23704
23705 var require$$1$1 = ( streets$1 && streets ) || streets$1;
23706
23707 var maki = {
23708   layouts: {
23709     all: require$$0$1,
23710     streets: require$$1$1
23711   }
23712 };
23713
23714 var dataFeatureIcons = maki.layouts.all.all;
23715
23716 var data = {
23717     imagery: dataImagery,
23718     presets: {
23719         presets: presets,
23720         defaults: defaults,
23721         categories: categories,
23722         fields: fields
23723     }
23724 };
23725
23726 function osmEntity(attrs) {
23727     // For prototypal inheritance.
23728     if (this instanceof osmEntity) return;
23729
23730     // Create the appropriate subtype.
23731     if (attrs && attrs.type) {
23732         return osmEntity[attrs.type].apply(this, arguments);
23733     } else if (attrs && attrs.id) {
23734         return osmEntity[osmEntity.id.type(attrs.id)].apply(this, arguments);
23735     }
23736
23737     // Initialize a generic Entity (used only in tests).
23738     return (new osmEntity()).initialize(arguments);
23739 }
23740
23741
23742 osmEntity.id = function(type) {
23743     return osmEntity.id.fromOSM(type, osmEntity.id.next[type]--);
23744 };
23745
23746
23747 osmEntity.id.next = {
23748     changeset: -1, node: -1, way: -1, relation: -1
23749 };
23750
23751
23752 osmEntity.id.fromOSM = function(type, id) {
23753     return type[0] + id;
23754 };
23755
23756
23757 osmEntity.id.toOSM = function(id) {
23758     return id.slice(1);
23759 };
23760
23761
23762 osmEntity.id.type = function(id) {
23763     return { 'c': 'changeset', 'n': 'node', 'w': 'way', 'r': 'relation' }[id[0]];
23764 };
23765
23766
23767 // A function suitable for use as the second argument to d3.selection#data().
23768 osmEntity.key = function(entity) {
23769     return entity.id + 'v' + (entity.v || 0);
23770 };
23771
23772
23773 osmEntity.prototype = {
23774
23775     tags: {},
23776
23777
23778     initialize: function(sources) {
23779         for (var i = 0; i < sources.length; ++i) {
23780             var source = sources[i];
23781             for (var prop in source) {
23782                 if (Object.prototype.hasOwnProperty.call(source, prop)) {
23783                     if (source[prop] === undefined) {
23784                         delete this[prop];
23785                     } else {
23786                         this[prop] = source[prop];
23787                     }
23788                 }
23789             }
23790         }
23791
23792         if (!this.id && this.type) {
23793             this.id = osmEntity.id(this.type);
23794         }
23795         if (!this.hasOwnProperty('visible')) {
23796             this.visible = true;
23797         }
23798
23799         if (debug) {
23800             Object.freeze(this);
23801             Object.freeze(this.tags);
23802
23803             if (this.loc) Object.freeze(this.loc);
23804             if (this.nodes) Object.freeze(this.nodes);
23805             if (this.members) Object.freeze(this.members);
23806         }
23807
23808         return this;
23809     },
23810
23811
23812     copy: function(resolver, copies) {
23813         if (copies[this.id])
23814             return copies[this.id];
23815
23816         var copy = osmEntity(this, {id: undefined, user: undefined, version: undefined});
23817         copies[this.id] = copy;
23818
23819         return copy;
23820     },
23821
23822
23823     osmId: function() {
23824         return osmEntity.id.toOSM(this.id);
23825     },
23826
23827
23828     isNew: function() {
23829         return this.osmId() < 0;
23830     },
23831
23832
23833     update: function(attrs) {
23834         return osmEntity(this, attrs, {v: 1 + (this.v || 0)});
23835     },
23836
23837
23838     mergeTags: function(tags) {
23839         var merged = clone(this.tags), changed = false;
23840         for (var k in tags) {
23841             var t1 = merged[k],
23842                 t2 = tags[k];
23843             if (!t1) {
23844                 changed = true;
23845                 merged[k] = t2;
23846             } else if (t1 !== t2) {
23847                 changed = true;
23848                 merged[k] = union(t1.split(/;\s*/), t2.split(/;\s*/)).join(';');
23849             }
23850         }
23851         return changed ? this.update({tags: merged}) : this;
23852     },
23853
23854
23855     intersects: function(extent, resolver) {
23856         return this.extent(resolver).intersects(extent);
23857     },
23858
23859
23860     isUsed: function(resolver) {
23861         return without(Object.keys(this.tags), 'area').length > 0 ||
23862             resolver.parentRelations(this).length > 0;
23863     },
23864
23865
23866     hasInterestingTags: function() {
23867         return keys$1(this.tags).some(osmIsInterestingTag);
23868     },
23869
23870
23871     isHighwayIntersection: function() {
23872         return false;
23873     },
23874
23875     isDegenerate: function() {
23876         return true;
23877     },
23878
23879     deprecatedTags: function() {
23880         var tags = toPairs(this.tags);
23881         var deprecated = {};
23882
23883         dataDeprecated.forEach(function(d) {
23884             var match = toPairs(d.old)[0];
23885             tags.forEach(function(t) {
23886                 if (t[0] === match[0] &&
23887                     (t[1] === match[1] || match[1] === '*')) {
23888                     deprecated[t[0]] = t[1];
23889                 }
23890             });
23891         });
23892
23893         return deprecated;
23894     }
23895 };
23896
23897 function geoExtent(min, max) {
23898     if (!(this instanceof geoExtent)) return new geoExtent(min, max);
23899     if (min instanceof geoExtent) {
23900         return min;
23901     } else if (min && min.length === 2 && min[0].length === 2 && min[1].length === 2) {
23902         this[0] = min[0];
23903         this[1] = min[1];
23904     } else {
23905         this[0] = min        || [ Infinity,  Infinity];
23906         this[1] = max || min || [-Infinity, -Infinity];
23907     }
23908 }
23909
23910 geoExtent.prototype = new Array(2);
23911
23912 assignIn(geoExtent.prototype, {
23913
23914     equals: function (obj) {
23915         return this[0][0] === obj[0][0] &&
23916             this[0][1] === obj[0][1] &&
23917             this[1][0] === obj[1][0] &&
23918             this[1][1] === obj[1][1];
23919     },
23920
23921
23922     extend: function(obj) {
23923         if (!(obj instanceof geoExtent)) obj = new geoExtent(obj);
23924         return geoExtent(
23925             [Math.min(obj[0][0], this[0][0]), Math.min(obj[0][1], this[0][1])],
23926             [Math.max(obj[1][0], this[1][0]), Math.max(obj[1][1], this[1][1])]
23927         );
23928     },
23929
23930
23931     _extend: function(extent) {
23932         this[0][0] = Math.min(extent[0][0], this[0][0]);
23933         this[0][1] = Math.min(extent[0][1], this[0][1]);
23934         this[1][0] = Math.max(extent[1][0], this[1][0]);
23935         this[1][1] = Math.max(extent[1][1], this[1][1]);
23936     },
23937
23938
23939     area: function() {
23940         return Math.abs((this[1][0] - this[0][0]) * (this[1][1] - this[0][1]));
23941     },
23942
23943
23944     center: function() {
23945         return [(this[0][0] + this[1][0]) / 2,
23946                 (this[0][1] + this[1][1]) / 2];
23947     },
23948
23949
23950     rectangle: function() {
23951         return [this[0][0], this[0][1], this[1][0], this[1][1]];
23952     },
23953
23954
23955     bbox: function() {
23956         return { minX: this[0][0], minY: this[0][1], maxX: this[1][0], maxY: this[1][1] };
23957     },
23958
23959
23960     polygon: function() {
23961         return [
23962             [this[0][0], this[0][1]],
23963             [this[0][0], this[1][1]],
23964             [this[1][0], this[1][1]],
23965             [this[1][0], this[0][1]],
23966             [this[0][0], this[0][1]]
23967         ];
23968     },
23969
23970
23971     contains: function(obj) {
23972         if (!(obj instanceof geoExtent)) obj = new geoExtent(obj);
23973         return obj[0][0] >= this[0][0] &&
23974                obj[0][1] >= this[0][1] &&
23975                obj[1][0] <= this[1][0] &&
23976                obj[1][1] <= this[1][1];
23977     },
23978
23979
23980     intersects: function(obj) {
23981         if (!(obj instanceof geoExtent)) obj = new geoExtent(obj);
23982         return obj[0][0] <= this[1][0] &&
23983                obj[0][1] <= this[1][1] &&
23984                obj[1][0] >= this[0][0] &&
23985                obj[1][1] >= this[0][1];
23986     },
23987
23988
23989     intersection: function(obj) {
23990         if (!this.intersects(obj)) return new geoExtent();
23991         return new geoExtent(
23992             [Math.max(obj[0][0], this[0][0]), Math.max(obj[0][1], this[0][1])],
23993             [Math.min(obj[1][0], this[1][0]), Math.min(obj[1][1], this[1][1])]
23994         );
23995     },
23996
23997
23998     percentContainedIn: function(obj) {
23999         if (!(obj instanceof geoExtent)) obj = new geoExtent(obj);
24000         var a1 = this.intersection(obj).area(),
24001             a2 = this.area();
24002
24003         if (a1 === Infinity || a2 === Infinity || a1 === 0 || a2 === 0) {
24004             return 0;
24005         } else {
24006             return a1 / a2;
24007         }
24008     },
24009
24010
24011     padByMeters: function(meters) {
24012         var dLat = geoMetersToLat(meters),
24013             dLon = geoMetersToLon(meters, this.center()[1]);
24014         return geoExtent(
24015             [this[0][0] - dLon, this[0][1] - dLat],
24016             [this[1][0] + dLon, this[1][1] + dLat]
24017         );
24018     },
24019
24020
24021     toParam: function() {
24022         return this.rectangle().join(',');
24023     }
24024
24025 });
24026
24027 // constants
24028 var TAU = 2 * Math.PI;
24029 var EQUATORIAL_RADIUS = 6356752.314245179;
24030 var POLAR_RADIUS = 6378137.0;
24031
24032
24033 function geoLatToMeters(dLat) {
24034     return dLat * (TAU * POLAR_RADIUS / 360);
24035 }
24036
24037
24038 function geoLonToMeters(dLon, atLat) {
24039     return Math.abs(atLat) >= 90 ? 0 :
24040         dLon * (TAU * EQUATORIAL_RADIUS / 360) * Math.abs(Math.cos(atLat * (Math.PI / 180)));
24041 }
24042
24043
24044 function geoMetersToLat(m) {
24045     return m / (TAU * POLAR_RADIUS / 360);
24046 }
24047
24048
24049 function geoMetersToLon(m, atLat) {
24050     return Math.abs(atLat) >= 90 ? 0 :
24051         m / (TAU * EQUATORIAL_RADIUS / 360) / Math.abs(Math.cos(atLat * (Math.PI / 180)));
24052 }
24053
24054
24055 function geoMetersToOffset(meters, tileSize) {
24056     tileSize = tileSize || 256;
24057     return [
24058         meters[0] * tileSize / (TAU * EQUATORIAL_RADIUS),
24059         -meters[1] * tileSize / (TAU * POLAR_RADIUS)
24060     ];
24061 }
24062
24063
24064 function geoOffsetToMeters(offset, tileSize) {
24065     tileSize = tileSize || 256;
24066     return [
24067         offset[0] * TAU * EQUATORIAL_RADIUS / tileSize,
24068         -offset[1] * TAU * POLAR_RADIUS / tileSize
24069     ];
24070 }
24071
24072
24073 // Equirectangular approximation of spherical distances on Earth
24074 function geoSphericalDistance(a, b) {
24075     var x = geoLonToMeters(a[0] - b[0], (a[1] + b[1]) / 2);
24076     var y = geoLatToMeters(a[1] - b[1]);
24077     return Math.sqrt((x * x) + (y * y));
24078 }
24079
24080
24081 // scale to zoom
24082 function geoScaleToZoom(k, tileSize) {
24083     tileSize = tileSize || 256;
24084     var log2ts = Math.log(tileSize) * Math.LOG2E;
24085     return Math.log(k * TAU) / Math.LN2 - log2ts;
24086 }
24087
24088
24089 // zoom to scale
24090 function geoZoomToScale(z, tileSize) {
24091     tileSize = tileSize || 256;
24092     return tileSize * Math.pow(2, z) / TAU;
24093 }
24094
24095 /**
24096  * A specialized version of `_.every` for arrays without support for
24097  * iteratee shorthands.
24098  *
24099  * @private
24100  * @param {Array} [array] The array to iterate over.
24101  * @param {Function} predicate The function invoked per iteration.
24102  * @returns {boolean} Returns `true` if all elements pass the predicate check,
24103  *  else `false`.
24104  */
24105 function arrayEvery(array, predicate) {
24106   var index = -1,
24107       length = array == null ? 0 : array.length;
24108
24109   while (++index < length) {
24110     if (!predicate(array[index], index, array)) {
24111       return false;
24112     }
24113   }
24114   return true;
24115 }
24116
24117 /**
24118  * The base implementation of `_.every` without support for iteratee shorthands.
24119  *
24120  * @private
24121  * @param {Array|Object} collection The collection to iterate over.
24122  * @param {Function} predicate The function invoked per iteration.
24123  * @returns {boolean} Returns `true` if all elements pass the predicate check,
24124  *  else `false`
24125  */
24126 function baseEvery(collection, predicate) {
24127   var result = true;
24128   baseEach(collection, function(value, index, collection) {
24129     result = !!predicate(value, index, collection);
24130     return result;
24131   });
24132   return result;
24133 }
24134
24135 /**
24136  * Checks if `predicate` returns truthy for **all** elements of `collection`.
24137  * Iteration is stopped once `predicate` returns falsey. The predicate is
24138  * invoked with three arguments: (value, index|key, collection).
24139  *
24140  * **Note:** This method returns `true` for
24141  * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
24142  * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
24143  * elements of empty collections.
24144  *
24145  * @static
24146  * @memberOf _
24147  * @since 0.1.0
24148  * @category Collection
24149  * @param {Array|Object} collection The collection to iterate over.
24150  * @param {Function} [predicate=_.identity] The function invoked per iteration.
24151  * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
24152  * @returns {boolean} Returns `true` if all elements pass the predicate check,
24153  *  else `false`.
24154  * @example
24155  *
24156  * _.every([true, 1, null, 'yes'], Boolean);
24157  * // => false
24158  *
24159  * var users = [
24160  *   { 'user': 'barney', 'age': 36, 'active': false },
24161  *   { 'user': 'fred',   'age': 40, 'active': false }
24162  * ];
24163  *
24164  * // The `_.matches` iteratee shorthand.
24165  * _.every(users, { 'user': 'barney', 'active': false });
24166  * // => false
24167  *
24168  * // The `_.matchesProperty` iteratee shorthand.
24169  * _.every(users, ['active', false]);
24170  * // => true
24171  *
24172  * // The `_.property` iteratee shorthand.
24173  * _.every(users, 'active');
24174  * // => false
24175  */
24176 function every(collection, predicate, guard) {
24177   var func = isArray(collection) ? arrayEvery : baseEvery;
24178   if (guard && isIterateeCall(collection, predicate, guard)) {
24179     predicate = undefined;
24180   }
24181   return func(collection, baseIteratee(predicate, 3));
24182 }
24183
24184 /**
24185  * The base implementation of `_.some` without support for iteratee shorthands.
24186  *
24187  * @private
24188  * @param {Array|Object} collection The collection to iterate over.
24189  * @param {Function} predicate The function invoked per iteration.
24190  * @returns {boolean} Returns `true` if any element passes the predicate check,
24191  *  else `false`.
24192  */
24193 function baseSome(collection, predicate) {
24194   var result;
24195
24196   baseEach(collection, function(value, index, collection) {
24197     result = predicate(value, index, collection);
24198     return !result;
24199   });
24200   return !!result;
24201 }
24202
24203 /**
24204  * Checks if `predicate` returns truthy for **any** element of `collection`.
24205  * Iteration is stopped once `predicate` returns truthy. The predicate is
24206  * invoked with three arguments: (value, index|key, collection).
24207  *
24208  * @static
24209  * @memberOf _
24210  * @since 0.1.0
24211  * @category Collection
24212  * @param {Array|Object} collection The collection to iterate over.
24213  * @param {Function} [predicate=_.identity] The function invoked per iteration.
24214  * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
24215  * @returns {boolean} Returns `true` if any element passes the predicate check,
24216  *  else `false`.
24217  * @example
24218  *
24219  * _.some([null, 0, 'yes', false], Boolean);
24220  * // => true
24221  *
24222  * var users = [
24223  *   { 'user': 'barney', 'active': true },
24224  *   { 'user': 'fred',   'active': false }
24225  * ];
24226  *
24227  * // The `_.matches` iteratee shorthand.
24228  * _.some(users, { 'user': 'barney', 'active': false });
24229  * // => false
24230  *
24231  * // The `_.matchesProperty` iteratee shorthand.
24232  * _.some(users, ['active', false]);
24233  * // => true
24234  *
24235  * // The `_.property` iteratee shorthand.
24236  * _.some(users, 'active');
24237  * // => true
24238  */
24239 function some(collection, predicate, guard) {
24240   var func = isArray(collection) ? arraySome : baseSome;
24241   if (guard && isIterateeCall(collection, predicate, guard)) {
24242     predicate = undefined;
24243   }
24244   return func(collection, baseIteratee(predicate, 3));
24245 }
24246
24247 // vector equals
24248 function geoVecEqual(a, b, epsilon) {
24249     if (epsilon) {
24250         return (Math.abs(a[0] - b[0]) <= epsilon) && (Math.abs(a[1] - b[1]) <= epsilon);
24251     } else {
24252         return (a[0] === b[0]) && (a[1] === b[1]);
24253     }
24254 }
24255
24256 // vector addition
24257 function geoVecAdd(a, b) {
24258     return [ a[0] + b[0], a[1] + b[1] ];
24259 }
24260
24261 // vector subtraction
24262 function geoVecSubtract(a, b) {
24263     return [ a[0] - b[0], a[1] - b[1] ];
24264 }
24265
24266 // vector scaling
24267 function geoVecScale(a, mag) {
24268     return [ a[0] * mag, a[1] * mag ];
24269 }
24270
24271 // vector rounding (was: geoRoundCoordinates)
24272 function geoVecFloor(a) {
24273     return [ Math.floor(a[0]), Math.floor(a[1]) ];
24274 }
24275
24276 // linear interpolation
24277 function geoVecInterp(a, b, t) {
24278     return [
24279         a[0] + (b[0] - a[0]) * t,
24280         a[1] + (b[1] - a[1]) * t
24281     ];
24282 }
24283
24284 // http://jsperf.com/id-dist-optimization
24285 function geoVecLength(a, b) {
24286     var x = a[0] - b[0];
24287     var y = a[1] - b[1];
24288     return Math.sqrt((x * x) + (y * y));
24289 }
24290
24291 // Return the counterclockwise angle in the range (-pi, pi)
24292 // between the positive X axis and the line intersecting a and b.
24293 function geoVecAngle(a, b) {
24294     return Math.atan2(b[1] - a[1], b[0] - a[0]);
24295 }
24296
24297 // dot product
24298 function geoVecDot(a, b, origin) {
24299     origin = origin || [0, 0];
24300     return (a[0] - origin[0]) * (b[0] - origin[0]) +
24301         (a[1] - origin[1]) * (b[1] - origin[1]);
24302 }
24303
24304 // 2D cross product of OA and OB vectors, returns magnitude of Z vector
24305 // Returns a positive value, if OAB makes a counter-clockwise turn,
24306 // negative for clockwise turn, and zero if the points are collinear.
24307 function geoVecCross(a, b, origin) {
24308     origin = origin || [0, 0];
24309     return (a[0] - origin[0]) * (b[1] - origin[1]) -
24310         (a[1] - origin[1]) * (b[0] - origin[0]);
24311 }
24312
24313 // Return the counterclockwise angle in the range (-pi, pi)
24314 // between the positive X axis and the line intersecting a and b.
24315 function geoAngle(a, b, projection) {
24316     return geoVecAngle(projection(a.loc), projection(b.loc));
24317 }
24318
24319 function geoEdgeEqual(a, b) {
24320     return (a[0] === b[0] && a[1] === b[1]) ||
24321         (a[0] === b[1] && a[1] === b[0]);
24322 }
24323
24324 // Rotate all points counterclockwise around a pivot point by given angle
24325 function geoRotate(points, angle, around) {
24326     return points.map(function(point) {
24327         var radial = geoVecSubtract(point, around);
24328         return [
24329             radial[0] * Math.cos(angle) - radial[1] * Math.sin(angle) + around[0],
24330             radial[0] * Math.sin(angle) + radial[1] * Math.cos(angle) + around[1]
24331         ];
24332     });
24333 }
24334
24335
24336 // Choose the edge with the minimal distance from `point` to its orthogonal
24337 // projection onto that edge, if such a projection exists, or the distance to
24338 // the closest vertex on that edge. Returns an object with the `index` of the
24339 // chosen edge, the chosen `loc` on that edge, and the `distance` to to it.
24340 function geoChooseEdge(nodes, point, projection, activeID) {
24341     var dist = geoVecLength;
24342     var points = nodes.map(function(n) { return projection(n.loc); });
24343     var ids = nodes.map(function(n) { return n.id; });
24344     var min = Infinity;
24345     var idx;
24346     var loc;
24347
24348     for (var i = 0; i < points.length - 1; i++) {
24349         if (ids[i] === activeID || ids[i + 1] === activeID) continue;
24350
24351         var o = points[i];
24352         var s = geoVecSubtract(points[i + 1], o);
24353         var v = geoVecSubtract(point, o);
24354         var proj = geoVecDot(v, s) / geoVecDot(s, s);
24355         var p;
24356
24357         if (proj < 0) {
24358             p = o;
24359         } else if (proj > 1) {
24360             p = points[i + 1];
24361         } else {
24362             p = [o[0] + proj * s[0], o[1] + proj * s[1]];
24363         }
24364
24365         var d = dist(p, point);
24366         if (d < min) {
24367             min = d;
24368             idx = i + 1;
24369             loc = projection.invert(p);
24370         }
24371     }
24372
24373     if (idx !== undefined) {
24374         return { index: idx, distance: min, loc: loc };
24375     } else {
24376         return null;
24377     }
24378 }
24379
24380
24381 // check active (dragged or drawing) segments against inactive segments
24382 function geoHasSelfIntersections(nodes, activeID) {
24383     var actives = [];
24384     var inactives = [];
24385     var j, k;
24386
24387     for (j = 0; j < nodes.length - 1; j++) {
24388         var n1 = nodes[j];
24389         var n2 = nodes[j+1];
24390         var segment = [n1.loc, n2.loc];
24391         if (n1.id === activeID || n2.id === activeID) {
24392             actives.push(segment);
24393         } else {
24394             inactives.push(segment);
24395         }
24396     }
24397
24398     for (j = 0; j < actives.length; j++) {
24399         for (k = 0; k < inactives.length; k++) {
24400             var p = actives[j];
24401             var q = inactives[k];
24402             // skip if segments share an endpoint
24403             if (geoVecEqual(p[1], q[0]) || geoVecEqual(p[0], q[1]) ||
24404                 geoVecEqual(p[0], q[0]) || geoVecEqual(p[1], q[1]) ) {
24405                 continue;
24406             }
24407
24408             var hit = geoLineIntersection(p, q);
24409             if (hit) {
24410                 var epsilon = 1e-8;
24411                 // skip if the hit is at the segment's endpoint
24412                 if (geoVecEqual(p[1], hit, epsilon) || geoVecEqual(p[0], hit, epsilon) ||
24413                     geoVecEqual(q[1], hit, epsilon) || geoVecEqual(q[0], hit, epsilon) ) {
24414                     continue;
24415                 } else {
24416                     return true;
24417                 }
24418             }
24419         }
24420     }
24421
24422     return false;
24423 }
24424
24425
24426 // Return the intersection point of 2 line segments.
24427 // From https://github.com/pgkelley4/line-segments-intersect
24428 // This uses the vector cross product approach described below:
24429 //  http://stackoverflow.com/a/565282/786339
24430 function geoLineIntersection(a, b) {
24431     var p = [a[0][0], a[0][1]];
24432     var p2 = [a[1][0], a[1][1]];
24433     var q = [b[0][0], b[0][1]];
24434     var q2 = [b[1][0], b[1][1]];
24435     var r = geoVecSubtract(p2, p);
24436     var s = geoVecSubtract(q2, q);
24437     var uNumerator = geoVecCross(geoVecSubtract(q, p), r);
24438     var denominator = geoVecCross(r, s);
24439
24440     if (uNumerator && denominator) {
24441         var u = uNumerator / denominator;
24442         var t = geoVecCross(geoVecSubtract(q, p), s) / denominator;
24443
24444         if ((t >= 0) && (t <= 1) && (u >= 0) && (u <= 1)) {
24445             return geoVecInterp(p, p2, t);
24446         }
24447     }
24448
24449     return null;
24450 }
24451
24452
24453 function geoPathIntersections(path1, path2) {
24454     var intersections = [];
24455     for (var i = 0; i < path1.length - 1; i++) {
24456         for (var j = 0; j < path2.length - 1; j++) {
24457             var a = [ path1[i], path1[i+1] ];
24458             var b = [ path2[j], path2[j+1] ];
24459             var hit = geoLineIntersection(a, b);
24460             if (hit) {
24461                 intersections.push(hit);
24462             }
24463         }
24464     }
24465     return intersections;
24466 }
24467
24468 function geoPathHasIntersections(path1, path2) {
24469     for (var i = 0; i < path1.length - 1; i++) {
24470         for (var j = 0; j < path2.length - 1; j++) {
24471             var a = [ path1[i], path1[i+1] ];
24472             var b = [ path2[j], path2[j+1] ];
24473             var hit = geoLineIntersection(a, b);
24474             if (hit) {
24475                 return true;
24476             }
24477         }
24478     }
24479     return false;
24480 }
24481
24482
24483 // Return whether point is contained in polygon.
24484 //
24485 // `point` should be a 2-item array of coordinates.
24486 // `polygon` should be an array of 2-item arrays of coordinates.
24487 //
24488 // From https://github.com/substack/point-in-polygon.
24489 // ray-casting algorithm based on
24490 // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
24491 //
24492 function geoPointInPolygon(point, polygon) {
24493     var x = point[0];
24494     var y = point[1];
24495     var inside = false;
24496
24497     for (var i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
24498         var xi = polygon[i][0];
24499         var yi = polygon[i][1];
24500         var xj = polygon[j][0];
24501         var yj = polygon[j][1];
24502
24503         var intersect = ((yi > y) !== (yj > y)) &&
24504             (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
24505         if (intersect) inside = !inside;
24506     }
24507
24508     return inside;
24509 }
24510
24511
24512 function geoPolygonContainsPolygon(outer, inner) {
24513     return every(inner, function(point) {
24514         return geoPointInPolygon(point, outer);
24515     });
24516 }
24517
24518
24519 function geoPolygonIntersectsPolygon(outer, inner, checkSegments) {
24520     function testPoints(outer, inner) {
24521         return some(inner, function(point) {
24522             return geoPointInPolygon(point, outer);
24523         });
24524     }
24525
24526    return testPoints(outer, inner) || (!!checkSegments && geoPathHasIntersections(outer, inner));
24527 }
24528
24529
24530 function geoPathLength(path) {
24531     var length = 0;
24532     for (var i = 0; i < path.length - 1; i++) {
24533         length += geoVecLength(path[i], path[i + 1]);
24534     }
24535     return length;
24536 }
24537
24538
24539 // If the given point is at the edge of the padded viewport,
24540 // return a vector that will nudge the viewport in that direction
24541 function geoViewportEdge(point, dimensions) {
24542     var pad = [80, 20, 50, 20];   // top, right, bottom, left
24543     var x = 0;
24544     var y = 0;
24545
24546     if (point[0] > dimensions[0] - pad[1])
24547         x = -10;
24548     if (point[0] < pad[3])
24549         x = 10;
24550     if (point[1] > dimensions[1] - pad[2])
24551         y = -10;
24552     if (point[1] < pad[0])
24553         y = 10;
24554
24555     if (x || y) {
24556         return [x, y];
24557     } else {
24558         return null;
24559     }
24560 }
24561
24562 /*
24563     Bypasses features of D3's default projection stream pipeline that are unnecessary:
24564     * Antimeridian clipping
24565     * Spherical rotation
24566     * Resampling
24567 */
24568 function geoRawMercator() {
24569     var project = mercatorRaw,
24570         k = 512 / Math.PI, // scale
24571         x = 0, y = 0, // translate
24572         clipExtent = [[0, 0], [0, 0]];
24573
24574
24575     function projection(point) {
24576         point = project(point[0] * Math.PI / 180, point[1] * Math.PI / 180);
24577         return [point[0] * k + x, y - point[1] * k];
24578     }
24579
24580
24581     projection.invert = function(point) {
24582         point = project.invert((point[0] - x) / k, (y - point[1]) / k);
24583         return point && [point[0] * 180 / Math.PI, point[1] * 180 / Math.PI];
24584     };
24585
24586
24587     projection.scale = function(_) {
24588         if (!arguments.length) return k;
24589         k = +_;
24590         return projection;
24591     };
24592
24593
24594     projection.translate = function(_) {
24595         if (!arguments.length) return [x, y];
24596         x = +_[0];
24597         y = +_[1];
24598         return projection;
24599     };
24600
24601
24602     projection.clipExtent = function(_) {
24603         if (!arguments.length) return clipExtent;
24604         clipExtent = _;
24605         return projection;
24606     };
24607
24608
24609     projection.transform = function(_) {
24610         if (!arguments.length) return identity$7.translate(x, y).scale(k);
24611         x = +_.x;
24612         y = +_.y;
24613         k = +_.k;
24614         return projection;
24615     };
24616
24617
24618     projection.stream = d3_geoTransform({
24619         point: function(x, y) {
24620             x = projection([x, y]);
24621             this.stream.point(x[0], x[1]);
24622         }
24623     }).stream;
24624
24625
24626     return projection;
24627 }
24628
24629 function osmChangeset() {
24630     if (!(this instanceof osmChangeset)) {
24631         return (new osmChangeset()).initialize(arguments);
24632     } else if (arguments.length) {
24633         this.initialize(arguments);
24634     }
24635 }
24636
24637
24638 osmEntity.changeset = osmChangeset;
24639
24640 osmChangeset.prototype = Object.create(osmEntity.prototype);
24641
24642 assignIn(osmChangeset.prototype, {
24643
24644     type: 'changeset',
24645
24646
24647     extent: function() {
24648         return new geoExtent();
24649     },
24650
24651
24652     geometry: function() {
24653         return 'changeset';
24654     },
24655
24656
24657     asJXON: function() {
24658         return {
24659             osm: {
24660                 changeset: {
24661                     tag: map$4(this.tags, function(value, key) {
24662                         return { '@k': key, '@v': value };
24663                     }),
24664                     '@version': 0.6,
24665                     '@generator': 'iD'
24666                 }
24667             }
24668         };
24669     },
24670
24671
24672     // Generate [osmChange](http://wiki.openstreetmap.org/wiki/OsmChange)
24673     // XML. Returns a string.
24674     osmChangeJXON: function(changes) {
24675         var changeset_id = this.id;
24676
24677         function nest(x, order) {
24678             var groups = {};
24679             for (var i = 0; i < x.length; i++) {
24680                 var tagName = Object.keys(x[i])[0];
24681                 if (!groups[tagName]) groups[tagName] = [];
24682                 groups[tagName].push(x[i][tagName]);
24683             }
24684             var ordered = {};
24685             order.forEach(function(o) {
24686                 if (groups[o]) ordered[o] = groups[o];
24687             });
24688             return ordered;
24689         }
24690
24691
24692         // sort relations in a changeset by dependencies
24693         function sort(changes) {
24694
24695             // find a referenced relation in the current changeset
24696             function resolve(item) {
24697                 return find$1(relations, function(relation) {
24698                     return item.keyAttributes.type === 'relation'
24699                         && item.keyAttributes.ref === relation['@id'];
24700                 });
24701             }
24702
24703             // a new item is an item that has not been already processed
24704             function isNew(item) {
24705                 return !sorted[ item['@id'] ] && !find$1(processing, function(proc) {
24706                     return proc['@id'] === item['@id'];
24707                 });
24708             }
24709
24710             var processing = [],
24711                 sorted = {},
24712                 relations = changes.relation;
24713
24714             if (!relations) return changes;
24715
24716             for (var i = 0; i < relations.length; i++) {
24717                 var relation = relations[i];
24718
24719                 // skip relation if already sorted
24720                 if (!sorted[relation['@id']]) {
24721                     processing.push(relation);
24722                 }
24723
24724                 while (processing.length > 0) {
24725                     var next = processing[0],
24726                     deps = filter(compact(next.member.map(resolve)), isNew);
24727                     if (deps.length === 0) {
24728                         sorted[next['@id']] = next;
24729                         processing.shift();
24730                     } else {
24731                         processing = deps.concat(processing);
24732                     }
24733                 }
24734             }
24735
24736             changes.relation = values$1(sorted);
24737             return changes;
24738         }
24739
24740         function rep(entity) {
24741             return entity.asJXON(changeset_id);
24742         }
24743
24744         return {
24745             osmChange: {
24746                 '@version': 0.6,
24747                 '@generator': 'iD',
24748                 'create': sort(nest(changes.created.map(rep), ['node', 'way', 'relation'])),
24749                 'modify': nest(changes.modified.map(rep), ['node', 'way', 'relation']),
24750                 'delete': assignIn(nest(changes.deleted.map(rep), ['relation', 'way', 'node']), { '@if-unused': true })
24751             }
24752         };
24753     },
24754
24755
24756     asGeoJSON: function() {
24757         return {};
24758     }
24759
24760 });
24761
24762 function osmNode() {
24763     if (!(this instanceof osmNode)) {
24764         return (new osmNode()).initialize(arguments);
24765     } else if (arguments.length) {
24766         this.initialize(arguments);
24767     }
24768 }
24769
24770 osmEntity.node = osmNode;
24771
24772 osmNode.prototype = Object.create(osmEntity.prototype);
24773
24774 assignIn(osmNode.prototype, {
24775
24776     type: 'node',
24777
24778
24779     extent: function() {
24780         return new geoExtent(this.loc);
24781     },
24782
24783
24784     geometry: function(graph) {
24785         return graph.transient(this, 'geometry', function() {
24786             return graph.isPoi(this) ? 'point' : 'vertex';
24787         });
24788     },
24789
24790
24791     move: function(loc) {
24792         return this.update({loc: loc});
24793     },
24794
24795
24796     isDegenerate: function() {
24797         return !(
24798             Array.isArray(this.loc) && this.loc.length === 2 &&
24799             this.loc[0] >= -180 && this.loc[0] <= 180 &&
24800             this.loc[1] >= -90 && this.loc[1] <= 90
24801         );
24802     },
24803
24804
24805     // Inspect tags and geometry to determine which direction(s) this node/vertex points
24806     directions: function(resolver, projection) {
24807         var val;
24808         var i;
24809
24810         // which tag to use?
24811         if (this.isHighwayIntersection(resolver) && (this.tags.stop || '').toLowerCase() === 'all') {
24812             // all-way stop tag on a highway intersection
24813             val = 'all';
24814         } else {
24815             // generic direction tag
24816             val = (this.tags.direction || '').toLowerCase();
24817
24818             // better suffix-style direction tag
24819             var re = /:direction$/i;
24820             var keys = Object.keys(this.tags);
24821             for (i = 0; i < keys.length; i++) {
24822                 if (re.test(keys[i])) {
24823                     val = this.tags[keys[i]].toLowerCase();
24824                     break;
24825                 }
24826             }
24827         }
24828
24829         // swap cardinal for numeric directions
24830         var cardinal = {
24831             north: 0,               n: 0,
24832             northnortheast: 22,     nne: 22,
24833             northeast: 45,          ne: 45,
24834             eastnortheast: 67,      ene: 67,
24835             east: 90,               e: 90,
24836             eastsoutheast: 112,     ese: 112,
24837             southeast: 135,         se: 135,
24838             southsoutheast: 157,    sse: 157,
24839             south: 180,             s: 180,
24840             southsouthwest: 202,    ssw: 202,
24841             southwest: 225,         sw: 225,
24842             westsouthwest: 247,     wsw: 247,
24843             west: 270,              w: 270,
24844             westnorthwest: 292,     wnw: 292,
24845             northwest: 315,         nw: 315,
24846             northnorthwest: 337,    nnw: 337
24847         };
24848         if (cardinal[val] !== undefined) {
24849             val = cardinal[val];
24850         }
24851
24852         // if direction is numeric, return early
24853         if (val !== '' && !isNaN(+val)) {
24854             return [(+val)];
24855         }
24856
24857         var lookBackward =
24858             (this.tags['traffic_sign:backward'] || val === 'backward' || val === 'both' || val === 'all');
24859         var lookForward =
24860             (this.tags['traffic_sign:forward'] || val === 'forward' || val === 'both' || val === 'all');
24861
24862         if (!lookForward && !lookBackward) return [];
24863
24864         var nodeIds = {};
24865         resolver.parentWays(this).forEach(function(parent) {
24866             var nodes = parent.nodes;
24867             for (i = 0; i < nodes.length; i++) {
24868                 if (nodes[i] === this.id) {  // match current entity
24869                     if (lookForward && i > 0) {
24870                         nodeIds[nodes[i - 1]] = true;  // look back to prev node
24871                     }
24872                     if (lookBackward && i < nodes.length - 1) {
24873                         nodeIds[nodes[i + 1]] = true;  // look ahead to next node
24874                     }
24875                 }
24876             }
24877         }, this);
24878
24879         return Object.keys(nodeIds).map(function(nodeId) {
24880             // +90 because geoAngle returns angle from X axis, not Y (north)
24881             return (geoAngle(this, resolver.entity(nodeId), projection) * (180 / Math.PI)) + 90;
24882         }, this);
24883     },
24884
24885
24886     isEndpoint: function(resolver) {
24887         return resolver.transient(this, 'isEndpoint', function() {
24888             var id = this.id;
24889             return resolver.parentWays(this).filter(function(parent) {
24890                 return !parent.isClosed() && !!parent.affix(id);
24891             }).length > 0;
24892         });
24893     },
24894
24895
24896     isConnected: function(resolver) {
24897         return resolver.transient(this, 'isConnected', function() {
24898             var parents = resolver.parentWays(this);
24899
24900             function isLine(entity) {
24901                 return entity.geometry(resolver) === 'line' &&
24902                     entity.hasInterestingTags();
24903             }
24904
24905             // vertex is connected to multiple parent lines
24906             if (parents.length > 1 && some(parents, isLine)) {
24907                 return true;
24908
24909             } else if (parents.length === 1) {
24910                 var way = parents[0],
24911                     nodes = way.nodes.slice();
24912                 if (way.isClosed()) { nodes.pop(); }  // ignore connecting node if closed
24913
24914                 // return true if vertex appears multiple times (way is self intersecting)
24915                 return nodes.indexOf(this.id) !== nodes.lastIndexOf(this.id);
24916             }
24917
24918             return false;
24919         });
24920     },
24921
24922
24923     isIntersection: function(resolver) {
24924         return resolver.transient(this, 'isIntersection', function() {
24925             return resolver.parentWays(this).filter(function(parent) {
24926                 return (parent.tags.highway ||
24927                     parent.tags.waterway ||
24928                     parent.tags.railway ||
24929                     parent.tags.aeroway) &&
24930                     parent.geometry(resolver) === 'line';
24931             }).length > 1;
24932         });
24933     },
24934
24935
24936     isHighwayIntersection: function(resolver) {
24937         return resolver.transient(this, 'isHighwayIntersection', function() {
24938             return resolver.parentWays(this).filter(function(parent) {
24939                 return parent.tags.highway && parent.geometry(resolver) === 'line';
24940             }).length > 1;
24941         });
24942     },
24943
24944
24945     isOnAddressLine: function(resolver) {
24946         return resolver.transient(this, 'isOnAddressLine', function() {
24947             return resolver.parentWays(this).filter(function(parent) {
24948                 return parent.tags.hasOwnProperty('addr:interpolation') &&
24949                     parent.geometry(resolver) === 'line';
24950             }).length > 0;
24951         });
24952     },
24953
24954
24955     asJXON: function(changeset_id) {
24956         var r = {
24957             node: {
24958                 '@id': this.osmId(),
24959                 '@lon': this.loc[0],
24960                 '@lat': this.loc[1],
24961                 '@version': (this.version || 0),
24962                 tag: map$4(this.tags, function(v, k) {
24963                     return { keyAttributes: { k: k, v: v } };
24964                 })
24965             }
24966         };
24967         if (changeset_id) r.node['@changeset'] = changeset_id;
24968         return r;
24969     },
24970
24971
24972     asGeoJSON: function() {
24973         return {
24974             type: 'Point',
24975             coordinates: this.loc
24976         };
24977     }
24978 });
24979
24980 /** Error message constants. */
24981 var FUNC_ERROR_TEXT$1 = 'Expected a function';
24982
24983 /**
24984  * Creates a function that negates the result of the predicate `func`. The
24985  * `func` predicate is invoked with the `this` binding and arguments of the
24986  * created function.
24987  *
24988  * @static
24989  * @memberOf _
24990  * @since 3.0.0
24991  * @category Function
24992  * @param {Function} predicate The predicate to negate.
24993  * @returns {Function} Returns the new negated function.
24994  * @example
24995  *
24996  * function isEven(n) {
24997  *   return n % 2 == 0;
24998  * }
24999  *
25000  * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
25001  * // => [1, 3, 5]
25002  */
25003 function negate(predicate) {
25004   if (typeof predicate != 'function') {
25005     throw new TypeError(FUNC_ERROR_TEXT$1);
25006   }
25007   return function() {
25008     var args = arguments;
25009     switch (args.length) {
25010       case 0: return !predicate.call(this);
25011       case 1: return !predicate.call(this, args[0]);
25012       case 2: return !predicate.call(this, args[0], args[1]);
25013       case 3: return !predicate.call(this, args[0], args[1], args[2]);
25014     }
25015     return !predicate.apply(this, args);
25016   };
25017 }
25018
25019 /**
25020  * The opposite of `_.filter`; this method returns the elements of `collection`
25021  * that `predicate` does **not** return truthy for.
25022  *
25023  * @static
25024  * @memberOf _
25025  * @since 0.1.0
25026  * @category Collection
25027  * @param {Array|Object} collection The collection to iterate over.
25028  * @param {Function} [predicate=_.identity] The function invoked per iteration.
25029  * @returns {Array} Returns the new filtered array.
25030  * @see _.filter
25031  * @example
25032  *
25033  * var users = [
25034  *   { 'user': 'barney', 'age': 36, 'active': false },
25035  *   { 'user': 'fred',   'age': 40, 'active': true }
25036  * ];
25037  *
25038  * _.reject(users, function(o) { return !o.active; });
25039  * // => objects for ['fred']
25040  *
25041  * // The `_.matches` iteratee shorthand.
25042  * _.reject(users, { 'age': 40, 'active': true });
25043  * // => objects for ['barney']
25044  *
25045  * // The `_.matchesProperty` iteratee shorthand.
25046  * _.reject(users, ['active', false]);
25047  * // => objects for ['fred']
25048  *
25049  * // The `_.property` iteratee shorthand.
25050  * _.reject(users, 'active');
25051  * // => objects for ['barney']
25052  */
25053 function reject(collection, predicate) {
25054   var func = isArray(collection) ? arrayFilter : baseFilter;
25055   return func(collection, negate(baseIteratee(predicate, 3)));
25056 }
25057
25058 /**
25059  * An alternative to `_.reduce`; this method transforms `object` to a new
25060  * `accumulator` object which is the result of running each of its own
25061  * enumerable string keyed properties thru `iteratee`, with each invocation
25062  * potentially mutating the `accumulator` object. If `accumulator` is not
25063  * provided, a new object with the same `[[Prototype]]` will be used. The
25064  * iteratee is invoked with four arguments: (accumulator, value, key, object).
25065  * Iteratee functions may exit iteration early by explicitly returning `false`.
25066  *
25067  * @static
25068  * @memberOf _
25069  * @since 1.3.0
25070  * @category Object
25071  * @param {Object} object The object to iterate over.
25072  * @param {Function} [iteratee=_.identity] The function invoked per iteration.
25073  * @param {*} [accumulator] The custom accumulator value.
25074  * @returns {*} Returns the accumulated value.
25075  * @example
25076  *
25077  * _.transform([2, 3, 4], function(result, n) {
25078  *   result.push(n *= n);
25079  *   return n % 2 == 0;
25080  * }, []);
25081  * // => [4, 9]
25082  *
25083  * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
25084  *   (result[value] || (result[value] = [])).push(key);
25085  * }, {});
25086  * // => { '1': ['a', 'c'], '2': ['b'] }
25087  */
25088 function transform$1(object, iteratee, accumulator) {
25089   var isArr = isArray(object),
25090       isArrLike = isArr || isBuffer(object) || isTypedArray(object);
25091
25092   iteratee = baseIteratee(iteratee, 4);
25093   if (accumulator == null) {
25094     var Ctor = object && object.constructor;
25095     if (isArrLike) {
25096       accumulator = isArr ? new Ctor : [];
25097     }
25098     else if (isObject(object)) {
25099       accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
25100     }
25101     else {
25102       accumulator = {};
25103     }
25104   }
25105   (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
25106     return iteratee(accumulator, value, index, object);
25107   });
25108   return accumulator;
25109 }
25110
25111 /*
25112   Order the nodes of a way in reverse order and reverse any direction dependent tags
25113   other than `oneway`. (We assume that correcting a backwards oneway is the primary
25114   reason for reversing a way.)
25115
25116   The following transforms are performed:
25117
25118     Keys:
25119           *:right=* ⟺ *:left=*
25120         *:forward=* ⟺ *:backward=*
25121        direction=up ⟺ direction=down
25122          incline=up ⟺ incline=down
25123             *=right ⟺ *=left
25124
25125     Relation members:
25126        role=forward ⟺ role=backward
25127          role=north ⟺ role=south
25128           role=east ⟺ role=west
25129
25130    In addition, numeric-valued `incline` tags are negated.
25131
25132    The JOSM implementation was used as a guide, but transformations that were of unclear benefit
25133    or adjusted tags that don't seem to be used in practice were omitted.
25134
25135    Also, each node on the way is examined for its own tags and the following transformations are performed
25136    in order to ensure associated nodes (eg a Stop Sign) is also reversed
25137
25138     Node Keys:
25139         *direction=forward ⟺ *direction=backward
25140         *direction=left ⟺ *direction=right
25141         *:forward=* ⟺ *:backward=*
25142         *:left=* ⟺ *:right=*
25143
25144    References:
25145       http://wiki.openstreetmap.org/wiki/Forward_%26_backward,_left_%26_right
25146       http://wiki.openstreetmap.org/wiki/Key:direction#Steps
25147       http://wiki.openstreetmap.org/wiki/Key:incline
25148       http://wiki.openstreetmap.org/wiki/Route#Members
25149       http://josm.openstreetmap.de/browser/josm/trunk/src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java
25150       http://wiki.openstreetmap.org/wiki/Tag:highway%3Dstop
25151       http://wiki.openstreetmap.org/wiki/Key:traffic_sign#On_a_way_or_area
25152  */
25153 function actionReverse(wayId, options) {
25154     var replacements = [
25155             [/:right$/, ':left'], [/:left$/, ':right'],
25156             [/:forward$/, ':backward'], [/:backward$/, ':forward']
25157         ],
25158         numeric = /^([+\-]?)(?=[\d.])/,
25159         roleReversals = {
25160             forward: 'backward',
25161             backward: 'forward',
25162             north: 'south',
25163             south: 'north',
25164             east: 'west',
25165             west: 'east'
25166         };
25167
25168
25169     function reverseKey(key) {
25170         for (var i = 0; i < replacements.length; ++i) {
25171             var replacement = replacements[i];
25172             if (replacement[0].test(key)) {
25173                 return key.replace(replacement[0], replacement[1]);
25174             }
25175         }
25176         return key;
25177     }
25178
25179
25180     function reverseValue(key, value) {
25181         if (key === 'incline' && numeric.test(value)) {
25182             return value.replace(numeric, function(_, sign) { return sign === '-' ? '' : '-'; });
25183         } else if (key === 'incline' || key === 'direction') {
25184             return {up: 'down', down: 'up'}[value] || value;
25185         } else if (options && options.reverseOneway && key === 'oneway') {
25186             return {yes: '-1', '1': '-1', '-1': 'yes'}[value] || value;
25187         } else {
25188             return {left: 'right', right: 'left'}[value] || value;
25189         }
25190     }
25191
25192
25193     function reverseDirectionTags(node) {
25194         // Update the direction based tags as appropriate then return an updated node
25195         return node.update({tags: transform$1(node.tags, function(acc, tagValue, tagKey) {
25196             // See if this is a direction tag and reverse (or use existing value if not recognised)
25197             var re = /direction$/;
25198             if (re.test(tagKey)) {
25199                 acc[tagKey] = {forward: 'backward', backward: 'forward', left: 'right', right: 'left'}[tagValue] || tagValue;
25200             } else {
25201                 // Use the reverseKey method to cater for situations such as traffic_sign:forward=stop
25202                 // This will pass through other tags unchanged
25203                 acc[reverseKey(tagKey)] = tagValue;
25204             }
25205             return acc;
25206         }, {})});
25207     }
25208
25209
25210     function reverseTagsOnNodes(graph, nodeIds) {
25211         // Reverse the direction of appropriate tags attached to the nodes (#3076)
25212         return nodeIds
25213             // Get each node from the graph
25214             .map(function(nodeId) { return graph.entity(nodeId);})
25215             // Check tags on the node, if there aren't any, we can skip
25216             .filter(function(existingNode) { return existingNode.tags !== undefined;})
25217             // Get a new version of each node with the appropriate tags reversed
25218             .map(function(existingNode) { return reverseDirectionTags(existingNode);})
25219             // Chain together consecutive updates to the graph for each updated node and return
25220             .reduce(function (accGraph, value) { return accGraph.replace(value); }, graph);
25221     }
25222
25223
25224     return function(graph) {
25225         var way = graph.entity(wayId),
25226             nodes = way.nodes.slice().reverse(),
25227             tags = {}, key, role;
25228
25229         for (key in way.tags) {
25230             tags[reverseKey(key)] = reverseValue(key, way.tags[key]);
25231         }
25232
25233         graph.parentRelations(way).forEach(function(relation) {
25234             relation.members.forEach(function(member, index) {
25235                 if (member.id === way.id && (role = roleReversals[member.role])) {
25236                     relation = relation.updateMember({role: role}, index);
25237                     graph = graph.replace(relation);
25238                 }
25239             });
25240         });
25241
25242         // Reverse any associated directions on nodes on the way and then replace
25243         // the way itself with the reversed node ids and updated way tags
25244         return reverseTagsOnNodes(graph, nodes).replace(way.update({nodes: nodes, tags: tags}));
25245     };
25246 }
25247
25248 /**
25249  * Creates a duplicate-free version of an array, using
25250  * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
25251  * for equality comparisons, in which only the first occurrence of each element
25252  * is kept. The order of result values is determined by the order they occur
25253  * in the array.
25254  *
25255  * @static
25256  * @memberOf _
25257  * @since 0.1.0
25258  * @category Array
25259  * @param {Array} array The array to inspect.
25260  * @returns {Array} Returns the new duplicate free array.
25261  * @example
25262  *
25263  * _.uniq([2, 1, 2]);
25264  * // => [2, 1]
25265  */
25266 function uniq(array) {
25267   return (array && array.length) ? baseUniq(array) : [];
25268 }
25269
25270 /** `Object#toString` result references. */
25271 var numberTag$4 = '[object Number]';
25272
25273 /**
25274  * Checks if `value` is classified as a `Number` primitive or object.
25275  *
25276  * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
25277  * classified as numbers, use the `_.isFinite` method.
25278  *
25279  * @static
25280  * @memberOf _
25281  * @since 0.1.0
25282  * @category Lang
25283  * @param {*} value The value to check.
25284  * @returns {boolean} Returns `true` if `value` is a number, else `false`.
25285  * @example
25286  *
25287  * _.isNumber(3);
25288  * // => true
25289  *
25290  * _.isNumber(Number.MIN_VALUE);
25291  * // => true
25292  *
25293  * _.isNumber(Infinity);
25294  * // => true
25295  *
25296  * _.isNumber('3');
25297  * // => false
25298  */
25299 function isNumber(value) {
25300   return typeof value == 'number' ||
25301     (isObjectLike(value) && baseGetTag(value) == numberTag$4);
25302 }
25303
25304 /** `Object#toString` result references. */
25305 var stringTag$4 = '[object String]';
25306
25307 /**
25308  * Checks if `value` is classified as a `String` primitive or object.
25309  *
25310  * @static
25311  * @since 0.1.0
25312  * @memberOf _
25313  * @category Lang
25314  * @param {*} value The value to check.
25315  * @returns {boolean} Returns `true` if `value` is a string, else `false`.
25316  * @example
25317  *
25318  * _.isString('abc');
25319  * // => true
25320  *
25321  * _.isString(1);
25322  * // => false
25323  */
25324 function isString(value) {
25325   return typeof value == 'string' ||
25326     (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag$4);
25327 }
25328
25329 /**
25330  * Checks if `value` is `NaN`.
25331  *
25332  * **Note:** This method is based on
25333  * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
25334  * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
25335  * `undefined` and other non-number values.
25336  *
25337  * @static
25338  * @memberOf _
25339  * @since 0.1.0
25340  * @category Lang
25341  * @param {*} value The value to check.
25342  * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
25343  * @example
25344  *
25345  * _.isNaN(NaN);
25346  * // => true
25347  *
25348  * _.isNaN(new Number(NaN));
25349  * // => true
25350  *
25351  * isNaN(undefined);
25352  * // => true
25353  *
25354  * _.isNaN(undefined);
25355  * // => false
25356  */
25357 function isNaN$1(value) {
25358   // An `NaN` primitive is the only value that is not equal to itself.
25359   // Perform the `toStringTag` check first to avoid errors with some
25360   // ActiveX objects in IE.
25361   return isNumber(value) && value != +value;
25362 }
25363
25364 function osmLanes(entity) {
25365     if (entity.type !== 'way') return null;
25366     if (!entity.tags.highway) return null;
25367
25368     var tags = entity.tags;
25369     var isOneWay = entity.isOneWay();
25370     var laneCount = getLaneCount(tags, isOneWay);
25371     var maxspeed = parseMaxspeed(tags);
25372
25373     var laneDirections = parseLaneDirections(tags, isOneWay, laneCount);
25374     var forward = laneDirections.forward;
25375     var backward = laneDirections.backward;
25376     var bothways = laneDirections.bothways;
25377
25378     // parse the piped string 'x|y|z' format
25379     var turnLanes = {};
25380     turnLanes.unspecified = parseTurnLanes(tags['turn:lanes']);
25381     turnLanes.forward = parseTurnLanes(tags['turn:lanes:forward']);
25382     turnLanes.backward = parseTurnLanes(tags['turn:lanes:backward']);
25383
25384     var maxspeedLanes = {};
25385     maxspeedLanes.unspecified = parseMaxspeedLanes(tags['maxspeed:lanes'], maxspeed);
25386     maxspeedLanes.forward = parseMaxspeedLanes(tags['maxspeed:lanes:forward'], maxspeed);
25387     maxspeedLanes.backward = parseMaxspeedLanes(tags['maxspeed:lanes:backward'], maxspeed);
25388
25389     var psvLanes = {};
25390     psvLanes.unspecified = parseMiscLanes(tags['psv:lanes']);
25391     psvLanes.forward = parseMiscLanes(tags['psv:lanes:forward']);
25392     psvLanes.backward = parseMiscLanes(tags['psv:lanes:backward']);
25393
25394     var busLanes = {};
25395     busLanes.unspecified = parseMiscLanes(tags['bus:lanes']);
25396     busLanes.forward = parseMiscLanes(tags['bus:lanes:forward']);
25397     busLanes.backward = parseMiscLanes(tags['bus:lanes:backward']);
25398
25399     var taxiLanes = {};
25400     taxiLanes.unspecified = parseMiscLanes(tags['taxi:lanes']);
25401     taxiLanes.forward = parseMiscLanes(tags['taxi:lanes:forward']);
25402     taxiLanes.backward = parseMiscLanes(tags['taxi:lanes:backward']);
25403
25404     var hovLanes = {};
25405     hovLanes.unspecified = parseMiscLanes(tags['hov:lanes']);
25406     hovLanes.forward = parseMiscLanes(tags['hov:lanes:forward']);
25407     hovLanes.backward = parseMiscLanes(tags['hov:lanes:backward']);
25408
25409     var hgvLanes = {};
25410     hgvLanes.unspecified = parseMiscLanes(tags['hgv:lanes']);
25411     hgvLanes.forward = parseMiscLanes(tags['hgv:lanes:forward']);
25412     hgvLanes.backward = parseMiscLanes(tags['hgv:lanes:backward']);
25413
25414     var bicyclewayLanes = {};
25415     bicyclewayLanes.unspecified = parseBicycleWay(tags['bicycleway:lanes']);
25416     bicyclewayLanes.forward = parseBicycleWay(tags['bicycleway:lanes:forward']);
25417     bicyclewayLanes.backward = parseBicycleWay(tags['bicycleway:lanes:backward']);
25418
25419     var lanesObj = {
25420         forward: [],
25421         backward: [],
25422         unspecified: []
25423     };
25424
25425     // map forward/backward/unspecified of each lane type to lanesObj
25426     mapToLanesObj(lanesObj, turnLanes, 'turnLane');
25427     mapToLanesObj(lanesObj, maxspeedLanes, 'maxspeed');
25428     mapToLanesObj(lanesObj, psvLanes, 'psv');
25429     mapToLanesObj(lanesObj, busLanes, 'bus');
25430     mapToLanesObj(lanesObj, taxiLanes, 'taxi');
25431     mapToLanesObj(lanesObj, hovLanes, 'hov');
25432     mapToLanesObj(lanesObj, hgvLanes, 'hgv');
25433     mapToLanesObj(lanesObj, bicyclewayLanes, 'bicycleway');
25434
25435     return {
25436         metadata: {
25437             count: laneCount,
25438             oneway: isOneWay,
25439             forward: forward,
25440             backward: backward,
25441             bothways: bothways,
25442             turnLanes: turnLanes,
25443             maxspeed: maxspeed,
25444             maxspeedLanes: maxspeedLanes,
25445             psvLanes: psvLanes,
25446             busLanes: busLanes,
25447             taxiLanes: taxiLanes,
25448             hovLanes: hovLanes,
25449             hgvLanes: hgvLanes,
25450             bicyclewayLanes: bicyclewayLanes
25451         },
25452         lanes: lanesObj
25453     };
25454 }
25455
25456
25457 function getLaneCount(tags, isOneWay) {
25458     var count;
25459     if (tags.lanes) {
25460         count = parseInt(tags.lanes, 10);
25461         if (count > 0) {
25462             return count;
25463         }
25464     }
25465
25466
25467     switch (tags.highway) {
25468         case 'trunk':
25469         case 'motorway':
25470             count = isOneWay ? 2 : 4;
25471             break;
25472         default:
25473             count = isOneWay ? 1 : 2;
25474             break;
25475     }
25476
25477     return count;
25478 }
25479
25480
25481 function parseMaxspeed(tags) {
25482     var maxspeed = tags.maxspeed;
25483     if (isNumber(maxspeed)) return maxspeed;
25484     if (isString(maxspeed)) {
25485         maxspeed = maxspeed.match(/^([0-9][\.0-9]+?)(?:[ ]?(?:km\/h|kmh|kph|mph|knots))?$/g);
25486         if (!maxspeed) return;
25487         return parseInt(maxspeed, 10);
25488     }
25489 }
25490
25491
25492 function parseLaneDirections(tags, isOneWay, laneCount) {
25493     var forward = parseInt(tags['lanes:forward'], 10);
25494     var backward = parseInt(tags['lanes:backward'], 10);
25495     var bothways = parseInt(tags['lanes:both_ways'], 10) > 0 ? 1 : 0;
25496
25497     if (parseInt(tags.oneway, 10) === -1) {
25498         forward = 0;
25499         bothways = 0;
25500         backward = laneCount;
25501     }
25502     else if (isOneWay) {
25503         forward = laneCount;
25504         bothways = 0;
25505         backward = 0;
25506     }
25507     else if (isNaN$1(forward) && isNaN$1(backward)) {
25508         backward = Math.floor((laneCount - bothways) / 2);
25509         forward = laneCount - bothways - backward;
25510     }
25511     else if (isNaN$1(forward)) {
25512         if (backward > laneCount - bothways) {
25513             backward = laneCount - bothways;
25514         }
25515         forward = laneCount - bothways - backward;
25516     }
25517     else if (isNaN$1(backward)) {
25518         if (forward > laneCount - bothways) {
25519             forward = laneCount - bothways;
25520         }
25521         backward = laneCount - bothways - forward;
25522     }
25523     return {
25524         forward: forward,
25525         backward: backward,
25526         bothways: bothways
25527     };
25528 }
25529
25530
25531 function parseTurnLanes(tag){
25532     if (!tag) return;
25533
25534     var validValues = [
25535         'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right',
25536         'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none'
25537     ];
25538
25539     return tag.split('|')
25540         .map(function (s) {
25541             if (s === '') s = 'none';
25542             return s.split(';')
25543                 .map(function (d) {
25544                     return validValues.indexOf(d) === -1 ? 'unknown': d;
25545                 });
25546         });
25547 }
25548
25549
25550 function parseMaxspeedLanes(tag, maxspeed) {
25551     if (!tag) return;
25552
25553     return tag.split('|')
25554         .map(function (s) {
25555             if (s === 'none') return s;
25556             var m = parseInt(s, 10);
25557             if (s === '' || m === maxspeed) return null;
25558             return isNaN$1(m) ? 'unknown': m;
25559         });
25560 }
25561
25562
25563 function parseMiscLanes(tag) {
25564     if (!tag) return;
25565
25566     var validValues = [
25567         'yes', 'no', 'designated'
25568     ];
25569
25570     return tag.split('|')
25571         .map(function (s) {
25572             if (s === '') s = 'no';
25573             return validValues.indexOf(s) === -1 ? 'unknown': s;
25574         });
25575 }
25576
25577
25578 function parseBicycleWay(tag) {
25579     if (!tag) return;
25580
25581     var validValues = [
25582         'yes', 'no', 'designated', 'lane'
25583     ];
25584
25585     return tag.split('|')
25586         .map(function (s) {
25587             if (s === '') s = 'no';
25588             return validValues.indexOf(s) === -1 ? 'unknown': s;
25589         });
25590 }
25591
25592
25593 function mapToLanesObj(lanesObj, data, key) {
25594     if (data.forward) data.forward.forEach(function(l, i) {
25595         if (!lanesObj.forward[i]) lanesObj.forward[i] = {};
25596         lanesObj.forward[i][key] = l;
25597     });
25598     if (data.backward) data.backward.forEach(function(l, i) {
25599         if (!lanesObj.backward[i]) lanesObj.backward[i] = {};
25600         lanesObj.backward[i][key] = l;
25601     });
25602     if (data.unspecified) data.unspecified.forEach(function(l, i) {
25603         if (!lanesObj.unspecified[i]) lanesObj.unspecified[i] = {};
25604         lanesObj.unspecified[i][key] = l;
25605     });
25606 }
25607
25608 /** Used to compose bitmasks for cloning. */
25609 var CLONE_DEEP_FLAG$4 = 1;
25610 var CLONE_SYMBOLS_FLAG$3 = 4;
25611
25612 /**
25613  * This method is like `_.clone` except that it recursively clones `value`.
25614  *
25615  * @static
25616  * @memberOf _
25617  * @since 1.0.0
25618  * @category Lang
25619  * @param {*} value The value to recursively clone.
25620  * @returns {*} Returns the deep cloned value.
25621  * @see _.clone
25622  * @example
25623  *
25624  * var objects = [{ 'a': 1 }, { 'b': 2 }];
25625  *
25626  * var deep = _.cloneDeep(objects);
25627  * console.log(deep[0] === objects[0]);
25628  * // => false
25629  */
25630 function cloneDeep(value) {
25631   return baseClone(value, CLONE_DEEP_FLAG$4 | CLONE_SYMBOLS_FLAG$3);
25632 }
25633
25634 /**
25635  * Gets the timestamp of the number of milliseconds that have elapsed since
25636  * the Unix epoch (1 January 1970 00:00:00 UTC).
25637  *
25638  * @static
25639  * @memberOf _
25640  * @since 2.4.0
25641  * @category Date
25642  * @returns {number} Returns the timestamp.
25643  * @example
25644  *
25645  * _.defer(function(stamp) {
25646  *   console.log(_.now() - stamp);
25647  * }, _.now());
25648  * // => Logs the number of milliseconds it took for the deferred invocation.
25649  */
25650 var now$1 = function() {
25651   return root$2.Date.now();
25652 };
25653
25654 /** Error message constants. */
25655 var FUNC_ERROR_TEXT$2 = 'Expected a function';
25656
25657 /* Built-in method references for those with the same name as other `lodash` methods. */
25658 var nativeMax$2 = Math.max;
25659 var nativeMin = Math.min;
25660
25661 /**
25662  * Creates a debounced function that delays invoking `func` until after `wait`
25663  * milliseconds have elapsed since the last time the debounced function was
25664  * invoked. The debounced function comes with a `cancel` method to cancel
25665  * delayed `func` invocations and a `flush` method to immediately invoke them.
25666  * Provide `options` to indicate whether `func` should be invoked on the
25667  * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
25668  * with the last arguments provided to the debounced function. Subsequent
25669  * calls to the debounced function return the result of the last `func`
25670  * invocation.
25671  *
25672  * **Note:** If `leading` and `trailing` options are `true`, `func` is
25673  * invoked on the trailing edge of the timeout only if the debounced function
25674  * is invoked more than once during the `wait` timeout.
25675  *
25676  * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
25677  * until to the next tick, similar to `setTimeout` with a timeout of `0`.
25678  *
25679  * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
25680  * for details over the differences between `_.debounce` and `_.throttle`.
25681  *
25682  * @static
25683  * @memberOf _
25684  * @since 0.1.0
25685  * @category Function
25686  * @param {Function} func The function to debounce.
25687  * @param {number} [wait=0] The number of milliseconds to delay.
25688  * @param {Object} [options={}] The options object.
25689  * @param {boolean} [options.leading=false]
25690  *  Specify invoking on the leading edge of the timeout.
25691  * @param {number} [options.maxWait]
25692  *  The maximum time `func` is allowed to be delayed before it's invoked.
25693  * @param {boolean} [options.trailing=true]
25694  *  Specify invoking on the trailing edge of the timeout.
25695  * @returns {Function} Returns the new debounced function.
25696  * @example
25697  *
25698  * // Avoid costly calculations while the window size is in flux.
25699  * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
25700  *
25701  * // Invoke `sendMail` when clicked, debouncing subsequent calls.
25702  * jQuery(element).on('click', _.debounce(sendMail, 300, {
25703  *   'leading': true,
25704  *   'trailing': false
25705  * }));
25706  *
25707  * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
25708  * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
25709  * var source = new EventSource('/stream');
25710  * jQuery(source).on('message', debounced);
25711  *
25712  * // Cancel the trailing debounced invocation.
25713  * jQuery(window).on('popstate', debounced.cancel);
25714  */
25715 function debounce(func, wait, options) {
25716   var lastArgs,
25717       lastThis,
25718       maxWait,
25719       result,
25720       timerId,
25721       lastCallTime,
25722       lastInvokeTime = 0,
25723       leading = false,
25724       maxing = false,
25725       trailing = true;
25726
25727   if (typeof func != 'function') {
25728     throw new TypeError(FUNC_ERROR_TEXT$2);
25729   }
25730   wait = toNumber(wait) || 0;
25731   if (isObject(options)) {
25732     leading = !!options.leading;
25733     maxing = 'maxWait' in options;
25734     maxWait = maxing ? nativeMax$2(toNumber(options.maxWait) || 0, wait) : maxWait;
25735     trailing = 'trailing' in options ? !!options.trailing : trailing;
25736   }
25737
25738   function invokeFunc(time) {
25739     var args = lastArgs,
25740         thisArg = lastThis;
25741
25742     lastArgs = lastThis = undefined;
25743     lastInvokeTime = time;
25744     result = func.apply(thisArg, args);
25745     return result;
25746   }
25747
25748   function leadingEdge(time) {
25749     // Reset any `maxWait` timer.
25750     lastInvokeTime = time;
25751     // Start the timer for the trailing edge.
25752     timerId = setTimeout(timerExpired, wait);
25753     // Invoke the leading edge.
25754     return leading ? invokeFunc(time) : result;
25755   }
25756
25757   function remainingWait(time) {
25758     var timeSinceLastCall = time - lastCallTime,
25759         timeSinceLastInvoke = time - lastInvokeTime,
25760         result = wait - timeSinceLastCall;
25761
25762     return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
25763   }
25764
25765   function shouldInvoke(time) {
25766     var timeSinceLastCall = time - lastCallTime,
25767         timeSinceLastInvoke = time - lastInvokeTime;
25768
25769     // Either this is the first call, activity has stopped and we're at the
25770     // trailing edge, the system time has gone backwards and we're treating
25771     // it as the trailing edge, or we've hit the `maxWait` limit.
25772     return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
25773       (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
25774   }
25775
25776   function timerExpired() {
25777     var time = now$1();
25778     if (shouldInvoke(time)) {
25779       return trailingEdge(time);
25780     }
25781     // Restart the timer.
25782     timerId = setTimeout(timerExpired, remainingWait(time));
25783   }
25784
25785   function trailingEdge(time) {
25786     timerId = undefined;
25787
25788     // Only invoke if we have `lastArgs` which means `func` has been
25789     // debounced at least once.
25790     if (trailing && lastArgs) {
25791       return invokeFunc(time);
25792     }
25793     lastArgs = lastThis = undefined;
25794     return result;
25795   }
25796
25797   function cancel() {
25798     if (timerId !== undefined) {
25799       clearTimeout(timerId);
25800     }
25801     lastInvokeTime = 0;
25802     lastArgs = lastCallTime = lastThis = timerId = undefined;
25803   }
25804
25805   function flush() {
25806     return timerId === undefined ? result : trailingEdge(now$1());
25807   }
25808
25809   function debounced() {
25810     var time = now$1(),
25811         isInvoking = shouldInvoke(time);
25812
25813     lastArgs = arguments;
25814     lastThis = this;
25815     lastCallTime = time;
25816
25817     if (isInvoking) {
25818       if (timerId === undefined) {
25819         return leadingEdge(lastCallTime);
25820       }
25821       if (maxing) {
25822         // Handle invocations in a tight loop.
25823         timerId = setTimeout(timerExpired, wait);
25824         return invokeFunc(lastCallTime);
25825       }
25826     }
25827     if (timerId === undefined) {
25828       timerId = setTimeout(timerExpired, wait);
25829     }
25830     return result;
25831   }
25832   debounced.cancel = cancel;
25833   debounced.flush = flush;
25834   return debounced;
25835 }
25836
25837 /**
25838  * Casts `value` to `identity` if it's not a function.
25839  *
25840  * @private
25841  * @param {*} value The value to inspect.
25842  * @returns {Function} Returns cast function.
25843  */
25844 function castFunction(value) {
25845   return typeof value == 'function' ? value : identity$8;
25846 }
25847
25848 /**
25849  * Iterates over elements of `collection` and invokes `iteratee` for each element.
25850  * The iteratee is invoked with three arguments: (value, index|key, collection).
25851  * Iteratee functions may exit iteration early by explicitly returning `false`.
25852  *
25853  * **Note:** As with other "Collections" methods, objects with a "length"
25854  * property are iterated like arrays. To avoid this behavior use `_.forIn`
25855  * or `_.forOwn` for object iteration.
25856  *
25857  * @static
25858  * @memberOf _
25859  * @since 0.1.0
25860  * @alias each
25861  * @category Collection
25862  * @param {Array|Object} collection The collection to iterate over.
25863  * @param {Function} [iteratee=_.identity] The function invoked per iteration.
25864  * @returns {Array|Object} Returns `collection`.
25865  * @see _.forEachRight
25866  * @example
25867  *
25868  * _.forEach([1, 2], function(value) {
25869  *   console.log(value);
25870  * });
25871  * // => Logs `1` then `2`.
25872  *
25873  * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
25874  *   console.log(key);
25875  * });
25876  * // => Logs 'a' then 'b' (iteration order is not guaranteed).
25877  */
25878 function forEach(collection, iteratee) {
25879   var func = isArray(collection) ? arrayEach : baseEach;
25880   return func(collection, castFunction(iteratee));
25881 }
25882
25883 /**
25884  * Iterates over own enumerable string keyed properties of an object and
25885  * invokes `iteratee` for each property. The iteratee is invoked with three
25886  * arguments: (value, key, object). Iteratee functions may exit iteration
25887  * early by explicitly returning `false`.
25888  *
25889  * @static
25890  * @memberOf _
25891  * @since 0.3.0
25892  * @category Object
25893  * @param {Object} object The object to iterate over.
25894  * @param {Function} [iteratee=_.identity] The function invoked per iteration.
25895  * @returns {Object} Returns `object`.
25896  * @see _.forOwnRight
25897  * @example
25898  *
25899  * function Foo() {
25900  *   this.a = 1;
25901  *   this.b = 2;
25902  * }
25903  *
25904  * Foo.prototype.c = 3;
25905  *
25906  * _.forOwn(new Foo, function(value, key) {
25907  *   console.log(key);
25908  * });
25909  * // => Logs 'a' then 'b' (iteration order is not guaranteed).
25910  */
25911 function forOwn(object, iteratee) {
25912   return object && baseForOwn(object, castFunction(iteratee));
25913 }
25914
25915 var translations = Object.create(null);
25916
25917 var currentLocale = 'en';
25918 var textDirection = 'ltr';
25919
25920 function setLocale(_) {
25921     if (translations[_] !== undefined) {
25922         currentLocale = _;
25923     } else if (translations[_.split('-')[0]]) {
25924         currentLocale = _.split('-')[0];
25925     }
25926 }
25927
25928 function addTranslation(id, value) {
25929     translations[id] = value;
25930 }
25931
25932 /**
25933  * Given a string identifier, try to find that string in the current
25934  * language, and return it.
25935  *
25936  * @param {string} s string identifier
25937  * @returns {string?} locale string
25938  */
25939 function t(s, o, loc) {
25940     loc = loc || currentLocale;
25941
25942     var path = s
25943         .split('.')
25944         .map(function(s) { return s.replace('<TX_DOT>', '.'); })
25945         .reverse();
25946
25947     var rep = translations[loc];
25948
25949     while (rep !== undefined && path.length) rep = rep[path.pop()];
25950
25951     if (rep !== undefined) {
25952         if (o) for (var k in o) rep = rep.replace('{' + k + '}', o[k]);
25953         return rep;
25954     }
25955
25956     if (loc !== 'en') {
25957         return t(s, o, 'en');
25958     }
25959
25960     if (o && 'default' in o) {
25961         return o.default;
25962     }
25963
25964     var missing = 'Missing ' + loc + ' translation: ' + s;
25965     if (typeof console !== 'undefined') console.error(missing); // eslint-disable-line
25966
25967     return missing;
25968 }
25969
25970 /**
25971  * Given string 'ltr' or 'rtl', save that setting
25972  *
25973  * @param {string} s ltr or rtl
25974  */
25975
25976 function setTextDirection(dir) {
25977     textDirection = dir;
25978 }
25979
25980 /** Used to compose bitmasks for cloning. */
25981 var CLONE_DEEP_FLAG$5 = 1;
25982 var CLONE_SYMBOLS_FLAG$4 = 4;
25983
25984 /**
25985  * This method is like `_.cloneWith` except that it recursively clones `value`.
25986  *
25987  * @static
25988  * @memberOf _
25989  * @since 4.0.0
25990  * @category Lang
25991  * @param {*} value The value to recursively clone.
25992  * @param {Function} [customizer] The function to customize cloning.
25993  * @returns {*} Returns the deep cloned value.
25994  * @see _.cloneWith
25995  * @example
25996  *
25997  * function customizer(value) {
25998  *   if (_.isElement(value)) {
25999  *     return value.cloneNode(true);
26000  *   }
26001  * }
26002  *
26003  * var el = _.cloneDeepWith(document.body, customizer);
26004  *
26005  * console.log(el === document.body);
26006  * // => false
26007  * console.log(el.nodeName);
26008  * // => 'BODY'
26009  * console.log(el.childNodes.length);
26010  * // => 20
26011  */
26012 function cloneDeepWith(value, customizer) {
26013   customizer = typeof customizer == 'function' ? customizer : undefined;
26014   return baseClone(value, CLONE_DEEP_FLAG$5 | CLONE_SYMBOLS_FLAG$4, customizer);
26015 }
26016
26017 /**
26018  * Creates an array of `array` values not included in the other given arrays
26019  * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
26020  * for equality comparisons. The order and references of result values are
26021  * determined by the first array.
26022  *
26023  * **Note:** Unlike `_.pullAll`, this method returns a new array.
26024  *
26025  * @static
26026  * @memberOf _
26027  * @since 0.1.0
26028  * @category Array
26029  * @param {Array} array The array to inspect.
26030  * @param {...Array} [values] The values to exclude.
26031  * @returns {Array} Returns the new array of filtered values.
26032  * @see _.without, _.xor
26033  * @example
26034  *
26035  * _.difference([2, 1], [2, 3]);
26036  * // => [1]
26037  */
26038 var difference = baseRest(function(array, values) {
26039   return isArrayLikeObject(array)
26040     ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
26041     : [];
26042 });
26043
26044 /** `Object#toString` result references. */
26045 var mapTag$6 = '[object Map]';
26046 var setTag$6 = '[object Set]';
26047
26048 /** Used for built-in method references. */
26049 var objectProto$17 = Object.prototype;
26050
26051 /** Used to check objects for own properties. */
26052 var hasOwnProperty$14 = objectProto$17.hasOwnProperty;
26053
26054 /**
26055  * Checks if `value` is an empty object, collection, map, or set.
26056  *
26057  * Objects are considered empty if they have no own enumerable string keyed
26058  * properties.
26059  *
26060  * Array-like values such as `arguments` objects, arrays, buffers, strings, or
26061  * jQuery-like collections are considered empty if they have a `length` of `0`.
26062  * Similarly, maps and sets are considered empty if they have a `size` of `0`.
26063  *
26064  * @static
26065  * @memberOf _
26066  * @since 0.1.0
26067  * @category Lang
26068  * @param {*} value The value to check.
26069  * @returns {boolean} Returns `true` if `value` is empty, else `false`.
26070  * @example
26071  *
26072  * _.isEmpty(null);
26073  * // => true
26074  *
26075  * _.isEmpty(true);
26076  * // => true
26077  *
26078  * _.isEmpty(1);
26079  * // => true
26080  *
26081  * _.isEmpty([1, 2, 3]);
26082  * // => false
26083  *
26084  * _.isEmpty({ 'a': 1 });
26085  * // => false
26086  */
26087 function isEmpty(value) {
26088   if (value == null) {
26089     return true;
26090   }
26091   if (isArrayLike(value) &&
26092       (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
26093         isBuffer(value) || isTypedArray(value) || isArguments(value))) {
26094     return !value.length;
26095   }
26096   var tag = getTag$1(value);
26097   if (tag == mapTag$6 || tag == setTag$6) {
26098     return !value.size;
26099   }
26100   if (isPrototype(value)) {
26101     return !baseKeys(value).length;
26102   }
26103   for (var key in value) {
26104     if (hasOwnProperty$14.call(value, key)) {
26105       return false;
26106     }
26107   }
26108   return true;
26109 }
26110
26111 var detected;
26112
26113 function utilDetect(force) {
26114     if (detected && !force) return detected;
26115     detected = {};
26116
26117     var ua = navigator.userAgent,
26118         m = null;
26119
26120     m = ua.match(/(edge)\/?\s*(\.?\d+(\.\d+)*)/i);   // Edge
26121     if (m !== null) {
26122         detected.browser = m[1];
26123         detected.version = m[2];
26124     }
26125     if (!detected.browser) {
26126         m = ua.match(/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/i);   // IE11
26127         if (m !== null) {
26128             detected.browser = 'msie';
26129             detected.version = m[1];
26130         }
26131     }
26132     if (!detected.browser) {
26133         m = ua.match(/(opr)\/?\s*(\.?\d+(\.\d+)*)/i);   // Opera 15+
26134         if (m !== null) {
26135             detected.browser = 'Opera';
26136             detected.version = m[2];
26137         }
26138     }
26139     if (!detected.browser) {
26140         m = ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
26141         if (m !== null) {
26142             detected.browser = m[1];
26143             detected.version = m[2];
26144             m = ua.match(/version\/([\.\d]+)/i);
26145             if (m !== null) detected.version = m[1];
26146         }
26147     }
26148     if (!detected.browser) {
26149         detected.browser = navigator.appName;
26150         detected.version = navigator.appVersion;
26151     }
26152
26153     // keep major.minor version only..
26154     detected.version = detected.version.split(/\W/).slice(0,2).join('.');
26155
26156     if (detected.browser.toLowerCase() === 'msie') {
26157         detected.ie = true;
26158         detected.browser = 'Internet Explorer';
26159         detected.support = parseFloat(detected.version) >= 11;
26160     } else {
26161         detected.ie = false;
26162         detected.support = true;
26163     }
26164
26165     // Added due to incomplete svg style support. See #715
26166     detected.opera = (detected.browser.toLowerCase() === 'opera' && parseFloat(detected.version) < 15 );
26167
26168     detected.locale = (navigator.language || navigator.userLanguage || 'en-US');
26169     detected.language = detected.locale.split('-')[0];
26170
26171     // Search `navigator.languages` for a better locale.. Prefer the first language,
26172     // unless the second language is a culture-specific version of the first one, see #3842
26173     if (navigator.languages && navigator.languages.length > 0) {
26174         var code0 = navigator.languages[0],
26175             parts0 = code0.split('-');
26176
26177         detected.locale = code0;
26178         detected.language = parts0[0];
26179
26180         if (navigator.languages.length > 1 && parts0.length === 1) {
26181             var code1 = navigator.languages[1],
26182                 parts1 = code1.split('-');
26183
26184             if (parts1[0] === parts0[0]) {
26185                 detected.locale = code1;
26186             }
26187         }
26188     }
26189
26190     // Loaded locale is stored in currentLocale
26191     // return that instead (except in the situation where 'en' might override 'en-US')
26192     var loadedLocale = currentLocale || 'en';
26193     if (loadedLocale !== 'en') {
26194         detected.locale = loadedLocale;
26195         detected.language = detected.locale.split('-')[0];
26196     }
26197
26198     // detect text direction
26199     var q = utilStringQs(window.location.hash.substring(1));
26200     var lang = dataLocales[detected.locale];
26201     if ((lang && lang.rtl) || (q.rtl === 'true')) {
26202         detected.textDirection = 'rtl';
26203     } else {
26204         detected.textDirection = 'ltr';
26205     }
26206     setTextDirection(detected.textDirection);
26207
26208     // detect host
26209     var loc = window.top.location;
26210     var origin = loc.origin;
26211     if (!origin) {  // for unpatched IE11
26212         origin = loc.protocol + '//' + loc.hostname + (loc.port ? ':' + loc.port: '');
26213     }
26214
26215     detected.host = origin + loc.pathname;
26216
26217     detected.filedrop = (window.FileReader && 'ondrop' in window);
26218
26219     detected.download = !(detected.ie || detected.browser.toLowerCase() === 'edge');
26220
26221     detected.cssfilters = !(detected.ie || detected.browser.toLowerCase() === 'edge');
26222
26223     function nav(x) {
26224         return navigator.userAgent.indexOf(x) !== -1;
26225     }
26226
26227     if (nav('Win')) {
26228         detected.os = 'win';
26229         detected.platform = 'Windows';
26230     }
26231     else if (nav('Mac')) {
26232         detected.os = 'mac';
26233         detected.platform = 'Macintosh';
26234     }
26235     else if (nav('X11') || nav('Linux')) {
26236         detected.os = 'linux';
26237         detected.platform = 'Linux';
26238     }
26239     else {
26240         detected.os = 'win';
26241         detected.platform = 'Unknown';
26242     }
26243
26244     return detected;
26245 }
26246
26247 var remove$1 = removeDiacritics;
26248
26249 var replacementList = [
26250   {
26251     base: ' ',
26252     chars: "\u00A0",
26253   }, {
26254     base: '0',
26255     chars: "\u07C0",
26256   }, {
26257     base: 'A',
26258     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",
26259   }, {
26260     base: 'AA',
26261     chars: "\uA732",
26262   }, {
26263     base: 'AE',
26264     chars: "\u00C6\u01FC\u01E2",
26265   }, {
26266     base: 'AO',
26267     chars: "\uA734",
26268   }, {
26269     base: 'AU',
26270     chars: "\uA736",
26271   }, {
26272     base: 'AV',
26273     chars: "\uA738\uA73A",
26274   }, {
26275     base: 'AY',
26276     chars: "\uA73C",
26277   }, {
26278     base: 'B',
26279     chars: "\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0181",
26280   }, {
26281     base: 'C',
26282     chars: "\u24b8\uff23\uA73E\u1E08\u0106\u0043\u0108\u010A\u010C\u00C7\u0187\u023B",
26283   }, {
26284     base: 'D',
26285     chars: "\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018A\u0189\u1D05\uA779",
26286   }, {
26287     base: 'Dh',
26288     chars: "\u00D0",
26289   }, {
26290     base: 'DZ',
26291     chars: "\u01F1\u01C4",
26292   }, {
26293     base: 'Dz',
26294     chars: "\u01F2\u01C5",
26295   }, {
26296     base: 'E',
26297     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",
26298   }, {
26299     base: 'F',
26300     chars: "\uA77C\u24BB\uFF26\u1E1E\u0191\uA77B",
26301   }, {
26302     base: 'G',
26303     chars: "\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E\u0262",
26304   }, {
26305     base: 'H',
26306     chars: "\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D",
26307   }, {
26308     base: 'I',
26309     chars: "\u24BE\uFF29\xCC\xCD\xCE\u0128\u012A\u012C\u0130\xCF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197",
26310   }, {
26311     base: 'J',
26312     chars: "\u24BF\uFF2A\u0134\u0248\u0237",
26313   }, {
26314     base: 'K',
26315     chars: "\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2",
26316   }, {
26317     base: 'L',
26318     chars: "\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780",
26319   }, {
26320     base: 'LJ',
26321     chars: "\u01C7",
26322   }, {
26323     base: 'Lj',
26324     chars: "\u01C8",
26325   }, {
26326     base: 'M',
26327     chars: "\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C\u03FB",
26328   }, {
26329     base: 'N',
26330     chars: "\uA7A4\u0220\u24C3\uFF2E\u01F8\u0143\xD1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u019D\uA790\u1D0E",
26331   }, {
26332     base: 'NJ',
26333     chars: "\u01CA",
26334   }, {
26335     base: 'Nj',
26336     chars: "\u01CB",
26337   }, {
26338     base: 'O',
26339     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",
26340   }, {
26341     base: 'OE',
26342     chars: "\u0152",
26343   }, {
26344     base: 'OI',
26345     chars: "\u01A2",
26346   }, {
26347     base: 'OO',
26348     chars: "\uA74E",
26349   }, {
26350     base: 'OU',
26351     chars: "\u0222",
26352   }, {
26353     base: 'P',
26354     chars: "\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754",
26355   }, {
26356     base: 'Q',
26357     chars: "\u24C6\uFF31\uA756\uA758\u024A",
26358   }, {
26359     base: 'R',
26360     chars: "\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782",
26361   }, {
26362     base: 'S',
26363     chars: "\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784",
26364   }, {
26365     base: 'T',
26366     chars: "\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786",
26367   }, {
26368     base: 'Th',
26369     chars: "\u00DE",
26370   }, {
26371     base: 'TZ',
26372     chars: "\uA728",
26373   }, {
26374     base: 'U',
26375     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",
26376   }, {
26377     base: 'V',
26378     chars: "\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245",
26379   }, {
26380     base: 'VY',
26381     chars: "\uA760",
26382   }, {
26383     base: 'W',
26384     chars: "\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72",
26385   }, {
26386     base: 'X',
26387     chars: "\u24CD\uFF38\u1E8A\u1E8C",
26388   }, {
26389     base: 'Y',
26390     chars: "\u24CE\uFF39\u1EF2\xDD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE",
26391   }, {
26392     base: 'Z',
26393     chars: "\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762",
26394   }, {
26395     base: 'a',
26396     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",
26397   }, {
26398     base: 'aa',
26399     chars: "\uA733",
26400   }, {
26401     base: 'ae',
26402     chars: "\u00E6\u01FD\u01E3",
26403   }, {
26404     base: 'ao',
26405     chars: "\uA735",
26406   }, {
26407     base: 'au',
26408     chars: "\uA737",
26409   }, {
26410     base: 'av',
26411     chars: "\uA739\uA73B",
26412   }, {
26413     base: 'ay',
26414     chars: "\uA73D",
26415   }, {
26416     base: 'b',
26417     chars: "\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253\u0182",
26418   }, {
26419     base: 'c',
26420     chars: "\uFF43\u24D2\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184",
26421   }, {
26422     base: 'd',
26423     chars: "\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\u018B\u13E7\u0501\uA7AA",
26424   }, {
26425     base: 'dh',
26426     chars: "\u00F0",
26427   }, {
26428     base: 'dz',
26429     chars: "\u01F3\u01C6",
26430   }, {
26431     base: 'e',
26432     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",
26433   }, {
26434     base: 'f',
26435     chars: "\u24D5\uFF46\u1E1F\u0192",
26436   }, {
26437     base: 'ff',
26438     chars: "\uFB00",
26439   }, {
26440     base: 'fi',
26441     chars: "\uFB01",
26442   }, {
26443     base: 'fl',
26444     chars: "\uFB02",
26445   }, {
26446     base: 'ffi',
26447     chars: "\uFB03",
26448   }, {
26449     base: 'ffl',
26450     chars: "\uFB04",
26451   }, {
26452     base: 'g',
26453     chars: "\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\uA77F\u1D79",
26454   }, {
26455     base: 'h',
26456     chars: "\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265",
26457   }, {
26458     base: 'hv',
26459     chars: "\u0195",
26460   }, {
26461     base: 'i',
26462     chars: "\u24D8\uFF49\xEC\xED\xEE\u0129\u012B\u012D\xEF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131",
26463   }, {
26464     base: 'j',
26465     chars: "\u24D9\uFF4A\u0135\u01F0\u0249",
26466   }, {
26467     base: 'k',
26468     chars: "\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3",
26469   }, {
26470     base: 'l',
26471     chars: "\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747\u026D",
26472   }, {
26473     base: 'lj',
26474     chars: "\u01C9",
26475   }, {
26476     base: 'm',
26477     chars: "\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F",
26478   }, {
26479     base: 'n',
26480     chars: "\u24DD\uFF4E\u01F9\u0144\xF1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5\u043B\u0509",
26481   }, {
26482     base: 'nj',
26483     chars: "\u01CC",
26484   }, {
26485     base: 'o',
26486     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",
26487   }, {
26488     base: 'oe',
26489     chars: "\u0153",
26490   }, {
26491     base: 'oi',
26492     chars: "\u01A3",
26493   }, {
26494     base: 'oo',
26495     chars: "\uA74F",
26496   }, {
26497     base: 'ou',
26498     chars: "\u0223",
26499   }, {
26500     base: 'p',
26501     chars: "\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755\u03C1",
26502   }, {
26503     base: 'q',
26504     chars: "\u24E0\uFF51\u024B\uA757\uA759",
26505   }, {
26506     base: 'r',
26507     chars: "\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783",
26508   }, {
26509     base: 's',
26510     chars: "\u24E2\uFF53\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B\u0282",
26511   }, {
26512     base: 'ss',
26513     chars: "\xDF",
26514   }, {
26515     base: 't',
26516     chars: "\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787",
26517   }, {
26518     base: 'th',
26519     chars: "\u00FE",
26520   }, {
26521     base: 'tz',
26522     chars: "\uA729",
26523   }, {
26524     base: 'u',
26525     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",
26526   }, {
26527     base: 'v',
26528     chars: "\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C",
26529   }, {
26530     base: 'vy',
26531     chars: "\uA761",
26532   }, {
26533     base: 'w',
26534     chars: "\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73",
26535   }, {
26536     base: 'x',
26537     chars: "\u24E7\uFF58\u1E8B\u1E8D",
26538   }, {
26539     base: 'y',
26540     chars: "\u24E8\uFF59\u1EF3\xFD\u0177\u1EF9\u0233\u1E8F\xFF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF",
26541   }, {
26542     base: 'z',
26543     chars: "\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763",
26544   }
26545 ];
26546
26547 var diacriticsMap = {};
26548 for (var i = 0; i < replacementList.length; i += 1) {
26549   var chars = replacementList[i].chars;
26550   for (var j = 0; j < chars.length; j += 1) {
26551     diacriticsMap[chars[j]] = replacementList[i].base;
26552   }
26553 }
26554
26555 function removeDiacritics(str) {
26556   return str.replace(/[^\u0000-\u007e]/g, function(c) {
26557     return diacriticsMap[c] || c;
26558   });
26559 }
26560
26561 // see https://github.com/openstreetmap/iD/pull/3707
26562 // https://gist.github.com/mapmeld/556b09ddec07a2044c76e1ef45f01c60
26563
26564 var chars$1 = {
26565     // madda above alef
26566     1570: { initial: 'آ‎', isolated: 'ﺁ', medial: 'ﺁ', final: 'ﺂ' },
26567
26568     // hamza above and below alef
26569     1571: { initial: 'أ', isolated: 'ﺃ', medial: '', final: 'ﺄ' },
26570     // 1572 is ؤ
26571     1573: { initial: 'إ', isolated: 'ﺇ', medial: '', final: 'ﺈ' },
26572     // 1574 is ئ
26573     1575: { initial: 'ا', isolated: 'ا', medial: '', final: 'ﺎ' },
26574     1576: { initial: 'ﺑ', isolated: 'ﺏ', medial: 'ﺒ', final: 'ﺐ' },
26575
26576     // 1577 ة
26577     1577: { initial: '', isolated: 'ة', medial: '', final: 'ﺔ' },
26578
26579     1578: { initial: 'ﺗ', isolated: 'ﺕ', medial: 'ﺘ', final: 'ﺖ' },
26580     1579: { initial: 'ﺛ', isolated: 'ﺙ', medial: 'ﺜ', final: 'ﺚ' },
26581     1580: { initial: 'ﺟ', isolated: 'ﺝ', medial: 'ﺠ', final: 'ﺞ' },
26582     1581: { initial: 'ﺣ', isolated: 'ﺡ', medial: 'ﺤ', final: 'ﺢ' },
26583     1582: { initial: 'ﺧ', isolated: 'ﺥ', medial: 'ﺨ', final: 'ﺦ' },
26584     1583: { initial: 'ﺩ', isolated: 'ﺩ', medial: '', final: 'ﺪ' },
26585     1584: { initial: 'ﺫ', isolated: 'ﺫ', medial: '', final: 'ﺬ' },
26586     1585: { initial: 'ﺭ', isolated: 'ﺭ', medial: '', final: 'ﺮ' },
26587     1586: { initial: 'ﺯ', isolated: 'ﺯ', medial: '', final: 'ﺰ' },
26588     1688: { initial: 'ﮊ', isolated: 'ﮊ', medial: '', final: 'ﮋ' },
26589     1587: { initial: 'ﺳ', isolated: 'ﺱ', medial: 'ﺴ', final: 'ﺲ' },
26590     1588: { initial: 'ﺷ', isolated: 'ﺵ', medial: 'ﺸ', final: 'ﺶ' },
26591     1589: { initial: 'ﺻ', isolated: 'ﺹ', medial: 'ﺼ', final: 'ﺺ' },
26592     1590: { initial: 'ﺿ', isolated: 'ﺽ', medial: 'ﻀ', final: 'ﺾ' },
26593     1591: { initial: 'ﻃ', isolated: 'ﻁ', medial: 'ﻄ', final: 'ﻂ' },
26594     1592: { initial: 'ﻇ', isolated: 'ﻅ', medial: 'ﻈ', final: 'ﻆ' },
26595     1593: { initial: 'ﻋ', isolated: 'ﻉ', medial: 'ﻌ', final: 'ﻊ' },
26596     1594: { initial: 'ﻏ', isolated: 'ﻍ', medial: 'ﻐ', final: 'ﻎ' },
26597
26598     // 1595 ػ - may be very rare
26599
26600     1601: { initial: 'ﻓ', isolated: 'ﻑ', medial: 'ﻔ', final: 'ﻒ' },
26601     1602: { initial: 'ﻗ', isolated: 'ﻕ', medial: 'ﻘ', final: 'ﻖ' },
26602     1604: { initial: 'ﻟ', isolated: 'ﻝ', medial: 'ﻠ', final: 'ﻞ' },
26603     1605: { initial: 'ﻣ', isolated: 'ﻡ', medial: 'ﻤ', final: 'ﻢ' },
26604     1606: { initial: 'ﻧ', isolated: 'ﻥ', medial: 'ﻨ', final: 'ﻦ' },
26605     1607: { initial: 'ﻫ', isolated: 'ﻩ', medial: 'ﻬ', final: 'ﻪ' },
26606     1608: { initial: 'ﻭ', isolated: 'ﻭ', medial: '', final: 'ﻮ' },
26607
26608     // 1609 ى
26609     1609: { initial: 'ﯨ', isolated: 'ﻯ', medial: 'ﯩ', final: 'ﻰ' },
26610     // 1610 ي
26611     1610: { initial: 'ﻳ', isolated: 'ﻱ', medial: 'ﻴ', final: 'ﻲ' },
26612
26613     // short vowel sounds / tashkil markings
26614
26615     1662: { initial: 'ﭘ', isolated: 'ﭖ', medial: 'ﭙ', final: 'ﭗ' },
26616
26617     1670: { initial: 'ﭼ', isolated: 'ﭺ', medial: 'ﭽ', final: 'ﭻ' },
26618     1603: { initial: 'ﻛ', isolated: 'ﻙ', medial: 'ﻜ', final: 'ﻚ' },
26619     1705: { initial: 'ﻛ', isolated: 'ﮎ', medial: 'ﻜ', final: 'ﮏ' },
26620     1711: { initial: 'ﮔ', isolated: 'ﮒ', medial: 'ﮕ', final: 'ﮓ' },
26621     1740: { initial: 'ﻳ', isolated: 'ﻯ', medial: 'ﻴ', final: 'ﻰ' },
26622     5000: { initial: 'ﻻ', isolated: 'ﻻ', medial: '', final: 'ﻼ' }
26623 };
26624
26625 var rtlRegex = /[\u0590-\u05FF\u0600-\u06FF\u0780-\u07BF]/;
26626
26627 function fixRTLTextForSvg(inputText) {
26628     var context = true;
26629     var ret = '';
26630     var rtlBuffer = [];
26631     var arabicRegex = /[\u0600-\u06FF]/g;
26632     var arabicTashkil = /[\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED]/;
26633     var thaanaVowel = /[\u07A6-\u07B0]/;
26634     var hebrewSign = /[\u0591-\u05bd\u05bf\u05c1-\u05c5\u05c7]/;
26635
26636     if (!arabicRegex.test(inputText)) {
26637         // Hebrew or Thaana RTL script
26638         for (var n = 0; n < inputText.length; n++) {
26639             var c = inputText[n];
26640             if ((thaanaVowel.test(c) || hebrewSign.test(c)) && rtlBuffer.length) {
26641                 rtlBuffer[rtlBuffer.length - 1] += c;
26642             } else if (rtlRegex.test(c)) {
26643                 rtlBuffer.push(c);
26644             } else if (c === ' ' && rtlBuffer.length) {
26645                 // whitespace within RTL text
26646                 rtlBuffer = [rtlBuffer.reverse().join('') + ' '];
26647             } else {
26648                 // non-RTL character
26649                 ret += rtlBuffer.reverse().join('') + c;
26650                 rtlBuffer = [];
26651             }
26652         }
26653     } else {
26654         for (var i = 0, l = inputText.length; i < l; i++) {
26655             var code = inputText[i].charCodeAt(0);
26656             var nextCode = inputText[i + 1] ? inputText[i + 1].charCodeAt(0) : 0;
26657
26658             if (!chars$1[code]) {
26659                 if (code === 32 && rtlBuffer.length) {
26660                     // whitespace
26661                     rtlBuffer = [rtlBuffer.reverse().join('') + ' '];
26662                 } else if (arabicTashkil.test(inputText[i]) && rtlBuffer.length) {
26663                     // tashkil mark
26664                     rtlBuffer[rtlBuffer.length - 1] += inputText[i];
26665                 } else {
26666                     // non-RTL character
26667                     ret += rtlBuffer.reverse().join('') + inputText[i];
26668                     rtlBuffer = [];
26669                 }
26670                 continue;
26671             }
26672             if (context) {
26673                 if (i === l - 1 || nextCode === 32) {
26674                     rtlBuffer.push(chars$1[code].isolated);
26675                 } else {
26676                     // special case for لا
26677                     if (code === 1604 && nextCode === 1575) {
26678                         rtlBuffer.push(chars$1[5000].initial);
26679                         i++;
26680                         context = true;
26681                         continue;
26682                     }
26683                     rtlBuffer.push(chars$1[code].initial);
26684                 }
26685             } else {
26686                 if (i === l - 1 || nextCode === 32){
26687                     rtlBuffer.push(chars$1[code].final);
26688                 } else {
26689                     // special case for ﻼ
26690                     if (code === 1604 && nextCode === 1575){
26691                         rtlBuffer.push(chars$1[5000].final);
26692                         i++;
26693                         context = true;
26694                         continue;
26695                     }
26696                     if (chars$1[code].medial === ''){
26697                         rtlBuffer.push(chars$1[code].final);
26698                     } else {
26699                         rtlBuffer.push(chars$1[code].medial);
26700                     }
26701                 }
26702             }
26703             context = (chars$1[code].medial === '') || nextCode === 32;
26704         }
26705     }
26706     ret += rtlBuffer.reverse().join('');
26707     return ret;
26708 }
26709
26710 function utilTagText(entity) {
26711     return map$4(entity.tags, function(v, k) {
26712         return k + '=' + v;
26713     }).join(', ');
26714 }
26715
26716
26717 function utilEntitySelector(ids) {
26718     return ids.length ? '.' + ids.join(',.') : 'nothing';
26719 }
26720
26721
26722 function utilEntityOrMemberSelector(ids, graph) {
26723     var s = utilEntitySelector(ids);
26724
26725     ids.forEach(function(id) {
26726         var entity = graph.hasEntity(id);
26727         if (entity && entity.type === 'relation') {
26728             entity.members.forEach(function(member) {
26729                 s += ',.' + member.id;
26730             });
26731         }
26732     });
26733
26734     return s;
26735 }
26736
26737
26738 function utilGetAllNodes(ids, graph) {
26739     var seen = {};
26740     var nodes = [];
26741     ids.forEach(getNodes);
26742     return nodes;
26743
26744     function getNodes(id) {
26745         if (seen[id]) return;
26746         seen[id] = true;
26747
26748         var entity = graph.hasEntity(id);
26749         if (!entity) return;
26750
26751         if (entity.type === 'node') {
26752             nodes.push(entity);
26753         } else if (entity.type === 'way') {
26754             entity.nodes.forEach(getNodes);
26755         } else {
26756             entity.members.map(function(member) { return member.id; }).forEach(getNodes);
26757         }
26758     }
26759 }
26760
26761
26762 function utilDisplayName(entity) {
26763     var localizedNameKey = 'name:' + utilDetect().locale.toLowerCase().split('-')[0],
26764         name = entity.tags[localizedNameKey] || entity.tags.name || '',
26765         network = entity.tags.cycle_network || entity.tags.network;
26766
26767     if (!name && entity.tags.ref) {
26768         name = entity.tags.ref;
26769         if (network) {
26770             name = network + ' ' + name;
26771         }
26772     }
26773
26774     return name;
26775 }
26776
26777
26778 function utilDisplayNameForPath(entity) {
26779     var name = utilDisplayName(entity);
26780     var isFirefox = utilDetect().browser.toLowerCase().indexOf('firefox') > -1;
26781
26782     if (!isFirefox && name && rtlRegex.test(name)) {
26783         name = fixRTLTextForSvg(name);
26784     }
26785
26786     return name;
26787 }
26788
26789
26790 function utilDisplayType(id) {
26791     return {
26792         n: t('inspector.node'),
26793         w: t('inspector.way'),
26794         r: t('inspector.relation')
26795     }[id.charAt(0)];
26796 }
26797
26798
26799 function utilStringQs(str) {
26800     return str.split('&').reduce(function(obj, pair){
26801         var parts = pair.split('=');
26802         if (parts.length === 2) {
26803             obj[parts[0]] = (null === parts[1]) ? '' : decodeURIComponent(parts[1]);
26804         }
26805         return obj;
26806     }, {});
26807 }
26808
26809
26810 function utilQsString(obj, noencode) {
26811     function softEncode(s) {
26812       // encode everything except special characters used in certain hash parameters:
26813       // "/" in map states, ":", ",", {" and "}" in background
26814       return encodeURIComponent(s).replace(/(%2F|%3A|%2C|%7B|%7D)/g, decodeURIComponent);
26815     }
26816     return Object.keys(obj).sort().map(function(key) {
26817         return encodeURIComponent(key) + '=' + (
26818             noencode ? softEncode(obj[key]) : encodeURIComponent(obj[key]));
26819     }).join('&');
26820 }
26821
26822
26823 function utilPrefixDOMProperty(property) {
26824     var prefixes = ['webkit', 'ms', 'moz', 'o'],
26825         i = -1,
26826         n = prefixes.length,
26827         s = document.body;
26828
26829     if (property in s)
26830         return property;
26831
26832     property = property.substr(0, 1).toUpperCase() + property.substr(1);
26833
26834     while (++i < n)
26835         if (prefixes[i] + property in s)
26836             return prefixes[i] + property;
26837
26838     return false;
26839 }
26840
26841
26842 function utilPrefixCSSProperty(property) {
26843     var prefixes = ['webkit', 'ms', 'Moz', 'O'],
26844         i = -1,
26845         n = prefixes.length,
26846         s = document.body.style;
26847
26848     if (property.toLowerCase() in s)
26849         return property.toLowerCase();
26850
26851     while (++i < n)
26852         if (prefixes[i] + property in s)
26853             return '-' + prefixes[i].toLowerCase() + property.replace(/([A-Z])/g, '-$1').toLowerCase();
26854
26855     return false;
26856 }
26857
26858
26859 var transformProperty;
26860 function utilSetTransform(el, x, y, scale) {
26861     var prop = transformProperty = transformProperty || utilPrefixCSSProperty('Transform'),
26862         translate = utilDetect().opera ?
26863             'translate('   + x + 'px,' + y + 'px)' :
26864             'translate3d(' + x + 'px,' + y + 'px,0)';
26865     return el.style(prop, translate + (scale ? ' scale(' + scale + ')' : ''));
26866 }
26867
26868
26869 // Calculates Levenshtein distance between two strings
26870 // see:  https://en.wikipedia.org/wiki/Levenshtein_distance
26871 // first converts the strings to lowercase and replaces diacritic marks with ascii equivalents.
26872 function utilEditDistance(a, b) {
26873     a = remove$1(a.toLowerCase());
26874     b = remove$1(b.toLowerCase());
26875     if (a.length === 0) return b.length;
26876     if (b.length === 0) return a.length;
26877     var matrix = [];
26878     for (var i = 0; i <= b.length; i++) { matrix[i] = [i]; }
26879     for (var j = 0; j <= a.length; j++) { matrix[0][j] = j; }
26880     for (i = 1; i <= b.length; i++) {
26881         for (j = 1; j <= a.length; j++) {
26882             if (b.charAt(i-1) === a.charAt(j-1)) {
26883                 matrix[i][j] = matrix[i-1][j-1];
26884             } else {
26885                 matrix[i][j] = Math.min(matrix[i-1][j-1] + 1, // substitution
26886                     Math.min(matrix[i][j-1] + 1, // insertion
26887                     matrix[i-1][j] + 1)); // deletion
26888             }
26889         }
26890     }
26891     return matrix[b.length][a.length];
26892 }
26893
26894
26895 // a d3.mouse-alike which
26896 // 1. Only works on HTML elements, not SVG
26897 // 2. Does not cause style recalculation
26898 function utilFastMouse(container) {
26899     var rect = container.getBoundingClientRect(),
26900         rectLeft = rect.left,
26901         rectTop = rect.top,
26902         clientLeft = +container.clientLeft,
26903         clientTop = +container.clientTop;
26904     if (textDirection === 'rtl') {
26905         rectLeft = 0;
26906     }
26907     return function(e) {
26908         return [
26909             e.clientX - rectLeft - clientLeft,
26910             e.clientY - rectTop - clientTop];
26911     };
26912 }
26913
26914
26915 /* eslint-disable no-proto */
26916 var utilGetPrototypeOf = Object.getPrototypeOf || function(obj) { return obj.__proto__; };
26917 /* eslint-enable no-proto */
26918
26919
26920 function utilAsyncMap(inputs, func, callback) {
26921     var remaining = inputs.length,
26922         results = [],
26923         errors = [];
26924
26925     inputs.forEach(function(d, i) {
26926         func(d, function done(err, data) {
26927             errors[i] = err;
26928             results[i] = data;
26929             remaining--;
26930             if (!remaining) callback(errors, results);
26931         });
26932     });
26933 }
26934
26935
26936 // wraps an index to an interval [0..length-1]
26937 function utilWrap(index, length) {
26938     if (index < 0)
26939         index += Math.ceil(-index/length)*length;
26940     return index % length;
26941 }
26942
26943
26944 /**
26945  * a replacement for functor
26946  *
26947  * @param {*} value any value
26948  * @returns {Function} a function that returns that value or the value if it's a function
26949  */
26950 function utilFunctor(value) {
26951     if (typeof value === 'function') return value;
26952     return function() {
26953         return value;
26954     };
26955 }
26956
26957
26958 function utilNoAuto(selection) {
26959     var isText = (selection.size() && selection.node().tagName.toLowerCase() === 'textarea');
26960
26961     return selection
26962         .attr('autocomplete', 'off')
26963         .attr('autocorrect', 'off')
26964         .attr('autocapitalize', 'off')
26965         .attr('spellcheck', isText ? 'true' : 'false');
26966 }
26967
26968 // note the function should be of low priority
26969 // and should not be returning a value.
26970 function utilCallWhenIdle(func, timeout) {
26971     return function() {
26972         var args = arguments;
26973         var that = this;
26974         window.requestIdleCallback(function() {
26975             func.apply(that, args);
26976         }, {timeout: timeout});
26977     };
26978 }
26979
26980 // Like selection.property('value', ...), but avoids no-op value sets,
26981 // which can result in layout/repaint thrashing in some situations.
26982 function utilGetSetValue(selection, value) {
26983     function d3_selection_value(value) {
26984         function valueNull() {
26985             delete this.value;
26986         }
26987
26988         function valueConstant() {
26989             if (this.value !== value) {
26990                 this.value = value;
26991             }
26992         }
26993
26994         function valueFunction() {
26995             var x = value.apply(this, arguments);
26996             if (x == null) {
26997                 delete this.value;
26998             } else if (this.value !== x) {
26999                 this.value = x;
27000             }
27001         }
27002
27003         return value == null
27004             ? valueNull : (typeof value === 'function'
27005             ? valueFunction : valueConstant);
27006     }
27007
27008     if (arguments.length === 1) {
27009         return selection.property('value');
27010     }
27011
27012     return selection.each(d3_selection_value(value));
27013 }
27014
27015 function utilIdleWorker(tasks, processor, callback) {
27016     var results = [], result;
27017     for (var i = 0; i < tasks.length; i++) {
27018         result = processor(tasks[i]);
27019         if (result) results.push(result);
27020     }
27021     callback(results);
27022
27023     // var processed = [];
27024     // var currentPos = 0;
27025     // var totalTasks = tasks.length;
27026
27027     // function worker(deadline) {
27028     //     while (deadline.timeRemaining() > 0 && currentPos < totalTasks) {
27029     //         var result = processor(tasks[currentPos]);
27030
27031     //         // if falsy dont add to the processed list
27032     //         if (result) processed.push(result);
27033     //         currentPos++;
27034     //     }
27035
27036     //     // more tasks are left, we might need more idleCallbacks
27037     //     if (currentPos < totalTasks) {
27038     //         return window.requestIdleCallback(function(deadline) {worker(deadline);});
27039     //     }
27040
27041     //     // tasks are completed
27042     //     return callback(processed);
27043     // }
27044
27045     // window.requestIdleCallback(function(deadline) {worker(deadline);});
27046 }
27047
27048 // shim
27049 window.requestIdleCallback =
27050     window.requestIdleCallback ||
27051     function(cb) {
27052         var start = Date.now();
27053         return setTimeout(function() {
27054             cb({
27055                 didTimeout: false,
27056                 timeRemaining: function() {
27057                     return Math.max(0, 50 - (Date.now() - start));
27058                 }
27059             });
27060         }, 1);
27061     };
27062
27063 window.cancelIdleCallback =
27064     window.cancelIdleCallback ||
27065     function(id) {
27066         clearTimeout(id);
27067     };
27068
27069 // Copies a variable number of methods from source to target.
27070 function utilRebind(target, source) {
27071     var i = 1, n = arguments.length, method;
27072     while (++i < n) {
27073         target[method = arguments[i]] = d3_rebind(target, source, source[method]);
27074     }
27075     return target;
27076 }
27077
27078 // Method is assumed to be a standard D3 getter-setter:
27079 // If passed with no arguments, gets the value.
27080 // If passed with arguments, sets the value and returns the target.
27081 function d3_rebind(target, source, method) {
27082     return function() {
27083         var value = method.apply(source, arguments);
27084         return value === source ? target : value;
27085     };
27086 }
27087
27088 // A per-domain session mutex backed by a cookie and dead man's
27089 // switch. If the session crashes, the mutex will auto-release
27090 // after 5 seconds.
27091
27092 function utilSessionMutex(name) {
27093     var mutex = {},
27094         intervalID;
27095
27096     function renew() {
27097         var expires = new Date();
27098         expires.setSeconds(expires.getSeconds() + 5);
27099         document.cookie = name + '=1; expires=' + expires.toUTCString();
27100     }
27101
27102     mutex.lock = function() {
27103         if (intervalID) return true;
27104         var cookie = document.cookie.replace(new RegExp('(?:(?:^|.*;)\\s*' + name + '\\s*\\=\\s*([^;]*).*$)|^.*$'), '$1');
27105         if (cookie) return false;
27106         renew();
27107         intervalID = window.setInterval(renew, 4000);
27108         return true;
27109     };
27110
27111     mutex.unlock = function() {
27112         if (!intervalID) return;
27113         document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT';
27114         clearInterval(intervalID);
27115         intervalID = null;
27116     };
27117
27118     mutex.locked = function() {
27119         return !!intervalID;
27120     };
27121
27122     return mutex;
27123 }
27124
27125 function utilSuggestNames(preset, suggestions) {
27126     preset = preset.id.split('/', 2);
27127     var k = preset[0],
27128         v = preset[1];
27129
27130     return function(value, callback) {
27131         var result = [];
27132         if (value && value.length > 2) {
27133             if (suggestions[k] && suggestions[k][v]) {
27134                 for (var sugg in suggestions[k][v]) {
27135                     var dist = utilEditDistance(value, sugg.substring(0, value.length));
27136                     if (dist < 3) {
27137                         result.push({
27138                             title: sugg,
27139                             value: sugg,
27140                             dist: dist
27141                         });
27142                     }
27143                 }
27144             }
27145             result.sort(function(a, b) {
27146                 return a.dist - b.dist;
27147             });
27148         }
27149         result = result.slice(0,3);
27150         callback(result);
27151     };
27152 }
27153
27154 function utilTriggerEvent(target, type) {
27155     target.each(function() {
27156         var evt = document.createEvent('HTMLEvents');
27157         evt.initEvent(type, true, true);
27158         this.dispatchEvent(evt);
27159     });
27160 }
27161
27162 function validationDeprecatedTag() {
27163
27164     var validation = function(changes) {
27165         var warnings = [];
27166         for (var i = 0; i < changes.created.length; i++) {
27167             var change = changes.created[i],
27168                 deprecatedTags = change.deprecatedTags();
27169
27170             if (!isEmpty(deprecatedTags)) {
27171                 var tags = utilTagText({ tags: deprecatedTags });
27172                 warnings.push({
27173                     id: 'deprecated_tags',
27174                     message: t('validations.deprecated_tags', { tags: tags }),
27175                     entity: change
27176                 });
27177             }
27178         }
27179
27180         return warnings;
27181     };
27182
27183
27184     return validation;
27185 }
27186
27187 function validationDisconnectedHighway() {
27188
27189     function isDisconnectedHighway(entity, graph) {
27190         if (!entity.tags.highway) return false;
27191         if (entity.geometry(graph) !== 'line') return false;
27192
27193         return graph.childNodes(entity)
27194             .every(function(vertex) {
27195                 var parents = graph.parentWays(vertex);
27196                 if (parents.length === 1) {  // standalone vertex
27197                     return true;
27198                 } else {                     // shared vertex
27199                     return !vertex.tags.entrance &&
27200                         parents.filter(function(parent) {
27201                             return parent.tags.highway && parent !== entity;
27202                         }).length === 0;
27203                 }
27204             });
27205     }
27206
27207
27208     var validation = function(changes, graph) {
27209         var warnings = [];
27210         for (var i = 0; i < changes.created.length; i++) {
27211             var entity = changes.created[i];
27212
27213             if (isDisconnectedHighway(entity, graph)) {
27214                 warnings.push({
27215                     id: 'disconnected_highway',
27216                     message: t('validations.disconnected_highway'),
27217                     tooltip: t('validations.disconnected_highway_tooltip'),
27218                     entity: entity
27219                 });
27220             }
27221         }
27222
27223         return warnings;
27224     };
27225
27226
27227     return validation;
27228 }
27229
27230 function validationManyDeletions() {
27231     var threshold = 100;
27232
27233     var validation = function(changes) {
27234         var warnings = [];
27235         if (changes.deleted.length > threshold) {
27236             warnings.push({
27237                 id: 'many_deletions',
27238                 message: t('validations.many_deletions', { n: changes.deleted.length })
27239             });
27240         }
27241
27242         return warnings;
27243     };
27244
27245
27246     return validation;
27247 }
27248
27249 function validationMissingTag() {
27250
27251     // Slightly stricter check than Entity#isUsed (#3091)
27252     function hasTags(entity, graph) {
27253         return without(Object.keys(entity.tags), 'area', 'name').length > 0 ||
27254             graph.parentRelations(entity).length > 0;
27255     }
27256
27257     var validation = function(changes, graph) {
27258         var types = ['point', 'line', 'area', 'relation'],
27259             warnings = [];
27260
27261         for (var i = 0; i < changes.created.length; i++) {
27262             var change = changes.created[i],
27263                 geometry = change.geometry(graph);
27264
27265             if (types.indexOf(geometry) !== -1 && !hasTags(change, graph)) {
27266                 warnings.push({
27267                     id: 'missing_tag',
27268                     message: t('validations.untagged_' + geometry),
27269                     tooltip: t('validations.untagged_' + geometry + '_tooltip'),
27270                     entity: change
27271                 });
27272             }
27273         }
27274
27275         return warnings;
27276     };
27277
27278
27279     return validation;
27280 }
27281
27282 function validationOldMultipolygon() {
27283
27284     return function validation(changes, graph) {
27285         var warnings = [];
27286         for (var i = 0; i < changes.created.length; i++) {
27287             var entity = changes.created[i];
27288             var parent = osmIsSimpleMultipolygonOuterMember(entity, graph);
27289             if (parent) {
27290                 warnings.push({
27291                     id: 'old_multipolygon',
27292                     message: t('validations.old_multipolygon'),
27293                     tooltip: t('validations.old_multipolygon_tooltip'),
27294                     entity: parent
27295                 });
27296             }
27297         }
27298         return warnings;
27299     };
27300 }
27301
27302 // https://github.com/openstreetmap/josm/blob/mirror/src/org/
27303 // openstreetmap/josm/data/validation/tests/UnclosedWays.java#L80
27304 function validationTagSuggestsArea() {
27305
27306     function tagSuggestsArea(tags) {
27307         if (isEmpty(tags)) return false;
27308
27309         var presence = ['landuse', 'amenities', 'tourism', 'shop'];
27310         for (var i = 0; i < presence.length; i++) {
27311             if (tags[presence[i]] !== undefined) {
27312                 return presence[i] + '=' + tags[presence[i]];
27313             }
27314         }
27315
27316         if (tags.building && tags.building === 'yes') return 'building=yes';
27317     }
27318
27319
27320     var validation = function(changes, graph) {
27321         var warnings = [];
27322         for (var i = 0; i < changes.created.length; i++) {
27323             var change = changes.created[i],
27324                 geometry = change.geometry(graph),
27325                 suggestion = (geometry === 'line' ? tagSuggestsArea(change.tags) : undefined);
27326
27327             if (suggestion) {
27328                 warnings.push({
27329                     id: 'tag_suggests_area',
27330                     message: t('validations.tag_suggests_area', { tag: suggestion }),
27331                     entity: change
27332                 });
27333             }
27334         }
27335
27336         return warnings;
27337     };
27338
27339
27340     return validation;
27341 }
27342
27343
27344
27345 var Validations = Object.freeze({
27346         validationDeprecatedTag: validationDeprecatedTag,
27347         validationDisconnectedHighway: validationDisconnectedHighway,
27348         validationManyDeletions: validationManyDeletions,
27349         validationMissingTag: validationMissingTag,
27350         validationOldMultipolygon: validationOldMultipolygon,
27351         validationTagSuggestsArea: validationTagSuggestsArea
27352 });
27353
27354 /**
27355  * Performs a deep comparison between two values to determine if they are
27356  * equivalent.
27357  *
27358  * **Note:** This method supports comparing arrays, array buffers, booleans,
27359  * date objects, error objects, maps, numbers, `Object` objects, regexes,
27360  * sets, strings, symbols, and typed arrays. `Object` objects are compared
27361  * by their own, not inherited, enumerable properties. Functions and DOM
27362  * nodes are compared by strict equality, i.e. `===`.
27363  *
27364  * @static
27365  * @memberOf _
27366  * @since 0.1.0
27367  * @category Lang
27368  * @param {*} value The value to compare.
27369  * @param {*} other The other value to compare.
27370  * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
27371  * @example
27372  *
27373  * var object = { 'a': 1 };
27374  * var other = { 'a': 1 };
27375  *
27376  * _.isEqual(object, other);
27377  * // => true
27378  *
27379  * object === other;
27380  * // => false
27381  */
27382 function isEqual(value, other) {
27383   return baseIsEqual(value, other);
27384 }
27385
27386 /*
27387     iD.Difference represents the difference between two graphs.
27388     It knows how to calculate the set of entities that were
27389     created, modified, or deleted, and also contains the logic
27390     for recursively extending a difference to the complete set
27391     of entities that will require a redraw, taking into account
27392     child and parent relationships.
27393  */
27394 function coreDifference(base, head) {
27395     var changes = {},
27396         difference$$1 = {},
27397         length = 0;
27398
27399
27400     function changed(h, b) {
27401         return h !== b && !isEqual(omit(h, 'v'), omit(b, 'v'));
27402     }
27403
27404
27405     forEach(head.entities, function(h, id) {
27406         var b = base.entities[id];
27407         if (changed(h, b)) {
27408             changes[id] = {base: b, head: h};
27409             length++;
27410         }
27411     });
27412
27413
27414     forEach(base.entities, function(b, id) {
27415         var h = head.entities[id];
27416         if (!changes[id] && changed(h, b)) {
27417             changes[id] = {base: b, head: h};
27418             length++;
27419         }
27420     });
27421
27422
27423     function addParents(parents, result) {
27424         for (var i = 0; i < parents.length; i++) {
27425             var parent = parents[i];
27426
27427             if (parent.id in result)
27428                 continue;
27429
27430             result[parent.id] = parent;
27431             addParents(head.parentRelations(parent), result);
27432         }
27433     }
27434
27435
27436     difference$$1.length = function() {
27437         return length;
27438     };
27439
27440
27441     difference$$1.changes = function() {
27442         return changes;
27443     };
27444
27445
27446     difference$$1.extantIDs = function() {
27447         var result = [];
27448         forEach(changes, function(change, id) {
27449             if (change.head) result.push(id);
27450         });
27451         return result;
27452     };
27453
27454
27455     difference$$1.modified = function() {
27456         var result = [];
27457         forEach(changes, function(change) {
27458             if (change.base && change.head) result.push(change.head);
27459         });
27460         return result;
27461     };
27462
27463
27464     difference$$1.created = function() {
27465         var result = [];
27466         forEach(changes, function(change) {
27467             if (!change.base && change.head) result.push(change.head);
27468         });
27469         return result;
27470     };
27471
27472
27473     difference$$1.deleted = function() {
27474         var result = [];
27475         forEach(changes, function(change) {
27476             if (change.base && !change.head) result.push(change.base);
27477         });
27478         return result;
27479     };
27480
27481
27482     difference$$1.summary = function() {
27483         var relevant = {};
27484
27485         function addEntity(entity, graph, changeType) {
27486             relevant[entity.id] = {
27487                 entity: entity,
27488                 graph: graph,
27489                 changeType: changeType
27490             };
27491         }
27492
27493         function addParents(entity) {
27494             var parents = head.parentWays(entity);
27495             for (var j = parents.length - 1; j >= 0; j--) {
27496                 var parent = parents[j];
27497                 if (!(parent.id in relevant)) addEntity(parent, head, 'modified');
27498             }
27499         }
27500
27501         forEach(changes, function(change) {
27502             if (change.head && change.head.geometry(head) !== 'vertex') {
27503                 addEntity(change.head, head, change.base ? 'modified' : 'created');
27504
27505             } else if (change.base && change.base.geometry(base) !== 'vertex') {
27506                 addEntity(change.base, base, 'deleted');
27507
27508             } else if (change.base && change.head) { // modified vertex
27509                 var moved    = !isEqual(change.base.loc,  change.head.loc),
27510                     retagged = !isEqual(change.base.tags, change.head.tags);
27511
27512                 if (moved) {
27513                     addParents(change.head);
27514                 }
27515
27516                 if (retagged || (moved && change.head.hasInterestingTags())) {
27517                     addEntity(change.head, head, 'modified');
27518                 }
27519
27520             } else if (change.head && change.head.hasInterestingTags()) { // created vertex
27521                 addEntity(change.head, head, 'created');
27522
27523             } else if (change.base && change.base.hasInterestingTags()) { // deleted vertex
27524                 addEntity(change.base, base, 'deleted');
27525             }
27526         });
27527
27528         return values$1(relevant);
27529     };
27530
27531
27532     difference$$1.complete = function(extent) {
27533         var result = {}, id, change;
27534
27535         for (id in changes) {
27536             change = changes[id];
27537
27538             var h = change.head,
27539                 b = change.base,
27540                 entity = h || b;
27541
27542             if (extent &&
27543                 (!h || !h.intersects(extent, head)) &&
27544                 (!b || !b.intersects(extent, base)))
27545                 continue;
27546
27547             result[id] = h;
27548
27549             if (entity.type === 'way') {
27550                 var nh = h ? h.nodes : [],
27551                     nb = b ? b.nodes : [],
27552                     diff, i;
27553
27554                 diff = difference(nh, nb);
27555                 for (i = 0; i < diff.length; i++) {
27556                     result[diff[i]] = head.hasEntity(diff[i]);
27557                 }
27558
27559                 diff = difference(nb, nh);
27560                 for (i = 0; i < diff.length; i++) {
27561                     result[diff[i]] = head.hasEntity(diff[i]);
27562                 }
27563             }
27564
27565             addParents(head.parentWays(entity), result);
27566             addParents(head.parentRelations(entity), result);
27567         }
27568
27569         return result;
27570     };
27571
27572
27573     return difference$$1;
27574 }
27575
27576 /** Used for built-in method references. */
27577 var objectProto$18 = Object.prototype;
27578
27579 /** Used to check objects for own properties. */
27580 var hasOwnProperty$15 = objectProto$18.hasOwnProperty;
27581
27582 /**
27583  * Assigns own enumerable string keyed properties of source objects to the
27584  * destination object. Source objects are applied from left to right.
27585  * Subsequent sources overwrite property assignments of previous sources.
27586  *
27587  * **Note:** This method mutates `object` and is loosely based on
27588  * [`Object.assign`](https://mdn.io/Object/assign).
27589  *
27590  * @static
27591  * @memberOf _
27592  * @since 0.10.0
27593  * @category Object
27594  * @param {Object} object The destination object.
27595  * @param {...Object} [sources] The source objects.
27596  * @returns {Object} Returns `object`.
27597  * @see _.assignIn
27598  * @example
27599  *
27600  * function Foo() {
27601  *   this.a = 1;
27602  * }
27603  *
27604  * function Bar() {
27605  *   this.c = 3;
27606  * }
27607  *
27608  * Foo.prototype.b = 2;
27609  * Bar.prototype.d = 4;
27610  *
27611  * _.assign({ 'a': 0 }, new Foo, new Bar);
27612  * // => { 'a': 1, 'c': 3 }
27613  */
27614 var assign = createAssigner(function(object, source) {
27615   if (isPrototype(source) || isArrayLike(source)) {
27616     copyObject(source, keys$1(source), object);
27617     return;
27618   }
27619   for (var key in source) {
27620     if (hasOwnProperty$15.call(source, key)) {
27621       assignValue(object, key, source[key]);
27622     }
27623   }
27624 });
27625
27626 /* Built-in method references for those with the same name as other `lodash` methods. */
27627 var nativeMax$3 = Math.max;
27628
27629 /**
27630  * Checks if `value` is in `collection`. If `collection` is a string, it's
27631  * checked for a substring of `value`, otherwise
27632  * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
27633  * is used for equality comparisons. If `fromIndex` is negative, it's used as
27634  * the offset from the end of `collection`.
27635  *
27636  * @static
27637  * @memberOf _
27638  * @since 0.1.0
27639  * @category Collection
27640  * @param {Array|Object|string} collection The collection to inspect.
27641  * @param {*} value The value to search for.
27642  * @param {number} [fromIndex=0] The index to search from.
27643  * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
27644  * @returns {boolean} Returns `true` if `value` is found, else `false`.
27645  * @example
27646  *
27647  * _.includes([1, 2, 3], 1);
27648  * // => true
27649  *
27650  * _.includes([1, 2, 3], 1, 2);
27651  * // => false
27652  *
27653  * _.includes({ 'a': 1, 'b': 2 }, 1);
27654  * // => true
27655  *
27656  * _.includes('abcd', 'bc');
27657  * // => true
27658  */
27659 function includes(collection, value, fromIndex, guard) {
27660   collection = isArrayLike(collection) ? collection : values$1(collection);
27661   fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
27662
27663   var length = collection.length;
27664   if (fromIndex < 0) {
27665     fromIndex = nativeMax$3(length + fromIndex, 0);
27666   }
27667   return isString(collection)
27668     ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
27669     : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
27670 }
27671
27672 function coreGraph(other, mutable) {
27673     if (!(this instanceof coreGraph)) return new coreGraph(other, mutable);
27674
27675     if (other instanceof coreGraph) {
27676         var base = other.base();
27677         this.entities = assign(Object.create(base.entities), other.entities);
27678         this._parentWays = assign(Object.create(base.parentWays), other._parentWays);
27679         this._parentRels = assign(Object.create(base.parentRels), other._parentRels);
27680
27681     } else {
27682         this.entities = Object.create({});
27683         this._parentWays = Object.create({});
27684         this._parentRels = Object.create({});
27685         this.rebase(other || [], [this]);
27686     }
27687
27688     this.transients = {};
27689     this._childNodes = {};
27690     this.frozen = !mutable;
27691 }
27692
27693
27694 coreGraph.prototype = {
27695
27696     hasEntity: function(id) {
27697         return this.entities[id];
27698     },
27699
27700
27701     entity: function(id) {
27702         var entity = this.entities[id];
27703
27704         //https://github.com/openstreetmap/iD/issues/3973#issuecomment-307052376
27705         if (!entity) {
27706             entity = this.entities.__proto__[id];  // eslint-disable-line no-proto
27707         }
27708
27709         if (!entity) {
27710             throw new Error('entity ' + id + ' not found');
27711         }
27712         return entity;
27713     },
27714
27715
27716     transient: function(entity, key, fn) {
27717         var id = entity.id,
27718             transients = this.transients[id] ||
27719             (this.transients[id] = {});
27720
27721         if (transients[key] !== undefined) {
27722             return transients[key];
27723         }
27724
27725         transients[key] = fn.call(entity);
27726
27727         return transients[key];
27728     },
27729
27730
27731     parentWays: function(entity) {
27732         var parents = this._parentWays[entity.id],
27733             result = [];
27734
27735         if (parents) {
27736             for (var i = 0; i < parents.length; i++) {
27737                 result.push(this.entity(parents[i]));
27738             }
27739         }
27740         return result;
27741     },
27742
27743
27744     isPoi: function(entity) {
27745         var parentWays = this._parentWays[entity.id];
27746         return !parentWays || parentWays.length === 0;
27747     },
27748
27749
27750     isShared: function(entity) {
27751         var parentWays = this._parentWays[entity.id];
27752         return parentWays && parentWays.length > 1;
27753     },
27754
27755
27756     parentRelations: function(entity) {
27757         var parents = this._parentRels[entity.id],
27758             result = [];
27759
27760         if (parents) {
27761             for (var i = 0; i < parents.length; i++) {
27762                 result.push(this.entity(parents[i]));
27763             }
27764         }
27765         return result;
27766     },
27767
27768
27769     childNodes: function(entity) {
27770         if (this._childNodes[entity.id]) return this._childNodes[entity.id];
27771         if (!entity.nodes) return [];
27772
27773         var nodes = [];
27774         for (var i = 0; i < entity.nodes.length; i++) {
27775             nodes[i] = this.entity(entity.nodes[i]);
27776         }
27777
27778         if (debug) Object.freeze(nodes);
27779
27780         this._childNodes[entity.id] = nodes;
27781         return this._childNodes[entity.id];
27782     },
27783
27784
27785     base: function() {
27786         return {
27787             'entities': utilGetPrototypeOf(this.entities),
27788             'parentWays': utilGetPrototypeOf(this._parentWays),
27789             'parentRels': utilGetPrototypeOf(this._parentRels)
27790         };
27791     },
27792
27793
27794     // Unlike other graph methods, rebase mutates in place. This is because it
27795     // is used only during the history operation that merges newly downloaded
27796     // data into each state. To external consumers, it should appear as if the
27797     // graph always contained the newly downloaded data.
27798     rebase: function(entities, stack, force) {
27799         var base = this.base(),
27800             i, j, k, id;
27801
27802         for (i = 0; i < entities.length; i++) {
27803             var entity = entities[i];
27804
27805             if (!entity.visible || (!force && base.entities[entity.id]))
27806                 continue;
27807
27808             // Merging data into the base graph
27809             base.entities[entity.id] = entity;
27810             this._updateCalculated(undefined, entity, base.parentWays, base.parentRels);
27811
27812             // Restore provisionally-deleted nodes that are discovered to have an extant parent
27813             if (entity.type === 'way') {
27814                 for (j = 0; j < entity.nodes.length; j++) {
27815                     id = entity.nodes[j];
27816                     for (k = 1; k < stack.length; k++) {
27817                         var ents = stack[k].entities;
27818                         if (ents.hasOwnProperty(id) && ents[id] === undefined) {
27819                             delete ents[id];
27820                         }
27821                     }
27822                 }
27823             }
27824         }
27825
27826         for (i = 0; i < stack.length; i++) {
27827             stack[i]._updateRebased();
27828         }
27829     },
27830
27831
27832     _updateRebased: function() {
27833         var base = this.base(),
27834             i, k, child, id, keys;
27835
27836         keys = Object.keys(this._parentWays);
27837         for (i = 0; i < keys.length; i++) {
27838             child = keys[i];
27839             if (base.parentWays[child]) {
27840                 for (k = 0; k < base.parentWays[child].length; k++) {
27841                     id = base.parentWays[child][k];
27842                     if (!this.entities.hasOwnProperty(id) && !includes(this._parentWays[child], id)) {
27843                         this._parentWays[child].push(id);
27844                     }
27845                 }
27846             }
27847         }
27848
27849         keys = Object.keys(this._parentRels);
27850         for (i = 0; i < keys.length; i++) {
27851             child = keys[i];
27852             if (base.parentRels[child]) {
27853                 for (k = 0; k < base.parentRels[child].length; k++) {
27854                     id = base.parentRels[child][k];
27855                     if (!this.entities.hasOwnProperty(id) && !includes(this._parentRels[child], id)) {
27856                         this._parentRels[child].push(id);
27857                     }
27858                 }
27859             }
27860         }
27861
27862         this.transients = {};
27863
27864         // this._childNodes is not updated, under the assumption that
27865         // ways are always downloaded with their child nodes.
27866     },
27867
27868
27869     // Updates calculated properties (parentWays, parentRels) for the specified change
27870     _updateCalculated: function(oldentity, entity, parentWays, parentRels) {
27871
27872         parentWays = parentWays || this._parentWays;
27873         parentRels = parentRels || this._parentRels;
27874
27875         var type = entity && entity.type || oldentity && oldentity.type,
27876             removed, added, ways, rels, i;
27877
27878
27879         if (type === 'way') {
27880
27881             // Update parentWays
27882             if (oldentity && entity) {
27883                 removed = difference(oldentity.nodes, entity.nodes);
27884                 added = difference(entity.nodes, oldentity.nodes);
27885             } else if (oldentity) {
27886                 removed = oldentity.nodes;
27887                 added = [];
27888             } else if (entity) {
27889                 removed = [];
27890                 added = entity.nodes;
27891             }
27892             for (i = 0; i < removed.length; i++) {
27893                 parentWays[removed[i]] = without(parentWays[removed[i]], oldentity.id);
27894             }
27895             for (i = 0; i < added.length; i++) {
27896                 ways = without(parentWays[added[i]], entity.id);
27897                 ways.push(entity.id);
27898                 parentWays[added[i]] = ways;
27899             }
27900
27901         } else if (type === 'relation') {
27902
27903             // Update parentRels
27904             if (oldentity && entity) {
27905                 removed = difference(oldentity.members, entity.members);
27906                 added = difference(entity.members, oldentity);
27907             } else if (oldentity) {
27908                 removed = oldentity.members;
27909                 added = [];
27910             } else if (entity) {
27911                 removed = [];
27912                 added = entity.members;
27913             }
27914             for (i = 0; i < removed.length; i++) {
27915                 parentRels[removed[i].id] = without(parentRels[removed[i].id], oldentity.id);
27916             }
27917             for (i = 0; i < added.length; i++) {
27918                 rels = without(parentRels[added[i].id], entity.id);
27919                 rels.push(entity.id);
27920                 parentRels[added[i].id] = rels;
27921             }
27922         }
27923     },
27924
27925
27926     replace: function(entity) {
27927         if (this.entities[entity.id] === entity)
27928             return this;
27929
27930         return this.update(function() {
27931             this._updateCalculated(this.entities[entity.id], entity);
27932             this.entities[entity.id] = entity;
27933         });
27934     },
27935
27936
27937     remove: function(entity) {
27938         return this.update(function() {
27939             this._updateCalculated(entity, undefined);
27940             this.entities[entity.id] = undefined;
27941         });
27942     },
27943
27944
27945     revert: function(id) {
27946         var baseEntity = this.base().entities[id],
27947             headEntity = this.entities[id];
27948
27949         if (headEntity === baseEntity)
27950             return this;
27951
27952         return this.update(function() {
27953             this._updateCalculated(headEntity, baseEntity);
27954             delete this.entities[id];
27955         });
27956     },
27957
27958
27959     update: function() {
27960         var graph = this.frozen ? coreGraph(this, true) : this;
27961
27962         for (var i = 0; i < arguments.length; i++) {
27963             arguments[i].call(graph, graph);
27964         }
27965
27966         if (this.frozen) graph.frozen = true;
27967
27968         return graph;
27969     },
27970
27971
27972     // Obliterates any existing entities
27973     load: function(entities) {
27974         var base = this.base();
27975         this.entities = Object.create(base.entities);
27976
27977         for (var i in entities) {
27978             this.entities[i] = entities[i];
27979             this._updateCalculated(base.entities[i], this.entities[i]);
27980         }
27981
27982         return this;
27983     }
27984 };
27985
27986 var quickselect_1 = quickselect;
27987 var default_1 = quickselect;
27988
27989 function quickselect(arr, k, left, right, compare) {
27990     quickselectStep(arr, k, left || 0, right || (arr.length - 1), compare || defaultCompare);
27991 }
27992
27993 function quickselectStep(arr, k, left, right, compare) {
27994
27995     while (right > left) {
27996         if (right - left > 600) {
27997             var n = right - left + 1;
27998             var m = k - left + 1;
27999             var z = Math.log(n);
28000             var s = 0.5 * Math.exp(2 * z / 3);
28001             var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);
28002             var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));
28003             var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));
28004             quickselectStep(arr, k, newLeft, newRight, compare);
28005         }
28006
28007         var t = arr[k];
28008         var i = left;
28009         var j = right;
28010
28011         swap(arr, left, k);
28012         if (compare(arr[right], t) > 0) swap(arr, left, right);
28013
28014         while (i < j) {
28015             swap(arr, i, j);
28016             i++;
28017             j--;
28018             while (compare(arr[i], t) < 0) i++;
28019             while (compare(arr[j], t) > 0) j--;
28020         }
28021
28022         if (compare(arr[left], t) === 0) swap(arr, left, j);
28023         else {
28024             j++;
28025             swap(arr, j, right);
28026         }
28027
28028         if (j <= k) left = j + 1;
28029         if (k <= j) right = j - 1;
28030     }
28031 }
28032
28033 function swap(arr, i, j) {
28034     var tmp = arr[i];
28035     arr[i] = arr[j];
28036     arr[j] = tmp;
28037 }
28038
28039 function defaultCompare(a, b) {
28040     return a < b ? -1 : a > b ? 1 : 0;
28041 }
28042
28043 quickselect_1.default = default_1;
28044
28045 var rbush_1 = rbush;
28046 var default_1$1 = rbush;
28047
28048
28049
28050 function rbush(maxEntries, format) {
28051     if (!(this instanceof rbush)) return new rbush(maxEntries, format);
28052
28053     // max entries in a node is 9 by default; min node fill is 40% for best performance
28054     this._maxEntries = Math.max(4, maxEntries || 9);
28055     this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));
28056
28057     if (format) {
28058         this._initFormat(format);
28059     }
28060
28061     this.clear();
28062 }
28063
28064 rbush.prototype = {
28065
28066     all: function () {
28067         return this._all(this.data, []);
28068     },
28069
28070     search: function (bbox) {
28071
28072         var node = this.data,
28073             result = [],
28074             toBBox = this.toBBox;
28075
28076         if (!intersects$1(bbox, node)) return result;
28077
28078         var nodesToSearch = [],
28079             i, len, child, childBBox;
28080
28081         while (node) {
28082             for (i = 0, len = node.children.length; i < len; i++) {
28083
28084                 child = node.children[i];
28085                 childBBox = node.leaf ? toBBox(child) : child;
28086
28087                 if (intersects$1(bbox, childBBox)) {
28088                     if (node.leaf) result.push(child);
28089                     else if (contains$2(bbox, childBBox)) this._all(child, result);
28090                     else nodesToSearch.push(child);
28091                 }
28092             }
28093             node = nodesToSearch.pop();
28094         }
28095
28096         return result;
28097     },
28098
28099     collides: function (bbox) {
28100
28101         var node = this.data,
28102             toBBox = this.toBBox;
28103
28104         if (!intersects$1(bbox, node)) return false;
28105
28106         var nodesToSearch = [],
28107             i, len, child, childBBox;
28108
28109         while (node) {
28110             for (i = 0, len = node.children.length; i < len; i++) {
28111
28112                 child = node.children[i];
28113                 childBBox = node.leaf ? toBBox(child) : child;
28114
28115                 if (intersects$1(bbox, childBBox)) {
28116                     if (node.leaf || contains$2(bbox, childBBox)) return true;
28117                     nodesToSearch.push(child);
28118                 }
28119             }
28120             node = nodesToSearch.pop();
28121         }
28122
28123         return false;
28124     },
28125
28126     load: function (data) {
28127         if (!(data && data.length)) return this;
28128
28129         if (data.length < this._minEntries) {
28130             for (var i = 0, len = data.length; i < len; i++) {
28131                 this.insert(data[i]);
28132             }
28133             return this;
28134         }
28135
28136         // recursively build the tree with the given data from scratch using OMT algorithm
28137         var node = this._build(data.slice(), 0, data.length - 1, 0);
28138
28139         if (!this.data.children.length) {
28140             // save as is if tree is empty
28141             this.data = node;
28142
28143         } else if (this.data.height === node.height) {
28144             // split root if trees have the same height
28145             this._splitRoot(this.data, node);
28146
28147         } else {
28148             if (this.data.height < node.height) {
28149                 // swap trees if inserted one is bigger
28150                 var tmpNode = this.data;
28151                 this.data = node;
28152                 node = tmpNode;
28153             }
28154
28155             // insert the small tree into the large tree at appropriate level
28156             this._insert(node, this.data.height - node.height - 1, true);
28157         }
28158
28159         return this;
28160     },
28161
28162     insert: function (item) {
28163         if (item) this._insert(item, this.data.height - 1);
28164         return this;
28165     },
28166
28167     clear: function () {
28168         this.data = createNode([]);
28169         return this;
28170     },
28171
28172     remove: function (item, equalsFn) {
28173         if (!item) return this;
28174
28175         var node = this.data,
28176             bbox = this.toBBox(item),
28177             path = [],
28178             indexes = [],
28179             i, parent, index, goingUp;
28180
28181         // depth-first iterative tree traversal
28182         while (node || path.length) {
28183
28184             if (!node) { // go up
28185                 node = path.pop();
28186                 parent = path[path.length - 1];
28187                 i = indexes.pop();
28188                 goingUp = true;
28189             }
28190
28191             if (node.leaf) { // check current node
28192                 index = findItem(item, node.children, equalsFn);
28193
28194                 if (index !== -1) {
28195                     // item found, remove the item and condense tree upwards
28196                     node.children.splice(index, 1);
28197                     path.push(node);
28198                     this._condense(path);
28199                     return this;
28200                 }
28201             }
28202
28203             if (!goingUp && !node.leaf && contains$2(node, bbox)) { // go down
28204                 path.push(node);
28205                 indexes.push(i);
28206                 i = 0;
28207                 parent = node;
28208                 node = node.children[0];
28209
28210             } else if (parent) { // go right
28211                 i++;
28212                 node = parent.children[i];
28213                 goingUp = false;
28214
28215             } else node = null; // nothing found
28216         }
28217
28218         return this;
28219     },
28220
28221     toBBox: function (item) { return item; },
28222
28223     compareMinX: compareNodeMinX,
28224     compareMinY: compareNodeMinY,
28225
28226     toJSON: function () { return this.data; },
28227
28228     fromJSON: function (data) {
28229         this.data = data;
28230         return this;
28231     },
28232
28233     _all: function (node, result) {
28234         var nodesToSearch = [];
28235         while (node) {
28236             if (node.leaf) result.push.apply(result, node.children);
28237             else nodesToSearch.push.apply(nodesToSearch, node.children);
28238
28239             node = nodesToSearch.pop();
28240         }
28241         return result;
28242     },
28243
28244     _build: function (items, left, right, height) {
28245
28246         var N = right - left + 1,
28247             M = this._maxEntries,
28248             node;
28249
28250         if (N <= M) {
28251             // reached leaf level; return leaf
28252             node = createNode(items.slice(left, right + 1));
28253             calcBBox(node, this.toBBox);
28254             return node;
28255         }
28256
28257         if (!height) {
28258             // target height of the bulk-loaded tree
28259             height = Math.ceil(Math.log(N) / Math.log(M));
28260
28261             // target number of root entries to maximize storage utilization
28262             M = Math.ceil(N / Math.pow(M, height - 1));
28263         }
28264
28265         node = createNode([]);
28266         node.leaf = false;
28267         node.height = height;
28268
28269         // split the items into M mostly square tiles
28270
28271         var N2 = Math.ceil(N / M),
28272             N1 = N2 * Math.ceil(Math.sqrt(M)),
28273             i, j, right2, right3;
28274
28275         multiSelect(items, left, right, N1, this.compareMinX);
28276
28277         for (i = left; i <= right; i += N1) {
28278
28279             right2 = Math.min(i + N1 - 1, right);
28280
28281             multiSelect(items, i, right2, N2, this.compareMinY);
28282
28283             for (j = i; j <= right2; j += N2) {
28284
28285                 right3 = Math.min(j + N2 - 1, right2);
28286
28287                 // pack each entry recursively
28288                 node.children.push(this._build(items, j, right3, height - 1));
28289             }
28290         }
28291
28292         calcBBox(node, this.toBBox);
28293
28294         return node;
28295     },
28296
28297     _chooseSubtree: function (bbox, node, level, path) {
28298
28299         var i, len, child, targetNode, area, enlargement, minArea, minEnlargement;
28300
28301         while (true) {
28302             path.push(node);
28303
28304             if (node.leaf || path.length - 1 === level) break;
28305
28306             minArea = minEnlargement = Infinity;
28307
28308             for (i = 0, len = node.children.length; i < len; i++) {
28309                 child = node.children[i];
28310                 area = bboxArea(child);
28311                 enlargement = enlargedArea(bbox, child) - area;
28312
28313                 // choose entry with the least area enlargement
28314                 if (enlargement < minEnlargement) {
28315                     minEnlargement = enlargement;
28316                     minArea = area < minArea ? area : minArea;
28317                     targetNode = child;
28318
28319                 } else if (enlargement === minEnlargement) {
28320                     // otherwise choose one with the smallest area
28321                     if (area < minArea) {
28322                         minArea = area;
28323                         targetNode = child;
28324                     }
28325                 }
28326             }
28327
28328             node = targetNode || node.children[0];
28329         }
28330
28331         return node;
28332     },
28333
28334     _insert: function (item, level, isNode) {
28335
28336         var toBBox = this.toBBox,
28337             bbox = isNode ? item : toBBox(item),
28338             insertPath = [];
28339
28340         // find the best node for accommodating the item, saving all nodes along the path too
28341         var node = this._chooseSubtree(bbox, this.data, level, insertPath);
28342
28343         // put the item into the node
28344         node.children.push(item);
28345         extend$1(node, bbox);
28346
28347         // split on node overflow; propagate upwards if necessary
28348         while (level >= 0) {
28349             if (insertPath[level].children.length > this._maxEntries) {
28350                 this._split(insertPath, level);
28351                 level--;
28352             } else break;
28353         }
28354
28355         // adjust bboxes along the insertion path
28356         this._adjustParentBBoxes(bbox, insertPath, level);
28357     },
28358
28359     // split overflowed node into two
28360     _split: function (insertPath, level) {
28361
28362         var node = insertPath[level],
28363             M = node.children.length,
28364             m = this._minEntries;
28365
28366         this._chooseSplitAxis(node, m, M);
28367
28368         var splitIndex = this._chooseSplitIndex(node, m, M);
28369
28370         var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex));
28371         newNode.height = node.height;
28372         newNode.leaf = node.leaf;
28373
28374         calcBBox(node, this.toBBox);
28375         calcBBox(newNode, this.toBBox);
28376
28377         if (level) insertPath[level - 1].children.push(newNode);
28378         else this._splitRoot(node, newNode);
28379     },
28380
28381     _splitRoot: function (node, newNode) {
28382         // split root node
28383         this.data = createNode([node, newNode]);
28384         this.data.height = node.height + 1;
28385         this.data.leaf = false;
28386         calcBBox(this.data, this.toBBox);
28387     },
28388
28389     _chooseSplitIndex: function (node, m, M) {
28390
28391         var i, bbox1, bbox2, overlap, area, minOverlap, minArea, index;
28392
28393         minOverlap = minArea = Infinity;
28394
28395         for (i = m; i <= M - m; i++) {
28396             bbox1 = distBBox(node, 0, i, this.toBBox);
28397             bbox2 = distBBox(node, i, M, this.toBBox);
28398
28399             overlap = intersectionArea(bbox1, bbox2);
28400             area = bboxArea(bbox1) + bboxArea(bbox2);
28401
28402             // choose distribution with minimum overlap
28403             if (overlap < minOverlap) {
28404                 minOverlap = overlap;
28405                 index = i;
28406
28407                 minArea = area < minArea ? area : minArea;
28408
28409             } else if (overlap === minOverlap) {
28410                 // otherwise choose distribution with minimum area
28411                 if (area < minArea) {
28412                     minArea = area;
28413                     index = i;
28414                 }
28415             }
28416         }
28417
28418         return index;
28419     },
28420
28421     // sorts node children by the best axis for split
28422     _chooseSplitAxis: function (node, m, M) {
28423
28424         var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX,
28425             compareMinY = node.leaf ? this.compareMinY : compareNodeMinY,
28426             xMargin = this._allDistMargin(node, m, M, compareMinX),
28427             yMargin = this._allDistMargin(node, m, M, compareMinY);
28428
28429         // if total distributions margin value is minimal for x, sort by minX,
28430         // otherwise it's already sorted by minY
28431         if (xMargin < yMargin) node.children.sort(compareMinX);
28432     },
28433
28434     // total margin of all possible split distributions where each node is at least m full
28435     _allDistMargin: function (node, m, M, compare) {
28436
28437         node.children.sort(compare);
28438
28439         var toBBox = this.toBBox,
28440             leftBBox = distBBox(node, 0, m, toBBox),
28441             rightBBox = distBBox(node, M - m, M, toBBox),
28442             margin = bboxMargin(leftBBox) + bboxMargin(rightBBox),
28443             i, child;
28444
28445         for (i = m; i < M - m; i++) {
28446             child = node.children[i];
28447             extend$1(leftBBox, node.leaf ? toBBox(child) : child);
28448             margin += bboxMargin(leftBBox);
28449         }
28450
28451         for (i = M - m - 1; i >= m; i--) {
28452             child = node.children[i];
28453             extend$1(rightBBox, node.leaf ? toBBox(child) : child);
28454             margin += bboxMargin(rightBBox);
28455         }
28456
28457         return margin;
28458     },
28459
28460     _adjustParentBBoxes: function (bbox, path, level) {
28461         // adjust bboxes along the given tree path
28462         for (var i = level; i >= 0; i--) {
28463             extend$1(path[i], bbox);
28464         }
28465     },
28466
28467     _condense: function (path) {
28468         // go through the path, removing empty nodes and updating bboxes
28469         for (var i = path.length - 1, siblings; i >= 0; i--) {
28470             if (path[i].children.length === 0) {
28471                 if (i > 0) {
28472                     siblings = path[i - 1].children;
28473                     siblings.splice(siblings.indexOf(path[i]), 1);
28474
28475                 } else this.clear();
28476
28477             } else calcBBox(path[i], this.toBBox);
28478         }
28479     },
28480
28481     _initFormat: function (format) {
28482         // data format (minX, minY, maxX, maxY accessors)
28483
28484         // uses eval-type function compilation instead of just accepting a toBBox function
28485         // because the algorithms are very sensitive to sorting functions performance,
28486         // so they should be dead simple and without inner calls
28487
28488         var compareArr = ['return a', ' - b', ';'];
28489
28490         this.compareMinX = new Function('a', 'b', compareArr.join(format[0]));
28491         this.compareMinY = new Function('a', 'b', compareArr.join(format[1]));
28492
28493         this.toBBox = new Function('a',
28494             'return {minX: a' + format[0] +
28495             ', minY: a' + format[1] +
28496             ', maxX: a' + format[2] +
28497             ', maxY: a' + format[3] + '};');
28498     }
28499 };
28500
28501 function findItem(item, items, equalsFn) {
28502     if (!equalsFn) return items.indexOf(item);
28503
28504     for (var i = 0; i < items.length; i++) {
28505         if (equalsFn(item, items[i])) return i;
28506     }
28507     return -1;
28508 }
28509
28510 // calculate node's bbox from bboxes of its children
28511 function calcBBox(node, toBBox) {
28512     distBBox(node, 0, node.children.length, toBBox, node);
28513 }
28514
28515 // min bounding rectangle of node children from k to p-1
28516 function distBBox(node, k, p, toBBox, destNode) {
28517     if (!destNode) destNode = createNode(null);
28518     destNode.minX = Infinity;
28519     destNode.minY = Infinity;
28520     destNode.maxX = -Infinity;
28521     destNode.maxY = -Infinity;
28522
28523     for (var i = k, child; i < p; i++) {
28524         child = node.children[i];
28525         extend$1(destNode, node.leaf ? toBBox(child) : child);
28526     }
28527
28528     return destNode;
28529 }
28530
28531 function extend$1(a, b) {
28532     a.minX = Math.min(a.minX, b.minX);
28533     a.minY = Math.min(a.minY, b.minY);
28534     a.maxX = Math.max(a.maxX, b.maxX);
28535     a.maxY = Math.max(a.maxY, b.maxY);
28536     return a;
28537 }
28538
28539 function compareNodeMinX(a, b) { return a.minX - b.minX; }
28540 function compareNodeMinY(a, b) { return a.minY - b.minY; }
28541
28542 function bboxArea(a)   { return (a.maxX - a.minX) * (a.maxY - a.minY); }
28543 function bboxMargin(a) { return (a.maxX - a.minX) + (a.maxY - a.minY); }
28544
28545 function enlargedArea(a, b) {
28546     return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) *
28547            (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY));
28548 }
28549
28550 function intersectionArea(a, b) {
28551     var minX = Math.max(a.minX, b.minX),
28552         minY = Math.max(a.minY, b.minY),
28553         maxX = Math.min(a.maxX, b.maxX),
28554         maxY = Math.min(a.maxY, b.maxY);
28555
28556     return Math.max(0, maxX - minX) *
28557            Math.max(0, maxY - minY);
28558 }
28559
28560 function contains$2(a, b) {
28561     return a.minX <= b.minX &&
28562            a.minY <= b.minY &&
28563            b.maxX <= a.maxX &&
28564            b.maxY <= a.maxY;
28565 }
28566
28567 function intersects$1(a, b) {
28568     return b.minX <= a.maxX &&
28569            b.minY <= a.maxY &&
28570            b.maxX >= a.minX &&
28571            b.maxY >= a.minY;
28572 }
28573
28574 function createNode(children) {
28575     return {
28576         children: children,
28577         height: 1,
28578         leaf: true,
28579         minX: Infinity,
28580         minY: Infinity,
28581         maxX: -Infinity,
28582         maxY: -Infinity
28583     };
28584 }
28585
28586 // sort an array so that items come in groups of n unsorted items, with groups sorted between each other;
28587 // combines selection algorithm with binary divide & conquer approach
28588
28589 function multiSelect(arr, left, right, n, compare) {
28590     var stack = [left, right],
28591         mid;
28592
28593     while (stack.length) {
28594         right = stack.pop();
28595         left = stack.pop();
28596
28597         if (right - left <= n) continue;
28598
28599         mid = left + Math.ceil((right - left) / n / 2) * n;
28600         quickselect_1(arr, mid, left, right, compare);
28601
28602         stack.push(left, mid, mid, right);
28603     }
28604 }
28605
28606 rbush_1.default = default_1$1;
28607
28608 function coreTree(head) {
28609     var rtree = rbush_1(),
28610         bboxes = {},
28611         tree = {};
28612
28613
28614     function entityBBox(entity) {
28615         var bbox = entity.extent(head).bbox();
28616         bbox.id = entity.id;
28617         bboxes[entity.id] = bbox;
28618         return bbox;
28619     }
28620
28621
28622     function updateParents(entity, insertions, memo) {
28623         head.parentWays(entity).forEach(function(way) {
28624             if (bboxes[way.id]) {
28625                 rtree.remove(bboxes[way.id]);
28626                 insertions[way.id] = way;
28627             }
28628             updateParents(way, insertions, memo);
28629         });
28630
28631         head.parentRelations(entity).forEach(function(relation) {
28632             if (memo[entity.id]) return;
28633             memo[entity.id] = true;
28634             if (bboxes[relation.id]) {
28635                 rtree.remove(bboxes[relation.id]);
28636                 insertions[relation.id] = relation;
28637             }
28638             updateParents(relation, insertions, memo);
28639         });
28640     }
28641
28642
28643     tree.rebase = function(entities, force) {
28644         var insertions = {};
28645
28646         for (var i = 0; i < entities.length; i++) {
28647             var entity = entities[i];
28648
28649             if (!entity.visible)
28650                 continue;
28651
28652             if (head.entities.hasOwnProperty(entity.id) || bboxes[entity.id]) {
28653                 if (!force) {
28654                     continue;
28655                 } else if (bboxes[entity.id]) {
28656                     rtree.remove(bboxes[entity.id]);
28657                 }
28658             }
28659
28660             insertions[entity.id] = entity;
28661             updateParents(entity, insertions, {});
28662         }
28663
28664         rtree.load(map$4(insertions, entityBBox));
28665
28666         return tree;
28667     };
28668
28669
28670     tree.intersects = function(extent, graph) {
28671         if (graph !== head) {
28672             var diff = coreDifference(head, graph),
28673                 insertions = {};
28674
28675             head = graph;
28676
28677             diff.deleted().forEach(function(entity) {
28678                 rtree.remove(bboxes[entity.id]);
28679                 delete bboxes[entity.id];
28680             });
28681
28682             diff.modified().forEach(function(entity) {
28683                 rtree.remove(bboxes[entity.id]);
28684                 insertions[entity.id] = entity;
28685                 updateParents(entity, insertions, {});
28686             });
28687
28688             diff.created().forEach(function(entity) {
28689                 insertions[entity.id] = entity;
28690             });
28691
28692             rtree.load(map$4(insertions, entityBBox));
28693         }
28694
28695         return rtree.search(extent.bbox()).map(function(bbox) {
28696             return head.entity(bbox.id);
28697         });
28698     };
28699
28700
28701     return tree;
28702 }
28703
28704 /*
28705  * This code is licensed under the MIT license.
28706  *
28707  * Copyright © 2013, iD authors.
28708  *
28709  * Portions copyright © 2011, Keith Cirkel
28710  * See https://github.com/keithamus/jwerty
28711  *
28712  */
28713 function d3keybinding(namespace) {
28714     var bindings = [];
28715
28716
28717     function testBindings(isCapturing) {
28718         var didMatch = false,
28719             i, binding;
28720
28721         // Most key shortcuts will accept either lower or uppercase ('h' or 'H'),
28722         // so we don't strictly match on the shift key, but we prioritize
28723         // shifted bindings first, and fallback to unshifted only if no match.
28724         // (This lets us differentiate between '←'/'⇧←' or '⌘Z'/'⌘⇧Z')
28725
28726         // priority match shifted bindings first
28727         for (i = 0; i < bindings.length; i++) {
28728             binding = bindings[i];
28729             if (!binding.event.modifiers.shiftKey) continue;  // no shift
28730             if (!!binding.capture !== isCapturing) continue;
28731             if (matches(binding, true)) {
28732                 binding.callback();
28733                 didMatch = true;
28734             }
28735         }
28736
28737         // then unshifted bindings
28738         if (didMatch) return;
28739         for (i = 0; i < bindings.length; i++) {
28740             binding = bindings[i];
28741             if (binding.event.modifiers.shiftKey) continue;   // shift
28742             if (!!binding.capture !== isCapturing) continue;
28743             if (matches(binding, false)) {
28744                 binding.callback();
28745             }
28746         }
28747
28748
28749         function matches(binding, testShift) {
28750             var event$$1 = event;
28751             var isMatch = false;
28752             var tryKeyCode = true;
28753
28754             // Prefer a match on `KeyboardEvent.key`
28755             if (event$$1.key !== undefined) {
28756                 tryKeyCode = (event$$1.key.charCodeAt(0) > 255);  // outside ISO-Latin-1
28757                 isMatch = true;
28758
28759                 if (binding.event.key === undefined) {
28760                     isMatch = false;
28761                 } else if (Array.isArray(binding.event.key)) {
28762                     if (binding.event.key.map(function(s) { return s.toLowerCase(); }).indexOf(event$$1.key.toLowerCase()) === -1)
28763                         isMatch = false;
28764                 } else {
28765                     if (event$$1.key.toLowerCase() !== binding.event.key.toLowerCase())
28766                         isMatch = false;
28767                 }
28768             }
28769
28770             // Fallback match on `KeyboardEvent.keyCode`, can happen if:
28771             // - browser doesn't support `KeyboardEvent.key`
28772             // - `KeyboardEvent.key` is outside ISO-Latin-1 range (cyrillic?)
28773             if (!isMatch && tryKeyCode) {
28774                 isMatch = (event$$1.keyCode === binding.event.keyCode);
28775             }
28776
28777             if (!isMatch) return false;
28778
28779             // test modifier keys
28780             if (!(event$$1.ctrlKey && event$$1.altKey)) {  // if both are set, assume AltGr and skip it - #4096
28781                 if (event$$1.ctrlKey !== binding.event.modifiers.ctrlKey) return false;
28782                 if (event$$1.altKey !== binding.event.modifiers.altKey) return false;
28783             }
28784             if (event$$1.metaKey !== binding.event.modifiers.metaKey) return false;
28785             if (testShift && event$$1.shiftKey !== binding.event.modifiers.shiftKey) return false;
28786
28787             return true;
28788         }
28789     }
28790
28791
28792     function capture() {
28793         testBindings(true);
28794     }
28795
28796
28797     function bubble() {
28798         var tagName = d3_select(event.target).node().tagName;
28799         if (tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA') {
28800             return;
28801         }
28802         testBindings(false);
28803     }
28804
28805
28806     function keybinding(selection) {
28807         selection = selection || d3_select(document);
28808         selection.on('keydown.capture' + namespace, capture, true);
28809         selection.on('keydown.bubble' + namespace, bubble, false);
28810         return keybinding;
28811     }
28812
28813
28814     keybinding.off = function(selection) {
28815         bindings = [];
28816         selection = selection || d3_select(document);
28817         selection.on('keydown.capture' + namespace, null);
28818         selection.on('keydown.bubble' + namespace, null);
28819         return keybinding;
28820     };
28821
28822
28823     keybinding.on = function(codes, callback, capture) {
28824         var arr = [].concat(codes);
28825         for (var i = 0; i < arr.length; i++) {
28826             var code = arr[i];
28827             var binding = {
28828                 event: {
28829                     key: undefined,  // preferred
28830                     keyCode: 0,      // fallback
28831                     modifiers: {
28832                         shiftKey: false,
28833                         ctrlKey: false,
28834                         altKey: false,
28835                         metaKey: false
28836                     }
28837                 },
28838                 capture: capture,
28839                 callback: callback
28840             };
28841
28842             code = code.toLowerCase().match(/(?:(?:[^+⇧⌃⌥⌘])+|[⇧⌃⌥⌘]|\+\+|^\+$)/g);
28843
28844             for (var j = 0; j < code.length; j++) {
28845                 // Normalise matching errors
28846                 if (code[j] === '++') code[j] = '+';
28847
28848                 if (code[j] in d3keybinding.modifierCodes) {
28849                     binding.event.modifiers[d3keybinding.modifierProperties[d3keybinding.modifierCodes[code[j]]]] = true;
28850                 } else {
28851                     binding.event.key = d3keybinding.keys[code[j]] || code[j];
28852                     if (code[j] in d3keybinding.keyCodes) {
28853                         binding.event.keyCode = d3keybinding.keyCodes[code[j]];
28854                     }
28855                 }
28856             }
28857
28858             bindings.push(binding);
28859         }
28860
28861         return keybinding;
28862     };
28863
28864     return keybinding;
28865 }
28866
28867
28868 d3keybinding.modifierCodes = {
28869     // Shift key, ⇧
28870     '⇧': 16, shift: 16,
28871     // CTRL key, on Mac: ⌃
28872     '⌃': 17, ctrl: 17,
28873     // ALT key, on Mac: ⌥ (Alt)
28874     '⌥': 18, alt: 18, option: 18,
28875     // META, on Mac: ⌘ (CMD), on Windows (Win), on Linux (Super)
28876     '⌘': 91, meta: 91, cmd: 91, 'super': 91, win: 91
28877 };
28878
28879 d3keybinding.modifierProperties = {
28880     16: 'shiftKey',
28881     17: 'ctrlKey',
28882     18: 'altKey',
28883     91: 'metaKey'
28884 };
28885
28886 d3keybinding.keys = {
28887     // Backspace key, on Mac: ⌫ (Backspace)
28888     '⌫': 'Backspace', backspace: 'Backspace',
28889     // Tab Key, on Mac: ⇥ (Tab), on Windows ⇥⇥
28890     '⇥': 'Tab', '⇆': 'Tab', tab: 'Tab',
28891     // Return key, ↩
28892     '↩': 'Enter', 'return': 'Enter', enter: 'Enter', '⌅': 'Enter',
28893     // Pause/Break key
28894     'pause': 'Pause', 'pause-break': 'Pause',
28895     // Caps Lock key, ⇪
28896     '⇪': 'CapsLock', caps: 'CapsLock', 'caps-lock': 'CapsLock',
28897     // Escape key, on Mac: ⎋, on Windows: Esc
28898     '⎋': ['Escape', 'Esc'], escape: ['Escape', 'Esc'], esc: ['Escape', 'Esc'],
28899     // Space key
28900     space: [' ', 'Spacebar'],
28901     // Page-Up key, or pgup, on Mac: ↖
28902     '↖': 'PageUp', pgup: 'PageUp', 'page-up': 'PageUp',
28903     // Page-Down key, or pgdown, on Mac: ↘
28904     '↘': 'PageDown', pgdown: 'PageDown', 'page-down': 'PageDown',
28905     // END key, on Mac: ⇟
28906     '⇟': 'End', end: 'End',
28907     // HOME key, on Mac: ⇞
28908     '⇞': 'Home', home: 'Home',
28909     // Insert key, or ins
28910     ins: 'Insert', insert: 'Insert',
28911     // Delete key, on Mac: ⌦ (Delete)
28912     '⌦': ['Delete', 'Del'], del: ['Delete', 'Del'], 'delete': ['Delete', 'Del'],
28913     // Left Arrow Key, or ←
28914     '←': ['ArrowLeft', 'Left'], left: ['ArrowLeft', 'Left'], 'arrow-left': ['ArrowLeft', 'Left'],
28915     // Up Arrow Key, or ↑
28916     '↑': ['ArrowUp', 'Up'], up: ['ArrowUp', 'Up'], 'arrow-up': ['ArrowUp', 'Up'],
28917     // Right Arrow Key, or →
28918     '→': ['ArrowRight', 'Right'], right: ['ArrowRight', 'Right'], 'arrow-right': ['ArrowRight', 'Right'],
28919     // Up Arrow Key, or ↓
28920     '↓': ['ArrowDown', 'Down'], down: ['ArrowDown', 'Down'], 'arrow-down': ['ArrowDown', 'Down'],
28921     // odities, stuff for backward compatibility (browsers and code):
28922     // Num-Multiply, or *
28923     '*': ['*', 'Multiply'], star: ['*', 'Multiply'], asterisk: ['*', 'Multiply'], multiply: ['*', 'Multiply'],
28924     // Num-Plus or +
28925     '+': ['+', 'Add'], 'plus': ['+', 'Add'],
28926     // Num-Subtract, or -
28927     '-': ['-', 'Subtract'], subtract: ['-', 'Subtract'], 'dash': ['-', 'Subtract'],
28928     // Semicolon
28929     semicolon: ';',
28930     // = or equals
28931     equals: '=',
28932     // Comma, or ,
28933     comma: ',',
28934     // Period, or ., or full-stop
28935     period: '.', 'full-stop': '.',
28936     // Slash, or /, or forward-slash
28937     slash: '/', 'forward-slash': '/',
28938     // Tick, or `, or back-quote
28939     tick: '`', 'back-quote': '`',
28940     // Open bracket, or [
28941     'open-bracket': '[',
28942     // Back slash, or \
28943     'back-slash': '\\',
28944     // Close backet, or ]
28945     'close-bracket': ']',
28946     // Apostrophe, or Quote, or '
28947     quote: '\'', apostrophe: '\'',
28948     // NUMPAD 0-9
28949     'num-0': '0',
28950     'num-1': '1',
28951     'num-2': '2',
28952     'num-3': '3',
28953     'num-4': '4',
28954     'num-5': '5',
28955     'num-6': '6',
28956     'num-7': '7',
28957     'num-8': '8',
28958     'num-9': '9',
28959     // F1-F25
28960     f1: 'F1',
28961     f2: 'F2',
28962     f3: 'F3',
28963     f4: 'F4',
28964     f5: 'F5',
28965     f6: 'F6',
28966     f7: 'F7',
28967     f8: 'F8',
28968     f9: 'F9',
28969     f10: 'F10',
28970     f11: 'F11',
28971     f12: 'F12',
28972     f13: 'F13',
28973     f14: 'F14',
28974     f15: 'F15',
28975     f16: 'F16',
28976     f17: 'F17',
28977     f18: 'F18',
28978     f19: 'F19',
28979     f20: 'F20',
28980     f21: 'F21',
28981     f22: 'F22',
28982     f23: 'F23',
28983     f24: 'F24',
28984     f25: 'F25'
28985 };
28986
28987 d3keybinding.keyCodes = {
28988     // Backspace key, on Mac: ⌫ (Backspace)
28989     '⌫': 8, backspace: 8,
28990     // Tab Key, on Mac: ⇥ (Tab), on Windows ⇥⇥
28991     '⇥': 9, '⇆': 9, tab: 9,
28992     // Return key, ↩
28993     '↩': 13, 'return': 13, enter: 13, '⌅': 13,
28994     // Pause/Break key
28995     'pause': 19, 'pause-break': 19,
28996     // Caps Lock key, ⇪
28997     '⇪': 20, caps: 20, 'caps-lock': 20,
28998     // Escape key, on Mac: ⎋, on Windows: Esc
28999     '⎋': 27, escape: 27, esc: 27,
29000     // Space key
29001     space: 32,
29002     // Page-Up key, or pgup, on Mac: ↖
29003     '↖': 33, pgup: 33, 'page-up': 33,
29004     // Page-Down key, or pgdown, on Mac: ↘
29005     '↘': 34, pgdown: 34, 'page-down': 34,
29006     // END key, on Mac: ⇟
29007     '⇟': 35, end: 35,
29008     // HOME key, on Mac: ⇞
29009     '⇞': 36, home: 36,
29010     // Insert key, or ins
29011     ins: 45, insert: 45,
29012     // Delete key, on Mac: ⌦ (Delete)
29013     '⌦': 46, del: 46, 'delete': 46,
29014     // Left Arrow Key, or ←
29015     '←': 37, left: 37, 'arrow-left': 37,
29016     // Up Arrow Key, or ↑
29017     '↑': 38, up: 38, 'arrow-up': 38,
29018     // Right Arrow Key, or →
29019     '→': 39, right: 39, 'arrow-right': 39,
29020     // Up Arrow Key, or ↓
29021     '↓': 40, down: 40, 'arrow-down': 40,
29022     // odities, printing characters that come out wrong:
29023     // Firefox Equals
29024     'ffequals': 61,
29025     // Num-Multiply, or *
29026     '*': 106, star: 106, asterisk: 106, multiply: 106,
29027     // Num-Plus or +
29028     '+': 107, 'plus': 107,
29029     // Num-Subtract, or -
29030     '-': 109, subtract: 109,
29031     // Firefox Plus
29032     'ffplus': 171,
29033     // Firefox Minus
29034     'ffminus': 173,
29035     // Semicolon
29036     ';': 186, semicolon: 186,
29037     // = or equals
29038     '=': 187, 'equals': 187,
29039     // Comma, or ,
29040     ',': 188, comma: 188,
29041     // Dash / Underscore key
29042     'dash': 189,
29043     // Period, or ., or full-stop
29044     '.': 190, period: 190, 'full-stop': 190,
29045     // Slash, or /, or forward-slash
29046     '/': 191, slash: 191, 'forward-slash': 191,
29047     // Tick, or `, or back-quote
29048     '`': 192, tick: 192, 'back-quote': 192,
29049     // Open bracket, or [
29050     '[': 219, 'open-bracket': 219,
29051     // Back slash, or \
29052     '\\': 220, 'back-slash': 220,
29053     // Close backet, or ]
29054     ']': 221, 'close-bracket': 221,
29055     // Apostrophe, or Quote, or '
29056     '\'': 222, quote: 222, apostrophe: 222
29057 };
29058
29059 // NUMPAD 0-9
29060 var i$1 = 95;
29061 var n = 0;
29062 while (++i$1 < 106) {
29063     d3keybinding.keyCodes['num-' + n] = i$1;
29064     ++n;
29065 }
29066
29067 // 0-9
29068 i$1 = 47; n = 0;
29069 while (++i$1 < 58) {
29070     d3keybinding.keyCodes[n] = i$1;
29071     ++n;
29072 }
29073
29074 // F1-F25
29075 i$1 = 111; n = 1;
29076 while (++i$1 < 136) {
29077     d3keybinding.keyCodes['f' + n] = i$1;
29078     ++n;
29079 }
29080
29081 // a-z
29082 i$1 = 64;
29083 while (++i$1 < 91) {
29084     d3keybinding.keyCodes[String.fromCharCode(i$1).toLowerCase()] = i$1;
29085 }
29086
29087 function tooltip() {
29088   var tooltip = function(selection) {
29089       selection.each(setup);
29090     },
29091     animation = utilFunctor(false),
29092     html = utilFunctor(false),
29093     title = function() {
29094       var title = this.getAttribute('data-original-title');
29095       if (title) {
29096         return title;
29097       } else {
29098         title = this.getAttribute('title');
29099         this.removeAttribute('title');
29100         this.setAttribute('data-original-title', title);
29101       }
29102       return title;
29103     },
29104     over = 'mouseenter.tooltip',
29105     out = 'mouseleave.tooltip',
29106     placement = utilFunctor('top');
29107
29108
29109   tooltip.title = function(_) {
29110     if (arguments.length) {
29111       title = utilFunctor(_);
29112       return tooltip;
29113     } else {
29114       return title;
29115     }
29116   };
29117
29118
29119   tooltip.html = function(_) {
29120     if (arguments.length) {
29121       html = utilFunctor(_);
29122       return tooltip;
29123     } else {
29124       return html;
29125     }
29126   };
29127
29128
29129   tooltip.placement = function(_) {
29130     if (arguments.length) {
29131       placement = utilFunctor(_);
29132       return tooltip;
29133     } else {
29134       return placement;
29135     }
29136   };
29137
29138
29139   tooltip.show = function(selection) {
29140     selection.each(show);
29141   };
29142
29143
29144   tooltip.hide = function(selection) {
29145     selection.each(hide);
29146   };
29147
29148
29149   tooltip.toggle = function(selection) {
29150     selection.each(toggle);
29151   };
29152
29153
29154   tooltip.destroy = function(selection) {
29155     selection
29156       .on(over, null)
29157       .on(out, null)
29158       .attr('title', function() {
29159         return this.getAttribute('data-original-title') || this.getAttribute('title');
29160       })
29161       .attr('data-original-title', null)
29162       .selectAll('.tooltip')
29163       .remove();
29164   };
29165
29166
29167   function setup() {
29168     var root = d3_select(this),
29169         animate = animation.apply(this, arguments),
29170         tip = root.selectAll('.tooltip').data([0]);
29171
29172     var enter = tip.enter()
29173       .append('div')
29174       .attr('class', 'tooltip');
29175
29176     enter
29177       .append('div')
29178       .attr('class', 'tooltip-arrow');
29179
29180     enter
29181       .append('div')
29182       .attr('class', 'tooltip-inner');
29183
29184     tip = enter
29185       .merge(tip);
29186
29187     if (animate) {
29188       tip.classed('fade', true);
29189     }
29190
29191     var place = placement.apply(this, arguments);
29192     tip.classed(place, true);
29193
29194     root.on(over, show);
29195     root.on(out, hide);
29196   }
29197
29198
29199   function show() {
29200     var root = d3_select(this),
29201       content = title.apply(this, arguments),
29202       tip = root.selectAll('.tooltip')
29203         .classed('in', true),
29204       markup = html.apply(this, arguments);
29205
29206     tip.selectAll('.tooltip-inner')[markup ? 'html' : 'text'](content);
29207     var place = placement.apply(this, arguments),
29208       outer = getPosition(root.node()),
29209       inner = getPosition(tip.node()),
29210       pos;
29211
29212     switch (place) {
29213       case 'top':
29214         pos = {x: outer.x + (outer.w - inner.w) / 2, y: outer.y - inner.h};
29215         break;
29216       case 'right':
29217         pos = {x: outer.x + outer.w, y: outer.y + (outer.h - inner.h) / 2};
29218         break;
29219       case 'left':
29220         pos = {x: outer.x - inner.w, y: outer.y + (outer.h - inner.h) / 2};
29221         break;
29222       case 'bottom':
29223         pos = {x: Math.max(0, outer.x + (outer.w - inner.w) / 2), y: outer.y + outer.h};
29224         break;
29225     }
29226
29227     if (pos) {
29228       tip.style('left', ~~pos.x + 'px').style('top', ~~pos.y + 'px');
29229     } else {
29230       tip.style('left', null).style('top', null);
29231     }
29232
29233     this.tooltipVisible = true;
29234   }
29235
29236
29237   function hide() {
29238     d3_select(this).selectAll('.tooltip')
29239       .classed('in', false);
29240
29241     this.tooltipVisible = false;
29242   }
29243
29244
29245   function toggle() {
29246     if (this.tooltipVisible) {
29247       hide.apply(this, arguments);
29248     } else {
29249       show.apply(this, arguments);
29250     }
29251   }
29252
29253   return tooltip;
29254 }
29255
29256
29257 function getPosition(node) {
29258   var mode = d3_select(node).style('position');
29259   if (mode === 'absolute' || mode === 'static') {
29260     return {
29261       x: node.offsetLeft,
29262       y: node.offsetTop,
29263       w: node.offsetWidth,
29264       h: node.offsetHeight
29265     };
29266   } else {
29267     return {
29268       x: 0,
29269       y: 0,
29270       w: node.offsetWidth,
29271       h: node.offsetHeight
29272     };
29273   }
29274 }
29275
29276 function behaviorEdit(context) {
29277
29278     function edit() {
29279         context.map()
29280             .minzoom(context.minEditableZoom());
29281     }
29282
29283
29284     edit.off = function() {
29285         context.map()
29286             .minzoom(0);
29287     };
29288
29289
29290     return edit;
29291 }
29292
29293 /*
29294    The hover behavior adds the `.hover` class on mouseover to all elements to which
29295    the identical datum is bound, and removes it on mouseout.
29296
29297    The :hover pseudo-class is insufficient for iD's purposes because a datum's visual
29298    representation may consist of several elements scattered throughout the DOM hierarchy.
29299    Only one of these elements can have the :hover pseudo-class, but all of them will
29300    have the .hover class.
29301  */
29302 function behaviorHover(context) {
29303     var dispatch$$1 = dispatch('hover');
29304     var _selection = d3_select(null);
29305     var _newId = null;
29306     var _buttonDown;
29307     var _altDisables;
29308     var _target;
29309
29310
29311     function keydown() {
29312         if (_altDisables && event.keyCode === d3keybinding.modifierCodes.alt) {
29313             _selection.selectAll('.hover')
29314                 .classed('hover-suppressed', true)
29315                 .classed('hover', false);
29316
29317             _selection
29318                 .classed('hover-disabled', true);
29319
29320             dispatch$$1.call('hover', this, null);
29321         }
29322     }
29323
29324
29325     function keyup() {
29326         if (_altDisables && event.keyCode === d3keybinding.modifierCodes.alt) {
29327             _selection.selectAll('.hover-suppressed')
29328                 .classed('hover-suppressed', false)
29329                 .classed('hover', true);
29330
29331             _selection
29332                 .classed('hover-disabled', false);
29333
29334             dispatch$$1.call('hover', this, _target ? _target.id : null);
29335         }
29336     }
29337
29338
29339     var hover = function(selection) {
29340         _selection = selection;
29341         _newId = null;
29342
29343         _selection
29344             .on('mouseover.hover', mouseover)
29345             .on('mouseout.hover', mouseout)
29346             .on('mousedown.hover', mousedown);
29347
29348         d3_select(window)
29349             .on('keydown.hover', keydown)
29350             .on('keyup.hover', keyup);
29351
29352
29353         function mouseover() {
29354             if (_buttonDown) return;
29355             var target = event.target;
29356             enter(target ? target.__data__ : null);
29357         }
29358
29359
29360         function mouseout() {
29361             if (_buttonDown) return;
29362             var target = event.relatedTarget;
29363             enter(target ? target.__data__ : null);
29364         }
29365
29366
29367         function mousedown() {
29368             _buttonDown = true;
29369             d3_select(window)
29370                 .on('mouseup.hover', mouseup, true);
29371         }
29372
29373
29374         function mouseup() {
29375             _buttonDown = false;
29376             d3_select(window)
29377                 .on('mouseup.hover', null, true);
29378         }
29379
29380
29381         function enter(datum) {
29382             if (datum === _target) return;
29383             _target = datum;
29384
29385             _selection.selectAll('.hover')
29386                 .classed('hover', false);
29387             _selection.selectAll('.hover-suppressed')
29388                 .classed('hover-suppressed', false);
29389
29390             var entity;
29391             if (datum instanceof osmEntity) {
29392                 entity = datum;
29393             } else {
29394                 entity = datum && datum.properties && datum.properties.entity;
29395             }
29396
29397             if (entity && entity.id !== _newId) {
29398                 // If drawing a way, don't hover on a node that was just placed. #3974
29399                 var mode = context.mode() && context.mode().id;
29400                 if ((mode === 'draw-line' || mode === 'draw-area') && !_newId && entity.type === 'node') {
29401                     _newId = entity.id;
29402                     return;
29403                 }
29404
29405                 var selector = '.' + entity.id;
29406
29407                 if (entity.type === 'relation') {
29408                     entity.members.forEach(function(member) {
29409                         selector += ', .' + member.id;
29410                     });
29411                 }
29412
29413                 var suppressed = _altDisables && event && event.altKey;
29414
29415                 _selection.selectAll(selector)
29416                     .classed(suppressed ? 'hover-suppressed' : 'hover', true);
29417
29418                 dispatch$$1.call('hover', this, !suppressed && entity.id);
29419
29420             } else {
29421                 dispatch$$1.call('hover', this, null);
29422             }
29423         }
29424
29425     };
29426
29427
29428     hover.off = function(selection) {
29429         selection.selectAll('.hover')
29430             .classed('hover', false);
29431         selection.selectAll('.hover-suppressed')
29432             .classed('hover-suppressed', false);
29433         selection
29434             .classed('hover-disabled', false);
29435
29436         selection
29437             .on('mouseover.hover', null)
29438             .on('mouseout.hover', null)
29439             .on('mousedown.hover', null);
29440
29441         d3_select(window)
29442             .on('keydown.hover', null)
29443             .on('keyup.hover', null);
29444     };
29445
29446
29447     hover.altDisables = function(_) {
29448         if (!arguments.length) return _altDisables;
29449         _altDisables = _;
29450         return hover;
29451     };
29452
29453
29454     return utilRebind(hover, dispatch$$1, 'on');
29455 }
29456
29457 function refresh(selection, node) {
29458     var cr = node.getBoundingClientRect();
29459     var prop = [cr.width, cr.height];
29460     selection.property('__dimensions__', prop);
29461     return prop;
29462 }
29463
29464 function utilGetDimensions(selection, force) {
29465     if (!selection || selection.empty()) {
29466         return [0, 0];
29467     }
29468     var node = selection.node(),
29469         cached = selection.property('__dimensions__');
29470     return (!cached || force) ? refresh(selection, node) : cached;
29471 }
29472
29473
29474 function utilSetDimensions(selection, dimensions) {
29475     if (!selection || selection.empty()) {
29476         return selection;
29477     }
29478     var node = selection.node();
29479     if (dimensions === null) {
29480         refresh(selection, node);
29481         return selection;
29482     }
29483     return selection
29484         .property('__dimensions__', [dimensions[0], dimensions[1]])
29485         .attr('width', dimensions[0])
29486         .attr('height', dimensions[1]);
29487 }
29488
29489 function behaviorTail() {
29490     var text,
29491         container,
29492         xmargin = 25,
29493         tooltipSize = [0, 0],
29494         selectionSize = [0, 0];
29495
29496
29497     function tail(selection) {
29498         if (!text) return;
29499
29500         d3_select(window)
29501             .on('resize.tail', function() { selectionSize = utilGetDimensions(selection); });
29502
29503         container = d3_select(document.body)
29504             .append('div')
29505             .style('display', 'none')
29506             .attr('class', 'tail tooltip-inner');
29507
29508         container.append('div')
29509             .text(text);
29510
29511         selection
29512             .on('mousemove.tail', mousemove)
29513             .on('mouseenter.tail', mouseenter)
29514             .on('mouseleave.tail', mouseleave);
29515
29516         container
29517             .on('mousemove.tail', mousemove);
29518
29519         tooltipSize = utilGetDimensions(container);
29520         selectionSize = utilGetDimensions(selection);
29521
29522
29523         function show() {
29524             container.style('display', 'block');
29525             tooltipSize = utilGetDimensions(container);
29526         }
29527
29528
29529         function mousemove() {
29530             if (container.style('display') === 'none') show();
29531             var xoffset = ((event.clientX + tooltipSize[0] + xmargin) > selectionSize[0]) ?
29532                 -tooltipSize[0] - xmargin : xmargin;
29533             container.classed('left', xoffset > 0);
29534             utilSetTransform(container, event.clientX + xoffset, event.clientY);
29535         }
29536
29537
29538         function mouseleave() {
29539             if (event.relatedTarget !== container.node()) {
29540                 container.style('display', 'none');
29541             }
29542         }
29543
29544
29545         function mouseenter() {
29546             if (event.relatedTarget !== container.node()) {
29547                 show();
29548             }
29549         }
29550     }
29551
29552
29553     tail.off = function(selection) {
29554         if (!text) return;
29555
29556         container
29557             .on('mousemove.tail', null)
29558             .remove();
29559
29560         selection
29561             .on('mousemove.tail', null)
29562             .on('mouseenter.tail', null)
29563             .on('mouseleave.tail', null);
29564
29565         d3_select(window)
29566             .on('resize.tail', null);
29567     };
29568
29569
29570     tail.text = function(_) {
29571         if (!arguments.length) return text;
29572         text = _;
29573         return tail;
29574     };
29575
29576
29577     return tail;
29578 }
29579
29580 var _usedTails = {};
29581 var _disableSpace = false;
29582 var _lastSpace = null;
29583
29584
29585 function behaviorDraw(context) {
29586     var dispatch$$1 = dispatch(
29587         'move', 'click', 'clickWay', 'clickNode', 'undo', 'cancel', 'finish'
29588     );
29589
29590     var keybinding = d3keybinding('draw');
29591
29592     var hover = behaviorHover(context).altDisables(true)
29593         .on('hover', context.ui().sidebar.hover);
29594     var tail = behaviorTail();
29595     var edit = behaviorEdit(context);
29596
29597     var closeTolerance = 4;
29598     var tolerance = 12;
29599     var _mouseLeave = false;
29600     var _lastMouse = null;
29601
29602
29603     // related code
29604     // - `mode/drag_node.js` `datum()`
29605     function datum() {
29606         if (event.altKey) return {};
29607
29608         var element;
29609         if (event.type === 'keydown') {
29610             element = _lastMouse && _lastMouse.target;
29611         } else {
29612             element = event.target;
29613         }
29614
29615         // When drawing, snap only to touch targets..
29616         // (this excludes area fills and active drawing elements)
29617         var d = element.__data__;
29618         return (d && d.properties && d.properties.target) ? d : {};
29619     }
29620
29621
29622     function mousedown() {
29623
29624         function point() {
29625             var p = context.container().node();
29626             return touchId !== null ? d3_touches(p).filter(function(p) {
29627                 return p.identifier === touchId;
29628             })[0] : d3_mouse(p);
29629         }
29630
29631         var element = d3_select(this);
29632         var touchId = event.touches ? event.changedTouches[0].identifier : null;
29633         var t1 = +new Date();
29634         var p1 = point();
29635
29636         element.on('mousemove.draw', null);
29637
29638         d3_select(window).on('mouseup.draw', function() {
29639             var t2 = +new Date();
29640             var p2 = point();
29641             var dist = geoVecLength(p1, p2);
29642
29643             element.on('mousemove.draw', mousemove);
29644             d3_select(window).on('mouseup.draw', null);
29645
29646             if (dist < closeTolerance || (dist < tolerance && (t2 - t1) < 500)) {
29647                 // Prevent a quick second click
29648                 d3_select(window).on('click.draw-block', function() {
29649                     event.stopPropagation();
29650                 }, true);
29651
29652                 context.map().dblclickEnable(false);
29653
29654                 window.setTimeout(function() {
29655                     context.map().dblclickEnable(true);
29656                     d3_select(window).on('click.draw-block', null);
29657                 }, 500);
29658
29659                 click();
29660             }
29661         }, true);
29662     }
29663
29664
29665     function mousemove() {
29666         _lastMouse = event;
29667         dispatch$$1.call('move', this, datum());
29668     }
29669
29670
29671     function mouseenter() {
29672         _mouseLeave = false;
29673     }
29674
29675
29676     function mouseleave() {
29677         _mouseLeave = true;
29678     }
29679
29680
29681     // related code
29682     // - `mode/drag_node.js`     `doMode()`
29683     // - `behavior/draw.js`      `click()`
29684     // - `behavior/draw_way.js`  `move()`
29685     function click() {
29686         var d = datum();
29687         var target = d && d.properties && d.properties.entity;
29688
29689         if (target && target.type === 'node') {   // Snap to a node
29690             dispatch$$1.call('clickNode', this, target, d);
29691             return;
29692
29693         } else if (target && target.type === 'way') {   // Snap to a way
29694             var choice = geoChooseEdge(
29695                 context.childNodes(target), context.mouse(), context.projection, context.activeID()
29696             );
29697             if (choice) {
29698                 var edge = [target.nodes[choice.index - 1], target.nodes[choice.index]];
29699                 dispatch$$1.call('clickWay', this, choice.loc, edge, d);
29700                 return;
29701             }
29702         }
29703
29704         dispatch$$1.call('click', this, context.map().mouseCoordinates(), d);
29705     }
29706
29707
29708     function space() {
29709         event.preventDefault();
29710         event.stopPropagation();
29711
29712         var currSpace = context.mouse();
29713         if (_disableSpace && _lastSpace) {
29714             var dist = geoVecLength(_lastSpace, currSpace);
29715             if (dist > tolerance) {
29716                 _disableSpace = false;
29717             }
29718         }
29719
29720         if (_disableSpace || _mouseLeave || !_lastMouse) return;
29721
29722         // user must move mouse or release space bar to allow another click
29723         _lastSpace = currSpace;
29724         _disableSpace = true;
29725
29726         d3_select(window).on('keyup.space-block', function() {
29727             event.preventDefault();
29728             event.stopPropagation();
29729             _disableSpace = false;
29730             d3_select(window).on('keyup.space-block', null);
29731         });
29732
29733         click();
29734     }
29735
29736
29737     function backspace() {
29738         event.preventDefault();
29739         dispatch$$1.call('undo');
29740     }
29741
29742
29743     function del() {
29744         event.preventDefault();
29745         dispatch$$1.call('cancel');
29746     }
29747
29748
29749     function ret() {
29750         event.preventDefault();
29751         dispatch$$1.call('finish');
29752     }
29753
29754
29755     function draw(selection) {
29756         context.install(hover);
29757         context.install(edit);
29758
29759         if (!context.inIntro() && !_usedTails[tail.text()]) {
29760             context.install(tail);
29761         }
29762
29763         keybinding
29764             .on('⌫', backspace)
29765             .on('⌦', del)
29766             .on('⎋', ret)
29767             .on('↩', ret)
29768             .on('space', space)
29769             .on('⌥space', space);
29770
29771         selection
29772             .on('mouseenter.draw', mouseenter)
29773             .on('mouseleave.draw', mouseleave)
29774             .on('mousedown.draw', mousedown)
29775             .on('mousemove.draw', mousemove);
29776
29777         d3_select(document)
29778             .call(keybinding);
29779
29780         return draw;
29781     }
29782
29783
29784     draw.off = function(selection) {
29785         context.ui().sidebar.hover.cancel();
29786         context.uninstall(hover);
29787         context.uninstall(edit);
29788
29789         if (!context.inIntro() && !_usedTails[tail.text()]) {
29790             context.uninstall(tail);
29791             _usedTails[tail.text()] = true;
29792         }
29793
29794         selection
29795             .on('mouseenter.draw', null)
29796             .on('mouseleave.draw', null)
29797             .on('mousedown.draw', null)
29798             .on('mousemove.draw', null);
29799
29800         d3_select(window)
29801             .on('mouseup.draw', null);
29802             // note: keyup.space-block, click.draw-block should remain
29803
29804         d3_select(document)
29805             .call(keybinding.off);
29806     };
29807
29808
29809     draw.tail = function(_) {
29810         tail.text(_);
29811         return draw;
29812     };
29813
29814
29815     return utilRebind(draw, dispatch$$1, 'on');
29816 }
29817
29818 function modeAddArea(context) {
29819     var mode = {
29820         id: 'add-area',
29821         button: 'area',
29822         title: t('modes.add_area.title'),
29823         description: t('modes.add_area.description'),
29824         key: '3'
29825     };
29826
29827     var behavior = behaviorAddWay(context)
29828             .tail(t('modes.add_area.tail'))
29829             .on('start', start)
29830             .on('startFromWay', startFromWay)
29831             .on('startFromNode', startFromNode),
29832         defaultTags = { area: 'yes' };
29833
29834
29835     function actionClose(wayId) {
29836         return function (graph) {
29837             return graph.replace(graph.entity(wayId).close());
29838         };
29839     }
29840
29841
29842     function start(loc) {
29843         var startGraph = context.graph(),
29844             node = osmNode({ loc: loc }),
29845             way = osmWay({ tags: defaultTags });
29846
29847         context.perform(
29848             actionAddEntity(node),
29849             actionAddEntity(way),
29850             actionAddVertex(way.id, node.id),
29851             actionClose(way.id)
29852         );
29853
29854         context.enter(modeDrawArea(context, way.id, startGraph));
29855     }
29856
29857
29858     function startFromWay(loc, edge) {
29859         var startGraph = context.graph(),
29860             node = osmNode({ loc: loc }),
29861             way = osmWay({ tags: defaultTags });
29862
29863         context.perform(
29864             actionAddEntity(node),
29865             actionAddEntity(way),
29866             actionAddVertex(way.id, node.id),
29867             actionClose(way.id),
29868             actionAddMidpoint({ loc: loc, edge: edge }, node)
29869         );
29870
29871         context.enter(modeDrawArea(context, way.id, startGraph));
29872     }
29873
29874
29875     function startFromNode(node) {
29876         var startGraph = context.graph(),
29877             way = osmWay({ tags: defaultTags });
29878
29879         context.perform(
29880             actionAddEntity(way),
29881             actionAddVertex(way.id, node.id),
29882             actionClose(way.id)
29883         );
29884
29885         context.enter(modeDrawArea(context, way.id, startGraph));
29886     }
29887
29888
29889     mode.enter = function() {
29890         context.install(behavior);
29891     };
29892
29893
29894     mode.exit = function() {
29895         context.uninstall(behavior);
29896     };
29897
29898
29899     return mode;
29900 }
29901
29902 function modeAddLine(context) {
29903     var mode = {
29904         id: 'add-line',
29905         button: 'line',
29906         title: t('modes.add_line.title'),
29907         description: t('modes.add_line.description'),
29908         key: '2'
29909     };
29910
29911     var behavior = behaviorAddWay(context)
29912         .tail(t('modes.add_line.tail'))
29913         .on('start', start)
29914         .on('startFromWay', startFromWay)
29915         .on('startFromNode', startFromNode);
29916
29917
29918     function start(loc) {
29919         var startGraph = context.graph(),
29920             node = osmNode({ loc: loc }),
29921             way = osmWay();
29922
29923         context.perform(
29924             actionAddEntity(node),
29925             actionAddEntity(way),
29926             actionAddVertex(way.id, node.id)
29927         );
29928
29929         context.enter(modeDrawLine(context, way.id, startGraph));
29930     }
29931
29932
29933     function startFromWay(loc, edge) {
29934         var startGraph = context.graph(),
29935             node = osmNode({ loc: loc }),
29936             way = osmWay();
29937
29938         context.perform(
29939             actionAddEntity(node),
29940             actionAddEntity(way),
29941             actionAddVertex(way.id, node.id),
29942             actionAddMidpoint({ loc: loc, edge: edge }, node)
29943         );
29944
29945         context.enter(modeDrawLine(context, way.id, startGraph));
29946     }
29947
29948
29949     function startFromNode(node) {
29950         var startGraph = context.graph(),
29951             way = osmWay();
29952
29953         context.perform(
29954             actionAddEntity(way),
29955             actionAddVertex(way.id, node.id)
29956         );
29957
29958         context.enter(modeDrawLine(context, way.id, startGraph));
29959     }
29960
29961
29962     mode.enter = function() {
29963         context.install(behavior);
29964     };
29965
29966
29967     mode.exit = function() {
29968         context.uninstall(behavior);
29969     };
29970
29971     return mode;
29972 }
29973
29974 function modeAddPoint(context) {
29975     var mode = {
29976         id: 'add-point',
29977         button: 'point',
29978         title: t('modes.add_point.title'),
29979         description: t('modes.add_point.description'),
29980         key: '1'
29981     };
29982
29983     var behavior = behaviorDraw(context)
29984         .tail(t('modes.add_point.tail'))
29985         .on('click', add)
29986         .on('clickWay', addWay)
29987         .on('clickNode', addNode)
29988         .on('cancel', cancel)
29989         .on('finish', cancel);
29990
29991
29992     function add(loc) {
29993         var node = osmNode({ loc: loc });
29994
29995         context.perform(
29996             actionAddEntity(node),
29997             t('operations.add.annotation.point')
29998         );
29999
30000         context.enter(
30001             modeSelect(context, [node.id]).newFeature(true)
30002         );
30003     }
30004
30005
30006     function addWay(loc) {
30007         add(loc);
30008     }
30009
30010
30011     function addNode(node) {
30012         add(node.loc);
30013     }
30014
30015
30016     function cancel() {
30017         context.enter(modeBrowse(context));
30018     }
30019
30020
30021     mode.enter = function() {
30022         context.install(behavior);
30023     };
30024
30025
30026     mode.exit = function() {
30027         context.uninstall(behavior);
30028     };
30029
30030
30031     return mode;
30032 }
30033
30034 function modeDragNode(context) {
30035     var mode = {
30036         id: 'drag-node',
30037         button: 'browse'
30038     };
30039     var hover = behaviorHover(context).altDisables(true)
30040         .on('hover', context.ui().sidebar.hover);
30041     var edit = behaviorEdit(context);
30042
30043     var _nudgeInterval;
30044     var _restoreSelectedIDs = [];
30045     var _wasMidpoint = false;
30046     var _isCancelled = false;
30047     var _activeEntity;
30048     var _startLoc;
30049     var _lastLoc;
30050
30051
30052     function startNudge(entity, nudge) {
30053         if (_nudgeInterval) window.clearInterval(_nudgeInterval);
30054         _nudgeInterval = window.setInterval(function() {
30055             context.pan(nudge);
30056             doMove(entity, nudge);
30057         }, 50);
30058     }
30059
30060
30061     function stopNudge() {
30062         if (_nudgeInterval) {
30063             window.clearInterval(_nudgeInterval);
30064             _nudgeInterval = null;
30065         }
30066     }
30067
30068
30069     function moveAnnotation(entity) {
30070         return t('operations.move.annotation.' + entity.geometry(context.graph()));
30071     }
30072
30073
30074     function connectAnnotation(entity) {
30075         return t('operations.connect.annotation.' + entity.geometry(context.graph()));
30076     }
30077
30078
30079     function origin(entity) {
30080         return context.projection(entity.loc);
30081     }
30082
30083
30084     function keydown() {
30085         if (event.keyCode === d3keybinding.modifierCodes.alt) {
30086             if (context.surface().classed('nope')) {
30087                 context.surface()
30088                     .classed('nope-suppressed', true);
30089             }
30090             context.surface()
30091                 .classed('nope', false)
30092                 .classed('nope-disabled', true);
30093         }
30094     }
30095
30096
30097     function keyup() {
30098         if (event.keyCode === d3keybinding.modifierCodes.alt) {
30099             if (context.surface().classed('nope-suppressed')) {
30100                 context.surface()
30101                     .classed('nope', true);
30102             }
30103             context.surface()
30104                 .classed('nope-suppressed', false)
30105                 .classed('nope-disabled', false);
30106         }
30107     }
30108
30109
30110     function start(entity) {
30111         _wasMidpoint = entity.type === 'midpoint';
30112         var hasHidden = context.features().hasHiddenConnections(entity, context.graph());
30113         _isCancelled = event.sourceEvent.shiftKey || hasHidden;
30114
30115
30116         if (_isCancelled) {
30117             if (hasHidden) {
30118                 uiFlash().text(t('modes.drag_node.connected_to_hidden'))();
30119             }
30120             return drag.cancel();
30121         }
30122
30123         if (_wasMidpoint) {
30124             var midpoint = entity;
30125             entity = osmNode();
30126             context.perform(actionAddMidpoint(midpoint, entity));
30127             entity = context.entity(entity.id);   // get post-action entity
30128
30129             var vertex = context.surface().selectAll('.' + entity.id);
30130             drag.target(vertex.node(), entity);
30131
30132         } else {
30133             context.perform(actionNoop());
30134         }
30135
30136         _activeEntity = entity;
30137         _startLoc = entity.loc;
30138
30139         context.surface().selectAll('.' + _activeEntity.id)
30140             .classed('active', true);
30141
30142         context.enter(mode);
30143     }
30144
30145
30146     // related code
30147     // - `behavior/draw.js` `datum()`
30148     function datum() {
30149         var event$$1 = event && event.sourceEvent;
30150         if (!event$$1 || event$$1.altKey) {
30151             return {};
30152         } else {
30153             // When dragging, snap only to touch targets..
30154             // (this excludes area fills and active drawing elements)
30155             var d = event$$1.target.__data__;
30156             return (d && d.properties && d.properties.target) ? d : {};
30157         }
30158     }
30159
30160
30161     function doMove(entity, nudge) {
30162         nudge = nudge || [0, 0];
30163
30164         var currPoint = (event && event.point) || context.projection(_lastLoc);
30165         var currMouse = geoVecSubtract(currPoint, nudge);
30166         var loc = context.projection.invert(currMouse);
30167
30168         if (!_nudgeInterval) {   // If not nudging at the edge of the viewport, try to snap..
30169             // related code
30170             // - `mode/drag_node.js`     `doMode()`
30171             // - `behavior/draw.js`      `click()`
30172             // - `behavior/draw_way.js`  `move()`
30173             var d = datum();
30174             var targetLoc = d && d.properties && d.properties.entity && d.properties.entity.loc;
30175             var targetNodes = d && d.properties && d.properties.nodes;
30176
30177             if (targetLoc) {   // snap to node/vertex - a point target with `.loc`
30178                 loc = targetLoc;
30179
30180             } else if (targetNodes) {   // snap to way - a line target with `.nodes`
30181                 var choice = geoChooseEdge(targetNodes, context.mouse(), context.projection, end.id);
30182                 if (choice) {
30183                     loc = choice.loc;
30184                 }
30185             }
30186         }
30187
30188         context.replace(
30189             actionMoveNode(entity.id, loc),
30190             moveAnnotation(entity)
30191         );
30192
30193
30194         // check if this movement causes the geometry to break
30195         var nopeDisabled = context.surface().classed('nope-disabled');
30196         var isInvalid = isInvalidGeometry(entity, context.graph());
30197         if (nopeDisabled) {
30198             context.surface()
30199                 .classed('nope', false)
30200                 .classed('nope-suppressed', isInvalid);
30201         } else {
30202             context.surface()
30203                 .classed('nope', isInvalid)
30204                 .classed('nope-suppressed', false);
30205         }
30206
30207         _lastLoc = loc;
30208     }
30209
30210
30211     function isInvalidGeometry(entity, graph) {
30212         var parents = graph.parentWays(entity);
30213         var i, j, k;
30214
30215         for (i = 0; i < parents.length; i++) {
30216             var parent = parents[i];
30217             var nodes = [];
30218             var activeIndex = null;    // which multipolygon ring contains node being dragged
30219
30220             // test any parent multipolygons for valid geometry
30221             var relations = graph.parentRelations(parent);
30222             for (j = 0; j < relations.length; j++) {
30223                 if (!relations[j].isMultipolygon()) continue;
30224
30225                 var rings = osmJoinWays(relations[j].members, graph);
30226
30227                 // find active ring and test it for self intersections
30228                 for (k = 0; k < rings.length; k++) {
30229                     nodes = rings[k].nodes;
30230                     if (find$1(nodes, function(n) { return n.id === entity.id; })) {
30231                         activeIndex = k;
30232                         if (geoHasSelfIntersections(nodes, entity.id)) {
30233                             return true;
30234                         }
30235                     }
30236                     rings[k].coords = nodes.map(function(n) { return n.loc; });
30237                 }
30238
30239                 // test active ring for intersections with other rings in the multipolygon
30240                 for (k = 0; k < rings.length; k++) {
30241                     if (k === activeIndex) continue;
30242
30243                     // make sure active ring doesnt cross passive rings
30244                     if (geoPathHasIntersections(rings[activeIndex].coords, rings[k].coords)) {
30245                         return true;
30246                     }
30247                 }
30248             }
30249
30250
30251             // If we still haven't tested this node's parent way for self-intersections.
30252             // (because it's not a member of a multipolygon), test it now.
30253             if (activeIndex === null) {
30254                 nodes = parent.nodes.map(function(nodeID) { return graph.entity(nodeID); });
30255                 if (nodes.length && geoHasSelfIntersections(nodes, entity.id)) {
30256                     return true;
30257                 }
30258             }
30259
30260         }
30261
30262         return false;
30263     }
30264
30265
30266     function move(entity) {
30267         if (_isCancelled) return;
30268         event.sourceEvent.stopPropagation();
30269
30270         context.surface().classed('nope-disabled', event.sourceEvent.altKey);
30271
30272         _lastLoc = context.projection.invert(event.point);
30273
30274         doMove(entity);
30275         var nudge = geoViewportEdge(event.point, context.map().dimensions());
30276         if (nudge) {
30277             startNudge(entity, nudge);
30278         } else {
30279             stopNudge();
30280         }
30281     }
30282
30283
30284     function end(entity) {
30285         if (_isCancelled) return;
30286
30287         var d = datum();
30288         var nope = (d && d.properties && d.properties.nope) || context.surface().classed('nope');
30289         var target = d && d.properties && d.properties.entity;   // entity to snap to
30290
30291         if (nope) {   // bounce back
30292             context.perform(
30293                 _actionBounceBack(entity.id, _startLoc)
30294             );
30295
30296         } else if (target && target.type === 'way') {
30297             var choice = geoChooseEdge(context.childNodes(target), context.mouse(), context.projection, entity.id);
30298             context.replace(
30299                 actionAddMidpoint({
30300                     loc: choice.loc,
30301                     edge: [target.nodes[choice.index - 1], target.nodes[choice.index]]
30302                 }, entity),
30303                 connectAnnotation(target)
30304             );
30305
30306         } else if (target && target.type === 'node') {
30307             context.replace(
30308                 actionConnect([target.id, entity.id]),
30309                 connectAnnotation(target)
30310             );
30311
30312         } else if (_wasMidpoint) {
30313             context.replace(
30314                 actionNoop(),
30315                 t('operations.add.annotation.vertex')
30316             );
30317
30318         } else {
30319             context.replace(
30320                 actionNoop(),
30321                 moveAnnotation(entity)
30322             );
30323         }
30324
30325         var reselection = _restoreSelectedIDs.filter(function(id) {
30326             return context.graph().hasEntity(id);
30327         });
30328
30329         if (reselection.length) {
30330             context.enter(modeSelect(context, reselection));
30331         } else {
30332             context.enter(modeBrowse(context));
30333         }
30334     }
30335
30336
30337     function _actionBounceBack(nodeID, toLoc) {
30338         var moveNode = actionMoveNode(nodeID, toLoc);
30339         var action = function(graph, t$$1) {
30340             // last time through, pop off the bounceback perform.
30341             // it will then overwrite the initial perform with a moveNode that does nothing
30342             if (t$$1 === 1) context.pop();
30343             return moveNode(graph, t$$1);
30344         };
30345         action.transitionable = true;
30346         return action;
30347     }
30348
30349
30350     function cancel() {
30351         drag.cancel();
30352         context.enter(modeBrowse(context));
30353     }
30354
30355
30356     var drag = behaviorDrag()
30357         .selector('.layer-points-targets .target')
30358         .surface(d3_select('#map').node())
30359         .origin(origin)
30360         .on('start', start)
30361         .on('move', move)
30362         .on('end', end);
30363
30364
30365     mode.enter = function() {
30366         context.install(hover);
30367         context.install(edit);
30368
30369         d3_select(window)
30370             .on('keydown.drawWay', keydown)
30371             .on('keyup.drawWay', keyup);
30372
30373         context.history()
30374             .on('undone.drag-node', cancel);
30375     };
30376
30377
30378     mode.exit = function() {
30379         context.ui().sidebar.hover.cancel();
30380         context.uninstall(hover);
30381         context.uninstall(edit);
30382
30383         d3_select(window)
30384             .on('keydown.hover', null)
30385             .on('keyup.hover', null);
30386
30387         context.history()
30388             .on('undone.drag-node', null);
30389
30390         context.map()
30391             .on('drawn.drag-node', null);
30392
30393         _activeEntity = null;
30394
30395         context.surface()
30396             .classed('nope', false)
30397             .classed('nope-suppressed', false)
30398             .classed('nope-disabled', false)
30399             .selectAll('.active')
30400             .classed('active', false);
30401
30402         stopNudge();
30403     };
30404
30405
30406     mode.selectedIDs = function() {
30407         if (!arguments.length) return _activeEntity ? [_activeEntity.id] : [];
30408         // no assign
30409         return mode;
30410     };
30411
30412
30413     mode.activeID = function() {
30414         if (!arguments.length) return _activeEntity && _activeEntity.id;
30415         // no assign
30416         return mode;
30417     };
30418
30419
30420     mode.restoreSelectedIDs = function(_) {
30421         if (!arguments.length) return _restoreSelectedIDs;
30422         _restoreSelectedIDs = _;
30423         return mode;
30424     };
30425
30426
30427     mode.behavior = drag;
30428
30429
30430     return mode;
30431 }
30432
30433 function modeBrowse(context) {
30434     var mode = {
30435         button: 'browse',
30436         id: 'browse',
30437         title: t('modes.browse.title'),
30438         description: t('modes.browse.description')
30439     }, sidebar;
30440
30441     var behaviors = [
30442         behaviorPaste(context),
30443         behaviorHover(context).on('hover', context.ui().sidebar.hover),
30444         behaviorSelect(context),
30445         behaviorLasso(context),
30446         modeDragNode(context).behavior
30447     ];
30448
30449
30450     mode.enter = function() {
30451         behaviors.forEach(function(behavior) {
30452             context.install(behavior);
30453         });
30454
30455         // Get focus on the body.
30456         if (document.activeElement && document.activeElement.blur) {
30457             document.activeElement.blur();
30458         }
30459
30460         if (sidebar) {
30461             context.ui().sidebar.show(sidebar);
30462         } else {
30463             context.ui().sidebar.select(null);
30464         }
30465     };
30466
30467
30468     mode.exit = function() {
30469         context.ui().sidebar.hover.cancel();
30470         behaviors.forEach(function(behavior) {
30471             context.uninstall(behavior);
30472         });
30473
30474         if (sidebar) {
30475             context.ui().sidebar.hide();
30476         }
30477     };
30478
30479
30480     mode.sidebar = function(_) {
30481         if (!arguments.length) return sidebar;
30482         sidebar = _;
30483         return mode;
30484     };
30485
30486
30487     return mode;
30488 }
30489
30490 function modeDrawArea(context, wayId, startGraph) {
30491     var mode = {
30492         button: 'area',
30493         id: 'draw-area'
30494     };
30495
30496     var behavior;
30497
30498
30499     mode.enter = function() {
30500         var way = context.entity(wayId);
30501
30502         behavior = behaviorDrawWay(context, wayId, undefined, mode, startGraph)
30503             .tail(t('modes.draw_area.tail'));
30504
30505         var addNode = behavior.addNode;
30506
30507         behavior.addNode = function(node, d) {
30508             var length = way.nodes.length;
30509             var penultimate = length > 2 ? way.nodes[length - 2] : null;
30510
30511             if (node.id === way.first() || node.id === penultimate) {
30512                 behavior.finish();
30513             } else {
30514                 addNode(node, d);
30515             }
30516         };
30517
30518         context.install(behavior);
30519     };
30520
30521
30522     mode.exit = function() {
30523         context.uninstall(behavior);
30524     };
30525
30526
30527     mode.selectedIDs = function() {
30528         return [wayId];
30529     };
30530
30531
30532     mode.activeID = function() {
30533         return (behavior && behavior.activeID()) || [];
30534     };
30535
30536
30537     return mode;
30538 }
30539
30540 function modeDrawLine(context, wayId, startGraph, affix) {
30541     var mode = {
30542         button: 'line',
30543         id: 'draw-line'
30544     };
30545
30546     var behavior;
30547
30548
30549     mode.enter = function() {
30550         var way = context.entity(wayId);
30551         var index = (affix === 'prefix') ? 0 : undefined;
30552         var headId = (affix === 'prefix') ? way.first() : way.last();
30553
30554         behavior = behaviorDrawWay(context, wayId, index, mode, startGraph)
30555             .tail(t('modes.draw_line.tail'));
30556
30557         var addNode = behavior.addNode;
30558         behavior.addNode = function(node, d) {
30559             if (node.id === headId) {
30560                 behavior.finish();
30561             } else {
30562                 addNode(node, d);
30563             }
30564         };
30565
30566         context.install(behavior);
30567     };
30568
30569
30570     mode.exit = function() {
30571         context.uninstall(behavior);
30572     };
30573
30574
30575     mode.selectedIDs = function() {
30576         return [wayId];
30577     };
30578
30579
30580     mode.activeID = function() {
30581         return (behavior && behavior.activeID()) || [];
30582     };
30583
30584     return mode;
30585 }
30586
30587 function operationCircularize(selectedIDs, context) {
30588     var entityId = selectedIDs[0],
30589         entity = context.entity(entityId),
30590         extent = entity.extent(context.graph()),
30591         geometry = context.geometry(entityId),
30592         action = actionCircularize(entityId, context.projection);
30593
30594
30595     var operation = function() {
30596         context.perform(action, operation.annotation());
30597     };
30598
30599
30600     operation.available = function() {
30601         return selectedIDs.length === 1 &&
30602             entity.type === 'way' &&
30603             uniq(entity.nodes).length > 1;
30604     };
30605
30606
30607     operation.disabled = function() {
30608         var reason;
30609         if (extent.percentContainedIn(context.extent()) < 0.8) {
30610             reason = 'too_large';
30611         } else if (context.hasHiddenConnections(entityId)) {
30612             reason = 'connected_to_hidden';
30613         }
30614         return action.disabled(context.graph()) || reason;
30615     };
30616
30617
30618     operation.tooltip = function() {
30619         var disable = operation.disabled();
30620         return disable ?
30621             t('operations.circularize.' + disable) :
30622             t('operations.circularize.description.' + geometry);
30623     };
30624
30625
30626     operation.annotation = function() {
30627         return t('operations.circularize.annotation.' + geometry);
30628     };
30629
30630
30631     operation.id = 'circularize';
30632     operation.keys = [t('operations.circularize.key')];
30633     operation.title = t('operations.circularize.title');
30634     operation.behavior = behaviorOperation(context).which(operation);
30635
30636     return operation;
30637 }
30638
30639 function operationContinue(selectedIDs, context) {
30640     var graph = context.graph(),
30641         entities = selectedIDs.map(function(id) { return graph.entity(id); }),
30642         geometries = assignIn({ line: [], vertex: [] },
30643             groupBy(entities, function(entity) { return entity.geometry(graph); })),
30644         vertex = geometries.vertex[0];
30645
30646
30647     function candidateWays() {
30648         return graph.parentWays(vertex).filter(function(parent) {
30649             return parent.geometry(graph) === 'line' &&
30650                 !parent.isClosed() &&
30651                 parent.affix(vertex.id) &&
30652                 (geometries.line.length === 0 || geometries.line[0] === parent);
30653         });
30654     }
30655
30656
30657     var operation = function() {
30658         var candidate = candidateWays()[0];
30659         context.enter(
30660             modeDrawLine(context, candidate.id, context.graph(), candidate.affix(vertex.id))
30661         );
30662     };
30663
30664
30665     operation.available = function() {
30666         return geometries.vertex.length === 1 && geometries.line.length <= 1 &&
30667             !context.features().hasHiddenConnections(vertex, context.graph());
30668     };
30669
30670
30671     operation.disabled = function() {
30672         var candidates = candidateWays();
30673         if (candidates.length === 0)
30674             return 'not_eligible';
30675         if (candidates.length > 1)
30676             return 'multiple';
30677     };
30678
30679
30680     operation.tooltip = function() {
30681         var disable = operation.disabled();
30682         return disable ?
30683             t('operations.continue.' + disable) :
30684             t('operations.continue.description');
30685     };
30686
30687
30688     operation.annotation = function() {
30689         return t('operations.continue.annotation.line');
30690     };
30691
30692
30693     operation.id = 'continue';
30694     operation.keys = [t('operations.continue.key')];
30695     operation.title = t('operations.continue.title');
30696     operation.behavior = behaviorOperation(context).which(operation);
30697
30698     return operation;
30699 }
30700
30701 function operationDelete(selectedIDs, context) {
30702     var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
30703         action = actionDeleteMultiple(selectedIDs),
30704         extent = selectedIDs.reduce(function(extent, id) {
30705                 return extent.extend(context.entity(id).extent(context.graph()));
30706             }, geoExtent());
30707
30708
30709     var operation = function() {
30710         var nextSelectedID;
30711         var nextSelectedLoc;
30712
30713         if (selectedIDs.length === 1) {
30714             var id = selectedIDs[0],
30715                 entity = context.entity(id),
30716                 geometry = context.geometry(id),
30717                 parents = context.graph().parentWays(entity),
30718                 parent = parents[0];
30719
30720             // Select the next closest node in the way.
30721             if (geometry === 'vertex') {
30722                 var nodes = parent.nodes,
30723                     i = nodes.indexOf(id);
30724
30725                 if (i === 0) {
30726                     i++;
30727                 } else if (i === nodes.length - 1) {
30728                     i--;
30729                 } else {
30730                     var a = geoSphericalDistance(entity.loc, context.entity(nodes[i - 1]).loc),
30731                         b = geoSphericalDistance(entity.loc, context.entity(nodes[i + 1]).loc);
30732                     i = a < b ? i - 1 : i + 1;
30733                 }
30734
30735                 nextSelectedID = nodes[i];
30736                 nextSelectedLoc = context.entity(nextSelectedID).loc;
30737             }
30738         }
30739
30740         context.perform(action, operation.annotation());
30741
30742         if (nextSelectedID && nextSelectedLoc) {
30743             if (context.hasEntity(nextSelectedID)) {
30744                 context.enter(modeSelect(context, [nextSelectedID]).follow(true));
30745             } else {
30746                 context.map().centerEase(nextSelectedLoc);
30747                 context.enter(modeBrowse(context));
30748             }
30749         } else {
30750             context.enter(modeBrowse(context));
30751         }
30752
30753     };
30754
30755
30756     operation.available = function() {
30757         return true;
30758     };
30759
30760
30761     operation.disabled = function() {
30762         var reason;
30763         if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
30764             reason = 'too_large';
30765         } else if (some(selectedIDs, context.hasHiddenConnections)) {
30766             reason = 'connected_to_hidden';
30767         } else if (some(selectedIDs, protectedMember)) {
30768             reason = 'part_of_relation';
30769         } else if (some(selectedIDs, incompleteRelation)) {
30770             reason = 'incomplete_relation';
30771         }
30772         return reason;
30773
30774         function incompleteRelation(id) {
30775             var entity = context.entity(id);
30776             return entity.type === 'relation' && !entity.isComplete(context.graph());
30777         }
30778
30779         function protectedMember(id) {
30780             var entity = context.entity(id);
30781             if (entity.type !== 'way') return false;
30782
30783             var parents = context.graph().parentRelations(entity);
30784             for (var i = 0; i < parents.length; i++) {
30785                 var parent = parents[i],
30786                     type = parent.tags.type,
30787                     role = parent.memberById(id).role || 'outer';
30788                 if (type === 'route' || type === 'boundary' || (type === 'multipolygon' && role === 'outer')) {
30789                     return true;
30790                 }
30791             }
30792             return false;
30793         }
30794
30795     };
30796
30797
30798     operation.tooltip = function() {
30799         var disable = operation.disabled();
30800         return disable ?
30801             t('operations.delete.' + disable + '.' + multi) :
30802             t('operations.delete.description' + '.' + multi);
30803     };
30804
30805
30806     operation.annotation = function() {
30807         return selectedIDs.length === 1 ?
30808             t('operations.delete.annotation.' + context.geometry(selectedIDs[0])) :
30809             t('operations.delete.annotation.multiple', { n: selectedIDs.length });
30810     };
30811
30812
30813     operation.id = 'delete';
30814     operation.keys = [uiCmd('⌘⌫'), uiCmd('⌘⌦'), uiCmd('⌦')];
30815     operation.title = t('operations.delete.title');
30816     operation.behavior = behaviorOperation(context).which(operation);
30817
30818     return operation;
30819 }
30820
30821 function operationDisconnect(selectedIDs, context) {
30822     var vertices = filter(selectedIDs, function(entityId) {
30823         return context.geometry(entityId) === 'vertex';
30824     });
30825
30826     var entityId = vertices[0],
30827         action = actionDisconnect(entityId);
30828
30829     if (selectedIDs.length > 1) {
30830         action.limitWays(without(selectedIDs, entityId));
30831     }
30832
30833
30834     var operation = function() {
30835         context.perform(action, operation.annotation());
30836     };
30837
30838
30839     operation.available = function() {
30840         return vertices.length === 1;
30841     };
30842
30843
30844     operation.disabled = function() {
30845         var reason;
30846         if (some(selectedIDs, context.hasHiddenConnections)) {
30847             reason = 'connected_to_hidden';
30848         }
30849         return action.disabled(context.graph()) || reason;
30850     };
30851
30852
30853     operation.tooltip = function() {
30854         var disable = operation.disabled();
30855         return disable ?
30856             t('operations.disconnect.' + disable) :
30857             t('operations.disconnect.description');
30858     };
30859
30860
30861     operation.annotation = function() {
30862         return t('operations.disconnect.annotation');
30863     };
30864
30865
30866     operation.id = 'disconnect';
30867     operation.keys = [t('operations.disconnect.key')];
30868     operation.title = t('operations.disconnect.title');
30869     operation.behavior = behaviorOperation(context).which(operation);
30870
30871     return operation;
30872 }
30873
30874 function operationMerge(selectedIDs, context) {
30875
30876     function updatePresetTags(newGraph, ids) {
30877         var id = ids[0],
30878             newEntity = newGraph.hasEntity(id);
30879
30880         if (!newEntity) return;
30881
30882         var newPreset = context.presets().match(newEntity, newGraph);
30883
30884         context.replace(actionChangePreset(id, null, newPreset), operation.annotation());
30885     }
30886
30887
30888     var join = actionJoin(selectedIDs),
30889         merge = actionMerge(selectedIDs),
30890         mergePolygon = actionMergePolygon(selectedIDs);
30891
30892
30893     var operation = function() {
30894         var origGraph = context.graph(),
30895             action;
30896
30897         if (!join.disabled(origGraph)) {
30898             action = join;
30899         } else if (!merge.disabled(origGraph)) {
30900             action = merge;
30901         } else {
30902             action = mergePolygon;
30903         }
30904
30905         context.perform(action, operation.annotation());
30906
30907         var ids = selectedIDs.filter(function(id) {
30908             var entity = context.hasEntity(id);
30909             return entity && entity.type !== 'node';
30910         });
30911
30912         // if we merged tags, rematch preset to update tags if necessary (#3851)
30913         if (action === merge) {
30914             updatePresetTags(context.graph(), ids);
30915         }
30916
30917         context.enter(modeSelect(context, ids));
30918     };
30919
30920
30921     operation.available = function() {
30922         return selectedIDs.length >= 2;
30923     };
30924
30925
30926     operation.disabled = function() {
30927         return join.disabled(context.graph()) &&
30928             merge.disabled(context.graph()) &&
30929             mergePolygon.disabled(context.graph());
30930     };
30931
30932
30933     operation.tooltip = function() {
30934         var j = join.disabled(context.graph()),
30935             m = merge.disabled(context.graph()),
30936             p = mergePolygon.disabled(context.graph());
30937
30938         if (j === 'restriction' && m && p) {
30939             return t('operations.merge.restriction',
30940                 { relation: context.presets().item('type/restriction').name() });
30941         }
30942
30943         if (p === 'incomplete_relation' && j && m) {
30944             return t('operations.merge.incomplete_relation');
30945         }
30946
30947         if (j && m && p) {
30948             return t('operations.merge.' + j);
30949         }
30950
30951         return t('operations.merge.description');
30952     };
30953
30954
30955     operation.annotation = function() {
30956         return t('operations.merge.annotation', { n: selectedIDs.length });
30957     };
30958
30959
30960     operation.id = 'merge';
30961     operation.keys = [t('operations.merge.key')];
30962     operation.title = t('operations.merge.title');
30963     operation.behavior = behaviorOperation(context).which(operation);
30964
30965     return operation;
30966 }
30967
30968 function operationMove(selectedIDs, context) {
30969     var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
30970         extent = selectedIDs.reduce(function(extent, id) {
30971             return extent.extend(context.entity(id).extent(context.graph()));
30972         }, geoExtent());
30973
30974
30975     var operation = function() {
30976         context.enter(modeMove(context, selectedIDs));
30977     };
30978
30979
30980     operation.available = function() {
30981         return selectedIDs.length > 1 ||
30982             context.entity(selectedIDs[0]).type !== 'node';
30983     };
30984
30985
30986     operation.disabled = function() {
30987         var reason;
30988         if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
30989             reason = 'too_large';
30990         } else if (some(selectedIDs, context.hasHiddenConnections)) {
30991             reason = 'connected_to_hidden';
30992         } else if (some(selectedIDs, incompleteRelation)) {
30993             reason = 'incomplete_relation';
30994         }
30995         return reason;
30996
30997         function incompleteRelation(id) {
30998             var entity = context.entity(id);
30999             return entity.type === 'relation' && !entity.isComplete(context.graph());
31000         }
31001     };
31002
31003
31004     operation.tooltip = function() {
31005         var disable = operation.disabled();
31006         return disable ?
31007             t('operations.move.' + disable + '.' + multi) :
31008             t('operations.move.description.' + multi);
31009     };
31010
31011
31012     operation.annotation = function() {
31013         return selectedIDs.length === 1 ?
31014             t('operations.move.annotation.' + context.geometry(selectedIDs[0])) :
31015             t('operations.move.annotation.multiple');
31016     };
31017
31018
31019     operation.id = 'move';
31020     operation.keys = [t('operations.move.key')];
31021     operation.title = t('operations.move.title');
31022     operation.behavior = behaviorOperation(context).which(operation);
31023
31024     return operation;
31025 }
31026
31027 function operationOrthogonalize(selectedIDs, context) {
31028     var entityId = selectedIDs[0],
31029         entity = context.entity(entityId),
31030         extent = entity.extent(context.graph()),
31031         geometry = context.geometry(entityId),
31032         action = actionOrthogonalize(entityId, context.projection);
31033
31034
31035     var operation = function() {
31036         context.perform(action, operation.annotation());
31037     };
31038
31039
31040     operation.available = function() {
31041         return selectedIDs.length === 1 &&
31042             entity.type === 'way' &&
31043             entity.isClosed() &&
31044             uniq(entity.nodes).length > 2;
31045     };
31046
31047
31048     operation.disabled = function() {
31049         var reason;
31050         if (extent.percentContainedIn(context.extent()) < 0.8) {
31051             reason = 'too_large';
31052         } else if (context.hasHiddenConnections(entityId)) {
31053             reason = 'connected_to_hidden';
31054         }
31055         return action.disabled(context.graph()) || reason;
31056     };
31057
31058
31059     operation.tooltip = function() {
31060         var disable = operation.disabled();
31061         return disable ?
31062             t('operations.orthogonalize.' + disable) :
31063             t('operations.orthogonalize.description.' + geometry);
31064     };
31065
31066
31067     operation.annotation = function() {
31068         return t('operations.orthogonalize.annotation.' + geometry);
31069     };
31070
31071
31072     operation.id = 'orthogonalize';
31073     operation.keys = [t('operations.orthogonalize.key')];
31074     operation.title = t('operations.orthogonalize.title');
31075     operation.behavior = behaviorOperation(context).which(operation);
31076
31077     return operation;
31078 }
31079
31080 /**
31081  * This method is like `_.uniq` except that it accepts `iteratee` which is
31082  * invoked for each element in `array` to generate the criterion by which
31083  * uniqueness is computed. The order of result values is determined by the
31084  * order they occur in the array. The iteratee is invoked with one argument:
31085  * (value).
31086  *
31087  * @static
31088  * @memberOf _
31089  * @since 4.0.0
31090  * @category Array
31091  * @param {Array} array The array to inspect.
31092  * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
31093  * @returns {Array} Returns the new duplicate free array.
31094  * @example
31095  *
31096  * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
31097  * // => [2.1, 1.2]
31098  *
31099  * // The `_.property` iteratee shorthand.
31100  * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
31101  * // => [{ 'x': 1 }, { 'x': 2 }]
31102  */
31103 function uniqBy(array, iteratee) {
31104   return (array && array.length) ? baseUniq(array, baseIteratee(iteratee, 2)) : [];
31105 }
31106
31107 function operationReflectShort(selectedIDs, context) {
31108     return operationReflect(selectedIDs, context, 'short');
31109 }
31110
31111
31112 function operationReflectLong(selectedIDs, context) {
31113     return operationReflect(selectedIDs, context, 'long');
31114 }
31115
31116
31117 function operationReflect(selectedIDs, context, axis) {
31118     axis = axis || 'long';
31119     var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
31120         extent = selectedIDs.reduce(function(extent, id) {
31121             return extent.extend(context.entity(id).extent(context.graph()));
31122         }, geoExtent());
31123
31124
31125     var operation = function() {
31126         var action = actionReflect(selectedIDs, context.projection)
31127             .useLongAxis(Boolean(axis === 'long'));
31128         context.perform(action, operation.annotation());
31129     };
31130
31131
31132     operation.available = function() {
31133         var nodes = utilGetAllNodes(selectedIDs, context.graph());
31134         return uniqBy(nodes, function(n) { return n.loc; }).length >= 3;
31135     };
31136
31137
31138     operation.disabled = function() {
31139         var reason;
31140         if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
31141             reason = 'too_large';
31142         } else if (some(selectedIDs, context.hasHiddenConnections)) {
31143             reason = 'connected_to_hidden';
31144         } else if (some(selectedIDs, incompleteRelation)) {
31145             reason = 'incomplete_relation';
31146         }
31147         return reason;
31148
31149         function incompleteRelation(id) {
31150             var entity = context.entity(id);
31151             return entity.type === 'relation' && !entity.isComplete(context.graph());
31152         }
31153     };
31154
31155
31156     operation.tooltip = function() {
31157         var disable = operation.disabled();
31158         return disable ?
31159             t('operations.reflect.' + disable + '.' + multi) :
31160             t('operations.reflect.description.' + axis + '.' + multi);
31161     };
31162
31163
31164     operation.annotation = function() {
31165         return t('operations.reflect.annotation.' + axis + '.' + multi);
31166     };
31167
31168
31169     operation.id = 'reflect-' + axis;
31170     operation.keys = [t('operations.reflect.key.' + axis)];
31171     operation.title = t('operations.reflect.title.' + axis);
31172     operation.behavior = behaviorOperation(context).which(operation);
31173
31174     return operation;
31175 }
31176
31177 function operationReverse(selectedIDs, context) {
31178     var entityId = selectedIDs[0];
31179
31180     var operation = function() {
31181         context.perform(actionReverse(entityId), operation.annotation());
31182     };
31183
31184
31185     operation.available = function() {
31186         return selectedIDs.length === 1 && context.geometry(entityId) === 'line';
31187     };
31188
31189
31190     operation.disabled = function() {
31191         return false;
31192     };
31193
31194
31195     operation.tooltip = function() {
31196         return t('operations.reverse.description');
31197     };
31198
31199
31200     operation.annotation = function() {
31201         return t('operations.reverse.annotation');
31202     };
31203
31204
31205     operation.id = 'reverse';
31206     operation.keys = [t('operations.reverse.key')];
31207     operation.title = t('operations.reverse.title');
31208     operation.behavior = behaviorOperation(context).which(operation);
31209
31210     return operation;
31211 }
31212
31213 function operationRotate(selectedIDs, context) {
31214     var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
31215         extent = selectedIDs.reduce(function(extent, id) {
31216             return extent.extend(context.entity(id).extent(context.graph()));
31217         }, geoExtent());
31218
31219
31220     var operation = function() {
31221         context.enter(modeRotate(context, selectedIDs));
31222     };
31223
31224
31225     operation.available = function() {
31226         var nodes = utilGetAllNodes(selectedIDs, context.graph());
31227         return uniqBy(nodes, function(n) { return n.loc; }).length >= 2;
31228     };
31229
31230
31231     operation.disabled = function() {
31232         var reason;
31233         if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
31234             reason = 'too_large';
31235         } else if (some(selectedIDs, context.hasHiddenConnections)) {
31236             reason = 'connected_to_hidden';
31237         } else if (some(selectedIDs, incompleteRelation)) {
31238             reason = 'incomplete_relation';
31239         }
31240         return reason;
31241
31242         function incompleteRelation(id) {
31243             var entity = context.entity(id);
31244             return entity.type === 'relation' && !entity.isComplete(context.graph());
31245         }
31246     };
31247
31248
31249     operation.tooltip = function() {
31250         var disable = operation.disabled();
31251         return disable ?
31252             t('operations.rotate.' + disable + '.' + multi) :
31253             t('operations.rotate.description.' + multi);
31254     };
31255
31256
31257     operation.annotation = function() {
31258         return selectedIDs.length === 1 ?
31259             t('operations.rotate.annotation.' + context.geometry(selectedIDs[0])) :
31260             t('operations.rotate.annotation.multiple');
31261     };
31262
31263
31264     operation.id = 'rotate';
31265     operation.keys = [t('operations.rotate.key')];
31266     operation.title = t('operations.rotate.title');
31267     operation.behavior = behaviorOperation(context).which(operation);
31268
31269     return operation;
31270 }
31271
31272 function operationSplit(selectedIDs, context) {
31273     var vertices = filter(selectedIDs, function(entityId) {
31274         return context.geometry(entityId) === 'vertex';
31275     });
31276
31277     var entityId = vertices[0],
31278         action = actionSplit(entityId),
31279         ways = [];
31280
31281     if (vertices.length === 1) {
31282         if (selectedIDs.length > 1) {
31283             action.limitWays(without(selectedIDs, entityId));
31284         }
31285         ways = action.ways(context.graph());
31286     }
31287
31288
31289     var operation = function() {
31290         var difference = context.perform(action, operation.annotation());
31291         context.enter(modeSelect(context, difference.extantIDs()));
31292     };
31293
31294
31295     operation.available = function() {
31296         return vertices.length === 1;
31297     };
31298
31299
31300     operation.disabled = function() {
31301         var reason;
31302         if (some(selectedIDs, context.hasHiddenConnections)) {
31303             reason = 'connected_to_hidden';
31304         }
31305         return action.disabled(context.graph()) || reason;
31306     };
31307
31308
31309     operation.tooltip = function() {
31310         var disable = operation.disabled();
31311         if (disable) {
31312             return t('operations.split.' + disable);
31313         }
31314         if (ways.length === 1) {
31315             return t('operations.split.description.' + context.geometry(ways[0].id));
31316         } else {
31317             return t('operations.split.description.multiple');
31318         }
31319     };
31320
31321
31322     operation.annotation = function() {
31323         return ways.length === 1 ?
31324             t('operations.split.annotation.' + context.geometry(ways[0].id)) :
31325             t('operations.split.annotation.multiple', { n: ways.length });
31326     };
31327
31328
31329     operation.id = 'split';
31330     operation.keys = [t('operations.split.key')];
31331     operation.title = t('operations.split.title');
31332     operation.behavior = behaviorOperation(context).which(operation);
31333
31334     return operation;
31335 }
31336
31337 function operationStraighten(selectedIDs, context) {
31338     var entityId = selectedIDs[0],
31339         action = actionStraighten(entityId, context.projection);
31340
31341
31342     function operation() {
31343         context.perform(action, operation.annotation());
31344     }
31345
31346
31347     operation.available = function() {
31348         var entity = context.entity(entityId);
31349         return selectedIDs.length === 1 &&
31350             entity.type === 'way' &&
31351             !entity.isClosed() &&
31352             uniq(entity.nodes).length > 2;
31353     };
31354
31355
31356     operation.disabled = function() {
31357         var reason;
31358         if (context.hasHiddenConnections(entityId)) {
31359             reason = 'connected_to_hidden';
31360         }
31361         return action.disabled(context.graph()) || reason;
31362     };
31363
31364
31365     operation.tooltip = function() {
31366         var disable = operation.disabled();
31367         return disable ?
31368             t('operations.straighten.' + disable) :
31369             t('operations.straighten.description');
31370     };
31371
31372
31373     operation.annotation = function() {
31374         return t('operations.straighten.annotation');
31375     };
31376
31377
31378     operation.id = 'straighten';
31379     operation.keys = [t('operations.straighten.key')];
31380     operation.title = t('operations.straighten.title');
31381     operation.behavior = behaviorOperation(context).which(operation);
31382
31383     return operation;
31384 }
31385
31386
31387
31388 var Operations = Object.freeze({
31389         operationCircularize: operationCircularize,
31390         operationContinue: operationContinue,
31391         operationDelete: operationDelete,
31392         operationDisconnect: operationDisconnect,
31393         operationMerge: operationMerge,
31394         operationMove: operationMove,
31395         operationOrthogonalize: operationOrthogonalize,
31396         operationReflectShort: operationReflectShort,
31397         operationReflectLong: operationReflectLong,
31398         operationReverse: operationReverse,
31399         operationRotate: operationRotate,
31400         operationSplit: operationSplit,
31401         operationStraighten: operationStraighten
31402 });
31403
31404 function modeMove(context, entityIDs, baseGraph) {
31405     var mode = {
31406         id: 'move',
31407         button: 'browse'
31408     };
31409
31410     var keybinding = d3keybinding('move');
31411     var behaviors = [
31412         behaviorEdit(context),
31413         operationCircularize(entityIDs, context).behavior,
31414         operationDelete(entityIDs, context).behavior,
31415         operationOrthogonalize(entityIDs, context).behavior,
31416         operationReflectLong(entityIDs, context).behavior,
31417         operationReflectShort(entityIDs, context).behavior,
31418         operationRotate(entityIDs, context).behavior
31419     ];
31420     var annotation = entityIDs.length === 1 ?
31421         t('operations.move.annotation.' + context.geometry(entityIDs[0])) :
31422         t('operations.move.annotation.multiple');
31423
31424     var _prevGraph;
31425     var _cache;
31426     var _origin;
31427     var _nudgeInterval;
31428
31429
31430     function vecSub(a, b) {
31431         return [a[0] - b[0], a[1] - b[1]];
31432     }
31433
31434
31435     function doMove(nudge) {
31436         nudge = nudge || [0, 0];
31437
31438         var fn;
31439         if (_prevGraph !== context.graph()) {
31440             _cache = {};
31441             _origin = context.map().mouseCoordinates();
31442             fn = context.perform;
31443         } else {
31444             fn = context.overwrite;
31445         }
31446
31447         var currMouse = context.mouse();
31448         var origMouse = context.projection(_origin);
31449         var delta = vecSub(vecSub(currMouse, origMouse), nudge);
31450
31451         fn(actionMove(entityIDs, delta, context.projection, _cache), annotation);
31452         _prevGraph = context.graph();
31453     }
31454
31455
31456     function startNudge(nudge) {
31457         if (_nudgeInterval) window.clearInterval(_nudgeInterval);
31458         _nudgeInterval = window.setInterval(function() {
31459             context.pan(nudge);
31460             doMove(nudge);
31461         }, 50);
31462     }
31463
31464
31465     function stopNudge() {
31466         if (_nudgeInterval) {
31467             window.clearInterval(_nudgeInterval);
31468             _nudgeInterval = null;
31469         }
31470     }
31471
31472
31473     function move() {
31474         doMove();
31475         var nudge = geoViewportEdge(context.mouse(), context.map().dimensions());
31476         if (nudge) {
31477             startNudge(nudge);
31478         } else {
31479             stopNudge();
31480         }
31481     }
31482
31483
31484     function finish() {
31485         event.stopPropagation();
31486         context.enter(modeSelect(context, entityIDs));
31487         stopNudge();
31488     }
31489
31490
31491     function cancel() {
31492         if (baseGraph) {
31493             while (context.graph() !== baseGraph) context.pop();
31494             context.enter(modeBrowse(context));
31495         } else {
31496             context.pop();
31497             context.enter(modeSelect(context, entityIDs));
31498         }
31499         stopNudge();
31500     }
31501
31502
31503     function undone() {
31504         context.enter(modeBrowse(context));
31505     }
31506
31507
31508     mode.enter = function() {
31509         _origin = context.map().mouseCoordinates();
31510         _prevGraph = null;
31511         _cache = {};
31512
31513         behaviors.forEach(function(behavior) {
31514             context.install(behavior);
31515         });
31516
31517         context.surface()
31518             .on('mousemove.move', move)
31519             .on('click.move', finish);
31520
31521         context.history()
31522             .on('undone.move', undone);
31523
31524         keybinding
31525             .on('⎋', cancel)
31526             .on('↩', finish);
31527
31528         d3_select(document)
31529             .call(keybinding);
31530     };
31531
31532
31533     mode.exit = function() {
31534         stopNudge();
31535
31536         behaviors.forEach(function(behavior) {
31537             context.uninstall(behavior);
31538         });
31539
31540         context.surface()
31541             .on('mousemove.move', null)
31542             .on('click.move', null);
31543
31544         context.history()
31545             .on('undone.move', null);
31546
31547         keybinding.off();
31548     };
31549
31550
31551     mode.selectedIDs = function() {
31552         if (!arguments.length) return entityIDs;
31553         // no assign
31554         return mode;
31555     };
31556
31557
31558     return mode;
31559 }
31560
31561 function modeRotate(context, entityIDs) {
31562     var mode = {
31563         id: 'rotate',
31564         button: 'browse'
31565     };
31566
31567     var keybinding = d3keybinding('rotate');
31568     var behaviors = [
31569         behaviorEdit(context),
31570         operationCircularize(entityIDs, context).behavior,
31571         operationDelete(entityIDs, context).behavior,
31572         operationMove(entityIDs, context).behavior,
31573         operationOrthogonalize(entityIDs, context).behavior,
31574         operationReflectLong(entityIDs, context).behavior,
31575         operationReflectShort(entityIDs, context).behavior
31576     ];
31577     var annotation = entityIDs.length === 1 ?
31578         t('operations.rotate.annotation.' + context.geometry(entityIDs[0])) :
31579         t('operations.rotate.annotation.multiple');
31580
31581     var _prevGraph;
31582     var _prevAngle;
31583     var _prevTransform;
31584     var _pivot;
31585
31586
31587     function doRotate() {
31588         var fn;
31589         if (context.graph() !== _prevGraph) {
31590             fn = context.perform;
31591         } else {
31592             fn = context.replace;
31593         }
31594
31595         // projection changed, recalculate _pivot
31596         var projection = context.projection;
31597         var currTransform = projection.transform();
31598         if (!_prevTransform ||
31599             currTransform.k !== _prevTransform.k ||
31600             currTransform.x !== _prevTransform.x ||
31601             currTransform.y !== _prevTransform.y) {
31602
31603             var nodes = utilGetAllNodes(entityIDs, context.graph());
31604             var points = nodes.map(function(n) { return projection(n.loc); });
31605
31606             if (points.length === 1) {  // degenerate case
31607                 _pivot = points[0];
31608             } else if (points.length === 2) {
31609                 _pivot = geoVecInterp(points[0], points[1], 0.5);
31610             } else {
31611                 _pivot = d3_polygonCentroid(d3_polygonHull(points));
31612             }
31613             _prevAngle = undefined;
31614         }
31615
31616
31617         var currMouse = context.mouse();
31618         var currAngle = Math.atan2(currMouse[1] - _pivot[1], currMouse[0] - _pivot[0]);
31619
31620         if (typeof _prevAngle === 'undefined') _prevAngle = currAngle;
31621         var delta = currAngle - _prevAngle;
31622
31623         fn(actionRotate(entityIDs, _pivot, delta, projection), annotation);
31624
31625         _prevTransform = currTransform;
31626         _prevAngle = currAngle;
31627         _prevGraph = context.graph();
31628     }
31629
31630
31631     function finish() {
31632         event.stopPropagation();
31633         context.enter(modeSelect(context, entityIDs));
31634     }
31635
31636
31637     function cancel() {
31638         context.pop();
31639         context.enter(modeSelect(context, entityIDs));
31640     }
31641
31642
31643     function undone() {
31644         context.enter(modeBrowse(context));
31645     }
31646
31647
31648     mode.enter = function() {
31649         behaviors.forEach(function(behavior) {
31650             context.install(behavior);
31651         });
31652
31653         context.surface()
31654             .on('mousemove.rotate', doRotate)
31655             .on('click.rotate', finish);
31656
31657         context.history()
31658             .on('undone.rotate', undone);
31659
31660         keybinding
31661             .on('⎋', cancel)
31662             .on('↩', finish);
31663
31664         d3_select(document)
31665             .call(keybinding);
31666     };
31667
31668
31669     mode.exit = function() {
31670         behaviors.forEach(function(behavior) {
31671             context.uninstall(behavior);
31672         });
31673
31674         context.surface()
31675             .on('mousemove.rotate', null)
31676             .on('click.rotate', null);
31677
31678         context.history()
31679             .on('undone.rotate', null);
31680
31681         keybinding.off();
31682     };
31683
31684
31685     mode.selectedIDs = function() {
31686         if (!arguments.length) return entityIDs;
31687         // no assign
31688         return mode;
31689     };
31690
31691
31692     return mode;
31693 }
31694
31695 /**
31696  * The base implementation of `_.reduce` and `_.reduceRight`, without support
31697  * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
31698  *
31699  * @private
31700  * @param {Array|Object} collection The collection to iterate over.
31701  * @param {Function} iteratee The function invoked per iteration.
31702  * @param {*} accumulator The initial value.
31703  * @param {boolean} initAccum Specify using the first or last element of
31704  *  `collection` as the initial value.
31705  * @param {Function} eachFunc The function to iterate over `collection`.
31706  * @returns {*} Returns the accumulated value.
31707  */
31708 function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
31709   eachFunc(collection, function(value, index, collection) {
31710     accumulator = initAccum
31711       ? (initAccum = false, value)
31712       : iteratee(accumulator, value, index, collection);
31713   });
31714   return accumulator;
31715 }
31716
31717 /**
31718  * Reduces `collection` to a value which is the accumulated result of running
31719  * each element in `collection` thru `iteratee`, where each successive
31720  * invocation is supplied the return value of the previous. If `accumulator`
31721  * is not given, the first element of `collection` is used as the initial
31722  * value. The iteratee is invoked with four arguments:
31723  * (accumulator, value, index|key, collection).
31724  *
31725  * Many lodash methods are guarded to work as iteratees for methods like
31726  * `_.reduce`, `_.reduceRight`, and `_.transform`.
31727  *
31728  * The guarded methods are:
31729  * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
31730  * and `sortBy`
31731  *
31732  * @static
31733  * @memberOf _
31734  * @since 0.1.0
31735  * @category Collection
31736  * @param {Array|Object} collection The collection to iterate over.
31737  * @param {Function} [iteratee=_.identity] The function invoked per iteration.
31738  * @param {*} [accumulator] The initial value.
31739  * @returns {*} Returns the accumulated value.
31740  * @see _.reduceRight
31741  * @example
31742  *
31743  * _.reduce([1, 2], function(sum, n) {
31744  *   return sum + n;
31745  * }, 0);
31746  * // => 3
31747  *
31748  * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
31749  *   (result[value] || (result[value] = [])).push(key);
31750  *   return result;
31751  * }, {});
31752  * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
31753  */
31754 function reduce(collection, iteratee, accumulator) {
31755   var func = isArray(collection) ? arrayReduce : baseReduce,
31756       initAccum = arguments.length < 3;
31757
31758   return func(collection, baseIteratee(iteratee, 4), accumulator, initAccum, baseEach);
31759 }
31760
31761 var _isSaving = false;
31762
31763
31764 function modeSave(context) {
31765     var mode = { id: 'save' };
31766     var keybinding = d3keybinding('save');
31767
31768     var loading = uiLoading(context)
31769         .message(t('save.uploading'))
31770         .blocking(true);
31771
31772     var commit = uiCommit(context)
31773         .on('cancel', cancel)
31774         .on('save', save);
31775
31776     var _toCheck = [];
31777     var _toLoad = [];
31778     var _loaded = {};
31779     var _toLoadCount = 0;
31780     var _toLoadTotal = 0;
31781
31782     var _conflicts = [];
31783     var _errors = [];
31784     var _origChanges;
31785
31786
31787     function cancel(selectedID) {
31788         if (selectedID) {
31789             context.enter(modeSelect(context, [selectedID]));
31790         } else {
31791             context.enter(modeBrowse(context));
31792         }
31793     }
31794
31795
31796     function save(changeset, tryAgain, checkConflicts) {
31797         // Guard against accidentally entering save code twice - #4641
31798         if (_isSaving && !tryAgain) {
31799             return;
31800         }
31801
31802         var osm = context.connection();
31803         if (!osm) {
31804             cancel();
31805             return;
31806         }
31807
31808         // If user somehow got logged out mid-save, try to reauthenticate..
31809         // This can happen if they were logged in from before, but the tokens are no longer valid.
31810         if (!osm.authenticated()) {
31811             osm.authenticate(function(err) {
31812                 if (err) {
31813                     cancel();   // quit save mode..
31814                 } else {
31815                     save(changeset, tryAgain, checkConflicts);  // continue where we left off..
31816                 }
31817             });
31818             return;
31819         }
31820
31821         if (!_isSaving) {
31822             keybindingOff();
31823             context.container().call(loading);  // block input
31824             _isSaving = true;
31825         }
31826
31827         var history = context.history();
31828         var localGraph = context.graph();
31829         var remoteGraph = coreGraph(history.base(), true);
31830
31831         _conflicts = [];
31832         _errors = [];
31833
31834         // Store original changes, in case user wants to download them as an .osc file
31835         _origChanges = history.changes(actionDiscardTags(history.difference()));
31836
31837         // First time, `history.perform` a no-op action.
31838         // Any conflict resolutions will be done as `history.replace`
31839         if (!tryAgain) {
31840             history.perform(actionNoop());
31841         }
31842
31843         // Attempt a fast upload.. If there are conflicts, re-enter with `checkConflicts = true`
31844         if (!checkConflicts) {
31845             upload(changeset);
31846
31847         // Do the full (slow) conflict check..
31848         } else {
31849             var modified = filter(history.difference().summary(), { changeType: 'modified' });
31850             _toCheck = map$4(map$4(modified, 'entity'), 'id');
31851             _toLoad = withChildNodes(_toCheck, localGraph);
31852             _loaded = {};
31853             _toLoadCount = 0;
31854             _toLoadTotal = _toLoad.length;
31855
31856             if (_toCheck.length) {
31857                 showProgress(_toLoadCount, _toLoadTotal);
31858                 _toLoad.forEach(function(id) { _loaded[id] = false; });
31859                 osm.loadMultiple(_toLoad, loaded);
31860             } else {
31861                 upload(changeset);
31862             }
31863         }
31864
31865         return;
31866
31867
31868         function withChildNodes(ids, graph) {
31869             return uniq(reduce(ids, function(result, id) {
31870                 var entity = graph.entity(id);
31871                 if (entity.type === 'way') {
31872                     try {
31873                         var children = graph.childNodes(entity);
31874                         result.push.apply(result, map$4(filter(children, 'version'), 'id'));
31875                     } catch (err) {
31876                         /* eslint-disable no-console */
31877                         if (typeof console !== 'undefined') console.error(err);
31878                         /* eslint-enable no-console */
31879                     }
31880                 }
31881                 return result;
31882             }, clone(ids)));
31883         }
31884
31885
31886         // Reload modified entities into an alternate graph and check for conflicts..
31887         function loaded(err, result) {
31888             if (_errors.length) return;
31889
31890             if (err) {
31891                 _errors.push({
31892                     msg: err.message || err.responseText,
31893                     details: [ t('save.status_code', { code: err.status }) ]
31894                 });
31895                 showErrors();
31896
31897             } else {
31898                 var loadMore = [];
31899
31900                 result.data.forEach(function(entity) {
31901                     remoteGraph.replace(entity);
31902                     _loaded[entity.id] = true;
31903                     _toLoad = without(_toLoad, entity.id);
31904
31905                     if (!entity.visible) return;
31906
31907                     // Because loadMultiple doesn't download /full like loadEntity,
31908                     // need to also load children that aren't already being checked..
31909                     var i, id;
31910                     if (entity.type === 'way') {
31911                         for (i = 0; i < entity.nodes.length; i++) {
31912                             id = entity.nodes[i];
31913                             if (_loaded[id] === undefined) {
31914                                 _loaded[id] = false;
31915                                 loadMore.push(id);
31916                             }
31917                         }
31918                     } else if (entity.type === 'relation' && entity.isMultipolygon()) {
31919                         for (i = 0; i < entity.members.length; i++) {
31920                             id = entity.members[i].id;
31921                             if (_loaded[id] === undefined) {
31922                                 _loaded[id] = false;
31923                                 loadMore.push(id);
31924                             }
31925                         }
31926                     }
31927                 });
31928
31929                 _toLoadCount += result.data.length;
31930                 _toLoadTotal += loadMore.length;
31931                 showProgress(_toLoadCount, _toLoadTotal);
31932
31933                 if (loadMore.length) {
31934                     _toLoad.push.apply(_toLoad, loadMore);
31935                     osm.loadMultiple(loadMore, loaded);
31936                 }
31937
31938                 if (!_toLoad.length) {
31939                     detectConflicts();
31940                 }
31941             }
31942         }
31943
31944
31945         function detectConflicts() {
31946             function choice(id, text, action) {
31947                 return { id: id, text: text, action: function() { history.replace(action); } };
31948             }
31949             function formatUser(d) {
31950                 return '<a href="' + osm.userURL(d) + '" target="_blank">' + d + '</a>';
31951             }
31952             function entityName(entity) {
31953                 return utilDisplayName(entity) || (utilDisplayType(entity.id) + ' ' + entity.id);
31954             }
31955
31956             function sameVersions(local, remote) {
31957                 if (local.version !== remote.version) return false;
31958
31959                 if (local.type === 'way') {
31960                     var children = union(local.nodes, remote.nodes);
31961                     for (var i = 0; i < children.length; i++) {
31962                         var a = localGraph.hasEntity(children[i]);
31963                         var b = remoteGraph.hasEntity(children[i]);
31964                         if (a && b && a.version !== b.version) return false;
31965                     }
31966                 }
31967
31968                 return true;
31969             }
31970
31971             _toCheck.forEach(function(id) {
31972                 var local = localGraph.entity(id);
31973                 var remote = remoteGraph.entity(id);
31974
31975                 if (sameVersions(local, remote)) return;
31976
31977                 var action = actionMergeRemoteChanges;
31978                 var merge = action(id, localGraph, remoteGraph, formatUser);
31979
31980                 history.replace(merge);
31981
31982                 var mergeConflicts = merge.conflicts();
31983                 if (!mergeConflicts.length) return;  // merged safely
31984
31985                 var forceLocal = action(id, localGraph, remoteGraph).withOption('force_local');
31986                 var forceRemote = action(id, localGraph, remoteGraph).withOption('force_remote');
31987                 var keepMine = t('save.conflict.' + (remote.visible ? 'keep_local' : 'restore'));
31988                 var keepTheirs = t('save.conflict.' + (remote.visible ? 'keep_remote' : 'delete'));
31989
31990                 _conflicts.push({
31991                     id: id,
31992                     name: entityName(local),
31993                     details: mergeConflicts,
31994                     chosen: 1,
31995                     choices: [
31996                         choice(id, keepMine, forceLocal),
31997                         choice(id, keepTheirs, forceRemote)
31998                     ]
31999                 });
32000             });
32001
32002             upload(changeset);
32003         }
32004     }
32005
32006
32007     function upload(changeset) {
32008         var osm = context.connection();
32009         if (!osm) {
32010             _errors.push({ msg: 'No OSM Service' });
32011         }
32012
32013         if (_conflicts.length) {
32014             _conflicts.sort(function(a, b) { return b.id.localeCompare(a.id); });
32015             showConflicts(changeset);
32016
32017         } else if (_errors.length) {
32018             showErrors();
32019
32020         } else {
32021             var history = context.history();
32022             var changes = history.changes(actionDiscardTags(history.difference()));
32023             if (changes.modified.length || changes.created.length || changes.deleted.length) {
32024                 osm.putChangeset(changeset, changes, uploadCallback);
32025             } else {        // changes were insignificant or reverted by user
32026                 d3_select('.inspector-wrap *').remove();
32027                 loading.close();
32028                 _isSaving = false;
32029                 context.flush();
32030                 cancel();
32031             }
32032         }
32033     }
32034
32035
32036     function uploadCallback(err, changeset) {
32037         if (err) {
32038             if (err.status === 409) {          // 409 Conflict
32039                 save(changeset, true, true);   // tryAgain = true, checkConflicts = true
32040             } else {
32041                 _errors.push({
32042                     msg: err.message || err.responseText,
32043                     details: [ t('save.status_code', { code: err.status }) ]
32044                 });
32045                 showErrors();
32046             }
32047
32048         } else {
32049             context.history().clearSaved();
32050             success(changeset);
32051             // Add delay to allow for postgres replication #1646 #2678
32052             window.setTimeout(function() {
32053                 d3_select('.inspector-wrap *').remove();
32054                 loading.close();
32055                 _isSaving = false;
32056                 context.flush();
32057             }, 2500);
32058         }
32059     }
32060
32061
32062     function showProgress(num, total) {
32063         var modal = context.container().select('.loading-modal .modal-section');
32064         var progress = modal.selectAll('.progress')
32065             .data([0]);
32066
32067         // enter/update
32068         progress.enter()
32069             .append('div')
32070             .attr('class', 'progress')
32071             .merge(progress)
32072             .text(t('save.conflict_progress', { num: num, total: total }));
32073     }
32074
32075
32076     function showConflicts(changeset) {
32077         var history = context.history();
32078         var selection = context.container()
32079             .select('#sidebar')
32080             .append('div')
32081             .attr('class','sidebar-component');
32082
32083         loading.close();
32084         _isSaving = false;
32085
32086         var ui = uiConflicts(context)
32087             .conflictList(_conflicts)
32088             .origChanges(_origChanges)
32089             .on('cancel', function() {
32090                 history.pop();
32091                 selection.remove();
32092                 keybindingOn();
32093             })
32094             .on('save', function() {
32095                 for (var i = 0; i < _conflicts.length; i++) {
32096                     if (_conflicts[i].chosen === 1) {  // user chose "keep theirs"
32097                         var entity = context.hasEntity(_conflicts[i].id);
32098                         if (entity && entity.type === 'way') {
32099                             var children = uniq(entity.nodes);
32100                             for (var j = 0; j < children.length; j++) {
32101                                 history.replace(actionRevert(children[j]));
32102                             }
32103                         }
32104                         history.replace(actionRevert(_conflicts[i].id));
32105                     }
32106                 }
32107
32108                 selection.remove();
32109                 save(changeset, true, false);  // tryAgain = true, checkConflicts = false
32110             });
32111
32112         selection.call(ui);
32113     }
32114
32115
32116     function showErrors() {
32117         keybindingOn();
32118         context.history().pop();
32119         loading.close();
32120         _isSaving = false;
32121
32122         var selection = uiConfirm(context.container());
32123         selection
32124             .select('.modal-section.header')
32125             .append('h3')
32126             .text(t('save.error'));
32127
32128         addErrors(selection, _errors);
32129         selection.okButton();
32130     }
32131
32132
32133     function addErrors(selection, data) {
32134         var message = selection
32135             .select('.modal-section.message-text');
32136
32137         var items = message
32138             .selectAll('.error-container')
32139             .data(data);
32140
32141         var enter = items.enter()
32142             .append('div')
32143             .attr('class', 'error-container');
32144
32145         enter
32146             .append('a')
32147             .attr('class', 'error-description')
32148             .attr('href', '#')
32149             .classed('hide-toggle', true)
32150             .text(function(d) { return d.msg || t('save.unknown_error_details'); })
32151             .on('click', function() {
32152                 event.preventDefault();
32153
32154                 var error = d3_select(this);
32155                 var detail = d3_select(this.nextElementSibling);
32156                 var exp = error.classed('expanded');
32157
32158                 detail.style('display', exp ? 'none' : 'block');
32159                 error.classed('expanded', !exp);
32160             });
32161
32162         var details = enter
32163             .append('div')
32164             .attr('class', 'error-detail-container')
32165             .style('display', 'none');
32166
32167         details
32168             .append('ul')
32169             .attr('class', 'error-detail-list')
32170             .selectAll('li')
32171             .data(function(d) { return d.details || []; })
32172             .enter()
32173             .append('li')
32174             .attr('class', 'error-detail-item')
32175             .text(function(d) { return d; });
32176
32177         items.exit()
32178             .remove();
32179     }
32180
32181
32182     function success(changeset) {
32183         commit.reset();
32184
32185         var ui = uiSuccess(context)
32186             .changeset(changeset)
32187             .on('cancel', function() { context.ui().sidebar.hide(); });
32188
32189         context.enter(modeBrowse(context).sidebar(ui));
32190     }
32191
32192
32193     function keybindingOn() {
32194         d3_select(document)
32195             .call(keybinding.on('⎋', cancel, true));
32196     }
32197
32198
32199     function keybindingOff() {
32200         d3_select(document)
32201             .call(keybinding.off);
32202     }
32203
32204
32205     mode.enter = function() {
32206         function done() {
32207             context.ui().sidebar.show(commit);
32208         }
32209
32210         keybindingOn();
32211
32212         context.container().selectAll('#content')
32213             .attr('class', 'inactive');
32214
32215         var osm = context.connection();
32216         if (!osm) {
32217             cancel();
32218             return;
32219         }
32220
32221         if (osm.authenticated()) {
32222             done();
32223         } else {
32224             osm.authenticate(function(err) {
32225                 if (err) {
32226                     cancel();
32227                 } else {
32228                     done();
32229                 }
32230             });
32231         }
32232     };
32233
32234
32235     mode.exit = function() {
32236         _isSaving = false;
32237
32238         keybindingOff();
32239
32240         context.container().selectAll('#content')
32241             .attr('class', 'active');
32242
32243         context.ui().sidebar.hide();
32244     };
32245
32246     return mode;
32247 }
32248
32249 /* Built-in method references for those with the same name as other `lodash` methods. */
32250 var nativeMin$1 = Math.min;
32251
32252 /**
32253  * The base implementation of methods like `_.intersection`, without support
32254  * for iteratee shorthands, that accepts an array of arrays to inspect.
32255  *
32256  * @private
32257  * @param {Array} arrays The arrays to inspect.
32258  * @param {Function} [iteratee] The iteratee invoked per element.
32259  * @param {Function} [comparator] The comparator invoked per element.
32260  * @returns {Array} Returns the new array of shared values.
32261  */
32262 function baseIntersection(arrays, iteratee, comparator) {
32263   var includes = comparator ? arrayIncludesWith : arrayIncludes,
32264       length = arrays[0].length,
32265       othLength = arrays.length,
32266       othIndex = othLength,
32267       caches = Array(othLength),
32268       maxLength = Infinity,
32269       result = [];
32270
32271   while (othIndex--) {
32272     var array = arrays[othIndex];
32273     if (othIndex && iteratee) {
32274       array = arrayMap(array, baseUnary(iteratee));
32275     }
32276     maxLength = nativeMin$1(array.length, maxLength);
32277     caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
32278       ? new SetCache(othIndex && array)
32279       : undefined;
32280   }
32281   array = arrays[0];
32282
32283   var index = -1,
32284       seen = caches[0];
32285
32286   outer:
32287   while (++index < length && result.length < maxLength) {
32288     var value = array[index],
32289         computed = iteratee ? iteratee(value) : value;
32290
32291     value = (comparator || value !== 0) ? value : 0;
32292     if (!(seen
32293           ? cacheHas(seen, computed)
32294           : includes(result, computed, comparator)
32295         )) {
32296       othIndex = othLength;
32297       while (--othIndex) {
32298         var cache = caches[othIndex];
32299         if (!(cache
32300               ? cacheHas(cache, computed)
32301               : includes(arrays[othIndex], computed, comparator))
32302             ) {
32303           continue outer;
32304         }
32305       }
32306       if (seen) {
32307         seen.push(computed);
32308       }
32309       result.push(value);
32310     }
32311   }
32312   return result;
32313 }
32314
32315 /**
32316  * Casts `value` to an empty array if it's not an array like object.
32317  *
32318  * @private
32319  * @param {*} value The value to inspect.
32320  * @returns {Array|Object} Returns the cast array-like object.
32321  */
32322 function castArrayLikeObject(value) {
32323   return isArrayLikeObject(value) ? value : [];
32324 }
32325
32326 /**
32327  * Creates an array of unique values that are included in all given arrays
32328  * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
32329  * for equality comparisons. The order and references of result values are
32330  * determined by the first array.
32331  *
32332  * @static
32333  * @memberOf _
32334  * @since 0.1.0
32335  * @category Array
32336  * @param {...Array} [arrays] The arrays to inspect.
32337  * @returns {Array} Returns the new array of intersecting values.
32338  * @example
32339  *
32340  * _.intersection([2, 1], [2, 3]);
32341  * // => [2]
32342  */
32343 var intersection = baseRest(function(arrays) {
32344   var mapped = arrayMap(arrays, castArrayLikeObject);
32345   return (mapped.length && mapped[0] === arrays[0])
32346     ? baseIntersection(mapped)
32347     : [];
32348 });
32349
32350 // Translate a MacOS key command into the appropriate Windows/Linux equivalent.
32351 // For example, ⌘Z -> Ctrl+Z
32352 var uiCmd = function (code) {
32353     var detected = utilDetect();
32354
32355     if (detected.os === 'mac') {
32356         return code;
32357     }
32358
32359     if (detected.os === 'win') {
32360         if (code === '⌘⇧Z') return 'Ctrl+Y';
32361     }
32362
32363     var result = '',
32364         replacements = {
32365             '⌘': 'Ctrl',
32366             '⇧': 'Shift',
32367             '⌥': 'Alt',
32368             '⌫': 'Backspace',
32369             '⌦': 'Delete'
32370         };
32371
32372     for (var i = 0; i < code.length; i++) {
32373         if (code[i] in replacements) {
32374             result += replacements[code[i]] + (i < code.length - 1 ? '+' : '');
32375         } else {
32376             result += code[i];
32377         }
32378     }
32379
32380     return result;
32381 };
32382
32383
32384 // return a display-focused string for a given keyboard code
32385 uiCmd.display = function(code) {
32386     if (code.length !== 1) return code;
32387
32388     var detected = utilDetect();
32389     var mac = (detected.os === 'mac');
32390     var replacements = {
32391         '⌘': mac ? '⌘ ' + t('shortcuts.key.cmd')    : t('shortcuts.key.ctrl'),
32392         '⇧': mac ? '⇧ ' + t('shortcuts.key.shift')  : t('shortcuts.key.shift'),
32393         '⌥': mac ? '⌥ ' + t('shortcuts.key.option') : t('shortcuts.key.alt'),
32394         '⌃': mac ? '⌃ ' + t('shortcuts.key.ctrl')   : t('shortcuts.key.ctrl'),
32395         '⌫': mac ? '⌫ ' + t('shortcuts.key.delete') : t('shortcuts.key.backspace'),
32396         '⌦': mac ? '⌦ ' + t('shortcuts.key.del')    : t('shortcuts.key.del'),
32397         '↖': mac ? '↖ ' + t('shortcuts.key.pgup')   : t('shortcuts.key.pgup'),
32398         '↘': mac ? '↘ ' + t('shortcuts.key.pgdn')   : t('shortcuts.key.pgdn'),
32399         '⇞': mac ? '⇞ ' + t('shortcuts.key.home')   : t('shortcuts.key.home'),
32400         '⇟': mac ? '⇟ ' + t('shortcuts.key.end')    : t('shortcuts.key.end'),
32401         '↵': mac ? '↵ ' + t('shortcuts.key.return') : t('shortcuts.key.enter'),
32402         '⎋': mac ? '⎋ ' + t('shortcuts.key.esc')    : t('shortcuts.key.esc'),
32403     };
32404
32405     return replacements[code] || code;
32406 };
32407
32408 // deprecation warning - Radial Menu to be removed in iD v3
32409 var relatedParent;
32410
32411
32412 function modeSelect(context, selectedIDs) {
32413     var mode = {
32414         id: 'select',
32415         button: 'browse'
32416     };
32417
32418     var keybinding = d3keybinding('select'),
32419         timeout = null,
32420         behaviors = [
32421             behaviorCopy(context),
32422             behaviorPaste(context),
32423             behaviorBreathe(context),
32424             behaviorHover(context),
32425             behaviorSelect(context),
32426             behaviorLasso(context),
32427             modeDragNode(context).restoreSelectedIDs(selectedIDs).behavior
32428         ],
32429         inspector,
32430         editMenu,
32431         newFeature = false,
32432         suppressMenu = true,
32433         follow = false;
32434
32435
32436     var wrap = context.container()
32437         .select('.inspector-wrap');
32438
32439
32440     function singular() {
32441         if (selectedIDs.length === 1) {
32442             return context.hasEntity(selectedIDs[0]);
32443         }
32444     }
32445
32446
32447     function checkSelectedIDs() {
32448         var ids = [];
32449         if (Array.isArray(selectedIDs)) {
32450             ids = selectedIDs.filter(function(id) {
32451                 return context.hasEntity(id);
32452             });
32453         }
32454
32455         if (ids.length) {
32456             selectedIDs = ids;
32457         } else {
32458             context.enter(modeBrowse(context));
32459         }
32460         return !!ids.length;
32461     }
32462
32463
32464     // find the common parent ways for nextVertex, previousVertex
32465     function commonParents() {
32466         var graph = context.graph(),
32467             commonParents = [];
32468
32469         for (var i = 0; i < selectedIDs.length; i++) {
32470             var entity = context.hasEntity(selectedIDs[i]);
32471             if (!entity || entity.geometry(graph) !== 'vertex') {
32472                 return [];  // selection includes some not vertexes
32473             }
32474
32475             var currParents = map$4(graph.parentWays(entity), 'id');
32476             if (!commonParents.length) {
32477                 commonParents = currParents;
32478                 continue;
32479             }
32480
32481             commonParents = intersection(commonParents, currParents);
32482             if (!commonParents.length) {
32483                 return [];
32484             }
32485         }
32486
32487         return commonParents;
32488     }
32489
32490
32491     function singularParent() {
32492         var parents = commonParents();
32493         if (!parents || parents.length === 0) {
32494             relatedParent = null;
32495             return null;
32496         }
32497
32498         // relatedParent is used when we visit a vertex with multiple
32499         // parents, and we want to remember which parent line we started on.
32500
32501         if (parents.length === 1) {
32502             relatedParent = parents[0];  // remember this parent for later
32503             return relatedParent;
32504         }
32505
32506         if (parents.indexOf(relatedParent) !== -1) {
32507             return relatedParent;   // prefer the previously seen parent
32508         }
32509
32510         return parents[0];
32511     }
32512
32513
32514     function closeMenu() {
32515         if (editMenu) {
32516             context.surface().call(editMenu.close);
32517         }
32518     }
32519
32520
32521     function positionMenu() {
32522         if (!editMenu) { return; }
32523
32524         var entity = singular();
32525         if (entity && context.geometry(entity.id) === 'relation') {
32526             suppressMenu = true;
32527         } else {
32528             var point = context.mouse(),
32529                 viewport = geoExtent(context.projection.clipExtent()).polygon();
32530
32531             if (point && geoPointInPolygon(point, viewport)) {
32532                 editMenu.center(point);
32533             } else {
32534                 suppressMenu = true;
32535             }
32536         }
32537     }
32538
32539
32540     function showMenu() {
32541         closeMenu();
32542         if (editMenu) {
32543             context.surface().call(editMenu);
32544         }
32545     }
32546
32547
32548     function toggleMenu() {
32549         // deprecation warning - Radial Menu to be removed in iD v3
32550         if (d3_select('.edit-menu, .radial-menu').empty()) {
32551             positionMenu();
32552             showMenu();
32553         } else {
32554             closeMenu();
32555         }
32556     }
32557
32558
32559     mode.selectedIDs = function() {
32560         return selectedIDs;
32561     };
32562
32563
32564     mode.reselect = function() {
32565         if (!checkSelectedIDs()) return;
32566
32567         var surfaceNode = context.surface().node();
32568         if (surfaceNode.focus) {   // FF doesn't support it
32569             surfaceNode.focus();
32570         }
32571
32572         positionMenu();
32573         if (!suppressMenu) {
32574             showMenu();
32575         }
32576     };
32577
32578
32579     mode.newFeature = function(_) {
32580         if (!arguments.length) return newFeature;
32581         newFeature = _;
32582         return mode;
32583     };
32584
32585
32586     mode.suppressMenu = function(_) {
32587         if (!arguments.length) return suppressMenu;
32588         suppressMenu = _;
32589         return mode;
32590     };
32591
32592
32593     mode.follow = function(_) {
32594         if (!arguments.length) return follow;
32595         follow = _;
32596         return mode;
32597     };
32598
32599
32600     mode.enter = function() {
32601
32602         function update() {
32603             closeMenu();
32604             checkSelectedIDs();
32605         }
32606
32607
32608         function dblclick() {
32609             var target = d3_select(event.target);
32610
32611             var datum = target.datum();
32612             var entity = datum && datum.properties && datum.properties.entity;
32613             if (!entity) return;
32614
32615             if (entity instanceof osmWay && target.classed('target')) {
32616                 var choice = geoChooseEdge(context.childNodes(entity), context.mouse(), context.projection);
32617                 var prev = entity.nodes[choice.index - 1];
32618                 var next = entity.nodes[choice.index];
32619
32620                 context.perform(
32621                     actionAddMidpoint({loc: choice.loc, edge: [prev, next]}, osmNode()),
32622                     t('operations.add.annotation.vertex')
32623                 );
32624
32625                 event.preventDefault();
32626                 event.stopPropagation();
32627
32628             } else if (entity.type === 'midpoint') {
32629                 context.perform(
32630                     actionAddMidpoint({loc: entity.loc, edge: entity.edge}, osmNode()),
32631                     t('operations.add.annotation.vertex'));
32632
32633                 event.preventDefault();
32634                 event.stopPropagation();
32635             }
32636         }
32637
32638
32639         function selectElements(drawn) {
32640             if (!checkSelectedIDs()) return;
32641
32642             var surface = context.surface(),
32643                 entity = singular();
32644
32645             if (entity && context.geometry(entity.id) === 'relation') {
32646                 suppressMenu = true;
32647                 return;
32648             }
32649
32650             surface.selectAll('.related')
32651                 .classed('related', false);
32652
32653             singularParent();
32654             if (relatedParent) {
32655                 surface.selectAll(utilEntitySelector([relatedParent]))
32656                     .classed('related', true);
32657             }
32658
32659             var selection = context.surface()
32660                 .selectAll(utilEntityOrMemberSelector(selectedIDs, context.graph()));
32661
32662             if (selection.empty()) {
32663                 // Return to browse mode if selected DOM elements have
32664                 // disappeared because the user moved them out of view..
32665                 var source = event && event.type === 'zoom' && event.sourceEvent;
32666                 if (drawn && source && (source.type === 'mousemove' || source.type === 'touchmove')) {
32667                     context.enter(modeBrowse(context));
32668                 }
32669             } else {
32670                 selection
32671                     .classed('selected', true);
32672             }
32673         }
32674
32675
32676         function esc() {
32677             context.enter(modeBrowse(context));
32678         }
32679
32680
32681         function firstVertex() {
32682             event.preventDefault();
32683             var parent = singularParent();
32684             if (parent) {
32685                 var way = context.entity(parent);
32686                 context.enter(
32687                     modeSelect(context, [way.first()]).follow(true)
32688                 );
32689             }
32690         }
32691
32692
32693         function lastVertex() {
32694             event.preventDefault();
32695             var parent = singularParent();
32696             if (parent) {
32697                 var way = context.entity(parent);
32698                 context.enter(
32699                     modeSelect(context, [way.last()]).follow(true)
32700                 );
32701             }
32702         }
32703
32704
32705         function previousVertex() {
32706             event.preventDefault();
32707             var parent = singularParent();
32708             if (!parent) return;
32709
32710             var way = context.entity(parent),
32711                 length = way.nodes.length,
32712                 curr = way.nodes.indexOf(selectedIDs[0]),
32713                 index = -1;
32714
32715             if (curr > 0) {
32716                 index = curr - 1;
32717             } else if (way.isClosed()) {
32718                 index = length - 2;
32719             }
32720
32721             if (index !== -1) {
32722                 context.enter(
32723                     modeSelect(context, [way.nodes[index]]).follow(true)
32724                 );
32725             }
32726         }
32727
32728
32729         function nextVertex() {
32730             event.preventDefault();
32731             var parent = singularParent();
32732             if (!parent) return;
32733
32734             var way = context.entity(parent),
32735                 length = way.nodes.length,
32736                 curr = way.nodes.indexOf(selectedIDs[0]),
32737                 index = -1;
32738
32739             if (curr < length - 1) {
32740                 index = curr + 1;
32741             } else if (way.isClosed()) {
32742                 index = 0;
32743             }
32744
32745             if (index !== -1) {
32746                 context.enter(
32747                     modeSelect(context, [way.nodes[index]]).follow(true)
32748                 );
32749             }
32750         }
32751
32752
32753         function nextParent() {
32754             event.preventDefault();
32755             var parents = uniq(commonParents());
32756             if (!parents || parents.length < 2) return;
32757
32758             var index = parents.indexOf(relatedParent);
32759             if (index < 0 || index > parents.length - 2) {
32760                 relatedParent = parents[0];
32761             } else {
32762                 relatedParent = parents[index + 1];
32763             }
32764
32765             var surface = context.surface();
32766             surface.selectAll('.related')
32767                 .classed('related', false);
32768
32769             if (relatedParent) {
32770                 surface.selectAll(utilEntitySelector([relatedParent]))
32771                     .classed('related', true);
32772             }
32773         }
32774
32775
32776         if (!checkSelectedIDs()) return;
32777
32778         var operations = without(values$1(Operations), operationDelete)
32779                 .map(function(o) { return o(selectedIDs, context); })
32780                 .filter(function(o) { return o.available(); });
32781
32782         // deprecation warning - Radial Menu to be removed in iD v3
32783         var isRadialMenu = context.storage('edit-menu-style') === 'radial';
32784         if (isRadialMenu) {
32785             operations = operations.slice(0,7);
32786             operations.unshift(operationDelete(selectedIDs, context));
32787         } else {
32788             operations.push(operationDelete(selectedIDs, context));
32789         }
32790
32791         operations.forEach(function(operation) {
32792             if (operation.behavior) {
32793                 behaviors.push(operation.behavior);
32794             }
32795         });
32796
32797         behaviors.forEach(function(behavior) {
32798             context.install(behavior);
32799         });
32800
32801         keybinding
32802             .on(['[', 'pgup'], previousVertex)
32803             .on([']', 'pgdown'], nextVertex)
32804             .on(['{', uiCmd('⌘['), 'home'], firstVertex)
32805             .on(['}', uiCmd('⌘]'), 'end'], lastVertex)
32806             .on(['\\', 'pause'], nextParent)
32807             .on('⎋', esc, true)
32808             .on('space', toggleMenu);
32809
32810         d3_select(document)
32811             .call(keybinding);
32812
32813
32814         // deprecation warning - Radial Menu to be removed in iD v3
32815         editMenu = isRadialMenu
32816             ? uiRadialMenu(context, operations)
32817             : uiEditMenu(context, operations);
32818
32819         context.ui().sidebar
32820             .select(singular() ? singular().id : null, newFeature);
32821
32822         context.history()
32823             .on('undone.select', update)
32824             .on('redone.select', update);
32825
32826         context.map()
32827             .on('move.select', closeMenu)
32828             .on('drawn.select', selectElements);
32829
32830         context.surface()
32831             .on('dblclick.select', dblclick);
32832
32833
32834         selectElements();
32835
32836         if (selectedIDs.length > 1) {
32837             var entities = uiSelectionList(context, selectedIDs);
32838             context.ui().sidebar.show(entities);
32839         }
32840
32841         if (follow) {
32842             var extent = geoExtent(),
32843                 graph = context.graph();
32844             selectedIDs.forEach(function(id) {
32845                 var entity = context.entity(id);
32846                 extent._extend(entity.extent(graph));
32847             });
32848
32849             var loc = extent.center();
32850             context.map().centerEase(loc);
32851         } else if (singular() && singular().type === 'way') {
32852             context.map().pan([0,0]);  // full redraw, to adjust z-sorting #2914
32853         }
32854
32855         timeout = window.setTimeout(function() {
32856             positionMenu();
32857             if (!suppressMenu) {
32858                 showMenu();
32859             }
32860         }, 270);  /* after any centerEase completes */
32861
32862     };
32863
32864
32865     mode.exit = function() {
32866         if (timeout) window.clearTimeout(timeout);
32867
32868         if (inspector) wrap.call(inspector.close);
32869
32870         behaviors.forEach(function(behavior) {
32871             context.uninstall(behavior);
32872         });
32873
32874         keybinding.off();
32875         closeMenu();
32876         editMenu = undefined;
32877
32878         context.history()
32879             .on('undone.select', null)
32880             .on('redone.select', null);
32881
32882         var surface = context.surface();
32883
32884         surface
32885             .on('dblclick.select', null);
32886
32887         surface
32888             .selectAll('.selected')
32889             .classed('selected', false);
32890
32891         surface
32892             .selectAll('.related')
32893             .classed('related', false);
32894
32895         context.map().on('drawn.select', null);
32896         context.ui().sidebar.hide();
32897     };
32898
32899
32900     return mode;
32901 }
32902
32903 function behaviorAddWay(context) {
32904     var dispatch$$1 = dispatch('start', 'startFromWay', 'startFromNode'),
32905         draw = behaviorDraw(context);
32906
32907     var addWay = function(surface) {
32908         draw.on('click', function() { dispatch$$1.apply('start', this, arguments); })
32909             .on('clickWay', function() { dispatch$$1.apply('startFromWay', this, arguments); })
32910             .on('clickNode', function() { dispatch$$1.apply('startFromNode', this, arguments); })
32911             .on('cancel', addWay.cancel)
32912             .on('finish', addWay.cancel);
32913
32914         context.map()
32915             .dblclickEnable(false);
32916
32917         surface.call(draw);
32918     };
32919
32920
32921     addWay.off = function(surface) {
32922         surface.call(draw.off);
32923     };
32924
32925
32926     addWay.cancel = function() {
32927         window.setTimeout(function() {
32928             context.map().dblclickEnable(true);
32929         }, 1000);
32930
32931         context.enter(modeBrowse(context));
32932     };
32933
32934
32935     addWay.tail = function(text) {
32936         draw.tail(text);
32937         return addWay;
32938     };
32939
32940
32941     return utilRebind(addWay, dispatch$$1, 'on');
32942 }
32943
32944 function behaviorBreathe() {
32945     var duration = 800,
32946         steps = 4,
32947         selector = '.selected.shadow, .selected .shadow',
32948         selected = d3_select(null),
32949         classed = '',
32950         params = {},
32951         done = false,
32952         timer$$1;
32953
32954
32955     function ratchetyInterpolator(a, b, steps, units) {
32956         a = parseFloat(a);
32957         b = parseFloat(b);
32958         var sample = quantize()
32959             .domain([0, 1])
32960             .range(d3_quantize(d3_interpolateNumber(a, b), steps));
32961
32962         return function(t) {
32963             return String(sample(t)) + (units || '');
32964         };
32965     }
32966
32967
32968     function reset(selection) {
32969         selection
32970             .style('stroke-opacity', null)
32971             .style('stroke-width', null)
32972             .style('fill-opacity', null)
32973             .style('r', null);
32974     }
32975
32976
32977     function setAnimationParams(transition, fromTo) {
32978         var toFrom = (fromTo === 'from' ? 'to' : 'from');
32979
32980         transition
32981             .styleTween('stroke-opacity', function(d) {
32982                 return ratchetyInterpolator(
32983                     params[d.id][toFrom].opacity,
32984                     params[d.id][fromTo].opacity,
32985                     steps
32986                 );
32987             })
32988             .styleTween('stroke-width', function(d) {
32989                 return ratchetyInterpolator(
32990                     params[d.id][toFrom].width,
32991                     params[d.id][fromTo].width,
32992                     steps,
32993                     'px'
32994                 );
32995             })
32996             .styleTween('fill-opacity', function(d) {
32997                 return ratchetyInterpolator(
32998                     params[d.id][toFrom].opacity,
32999                     params[d.id][fromTo].opacity,
33000                     steps
33001                 );
33002             })
33003             .styleTween('r', function(d) {
33004                 return ratchetyInterpolator(
33005                     params[d.id][toFrom].width,
33006                     params[d.id][fromTo].width,
33007                     steps,
33008                     'px'
33009                 );
33010             });
33011     }
33012
33013
33014     function calcAnimationParams(selection) {
33015         selection
33016             .call(reset)
33017             .each(function(d) {
33018                 var s = d3_select(this),
33019                     tag = s.node().tagName,
33020                     p = {'from': {}, 'to': {}},
33021                     opacity, width;
33022
33023                 // determine base opacity and width
33024                 if (tag === 'circle') {
33025                     opacity = parseFloat(s.style('fill-opacity') || 0.5);
33026                     width = parseFloat(s.style('r') || 15.5);
33027                 } else {
33028                     opacity = parseFloat(s.style('stroke-opacity') || 0.7);
33029                     width = parseFloat(s.style('stroke-width') || 10);
33030                 }
33031
33032                 // calculate from/to interpolation params..
33033                 p.tag = tag;
33034                 p.from.opacity = opacity * 0.6;
33035                 p.to.opacity = opacity * 1.25;
33036                 p.from.width = width * 0.7;
33037                 p.to.width = width * (tag === 'circle' ? 1.5 : 1);
33038                 params[d.id] = p;
33039             });
33040     }
33041
33042
33043     function run(surface, fromTo) {
33044         var toFrom = (fromTo === 'from' ? 'to' : 'from'),
33045             currSelected = surface.selectAll(selector),
33046             currClassed = surface.attr('class');
33047
33048         if (done || currSelected.empty()) {
33049             selected.call(reset);
33050             return;
33051         }
33052
33053         if (!isEqual(currSelected.data(), selected.data()) || currClassed !== classed) {
33054             selected.call(reset);
33055             classed = currClassed;
33056             selected = currSelected.call(calcAnimationParams);
33057         }
33058
33059         selected
33060             .transition()
33061             .duration(duration)
33062             .call(setAnimationParams, fromTo)
33063             .on('end', function() {
33064                 surface.call(run, toFrom);
33065             });
33066     }
33067
33068
33069     var breathe = function(surface) {
33070         done = false;
33071         timer$$1 = timer(function() {
33072             // wait for elements to actually become selected
33073             if (surface.selectAll(selector).empty()) {
33074                 return false;
33075             }
33076
33077             surface.call(run, 'from');
33078             timer$$1.stop();
33079             return true;
33080         }, 20);
33081     };
33082
33083
33084     breathe.off = function() {
33085         done = true;
33086         if (timer$$1) {
33087             timer$$1.stop();
33088         }
33089         selected
33090             .interrupt()
33091             .call(reset);
33092     };
33093
33094
33095     return breathe;
33096 }
33097
33098 function behaviorCopy(context) {
33099     var keybinding = d3keybinding('copy');
33100
33101
33102     function groupEntities(ids, graph) {
33103         var entities = ids.map(function (id) { return graph.entity(id); });
33104         return assignIn({relation: [], way: [], node: []},
33105             groupBy(entities, function(entity) { return entity.type; }));
33106     }
33107
33108
33109     function getDescendants(id, graph, descendants) {
33110         var entity = graph.entity(id),
33111             i, children;
33112
33113         descendants = descendants || {};
33114
33115         if (entity.type === 'relation') {
33116             children = map$4(entity.members, 'id');
33117         } else if (entity.type === 'way') {
33118             children = entity.nodes;
33119         } else {
33120             children = [];
33121         }
33122
33123         for (i = 0; i < children.length; i++) {
33124             if (!descendants[children[i]]) {
33125                 descendants[children[i]] = true;
33126                 descendants = getDescendants(children[i], graph, descendants);
33127             }
33128         }
33129
33130         return descendants;
33131     }
33132
33133
33134     function doCopy() {
33135         if (!getSelectionText()) event.preventDefault();
33136
33137         var graph = context.graph(),
33138             selected = groupEntities(context.selectedIDs(), graph),
33139             canCopy = [],
33140             skip = {},
33141             i, entity;
33142
33143         for (i = 0; i < selected.relation.length; i++) {
33144             entity = selected.relation[i];
33145             if (!skip[entity.id] && entity.isComplete(graph)) {
33146                 canCopy.push(entity.id);
33147                 skip = getDescendants(entity.id, graph, skip);
33148             }
33149         }
33150         for (i = 0; i < selected.way.length; i++) {
33151             entity = selected.way[i];
33152             if (!skip[entity.id]) {
33153                 canCopy.push(entity.id);
33154                 skip = getDescendants(entity.id, graph, skip);
33155             }
33156         }
33157         for (i = 0; i < selected.node.length; i++) {
33158             entity = selected.node[i];
33159             if (!skip[entity.id]) {
33160                 canCopy.push(entity.id);
33161             }
33162         }
33163
33164         context.copyIDs(canCopy);
33165     }
33166
33167
33168     function copy() {
33169         keybinding.on(uiCmd('⌘C'), doCopy);
33170         d3_select(document).call(keybinding);
33171         return copy;
33172     }
33173
33174     function getSelectionText() {
33175         return window.getSelection().toString();
33176     }
33177
33178     copy.off = function() {
33179         d3_select(document).call(keybinding.off);
33180     };
33181
33182
33183     return copy;
33184 }
33185
33186 /*
33187     `behaviorDrag` is like `d3_behavior.drag`, with the following differences:
33188
33189     * The `origin` function is expected to return an [x, y] tuple rather than an
33190       {x, y} object.
33191     * The events are `start`, `move`, and `end`.
33192       (https://github.com/mbostock/d3/issues/563)
33193     * The `start` event is not dispatched until the first cursor movement occurs.
33194       (https://github.com/mbostock/d3/pull/368)
33195     * The `move` event has a `point` and `delta` [x, y] tuple properties rather
33196       than `x`, `y`, `dx`, and `dy` properties.
33197     * The `end` event is not dispatched if no movement occurs.
33198     * An `off` function is available that unbinds the drag's internal event handlers.
33199  */
33200
33201 function behaviorDrag() {
33202     var dispatch$$1 = dispatch('start', 'move', 'end');
33203     var _origin = null;
33204     var _selector = '';
33205     var _event;
33206     var _target;
33207     var _surface;
33208
33209
33210     var d3_event_userSelectProperty = utilPrefixCSSProperty('UserSelect');
33211     var d3_event_userSelectSuppress = function() {
33212             var selection$$1 = selection();
33213             var select$$1 = selection$$1.style(d3_event_userSelectProperty);
33214             selection$$1.style(d3_event_userSelectProperty, 'none');
33215             return function() {
33216                 selection$$1.style(d3_event_userSelectProperty, select$$1);
33217             };
33218         };
33219
33220
33221     function d3_eventCancel() {
33222         event.stopPropagation();
33223         event.preventDefault();
33224     }
33225
33226
33227     function eventOf(thiz, argumentz) {
33228         return function(e1) {
33229             e1.target = drag;
33230             customEvent(e1, dispatch$$1.apply, dispatch$$1, [e1.type, thiz, argumentz]);
33231         };
33232     }
33233
33234
33235     function dragstart() {
33236         _target = this;
33237         _event = eventOf(_target, arguments);
33238
33239         var eventTarget = event.target;
33240         var touchId = event.touches ? event.changedTouches[0].identifier : null;
33241         var offset;
33242         var startOrigin = point();
33243         var started = false;
33244         var selectEnable = d3_event_userSelectSuppress(touchId !== null ? 'drag-' + touchId : 'drag');
33245
33246         d3_select(window)
33247             .on(touchId !== null ? 'touchmove.drag-' + touchId : 'mousemove.drag', dragmove)
33248             .on(touchId !== null ? 'touchend.drag-' + touchId : 'mouseup.drag', dragend, true);
33249
33250         if (_origin) {
33251             offset = _origin.apply(_target, arguments);
33252             offset = [offset[0] - startOrigin[0], offset[1] - startOrigin[1]];
33253         } else {
33254             offset = [0, 0];
33255         }
33256
33257         if (touchId === null) {
33258             event.stopPropagation();
33259         }
33260
33261
33262         function point() {
33263             var p = _surface || _target.parentNode;
33264             return touchId !== null ? d3_touches(p).filter(function(p) {
33265                 return p.identifier === touchId;
33266             })[0] : d3_mouse(p);
33267         }
33268
33269
33270         function dragmove() {
33271             var p = point();
33272             var dx = p[0] - startOrigin[0];
33273             var dy = p[1] - startOrigin[1];
33274
33275             if (dx === 0 && dy === 0)
33276                 return;
33277
33278             startOrigin = p;
33279             d3_eventCancel();
33280
33281             if (!started) {
33282                 started = true;
33283                 _event({ type: 'start' });
33284             } else {
33285                 _event({
33286                     type: 'move',
33287                     point: [p[0] + offset[0],  p[1] + offset[1]],
33288                     delta: [dx, dy]
33289                 });
33290             }
33291         }
33292
33293
33294         function dragend() {
33295             if (started) {
33296                 _event({ type: 'end' });
33297
33298                 d3_eventCancel();
33299                 if (event.target === eventTarget) {
33300                     d3_select(window)
33301                         .on('click.drag', click, true);
33302                 }
33303             }
33304
33305             d3_select(window)
33306                 .on(touchId !== null ? 'touchmove.drag-' + touchId : 'mousemove.drag', null)
33307                 .on(touchId !== null ? 'touchend.drag-' + touchId : 'mouseup.drag', null);
33308
33309             selectEnable();
33310         }
33311
33312
33313         function click() {
33314             d3_eventCancel();
33315             d3_select(window)
33316                 .on('click.drag', null);
33317         }
33318     }
33319
33320
33321     function drag(selection$$1) {
33322         var matchesSelector = utilPrefixDOMProperty('matchesSelector');
33323         var delegate = dragstart;
33324
33325         if (_selector) {
33326             delegate = function() {
33327                 var root = this;
33328                 var target = event.target;
33329                 for (; target && target !== root; target = target.parentNode) {
33330                     var datum = target.__data__;
33331                     var entity = datum && datum.properties && datum.properties.entity;
33332                     if (entity && target[matchesSelector](_selector)) {
33333                         return dragstart.call(target, entity);
33334                     }
33335                 }
33336             };
33337         }
33338
33339         selection$$1
33340             .on('mousedown.drag' + _selector, delegate)
33341             .on('touchstart.drag' + _selector, delegate);
33342     }
33343
33344
33345     drag.off = function(selection$$1) {
33346         selection$$1
33347             .on('mousedown.drag' + _selector, null)
33348             .on('touchstart.drag' + _selector, null);
33349     };
33350
33351
33352     drag.selector = function(_) {
33353         if (!arguments.length) return _selector;
33354         _selector = _;
33355         return drag;
33356     };
33357
33358
33359     drag.origin = function (_) {
33360         if (!arguments.length) return _origin;
33361         _origin = _;
33362         return drag;
33363     };
33364
33365
33366     drag.cancel = function() {
33367         d3_select(window)
33368             .on('mousemove.drag', null)
33369             .on('mouseup.drag', null);
33370         return drag;
33371     };
33372
33373
33374     drag.target = function() {
33375         if (!arguments.length) return _target;
33376         _target = arguments[0];
33377         _event = eventOf(_target, Array.prototype.slice.call(arguments, 1));
33378         return drag;
33379     };
33380
33381
33382     drag.surface = function() {
33383         if (!arguments.length) return _surface;
33384         _surface = arguments[0];
33385         return drag;
33386     };
33387
33388
33389     return utilRebind(drag, dispatch$$1, 'on');
33390 }
33391
33392 function behaviorDrawWay(context, wayId, index, mode, startGraph) {
33393     var origWay = context.entity(wayId);
33394     var annotation = t((origWay.isDegenerate() ?
33395         'operations.start.annotation.' :
33396         'operations.continue.annotation.') + context.geometry(wayId)
33397     );
33398     var behavior = behaviorDraw(context);
33399     var _tempEdits = 0;
33400
33401     var end = osmNode({ loc: context.map().mouseCoordinates() });
33402
33403     // Push an annotated state for undo to return back to.
33404     // We must make sure to remove this edit later.
33405     context.perform(actionNoop(), annotation);
33406     _tempEdits++;
33407
33408     // Add the drawing node to the graph.
33409     // We must make sure to remove this edit later.
33410     context.perform(_actionAddDrawNode());
33411     _tempEdits++;
33412
33413
33414
33415     function keydown() {
33416         if (event.keyCode === d3keybinding.modifierCodes.alt) {
33417             if (context.surface().classed('nope')) {
33418                 context.surface()
33419                     .classed('nope-suppressed', true);
33420             }
33421             context.surface()
33422                 .classed('nope', false)
33423                 .classed('nope-disabled', true);
33424         }
33425     }
33426
33427
33428     function keyup() {
33429         if (event.keyCode === d3keybinding.modifierCodes.alt) {
33430             if (context.surface().classed('nope-suppressed')) {
33431                 context.surface()
33432                     .classed('nope', true);
33433             }
33434             context.surface()
33435                 .classed('nope-suppressed', false)
33436                 .classed('nope-disabled', false);
33437         }
33438     }
33439
33440
33441     // related code
33442     // - `mode/drag_node.js`     `doMode()`
33443     // - `behavior/draw.js`      `click()`
33444     // - `behavior/draw_way.js`  `move()`
33445     function move(datum) {
33446         context.surface().classed('nope-disabled', event.altKey);
33447
33448         var targetLoc = datum && datum.properties && datum.properties.entity && datum.properties.entity.loc;
33449         var targetNodes = datum && datum.properties && datum.properties.nodes;
33450         var loc = context.map().mouseCoordinates();
33451
33452         if (targetLoc) {   // snap to node/vertex - a point target with `.loc`
33453             loc = targetLoc;
33454
33455         } else if (targetNodes) {   // snap to way - a line target with `.nodes`
33456             var choice = geoChooseEdge(targetNodes, context.mouse(), context.projection, end.id);
33457             if (choice) {
33458                 loc = choice.loc;
33459             }
33460         }
33461
33462         context.replace(actionMoveNode(end.id, loc));
33463         end = context.entity(end.id);
33464         checkGeometry(origWay.isClosed());    // skipLast = true when drawing areas
33465     }
33466
33467
33468     // Check whether this edit causes the geometry to break.
33469     // If so, class the surface with a nope cursor.
33470     // `skipLast` - include closing segment in the check, see #4655
33471     function checkGeometry(skipLast) {
33472         var nopeDisabled = context.surface().classed('nope-disabled');
33473         var isInvalid = isInvalidGeometry(end, context.graph(), skipLast);
33474
33475         if (nopeDisabled) {
33476             context.surface()
33477                 .classed('nope', false)
33478                 .classed('nope-suppressed', isInvalid);
33479         } else {
33480             context.surface()
33481                 .classed('nope', isInvalid)
33482                 .classed('nope-suppressed', false);
33483         }
33484     }
33485
33486
33487     function isInvalidGeometry(entity, graph, skipLast) {
33488         var parents = graph.parentWays(entity);
33489
33490         for (var i = 0; i < parents.length; i++) {
33491             var parent = parents[i];
33492             var nodes = parent.nodes.map(function(nodeID) { return graph.entity(nodeID); });
33493             if (skipLast)  nodes.pop();   // disregard closing segment - #4655
33494             if (geoHasSelfIntersections(nodes, entity.id)) {
33495                 return true;
33496             }
33497         }
33498
33499         return false;
33500     }
33501
33502
33503     function undone() {
33504         // Undo popped the history back to the initial annotated no-op edit.
33505         // Remove initial no-op edit and whatever edit happened immediately before it.
33506         context.pop(2);
33507         _tempEdits = 0;
33508
33509         if (context.hasEntity(wayId)) {
33510             context.enter(mode);
33511         } else {
33512             context.enter(modeBrowse(context));
33513         }
33514     }
33515
33516
33517     function setActiveElements() {
33518         context.surface().selectAll('.' + end.id)
33519             .classed('active', true);
33520     }
33521
33522
33523     var drawWay = function(surface) {
33524         behavior
33525             .on('move', move)
33526             .on('click', drawWay.add)
33527             .on('clickWay', drawWay.addWay)
33528             .on('clickNode', drawWay.addNode)
33529             .on('undo', context.undo)
33530             .on('cancel', drawWay.cancel)
33531             .on('finish', drawWay.finish);
33532
33533         d3_select(window)
33534             .on('keydown.drawWay', keydown)
33535             .on('keyup.drawWay', keyup);
33536
33537         context.map()
33538             .dblclickEnable(false)
33539             .on('drawn.draw', setActiveElements);
33540
33541         setActiveElements();
33542
33543         surface.call(behavior);
33544
33545         context.history()
33546             .on('undone.draw', undone);
33547     };
33548
33549
33550     drawWay.off = function(surface) {
33551         // Drawing was interrupted unexpectedly.
33552         // This can happen if the user changes modes,
33553         // clicks geolocate button, a hashchange event occurs, etc.
33554         if (_tempEdits) {
33555             context.pop(_tempEdits);
33556             while (context.graph() !== startGraph) {
33557                 context.pop();
33558             }
33559         }
33560
33561         context.map()
33562             .on('drawn.draw', null);
33563
33564         surface.call(behavior.off)
33565             .selectAll('.active')
33566             .classed('active', false);
33567
33568         surface
33569             .classed('nope', false)
33570             .classed('nope-suppressed', false)
33571             .classed('nope-disabled', false);
33572
33573         d3_select(window)
33574             .on('keydown.hover', null)
33575             .on('keyup.hover', null);
33576
33577         context.history()
33578             .on('undone.draw', null);
33579     };
33580
33581
33582     function _actionAddDrawNode() {
33583         return function(graph) {
33584             return graph
33585                 .replace(end)
33586                 .replace(origWay.addNode(end.id, index));
33587         };
33588     }
33589
33590
33591     function _actionReplaceDrawNode(newNode) {
33592         return function(graph) {
33593             return graph
33594                 .replace(origWay.addNode(newNode.id, index))
33595                 .remove(end);
33596         };
33597     }
33598
33599
33600     // Accept the current position of the drawing node and continue drawing.
33601     drawWay.add = function(loc, d) {
33602         if ((d && d.properties && d.properties.nope) || context.surface().classed('nope')) {
33603             return;   // can't click here
33604         }
33605
33606         context.pop(_tempEdits);
33607         _tempEdits = 0;
33608
33609         context.perform(
33610             _actionAddDrawNode(),
33611             annotation
33612         );
33613
33614         checkGeometry(false);   // skipLast = false
33615         context.enter(mode);
33616     };
33617
33618
33619     // Connect the way to an existing way.
33620     drawWay.addWay = function(loc, edge, d) {
33621         if ((d && d.properties && d.properties.nope) || context.surface().classed('nope')) {
33622             return;   // can't click here
33623         }
33624
33625         context.pop(_tempEdits);
33626         _tempEdits = 0;
33627
33628         context.perform(
33629             _actionAddDrawNode(),
33630             actionAddMidpoint({ loc: loc, edge: edge }, end),
33631             annotation
33632         );
33633
33634         checkGeometry(false);   // skipLast = false
33635         context.enter(mode);
33636     };
33637
33638
33639     // Connect the way to an existing node and continue drawing.
33640     drawWay.addNode = function(node, d) {
33641         if ((d && d.properties && d.properties.nope) || context.surface().classed('nope')) {
33642             return;   // can't click here
33643         }
33644
33645         context.pop(_tempEdits);
33646         _tempEdits = 0;
33647
33648         context.perform(
33649             _actionReplaceDrawNode(node),
33650             annotation
33651         );
33652
33653         checkGeometry(false);   // skipLast = false
33654         context.enter(mode);
33655     };
33656
33657
33658     // Finish the draw operation, removing the temporary edits.
33659     // If the way has enough nodes to be valid, it's selected.
33660     // Otherwise, delete everything and return to browse mode.
33661     drawWay.finish = function() {
33662         checkGeometry(true);   // skipLast = true
33663         if (context.surface().classed('nope')) {
33664             return;   // can't click here
33665         }
33666
33667         context.pop(_tempEdits);
33668         _tempEdits = 0;
33669
33670         var way = context.hasEntity(wayId);
33671         if (!way || way.isDegenerate()) {
33672             drawWay.cancel();
33673             return;
33674         }
33675
33676         window.setTimeout(function() {
33677             context.map().dblclickEnable(true);
33678         }, 1000);
33679
33680         context.enter(modeSelect(context, [wayId]).newFeature(true));
33681     };
33682
33683
33684     // Cancel the draw operation, delete everything, and return to browse mode.
33685     drawWay.cancel = function() {
33686         context.pop(_tempEdits);
33687         _tempEdits = 0;
33688
33689         while (context.graph() !== startGraph) {
33690             context.pop();
33691         }
33692
33693         window.setTimeout(function() {
33694             context.map().dblclickEnable(true);
33695         }, 1000);
33696
33697         context.surface()
33698             .classed('nope', false)
33699             .classed('nope-disabled', false)
33700             .classed('nope-suppressed', false);
33701
33702         context.enter(modeBrowse(context));
33703     };
33704
33705
33706     drawWay.activeID = function() {
33707         if (!arguments.length) return end.id;
33708         // no assign
33709         return drawWay;
33710     };
33711
33712
33713     drawWay.tail = function(text) {
33714         behavior.tail(text);
33715         return drawWay;
33716     };
33717
33718
33719     return drawWay;
33720 }
33721
33722 /** Error message constants. */
33723 var FUNC_ERROR_TEXT$3 = 'Expected a function';
33724
33725 /**
33726  * Creates a throttled function that only invokes `func` at most once per
33727  * every `wait` milliseconds. The throttled function comes with a `cancel`
33728  * method to cancel delayed `func` invocations and a `flush` method to
33729  * immediately invoke them. Provide `options` to indicate whether `func`
33730  * should be invoked on the leading and/or trailing edge of the `wait`
33731  * timeout. The `func` is invoked with the last arguments provided to the
33732  * throttled function. Subsequent calls to the throttled function return the
33733  * result of the last `func` invocation.
33734  *
33735  * **Note:** If `leading` and `trailing` options are `true`, `func` is
33736  * invoked on the trailing edge of the timeout only if the throttled function
33737  * is invoked more than once during the `wait` timeout.
33738  *
33739  * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
33740  * until to the next tick, similar to `setTimeout` with a timeout of `0`.
33741  *
33742  * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
33743  * for details over the differences between `_.throttle` and `_.debounce`.
33744  *
33745  * @static
33746  * @memberOf _
33747  * @since 0.1.0
33748  * @category Function
33749  * @param {Function} func The function to throttle.
33750  * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
33751  * @param {Object} [options={}] The options object.
33752  * @param {boolean} [options.leading=true]
33753  *  Specify invoking on the leading edge of the timeout.
33754  * @param {boolean} [options.trailing=true]
33755  *  Specify invoking on the trailing edge of the timeout.
33756  * @returns {Function} Returns the new throttled function.
33757  * @example
33758  *
33759  * // Avoid excessively updating the position while scrolling.
33760  * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
33761  *
33762  * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
33763  * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
33764  * jQuery(element).on('click', throttled);
33765  *
33766  * // Cancel the trailing throttled invocation.
33767  * jQuery(window).on('popstate', throttled.cancel);
33768  */
33769 function throttle(func, wait, options) {
33770   var leading = true,
33771       trailing = true;
33772
33773   if (typeof func != 'function') {
33774     throw new TypeError(FUNC_ERROR_TEXT$3);
33775   }
33776   if (isObject(options)) {
33777     leading = 'leading' in options ? !!options.leading : leading;
33778     trailing = 'trailing' in options ? !!options.trailing : trailing;
33779   }
33780   return debounce(func, wait, {
33781     'leading': leading,
33782     'maxWait': wait,
33783     'trailing': trailing
33784   });
33785 }
33786
33787 function behaviorHash(context) {
33788     var s0 = null, // cached window.location.hash
33789         lat = 90 - 1e-8; // allowable latitude range
33790
33791
33792     var parser = function(map, s) {
33793         var q = utilStringQs(s);
33794         var args = (q.map || '').split('/').map(Number);
33795
33796         if (args.length < 3 || args.some(isNaN)) {
33797             return true; // replace bogus hash
33798
33799         } else if (s !== formatter(map).slice(1)) {   // hash has changed
33800             var mode = context.mode(),
33801                 dist = geoSphericalDistance(map.center(), [args[2], args[1]]),
33802                 maxdist = 500;
33803
33804             // Don't allow the hash location to change too much while drawing
33805             // This can happen if the user accidently hit the back button.  #3996
33806             if (mode && mode.id.match(/^draw/) !== null && dist > maxdist) {
33807                 context.enter(modeBrowse(context));
33808             }
33809
33810             map.centerZoom([args[2], Math.min(lat, Math.max(-lat, args[1]))], args[0]);
33811         }
33812     };
33813
33814
33815     var formatter = function(map) {
33816         var center = map.center(),
33817             zoom = map.zoom(),
33818             precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2)),
33819             q = omit(utilStringQs(window.location.hash.substring(1)),
33820                 ['comment', 'hashtags', 'walkthrough']
33821             ),
33822             newParams = {};
33823
33824         delete q.id;
33825         var selected = context.selectedIDs().filter(function(id) {
33826             return !context.entity(id).isNew();
33827         });
33828         if (selected.length) {
33829             newParams.id = selected.join(',');
33830         }
33831
33832         newParams.map = zoom.toFixed(2) +
33833             '/' + center[1].toFixed(precision) +
33834             '/' + center[0].toFixed(precision);
33835
33836         return '#' + utilQsString(assign(q, newParams), true);
33837     };
33838
33839
33840     function update() {
33841         if (context.inIntro()) return;
33842         var s1 = formatter(context.map());
33843         if (s0 !== s1) {
33844             window.location.replace(s0 = s1);  // don't recenter the map!
33845         }
33846     }
33847
33848
33849     var throttledUpdate = throttle(update, 500);
33850
33851
33852     function hashchange() {
33853         if (window.location.hash === s0) return;  // ignore spurious hashchange events
33854         if (parser(context.map(), (s0 = window.location.hash).substring(1))) {
33855             update(); // replace bogus hash
33856         }
33857     }
33858
33859
33860     function hash() {
33861         context.map()
33862             .on('move.hash', throttledUpdate);
33863
33864         context
33865             .on('enter.hash', throttledUpdate);
33866
33867         d3_select(window)
33868             .on('hashchange.hash', hashchange);
33869
33870         if (window.location.hash) {
33871
33872             var q = utilStringQs(window.location.hash.substring(1));
33873
33874             if (q.id) {
33875                 context.zoomToEntity(q.id.split(',')[0], !q.map);
33876             }
33877
33878             if (q.comment) {
33879                 context.storage('comment', q.comment);
33880                 context.storage('commentDate', Date.now());
33881             }
33882
33883             if (q.hashtags) {
33884                 context.storage('hashtags', q.hashtags);
33885             }
33886
33887             if (q.walkthrough === 'true') {
33888                 hash.startWalkthrough = true;
33889             }
33890
33891             hashchange();
33892
33893             if (q.map) {
33894                 hash.hadHash = true;
33895             }
33896         }
33897     }
33898
33899
33900     hash.off = function() {
33901         throttledUpdate.cancel();
33902
33903         context.map()
33904             .on('move.hash', null);
33905
33906         context
33907             .on('enter.hash', null);
33908
33909         d3_select(window)
33910             .on('hashchange.hash', null);
33911
33912         window.location.hash = '';
33913     };
33914
33915
33916     return hash;
33917 }
33918
33919 function behaviorLasso(context) {
33920
33921     var behavior = function(selection) {
33922         var lasso;
33923
33924
33925         function mousedown() {
33926             var button = 0;  // left
33927             if (event.button === button && event.shiftKey === true) {
33928                 lasso = null;
33929
33930                 d3_select(window)
33931                     .on('mousemove.lasso', mousemove)
33932                     .on('mouseup.lasso', mouseup);
33933
33934                 event.stopPropagation();
33935             }
33936         }
33937
33938
33939         function mousemove() {
33940             if (!lasso) {
33941                 lasso = uiLasso(context);
33942                 context.surface().call(lasso);
33943             }
33944
33945             lasso.p(context.mouse());
33946         }
33947
33948
33949         function normalize(a, b) {
33950             return [
33951                 [Math.min(a[0], b[0]), Math.min(a[1], b[1])],
33952                 [Math.max(a[0], b[0]), Math.max(a[1], b[1])]];
33953         }
33954
33955
33956         function lassoed() {
33957             if (!lasso) return [];
33958
33959             var graph = context.graph(),
33960                 bounds = lasso.extent().map(context.projection.invert),
33961                 extent = geoExtent(normalize(bounds[0], bounds[1]));
33962
33963             return map$4(context.intersects(extent).filter(function(entity) {
33964                 return entity.type === 'node' &&
33965                     geoPointInPolygon(context.projection(entity.loc), lasso.coordinates) &&
33966                     !context.features().isHidden(entity, graph, entity.geometry(graph));
33967             }), 'id');
33968         }
33969
33970
33971         function mouseup() {
33972             d3_select(window)
33973                 .on('mousemove.lasso', null)
33974                 .on('mouseup.lasso', null);
33975
33976             if (!lasso) return;
33977
33978             var ids = lassoed();
33979             lasso.close();
33980
33981             if (ids.length) {
33982                 context.enter(modeSelect(context, ids));
33983             }
33984         }
33985
33986         selection
33987             .on('mousedown.lasso', mousedown);
33988     };
33989
33990
33991     behavior.off = function(selection) {
33992         selection.on('mousedown.lasso', null);
33993     };
33994
33995
33996     return behavior;
33997 }
33998
33999 /* Creates a keybinding behavior for an operation */
34000 function behaviorOperation() {
34001     var _operation, keybinding;
34002
34003     var behavior = function () {
34004         if (_operation && _operation.available()) {
34005             keybinding = d3keybinding('behavior.key.' + _operation.id);
34006             keybinding.on(_operation.keys, function() {
34007                 event.preventDefault();
34008                 var disabled = _operation.disabled();
34009                 var flash;
34010
34011                 if (disabled) {
34012                     flash = uiFlash()
34013                         .duration(4000)
34014                         .iconName('#operation-' + _operation.id)
34015                         .iconClass('operation disabled')
34016                         .text(_operation.tooltip);
34017
34018                     flash();
34019
34020                 } else {
34021                     flash = uiFlash()
34022                         .duration(2000)
34023                         .iconName('#operation-' + _operation.id)
34024                         .iconClass('operation')
34025                         .text(_operation.annotation() || _operation.title);
34026
34027                     flash();
34028                     _operation();
34029                 }
34030             });
34031
34032             d3_select(document).call(keybinding);
34033         }
34034
34035         return behavior;
34036     };
34037
34038
34039     behavior.off = function() {
34040         if (keybinding) {
34041             d3_select(document).call(keybinding.off);
34042         }
34043     };
34044
34045
34046     behavior.which = function (_) {
34047         if (!arguments.length) return _operation;
34048         _operation = _;
34049         return behavior;
34050     };
34051
34052
34053     return behavior;
34054 }
34055
34056 /**
34057  * The base implementation of `_.invert` and `_.invertBy` which inverts
34058  * `object` with values transformed by `iteratee` and set by `setter`.
34059  *
34060  * @private
34061  * @param {Object} object The object to iterate over.
34062  * @param {Function} setter The function to set `accumulator` values.
34063  * @param {Function} iteratee The iteratee to transform values.
34064  * @param {Object} accumulator The initial inverted object.
34065  * @returns {Function} Returns `accumulator`.
34066  */
34067 function baseInverter(object, setter, iteratee, accumulator) {
34068   baseForOwn(object, function(value, key, object) {
34069     setter(accumulator, iteratee(value), key, object);
34070   });
34071   return accumulator;
34072 }
34073
34074 /**
34075  * Creates a function like `_.invertBy`.
34076  *
34077  * @private
34078  * @param {Function} setter The function to set accumulator values.
34079  * @param {Function} toIteratee The function to resolve iteratees.
34080  * @returns {Function} Returns the new inverter function.
34081  */
34082 function createInverter(setter, toIteratee) {
34083   return function(object, iteratee) {
34084     return baseInverter(object, setter, toIteratee(iteratee), {});
34085   };
34086 }
34087
34088 /**
34089  * Creates an object composed of the inverted keys and values of `object`.
34090  * If `object` contains duplicate values, subsequent values overwrite
34091  * property assignments of previous values.
34092  *
34093  * @static
34094  * @memberOf _
34095  * @since 0.7.0
34096  * @category Object
34097  * @param {Object} object The object to invert.
34098  * @returns {Object} Returns the new inverted object.
34099  * @example
34100  *
34101  * var object = { 'a': 1, 'b': 2, 'c': 1 };
34102  *
34103  * _.invert(object);
34104  * // => { '1': 'c', '2': 'b' }
34105  */
34106 var invert = createInverter(function(result, value, key) {
34107   result[value] = key;
34108 }, constant$13(identity$8));
34109
34110 /**
34111  * Creates an object with the same keys as `object` and values generated
34112  * by running each own enumerable string keyed property of `object` thru
34113  * `iteratee`. The iteratee is invoked with three arguments:
34114  * (value, key, object).
34115  *
34116  * @static
34117  * @memberOf _
34118  * @since 2.4.0
34119  * @category Object
34120  * @param {Object} object The object to iterate over.
34121  * @param {Function} [iteratee=_.identity] The function invoked per iteration.
34122  * @returns {Object} Returns the new mapped object.
34123  * @see _.mapKeys
34124  * @example
34125  *
34126  * var users = {
34127  *   'fred':    { 'user': 'fred',    'age': 40 },
34128  *   'pebbles': { 'user': 'pebbles', 'age': 1 }
34129  * };
34130  *
34131  * _.mapValues(users, function(o) { return o.age; });
34132  * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
34133  *
34134  * // The `_.property` iteratee shorthand.
34135  * _.mapValues(users, 'age');
34136  * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
34137  */
34138 function mapValues(object, iteratee) {
34139   var result = {};
34140   iteratee = baseIteratee(iteratee, 3);
34141
34142   baseForOwn(object, function(value, key, object) {
34143     baseAssignValue(result, key, iteratee(value, key, object));
34144   });
34145   return result;
34146 }
34147
34148 function behaviorPaste(context) {
34149     var keybinding = d3keybinding('paste');
34150
34151
34152     function doPaste() {
34153         event.preventDefault();
34154
34155         var baseGraph = context.graph(),
34156             mouse = context.mouse(),
34157             projection = context.projection,
34158             viewport = geoExtent(projection.clipExtent()).polygon();
34159
34160         if (!geoPointInPolygon(mouse, viewport)) return;
34161
34162         var extent = geoExtent(),
34163             oldIDs = context.copyIDs(),
34164             oldGraph = context.copyGraph(),
34165             newIDs = [];
34166
34167         if (!oldIDs.length) return;
34168
34169         var action = actionCopyEntities(oldIDs, oldGraph);
34170         context.perform(action);
34171
34172         var copies = action.copies();
34173         var originals = invert(mapValues(copies, 'id'));
34174         for (var id in copies) {
34175             var oldEntity = oldGraph.entity(id),
34176                 newEntity = copies[id];
34177
34178             extent._extend(oldEntity.extent(oldGraph));
34179
34180             // Exclude child nodes from newIDs if their parent way was also copied.
34181             var parents = context.graph().parentWays(newEntity),
34182                 parentCopied = false;
34183             for (var i = 0; i < parents.length; i++) {
34184                 if (originals[parents[i].id]) {
34185                     parentCopied = true;
34186                     break;
34187                 }
34188             }
34189
34190             if (!parentCopied) {
34191                 newIDs.push(newEntity.id);
34192             }
34193         }
34194
34195         // Put pasted objects where mouse pointer is..
34196         var center = projection(extent.center()),
34197             delta = [ mouse[0] - center[0], mouse[1] - center[1] ];
34198
34199         context.perform(actionMove(newIDs, delta, projection));
34200         context.enter(modeMove(context, newIDs, baseGraph));
34201     }
34202
34203
34204     function paste() {
34205         keybinding.on(uiCmd('⌘V'), doPaste);
34206         d3_select(document).call(keybinding);
34207         return paste;
34208     }
34209
34210
34211     paste.off = function() {
34212         d3_select(document).call(keybinding.off);
34213     };
34214
34215
34216     return paste;
34217 }
34218
34219 function behaviorSelect(context) {
34220     var lastMouse = null;
34221     var suppressMenu = true;
34222     var tolerance = 4;
34223     var p1 = null;
34224
34225
34226     function point() {
34227         return d3_mouse(context.container().node());
34228     }
34229
34230
34231     function keydown() {
34232         var e = event;
34233         if (e && e.shiftKey) {
34234             context.surface()
34235                 .classed('behavior-multiselect', true);
34236         }
34237
34238         if (e && e.keyCode === 93) {  // context menu
34239             e.preventDefault();
34240             e.stopPropagation();
34241         }
34242     }
34243
34244
34245     function keyup() {
34246         var e = event;
34247         if (!e || !e.shiftKey) {
34248             context.surface()
34249                 .classed('behavior-multiselect', false);
34250         }
34251
34252
34253         if (e && e.keyCode === 93) {  // context menu
34254             e.preventDefault();
34255             e.stopPropagation();
34256             contextmenu();
34257         }
34258     }
34259
34260
34261     function mousedown() {
34262         if (!p1) p1 = point();
34263         d3_select(window)
34264             .on('mouseup.select', mouseup, true);
34265
34266         var isShowAlways = +context.storage('edit-menu-show-always') === 1;
34267         suppressMenu = !isShowAlways;
34268     }
34269
34270
34271     function mousemove() {
34272         if (event) lastMouse = event;
34273     }
34274
34275
34276     function mouseup() {
34277         click();
34278     }
34279
34280
34281     function contextmenu() {
34282         var e = event;
34283         e.preventDefault();
34284         e.stopPropagation();
34285
34286         if (!+e.clientX && !+e.clientY) {
34287             if (lastMouse) {
34288                 e.sourceEvent = lastMouse;
34289             } else {
34290                 return;
34291             }
34292         }
34293
34294         if (!p1) p1 = point();
34295         suppressMenu = false;
34296         click();
34297     }
34298
34299
34300     function click() {
34301         d3_select(window)
34302             .on('mouseup.select', null, true);
34303
34304         if (!p1) return;
34305         var p2 = point();
34306         var dist = geoVecLength(p1, p2);
34307
34308         p1 = null;
34309         if (dist > tolerance) {
34310             return;
34311         }
34312
34313         var isMultiselect = event.shiftKey || d3_select('#surface .lasso').node();
34314         var isShowAlways = +context.storage('edit-menu-show-always') === 1;
34315         var datum = event.target.__data__ || (lastMouse && lastMouse.target.__data__);
34316         var mode = context.mode();
34317
34318         var entity = datum && datum.properties && datum.properties.entity;
34319         if (entity) datum = entity;
34320
34321         if (datum && datum.type === 'midpoint') {
34322             datum = datum.parents[0];
34323         }
34324
34325         if (!(datum instanceof osmEntity)) {
34326             // clicked nothing..
34327             if (!isMultiselect && mode.id !== 'browse') {
34328                 context.enter(modeBrowse(context));
34329             }
34330
34331         } else {
34332             // clicked an entity..
34333             var selectedIDs = context.selectedIDs();
34334
34335             if (!isMultiselect) {
34336                 if (selectedIDs.length > 1 && (!suppressMenu && !isShowAlways)) {
34337                     // multiple things already selected, just show the menu...
34338                     mode.suppressMenu(false).reselect();
34339                 } else {
34340                     // select a single thing..
34341                     context.enter(modeSelect(context, [datum.id]).suppressMenu(suppressMenu));
34342                 }
34343
34344             } else {
34345                 if (selectedIDs.indexOf(datum.id) !== -1) {
34346                     // clicked entity is already in the selectedIDs list..
34347                     if (!suppressMenu && !isShowAlways) {
34348                         // don't deselect clicked entity, just show the menu.
34349                         mode.suppressMenu(false).reselect();
34350                     } else {
34351                         // deselect clicked entity, then reenter select mode or return to browse mode..
34352                         selectedIDs = without(selectedIDs, datum.id);
34353                         context.enter(selectedIDs.length ? modeSelect(context, selectedIDs) : modeBrowse(context));
34354                     }
34355                 } else {
34356                     // clicked entity is not in the selected list, add it..
34357                     selectedIDs = selectedIDs.concat([datum.id]);
34358                     context.enter(modeSelect(context, selectedIDs).suppressMenu(suppressMenu));
34359                 }
34360             }
34361         }
34362
34363         // reset for next time..
34364         suppressMenu = true;
34365     }
34366
34367
34368     var behavior = function(selection) {
34369         lastMouse = null;
34370         suppressMenu = true;
34371         p1 = null;
34372
34373         d3_select(window)
34374             .on('keydown.select', keydown)
34375             .on('keyup.select', keyup)
34376             .on('contextmenu.select-window', function() {
34377                 // Edge and IE really like to show the contextmenu on the
34378                 // menubar when user presses a keyboard menu button
34379                 // even after we've already preventdefaulted the key event.
34380                 var e = event;
34381                 if (+e.clientX === 0 && +e.clientY === 0) {
34382                     event.preventDefault();
34383                     event.stopPropagation();
34384                 }
34385             });
34386
34387         selection
34388             .on('mousedown.select', mousedown)
34389             .on('mousemove.select', mousemove)
34390             .on('contextmenu.select', contextmenu);
34391
34392         if (event && event.shiftKey) {
34393             context.surface()
34394                 .classed('behavior-multiselect', true);
34395         }
34396     };
34397
34398
34399     behavior.off = function(selection) {
34400         d3_select(window)
34401             .on('keydown.select', null)
34402             .on('keyup.select', null)
34403             .on('contextmenu.select-window', null)
34404             .on('mouseup.select', null, true);
34405
34406         selection
34407             .on('mousedown.select', null)
34408             .on('mousemove.select', null)
34409             .on('contextmenu.select', null);
34410
34411         context.surface()
34412             .classed('behavior-multiselect', false);
34413     };
34414
34415
34416     return behavior;
34417 }
34418
34419 function d3geoTile() {
34420   var size = [960, 500],
34421       scale = 256,
34422       scaleExtent = [0, 20],
34423       translate = [size[0] / 2, size[1] / 2],
34424       zoomDelta = 0;
34425
34426   function bound(_) {
34427       return Math.min(scaleExtent[1], Math.max(scaleExtent[0], _));
34428   }
34429
34430   function tile() {
34431     var z = Math.max(Math.log(scale) / Math.LN2 - 8, 0),
34432         z0 = bound(Math.round(z + zoomDelta)),
34433         k = Math.pow(2, z - z0 + 8),
34434         origin = [(translate[0] - scale / 2) / k, (translate[1] - scale / 2) / k],
34435         tiles = [],
34436         cols = d3_range(Math.max(0, Math.floor(-origin[0])), Math.max(0, Math.ceil(size[0] / k - origin[0]))),
34437         rows = d3_range(Math.max(0, Math.floor(-origin[1])), Math.max(0, Math.ceil(size[1] / k - origin[1])));
34438
34439     rows.forEach(function(y) {
34440       cols.forEach(function(x) {
34441         tiles.push([x, y, z0]);
34442       });
34443     });
34444
34445     tiles.translate = origin;
34446     tiles.scale = k;
34447
34448     return tiles;
34449   }
34450
34451   tile.scaleExtent = function(_) {
34452     if (!arguments.length) return scaleExtent;
34453     scaleExtent = _;
34454     return tile;
34455   };
34456
34457   tile.size = function(_) {
34458     if (!arguments.length) return size;
34459     size = _;
34460     return tile;
34461   };
34462
34463   tile.scale = function(_) {
34464     if (!arguments.length) return scale;
34465     scale = _;
34466     return tile;
34467   };
34468
34469   tile.translate = function(_) {
34470     if (!arguments.length) return translate;
34471     translate = _;
34472     return tile;
34473   };
34474
34475   tile.zoomDelta = function(_) {
34476     if (!arguments.length) return zoomDelta;
34477     zoomDelta = +_;
34478     return tile;
34479   };
34480
34481   return tile;
34482 }
34483
34484 /* global Mapillary:false */
34485 var apibase = 'https://a.mapillary.com/v3/';
34486 var viewercss = 'mapillary-js/mapillary.min.css';
34487 var viewerjs = 'mapillary-js/mapillary.min.js';
34488 var clientId = 'NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1ZWYyMmYwNjdmNDdlNmVi';
34489 var maxResults = 1000;
34490 var tileZoom = 14;
34491 var dispatch$1 = dispatch('loadedImages', 'loadedSigns');
34492 var _mlyCache;
34493 var _mlyClicks;
34494 var _mlySelectedImage;
34495 var _mlySignDefs;
34496 var _mlySignSprite;
34497 var _mlyViewer;
34498
34499
34500 function abortRequest(i) {
34501     i.abort();
34502 }
34503
34504
34505 function nearNullIsland(x, y, z) {
34506     if (z >= 7) {
34507         var center = Math.pow(2, z - 1),
34508             width = Math.pow(2, z - 6),
34509             min = center - (width / 2),
34510             max = center + (width / 2) - 1;
34511         return x >= min && x <= max && y >= min && y <= max;
34512     }
34513     return false;
34514 }
34515
34516
34517 function maxPageAtZoom(z) {
34518     if (z < 15)   return 2;
34519     if (z === 15) return 5;
34520     if (z === 16) return 10;
34521     if (z === 17) return 20;
34522     if (z === 18) return 40;
34523     if (z > 18)   return 80;
34524 }
34525
34526
34527 function localeTimestamp(s) {
34528     if (!s) return null;
34529     var detected = utilDetect();
34530     var options = {
34531         day: 'numeric', month: 'short', year: 'numeric',
34532         hour: 'numeric', minute: 'numeric', second: 'numeric',
34533         timeZone: 'UTC'
34534     };
34535     var d = new Date(s);
34536     if (isNaN(d.getTime())) return null;
34537     return d.toLocaleString(detected.locale, options);
34538 }
34539
34540
34541 function getTiles(projection) {
34542     var s = projection.scale() * 2 * Math.PI,
34543         z = Math.max(Math.log(s) / Math.log(2) - 8, 0),
34544         ts = 256 * Math.pow(2, z - tileZoom),
34545         origin = [
34546             s / 2 - projection.translate()[0],
34547             s / 2 - projection.translate()[1]];
34548
34549     return d3geoTile()
34550         .scaleExtent([tileZoom, tileZoom])
34551         .scale(s)
34552         .size(projection.clipExtent()[1])
34553         .translate(projection.translate())()
34554         .map(function(tile) {
34555             var x = tile[0] * ts - origin[0],
34556                 y = tile[1] * ts - origin[1];
34557
34558             return {
34559                 id: tile.toString(),
34560                 xyz: tile,
34561                 extent: geoExtent(
34562                     projection.invert([x, y + ts]),
34563                     projection.invert([x + ts, y])
34564                 )
34565             };
34566         });
34567 }
34568
34569
34570 function loadTiles(which, url, projection) {
34571     var s = projection.scale() * 2 * Math.PI,
34572         currZoom = Math.floor(Math.max(Math.log(s) / Math.log(2) - 8, 0));
34573
34574     var tiles = getTiles(projection).filter(function(t) {
34575             return !nearNullIsland(t.xyz[0], t.xyz[1], t.xyz[2]);
34576         });
34577
34578     filter(which.inflight, function(v, k) {
34579         var wanted = find$1(tiles, function(tile) { return k === (tile.id + ',0'); });
34580         if (!wanted) delete which.inflight[k];
34581         return !wanted;
34582     }).map(abortRequest);
34583
34584     tiles.forEach(function(tile) {
34585         loadNextTilePage(which, currZoom, url, tile);
34586     });
34587 }
34588
34589
34590 function loadNextTilePage(which, currZoom, url, tile) {
34591     var cache = _mlyCache[which],
34592         rect = tile.extent.rectangle(),
34593         maxPages = maxPageAtZoom(currZoom),
34594         nextPage = cache.nextPage[tile.id] || 0,
34595         nextURL = cache.nextURL[tile.id] || url +
34596             utilQsString({
34597                 per_page: maxResults,
34598                 page: nextPage,
34599                 client_id: clientId,
34600                 bbox: [rect[0], rect[1], rect[2], rect[3]].join(','),
34601             });
34602
34603     if (nextPage > maxPages) return;
34604
34605     var id = tile.id + ',' + String(nextPage);
34606     if (cache.loaded[id] || cache.inflight[id]) return;
34607     cache.inflight[id] = d3_request(nextURL)
34608         .mimeType('application/json')
34609         .response(function(xhr) {
34610             var linkHeader = xhr.getResponseHeader('Link');
34611             if (linkHeader) {
34612                 var pagination = parsePagination(xhr.getResponseHeader('Link'));
34613                 if (pagination.next) {
34614                     cache.nextURL[tile.id] = pagination.next;
34615                 }
34616             }
34617             return JSON.parse(xhr.responseText);
34618         })
34619         .get(function(err, data) {
34620             cache.loaded[id] = true;
34621             delete cache.inflight[id];
34622             if (err || !data.features || !data.features.length) return;
34623
34624             var features = data.features.map(function(feature) {
34625                 var loc = feature.geometry.coordinates,
34626                     d;
34627
34628                 if (which === 'images') {
34629                     d = {
34630                         loc: loc,
34631                         key: feature.properties.key,
34632                         ca: feature.properties.ca,
34633                         captured_at: feature.properties.captured_at,
34634                         captured_by: feature.properties.username,
34635                         pano: feature.properties.pano
34636                     };
34637                     cache.forImageKey[d.key] = d;     // cache imageKey -> image
34638
34639                 } else if (which === 'sequences') {
34640                     var sequenceKey = feature.properties.key;
34641                     cache.lineString[sequenceKey] = feature;           // cache sequenceKey -> lineString
34642                     feature.properties.coordinateProperties.image_keys.forEach(function(imageKey) {
34643                         cache.forImageKey[imageKey] = sequenceKey;     // cache imageKey -> sequenceKey
34644                     });
34645                     return false;  // because no `d` data worth loading into an rbush
34646
34647                 } else if (which === 'objects') {
34648                     d = {
34649                         loc: loc,
34650                         key: feature.properties.key,
34651                         value: feature.properties.value,
34652                         package: feature.properties.package,
34653                         detections: feature.properties.detections
34654                     };
34655
34656                     // cache imageKey -> detectionKey
34657                     feature.properties.detections.forEach(function(detection) {
34658                         var imageKey = detection.image_key;
34659                         var detectionKey = detection.detection_key;
34660                         if (!_mlyCache.detections[imageKey]) {
34661                             _mlyCache.detections[imageKey] = {};
34662                         }
34663                         if (!_mlyCache.detections[imageKey][detectionKey]) {
34664                             _mlyCache.detections[imageKey][detectionKey] = {};
34665                         }
34666                     });
34667                 }
34668
34669                 return {
34670                     minX: loc[0], minY: loc[1], maxX: loc[0], maxY: loc[1], data: d
34671                 };
34672
34673             }).filter(Boolean);
34674
34675             cache.rtree.load(features);
34676
34677             if (which === 'images' || which === 'sequences') {
34678                 dispatch$1.call('loadedImages');
34679             } else if (which === 'objects') {
34680                 dispatch$1.call('loadedSigns');
34681             }
34682
34683             if (data.features.length === maxResults) {  // more pages to load
34684                 cache.nextPage[tile.id] = nextPage + 1;
34685                 loadNextTilePage(which, currZoom, url, tile);
34686             } else {
34687                 cache.nextPage[tile.id] = Infinity;     // no more pages to load
34688             }
34689         });
34690 }
34691
34692 // extract links to pages of API results
34693 function parsePagination(links) {
34694     return links.split(',').map(function(rel) {
34695         var elements = rel.split(';');
34696         if (elements.length === 2) {
34697             return [
34698                 /<(.+)>/.exec(elements[0])[1],
34699                 /rel="(.+)"/.exec(elements[1])[1]
34700                 ];
34701         } else {
34702             return ['',''];
34703         }
34704     }).reduce(function(pagination, val) {
34705         pagination[val[1]] = val[0];
34706         return pagination;
34707     }, {});
34708 }
34709
34710
34711 // partition viewport into `psize` x `psize` regions
34712 function partitionViewport(psize, projection) {
34713     var dimensions = projection.clipExtent()[1];
34714     psize = psize || 16;
34715     var cols = d3_range(0, dimensions[0], psize),
34716         rows = d3_range(0, dimensions[1], psize),
34717         partitions = [];
34718
34719     rows.forEach(function(y) {
34720         cols.forEach(function(x) {
34721             var min = [x, y + psize],
34722                 max = [x + psize, y];
34723             partitions.push(
34724                 geoExtent(projection.invert(min), projection.invert(max)));
34725         });
34726     });
34727
34728     return partitions;
34729 }
34730
34731
34732 // no more than `limit` results per partition.
34733 function searchLimited(psize, limit, projection, rtree) {
34734     limit = limit || 3;
34735
34736     var partitions = partitionViewport(psize, projection);
34737     var results;
34738
34739     // console.time('previous');
34740     results =  flatten(map$4(partitions, function(extent) {
34741         return rtree.search(extent.bbox())
34742             .slice(0, limit)
34743             .map(function(d) { return d.data; });
34744     }));
34745     // console.timeEnd('previous');
34746
34747     // console.time('new');
34748     // results = partitions.reduce(function(result, extent) {
34749     //     var found = rtree.search(extent.bbox())
34750     //         .map(function(d) { return d.data; })
34751     //         .sort(function(a, b) {
34752     //             return a.loc[1] - b.loc[1];
34753     //             // return a.key.localeCompare(b.key);
34754     //         })
34755     //         .slice(0, limit);
34756
34757     //     return (found.length ? result.concat(found) : result);
34758     // }, []);
34759     // console.timeEnd('new');
34760
34761     return results;
34762 }
34763
34764
34765
34766 var serviceMapillary = {
34767
34768     init: function() {
34769         if (!_mlyCache) {
34770             this.reset();
34771         }
34772
34773         this.event = utilRebind(this, dispatch$1, 'on');
34774     },
34775
34776     reset: function() {
34777         var cache = _mlyCache;
34778
34779         if (cache) {
34780             if (cache.images && cache.images.inflight) {
34781                 forEach(cache.images.inflight, abortRequest);
34782             }
34783             if (cache.objects && cache.objects.inflight) {
34784                 forEach(cache.objects.inflight, abortRequest);
34785             }
34786             if (cache.sequences && cache.sequences.inflight) {
34787                 forEach(cache.sequences.inflight, abortRequest);
34788             }
34789         }
34790
34791         _mlyCache = {
34792             images: { inflight: {}, loaded: {}, nextPage: {}, nextURL: {}, rtree: rbush_1(), forImageKey: {} },
34793             objects: { inflight: {}, loaded: {}, nextPage: {}, nextURL: {}, rtree: rbush_1() },
34794             sequences: { inflight: {}, loaded: {}, nextPage: {}, nextURL: {}, rtree: rbush_1(), forImageKey: {}, lineString: {} },
34795             detections: {}
34796         };
34797
34798         _mlySelectedImage = null;
34799         _mlyClicks = [];
34800     },
34801
34802
34803     images: function(projection) {
34804         var psize = 16, limit = 3;
34805         return searchLimited(psize, limit, projection, _mlyCache.images.rtree);
34806     },
34807
34808
34809     signs: function(projection) {
34810         var psize = 32, limit = 3;
34811         return searchLimited(psize, limit, projection, _mlyCache.objects.rtree);
34812     },
34813
34814
34815     sequences: function(projection) {
34816         var viewport = projection.clipExtent();
34817         var min = [viewport[0][0], viewport[1][1]];
34818         var max = [viewport[1][0], viewport[0][1]];
34819         var bbox = geoExtent(projection.invert(min), projection.invert(max)).bbox();
34820         var sequenceKeys = {};
34821
34822         // all sequences for images in viewport
34823         _mlyCache.images.rtree.search(bbox)
34824             .forEach(function(d) {
34825                 var sequenceKey = _mlyCache.sequences.forImageKey[d.data.key];
34826                 if (sequenceKey) {
34827                     sequenceKeys[sequenceKey] = true;
34828                 }
34829             });
34830
34831         // Return lineStrings for the sequences
34832         return Object.keys(sequenceKeys).map(function(sequenceKey) {
34833             return _mlyCache.sequences.lineString[sequenceKey];
34834         });
34835     },
34836
34837
34838     signsSupported: function() {
34839         var detected = utilDetect();
34840         if (detected.ie) return false;
34841         if ((detected.browser.toLowerCase() === 'safari') && (parseFloat(detected.version) < 10)) return false;
34842         return true;
34843     },
34844
34845
34846     signHTML: function(d) {
34847         if (!_mlySignDefs || !_mlySignSprite) return;
34848         var position = _mlySignDefs[d.value];
34849         if (!position) return '<div></div>';
34850         var iconStyle = [
34851             'background-image:url(' + _mlySignSprite + ')',
34852             'background-repeat:no-repeat',
34853             'height:' + position.height + 'px',
34854             'width:' + position.width + 'px',
34855             'background-position-x:-' + position.x + 'px',
34856             'background-position-y:-' + position.y + 'px',
34857         ];
34858
34859         return '<div style="' + iconStyle.join(';') +'"></div>';
34860     },
34861
34862
34863     loadImages: function(projection) {
34864         loadTiles('images', apibase + 'images?', projection);
34865         loadTiles('sequences', apibase + 'sequences?', projection);
34866     },
34867
34868
34869     loadSigns: function(context, projection) {
34870         // if we are looking at signs, we'll actually need to fetch images too
34871         loadTiles('images', apibase + 'images?', projection);
34872         loadTiles('objects', apibase + 'objects?', projection);
34873
34874         // load traffic sign defs
34875         if (!_mlySignDefs) {
34876             _mlySignSprite = context.asset('img/traffic-signs/traffic-signs.png');
34877             _mlySignDefs = {};
34878             d3_json(context.asset('img/traffic-signs/traffic-signs.json'), function(err, data) {
34879                 if (err) return;
34880                 _mlySignDefs = data;
34881             });
34882         }
34883     },
34884
34885
34886     loadViewer: function(context) {
34887         // add mly-wrapper
34888         var wrap = d3_select('#photoviewer').selectAll('.mly-wrapper')
34889             .data([0]);
34890
34891         var wrapEnter = wrap.enter()
34892             .append('div')
34893             .attr('id', 'mly')
34894             .attr('class', 'photo-wrapper mly-wrapper')
34895             .classed('hide', true);
34896
34897         wrapEnter
34898             .append('div')
34899             .attr('class', 'photo-attribution fillD');
34900
34901
34902         // load mapillary-viewercss
34903         d3_select('head').selectAll('#mapillary-viewercss')
34904             .data([0])
34905             .enter()
34906             .append('link')
34907             .attr('id', 'mapillary-viewercss')
34908             .attr('rel', 'stylesheet')
34909             .attr('href', context.asset(viewercss));
34910
34911         // load mapillary-viewerjs
34912         d3_select('head').selectAll('#mapillary-viewerjs')
34913             .data([0])
34914             .enter()
34915             .append('script')
34916             .attr('id', 'mapillary-viewerjs')
34917             .attr('src', context.asset(viewerjs));
34918     },
34919
34920
34921     showViewer: function() {
34922         var wrap = d3_select('#photoviewer')
34923             .classed('hide', false);
34924
34925         var isHidden = wrap.selectAll('.photo-wrapper.mly-wrapper.hide').size();
34926
34927         if (isHidden) {
34928             wrap
34929                 .selectAll('.photo-wrapper:not(.mly-wrapper)')
34930                 .classed('hide', true);
34931
34932             wrap
34933                 .selectAll('.photo-wrapper.mly-wrapper')
34934                 .classed('hide', false);
34935
34936             _mlyViewer.resize();
34937         }
34938
34939         return this;
34940     },
34941
34942
34943     hideViewer: function() {
34944         _mlySelectedImage = null;
34945
34946         var viewer = d3_select('#photoviewer');
34947         if (!viewer.empty()) viewer.datum(null);
34948
34949         viewer
34950             .classed('hide', true)
34951             .selectAll('.photo-wrapper')
34952             .classed('hide', true);
34953
34954         d3_selectAll('.viewfield-group, .sequence, .icon-sign')
34955             .classed('selected', false);
34956
34957         return this.setStyles(null, true);
34958     },
34959
34960
34961     parsePagination: parsePagination,
34962
34963
34964     updateViewer: function(imageKey, context) {
34965         if (!imageKey) return this;
34966
34967         if (!_mlyViewer) {
34968             this.initViewer(imageKey, context);
34969         } else {
34970             _mlyViewer.moveToKey(imageKey);
34971         }
34972
34973         return this;
34974     },
34975
34976
34977     initViewer: function(imageKey, context) {
34978         var that = this;
34979         if (Mapillary && imageKey) {
34980             var opts = {
34981                 baseImageSize: 320,
34982                 component: {
34983                     cover: false,
34984                     keyboard: false,
34985                     tag: true
34986                 }
34987             };
34988
34989             _mlyViewer = new Mapillary.Viewer('mly', clientId, imageKey, opts);
34990             _mlyViewer.on('nodechanged', nodeChanged);
34991         }
34992
34993         // nodeChanged: called after the viewer has changed images and is ready.
34994         //
34995         // There is some logic here to batch up clicks into a _mlyClicks array
34996         // because the user might click on a lot of markers quickly and nodechanged
34997         // may be called out of order asychronously.
34998         //
34999         // Clicks are added to the array in `selectedImage` and removed here.
35000         //
35001         function nodeChanged(node) {
35002             _mlyViewer.getComponent('tag').removeAll();  // remove previous detections
35003
35004             var clicks = _mlyClicks;
35005             var index = clicks.indexOf(node.key);
35006             var selectedKey = _mlySelectedImage && _mlySelectedImage.key;
35007
35008             if (index > -1) {              // `nodechanged` initiated from clicking on a marker..
35009                 clicks.splice(index, 1);   // remove the click
35010                 // If `node.key` matches the current _mlySelectedImage, call `selectImage()`
35011                 // one more time to update the detections and attribution..
35012                 if (node.key === selectedKey) {
35013                     that.selectImage(_mlySelectedImage, node.key, true);
35014                 }
35015             } else {             // `nodechanged` initiated from the Mapillary viewer controls..
35016                 var loc = node.computedLatLon ? [node.computedLatLon.lon, node.computedLatLon.lat] : [node.latLon.lon, node.latLon.lat];
35017                 context.map().centerEase(loc);
35018                 that.selectImage(undefined, node.key, true);
35019             }
35020         }
35021     },
35022
35023
35024     // Pass the image datum itself in `d` or the `imageKey` string.
35025     // This allows images to be selected from places that dont have access
35026     // to the full image datum (like the street signs layer or the js viewer)
35027     selectImage: function(d, imageKey, fromViewer) {
35028         if (!d && imageKey) {
35029             // If the user clicked on something that's not an image marker, we
35030             // might get in here.. Cache lookup can fail, e.g. if the user
35031             // clicked a streetsign, but images are loading slowly asynchronously.
35032             // We'll try to carry on anyway if there is no datum.  There just
35033             // might be a delay before user sees detections, captured_at, etc.
35034             d = _mlyCache.images.forImageKey[imageKey];
35035         }
35036
35037         _mlySelectedImage = d;
35038         var viewer = d3_select('#photoviewer');
35039         if (!viewer.empty()) viewer.datum(d);
35040
35041         imageKey = (d && d.key) || imageKey;
35042         if (!fromViewer && imageKey) {
35043             _mlyClicks.push(imageKey);
35044         }
35045
35046         this.setStyles(null, true);
35047
35048         d3_selectAll('.layer-mapillary-signs .icon-sign')
35049             .classed('selected', function(d) {
35050                 return some(d.detections, function(detection) {
35051                     return detection.image_key === imageKey;
35052                 });
35053             });
35054
35055         var wrap = d3_select('#photoviewer .mly-wrapper');
35056         var attribution = wrap.selectAll('.photo-attribution').html('');
35057
35058         if (d) {
35059             if (d.captured_by) {
35060                 attribution
35061                     .append('a')
35062                     .attr('class', 'captured_by')
35063                     .attr('target', '_blank')
35064                     .attr('href', 'https://www.mapillary.com/app/user/' + encodeURIComponent(d.captured_by))
35065                     .text('@' + d.captured_by);
35066
35067                 attribution
35068                     .append('span')
35069                     .text('|');
35070             }
35071
35072             if (d.captured_at) {
35073                 attribution
35074                     .append('span')
35075                     .attr('class', 'captured_at')
35076                     .text(localeTimestamp(d.captured_at));
35077
35078                 attribution
35079                     .append('span')
35080                     .text('|');
35081             }
35082
35083             attribution
35084                 .append('a')
35085                 .attr('class', 'image_link')
35086                 .attr('target', '_blank')
35087                 .attr('href', 'https://www.mapillary.com/app/?pKey=' + encodeURIComponent(d.key) +
35088                     '&focus=photo&lat=' + d.loc[1] + '&lng=' + d.loc[0] + '&z=17')
35089                 .text('mapillary.com');
35090
35091             this.updateDetections(d);
35092         }
35093
35094         return this;
35095     },
35096
35097
35098     getSelectedImage: function() {
35099         return _mlySelectedImage;
35100     },
35101
35102
35103     getSequenceKeyForImage: function(d) {
35104         var imageKey = d && d.key;
35105         return imageKey && _mlyCache.sequences.forImageKey[imageKey];
35106     },
35107
35108
35109     setStyles: function(hovered, reset) {
35110         if (reset) {  // reset all layers
35111             d3_selectAll('.viewfield-group')
35112                 .classed('highlighted', false)
35113                 .classed('hovered', false)
35114                 .classed('selected', false);
35115
35116             d3_selectAll('.sequence')
35117                 .classed('highlighted', false)
35118                 .classed('selected', false);
35119         }
35120
35121         var hoveredImageKey = hovered && hovered.key;
35122         var hoveredSequenceKey = this.getSequenceKeyForImage(hovered);
35123         var hoveredLineString = hoveredSequenceKey && _mlyCache.sequences.lineString[hoveredSequenceKey];
35124         var hoveredImageKeys = (hoveredLineString && hoveredLineString.properties.coordinateProperties.image_keys) || [];
35125
35126         var viewer = d3_select('#photoviewer');
35127         var selected = viewer.empty() ? undefined : viewer.datum();
35128         var selectedImageKey = selected && selected.key;
35129         var selectedSequenceKey = this.getSequenceKeyForImage(selected);
35130         var selectedLineString = selectedSequenceKey && _mlyCache.sequences.lineString[selectedSequenceKey];
35131         var selectedImageKeys = (selectedLineString && selectedLineString.properties.coordinateProperties.image_keys) || [];
35132
35133         // highlight sibling viewfields on either the selected or the hovered sequences
35134         var highlightedImageKeys = union(hoveredImageKeys, selectedImageKeys);
35135
35136         d3_selectAll('.layer-mapillary-images .viewfield-group')
35137             .classed('highlighted', function(d) { return highlightedImageKeys.indexOf(d.key) !== -1; })
35138             .classed('hovered', function(d) { return d.key === hoveredImageKey; })
35139             .classed('selected', function(d) { return d.key === selectedImageKey; });
35140
35141         d3_selectAll('.layer-mapillary-images .sequence')
35142             .classed('highlighted', function(d) { return d.properties.key === hoveredSequenceKey; })
35143             .classed('selected', function(d) { return d.properties.key === selectedSequenceKey; });
35144
35145         return this;
35146     },
35147
35148
35149     updateDetections: function(d) {
35150         if (!_mlyViewer) return;
35151
35152         var imageKey = d && d.key;
35153         var detections = (imageKey && _mlyCache.detections[imageKey]) || [];
35154
35155         forEach(detections, function(data, k) {
35156             if (isEmpty(data)) {
35157                 loadDetection(k);
35158             } else {
35159                 var tag = makeTag(data);
35160                 if (tag) {
35161                     var tagComponent = _mlyViewer.getComponent('tag');
35162                     tagComponent.add([tag]);
35163                 }
35164             }
35165         });
35166
35167
35168         function loadDetection(detectionKey) {
35169             var url = apibase + 'detections/'+
35170                 detectionKey + '?' + utilQsString({
35171                     client_id: clientId,
35172                 });
35173
35174             d3_request(url)
35175                 .mimeType('application/json')
35176                 .response(function(xhr) {
35177                     return JSON.parse(xhr.responseText);
35178                 })
35179                 .get(function(err, data) {
35180                     if (!data || !data.properties) return;
35181
35182                     var imageKey = data.properties.image_key;
35183                     _mlyCache.detections[imageKey][detectionKey] = data;
35184
35185                     var selectedKey = _mlySelectedImage && _mlySelectedImage.key;
35186                     if (imageKey === selectedKey) {
35187                         var tag = makeTag(data);
35188                         if (tag) {
35189                             var tagComponent = _mlyViewer.getComponent('tag');
35190                             tagComponent.add([tag]);
35191                         }
35192                     }
35193                 });
35194         }
35195
35196
35197         function makeTag(data) {
35198             var valueParts = data.properties.value.split('--');
35199             if (valueParts.length !== 3) return;
35200
35201             var text = valueParts[1].replace(/-/g, ' ');
35202             var tag;
35203
35204             // Currently only two shapes <Polygon|Point>
35205             if (data.properties.shape.type === 'Polygon') {
35206                 var polygonGeometry = new Mapillary
35207                     .TagComponent
35208                     .PolygonGeometry(data.properties.shape.coordinates[0]);
35209
35210                 tag = new Mapillary.TagComponent.OutlineTag(
35211                     data.properties.key,
35212                     polygonGeometry,
35213                     {
35214                         text: text,
35215                         textColor: 0xffff00,
35216                         lineColor: 0xffff00,
35217                         lineWidth: 2,
35218                         fillColor: 0xffff00,
35219                         fillOpacity: 0.3,
35220                     }
35221                 );
35222
35223             } else if (data.properties.shape.type === 'Point') {
35224                 var pointGeometry = new Mapillary
35225                     .TagComponent
35226                     .PointGeometry(data.properties.shape.coordinates[0]);
35227
35228                 tag = new Mapillary.TagComponent.SpotTag(
35229                     data.properties.key,
35230                     pointGeometry,
35231                     {
35232                         text: text,
35233                         color: 0xffff00,
35234                         textColor: 0xffff00
35235                     }
35236                 );
35237             }
35238
35239             return tag;
35240         }
35241     },
35242
35243
35244     cache: function() {
35245         return _mlyCache;
35246     },
35247
35248
35249     signDefs: function(_) {
35250         if (!arguments.length) return _mlySignDefs;
35251         _mlySignDefs = _;
35252         return this;
35253     }
35254
35255 };
35256
35257 var apibase$1 = 'https://nominatim.openstreetmap.org/';
35258 var inflight = {};
35259 var nominatimCache;
35260
35261
35262 var serviceNominatim = {
35263
35264     init: function() {
35265         inflight = {};
35266         nominatimCache = rbush_1();
35267     },
35268
35269     reset: function() {
35270         forEach(inflight, function(req) { req.abort(); });
35271         inflight = {};
35272         nominatimCache = rbush_1();
35273     },
35274
35275
35276     countryCode: function (location, callback) {
35277         this.reverse(location, function(err, result) {
35278             if (err) {
35279                 return callback(err);
35280             } else if (result.address) {
35281                 return callback(null, result.address.country_code);
35282             } else {
35283                 return callback('Unable to geocode', null);
35284             }
35285         });
35286     },
35287
35288
35289     reverse: function (location, callback) {
35290         var cached = nominatimCache.search(
35291             { minX: location[0], minY: location[1], maxX: location[0], maxY: location[1] }
35292         );
35293
35294         if (cached.length > 0) {
35295             return callback(null, cached[0].data);
35296         }
35297
35298         var params = { zoom: 13, format: 'json', addressdetails: 1, lat: location[1], lon: location[0] };
35299         var url = apibase$1 + 'reverse?' + utilQsString(params);
35300         if (inflight[url]) return;
35301
35302         inflight[url] = d3_json(url, function(err, result) {
35303             delete inflight[url];
35304
35305             if (err) {
35306                 return callback(err);
35307             } else if (result && result.error) {
35308                 return callback(result.error);
35309             }
35310
35311             var extent = geoExtent(location).padByMeters(200);
35312             nominatimCache.insert(assign(extent.bbox(), {data: result}));
35313
35314             callback(null, result);
35315         });
35316     },
35317
35318
35319     search: function (val, callback) {
35320         var searchVal = encodeURIComponent(val);
35321         var url = apibase$1 + 'search/' + searchVal + '?limit=10&format=json';
35322         if (inflight[url]) return;
35323
35324         inflight[url] = d3_json(url, function(err, result) {
35325             delete inflight[url];
35326             callback(err, result);
35327         });
35328     }
35329
35330 };
35331
35332 var apibase$2 = 'https://openstreetcam.org';
35333 var maxResults$1 = 1000;
35334 var tileZoom$1 = 14;
35335 var dispatch$2 = dispatch('loadedImages');
35336 var imgZoom = d3_zoom()
35337         .extent([[0, 0], [320, 240]])
35338         .translateExtent([[0, 0], [320, 240]])
35339         .scaleExtent([1, 15])
35340         .on('zoom', zoomPan);
35341 var _oscCache;
35342 var _oscSelectedImage;
35343
35344
35345 function abortRequest$1(i) {
35346     i.abort();
35347 }
35348
35349
35350 function nearNullIsland$1(x, y, z) {
35351     if (z >= 7) {
35352         var center = Math.pow(2, z - 1),
35353             width = Math.pow(2, z - 6),
35354             min = center - (width / 2),
35355             max = center + (width / 2) - 1;
35356         return x >= min && x <= max && y >= min && y <= max;
35357     }
35358     return false;
35359 }
35360
35361
35362 function maxPageAtZoom$1(z) {
35363     if (z < 15)   return 2;
35364     if (z === 15) return 5;
35365     if (z === 16) return 10;
35366     if (z === 17) return 20;
35367     if (z === 18) return 40;
35368     if (z > 18)   return 80;
35369 }
35370
35371
35372 function getTiles$1(projection) {
35373     var s = projection.scale() * 2 * Math.PI,
35374         z = Math.max(Math.log(s) / Math.log(2) - 8, 0),
35375         ts = 256 * Math.pow(2, z - tileZoom$1),
35376         origin = [
35377             s / 2 - projection.translate()[0],
35378             s / 2 - projection.translate()[1]];
35379
35380     return d3geoTile()
35381         .scaleExtent([tileZoom$1, tileZoom$1])
35382         .scale(s)
35383         .size(projection.clipExtent()[1])
35384         .translate(projection.translate())()
35385         .map(function(tile) {
35386             var x = tile[0] * ts - origin[0],
35387                 y = tile[1] * ts - origin[1];
35388
35389             return {
35390                 id: tile.toString(),
35391                 xyz: tile,
35392                 extent: geoExtent(
35393                     projection.invert([x, y + ts]),
35394                     projection.invert([x + ts, y])
35395                 )
35396             };
35397         });
35398 }
35399
35400
35401 function loadTiles$1(which, url, projection) {
35402     var s = projection.scale() * 2 * Math.PI,
35403         currZoom = Math.floor(Math.max(Math.log(s) / Math.log(2) - 8, 0));
35404
35405     var tiles = getTiles$1(projection).filter(function(t) {
35406             return !nearNullIsland$1(t.xyz[0], t.xyz[1], t.xyz[2]);
35407         });
35408
35409     filter(which.inflight, function(v, k) {
35410         var wanted = find$1(tiles, function(tile) { return k === (tile.id + ',0'); });
35411         if (!wanted) delete which.inflight[k];
35412         return !wanted;
35413     }).map(abortRequest$1);
35414
35415     tiles.forEach(function(tile) {
35416         loadNextTilePage$1(which, currZoom, url, tile);
35417     });
35418 }
35419
35420
35421 function loadNextTilePage$1(which, currZoom, url, tile) {
35422     var cache = _oscCache[which];
35423     var bbox = tile.extent.bbox();
35424     var maxPages = maxPageAtZoom$1(currZoom);
35425     var nextPage = cache.nextPage[tile.id] || 1;
35426     var params = utilQsString({
35427             ipp: maxResults$1,
35428             page: nextPage,
35429             // client_id: clientId,
35430             bbTopLeft: [bbox.maxY, bbox.minX].join(','),
35431             bbBottomRight: [bbox.minY, bbox.maxX].join(',')
35432         }, true);
35433
35434     if (nextPage > maxPages) return;
35435
35436     var id = tile.id + ',' + String(nextPage);
35437     if (cache.loaded[id] || cache.inflight[id]) return;
35438
35439     cache.inflight[id] = d3_request(url)
35440         .mimeType('application/json')
35441         .header('Content-type', 'application/x-www-form-urlencoded')
35442         .response(function(xhr) { return JSON.parse(xhr.responseText); })
35443         .post(params, function(err, data) {
35444             cache.loaded[id] = true;
35445             delete cache.inflight[id];
35446             if (err || !data.currentPageItems || !data.currentPageItems.length) return;
35447
35448             function localeDateString(s) {
35449                 if (!s) return null;
35450                 var detected = utilDetect();
35451                 var options = { day: 'numeric', month: 'short', year: 'numeric' };
35452                 var d = new Date(s);
35453                 if (isNaN(d.getTime())) return null;
35454                 return d.toLocaleDateString(detected.locale, options);
35455             }
35456
35457             var features = data.currentPageItems.map(function(item) {
35458                 var loc = [+item.lng, +item.lat],
35459                     d;
35460
35461                 if (which === 'images') {
35462                     d = {
35463                         loc: loc,
35464                         key: item.id,
35465                         ca: +item.heading,
35466                         captured_at: localeDateString(item.shot_date || item.date_added),
35467                         captured_by: item.username,
35468                         imagePath: item.lth_name,
35469                         sequence_id: item.sequence_id,
35470                         sequence_index: +item.sequence_index
35471                     };
35472
35473                     // cache sequence info
35474                     var seq = _oscCache.sequences[d.sequence_id];
35475                     if (!seq) {
35476                         seq = { rotation: 0, images: [] };
35477                         _oscCache.sequences[d.sequence_id] = seq;
35478                     }
35479                     seq.images[d.sequence_index] = d;
35480                 }
35481
35482                 return {
35483                     minX: loc[0], minY: loc[1], maxX: loc[0], maxY: loc[1], data: d
35484                 };
35485             });
35486
35487             cache.rtree.load(features);
35488
35489             if (which === 'images') {
35490                 dispatch$2.call('loadedImages');
35491             }
35492
35493             if (data.currentPageItems.length === maxResults$1) {  // more pages to load
35494                 cache.nextPage[tile.id] = nextPage + 1;
35495                 loadNextTilePage$1(which, currZoom, url, tile);
35496             } else {
35497                 cache.nextPage[tile.id] = Infinity;     // no more pages to load
35498             }
35499         });
35500 }
35501
35502
35503 // partition viewport into `psize` x `psize` regions
35504 function partitionViewport$1(psize, projection) {
35505     var dimensions = projection.clipExtent()[1];
35506     psize = psize || 16;
35507     var cols = d3_range(0, dimensions[0], psize),
35508         rows = d3_range(0, dimensions[1], psize),
35509         partitions = [];
35510
35511     rows.forEach(function(y) {
35512         cols.forEach(function(x) {
35513             var min = [x, y + psize],
35514                 max = [x + psize, y];
35515             partitions.push(
35516                 geoExtent(projection.invert(min), projection.invert(max)));
35517         });
35518     });
35519
35520     return partitions;
35521 }
35522
35523
35524 // no more than `limit` results per partition.
35525 function searchLimited$1(psize, limit, projection, rtree) {
35526     limit = limit || 3;
35527
35528     var partitions = partitionViewport$1(psize, projection);
35529     var results;
35530
35531     results = flatten(map$4(partitions, function(extent) {
35532         return rtree.search(extent.bbox())
35533             .slice(0, limit)
35534             .map(function(d) { return d.data; });
35535     }));
35536     return results;
35537 }
35538
35539
35540 function zoomPan() {
35541     var t = event.transform;
35542     d3_select('#photoviewer .osc-image-wrap')
35543         .call(utilSetTransform, t.x, t.y, t.k);
35544 }
35545
35546
35547 var serviceOpenstreetcam = {
35548
35549     init: function() {
35550         if (!_oscCache) {
35551             this.reset();
35552         }
35553
35554         this.event = utilRebind(this, dispatch$2, 'on');
35555     },
35556
35557     reset: function() {
35558         var cache = _oscCache;
35559
35560         if (cache) {
35561             if (cache.images && cache.images.inflight) {
35562                 forEach(cache.images.inflight, abortRequest$1);
35563             }
35564         }
35565
35566         _oscCache = {
35567             images: { inflight: {}, loaded: {}, nextPage: {}, rtree: rbush_1() },
35568             sequences: {}
35569         };
35570
35571         _oscSelectedImage = null;
35572     },
35573
35574
35575     images: function(projection) {
35576         var psize = 16, limit = 3;
35577         return searchLimited$1(psize, limit, projection, _oscCache.images.rtree);
35578     },
35579
35580
35581     sequences: function(projection) {
35582         var viewport = projection.clipExtent();
35583         var min = [viewport[0][0], viewport[1][1]];
35584         var max = [viewport[1][0], viewport[0][1]];
35585         var bbox = geoExtent(projection.invert(min), projection.invert(max)).bbox();
35586         var sequenceKeys = {};
35587
35588         // all sequences for images in viewport
35589         _oscCache.images.rtree.search(bbox)
35590             .forEach(function(d) { sequenceKeys[d.data.sequence_id] = true; });
35591
35592         // make linestrings from those sequences
35593         var lineStrings = [];
35594         Object.keys(sequenceKeys)
35595             .forEach(function(sequenceKey) {
35596                 var seq = _oscCache.sequences[sequenceKey];
35597                 var images = seq && seq.images;
35598                 if (images) {
35599                     lineStrings.push({
35600                         type: 'LineString',
35601                         coordinates: images.map(function (d) { return d.loc; }).filter(Boolean),
35602                         properties: { key: sequenceKey }
35603                     });
35604                 }
35605             });
35606         return lineStrings;
35607     },
35608
35609
35610     loadImages: function(projection) {
35611         var url = apibase$2 + '/1.0/list/nearby-photos/';
35612         loadTiles$1('images', url, projection);
35613     },
35614
35615
35616     loadViewer: function(context) {
35617         var that = this;
35618
35619         // add osc-wrapper
35620         var wrap = d3_select('#photoviewer').selectAll('.osc-wrapper')
35621             .data([0]);
35622
35623         var wrapEnter = wrap.enter()
35624             .append('div')
35625             .attr('class', 'photo-wrapper osc-wrapper')
35626             .classed('hide', true)
35627             .call(imgZoom)
35628             .on('dblclick.zoom', null);
35629
35630         wrapEnter
35631             .append('div')
35632             .attr('class', 'photo-attribution fillD');
35633
35634         var controlsEnter = wrapEnter
35635             .append('div')
35636             .attr('class', 'osc-controls-wrap')
35637             .append('div')
35638             .attr('class', 'osc-controls');
35639
35640         controlsEnter
35641             .append('button')
35642             .on('click.back', step(-1))
35643             .text('◄');
35644
35645         controlsEnter
35646             .append('button')
35647             .on('click.rotate-ccw', rotate(-90))
35648             .text('⤿');
35649
35650         controlsEnter
35651             .append('button')
35652             .on('click.rotate-cw', rotate(90))
35653             .text('⤾');
35654
35655         controlsEnter
35656             .append('button')
35657             .on('click.forward', step(1))
35658             .text('►');
35659
35660         wrapEnter
35661             .append('div')
35662             .attr('class', 'osc-image-wrap');
35663
35664
35665         function rotate(deg) {
35666             return function() {
35667                 if (!_oscSelectedImage) return;
35668                 var sequenceKey = _oscSelectedImage.sequence_id;
35669                 var sequence = _oscCache.sequences[sequenceKey];
35670                 if (!sequence) return;
35671
35672                 var r = sequence.rotation || 0;
35673                 r += deg;
35674
35675                 if (r > 180) r -= 360;
35676                 if (r < -180) r += 360;
35677                 sequence.rotation = r;
35678
35679                 var wrap = d3_select('#photoviewer .osc-wrapper');
35680
35681                 wrap
35682                     .transition()
35683                     .duration(100)
35684                     .call(imgZoom.transform, identity$7);
35685
35686                 wrap.selectAll('.osc-image')
35687                     .transition()
35688                     .duration(100)
35689                     .style('transform', 'rotate(' + r + 'deg)');
35690             };
35691         }
35692
35693         function step(stepBy) {
35694             return function() {
35695                 if (!_oscSelectedImage) return;
35696                 var sequenceKey = _oscSelectedImage.sequence_id;
35697                 var sequence = _oscCache.sequences[sequenceKey];
35698                 if (!sequence) return;
35699
35700                 var nextIndex = _oscSelectedImage.sequence_index + stepBy;
35701                 var nextImage = sequence.images[nextIndex];
35702                 if (!nextImage) return;
35703
35704                 context.map().centerEase(nextImage.loc);
35705
35706                 that
35707                     .selectImage(nextImage)
35708                     .updateViewer(nextImage);
35709             };
35710         }
35711     },
35712
35713
35714     showViewer: function() {
35715         var viewer = d3_select('#photoviewer')
35716             .classed('hide', false);
35717
35718         var isHidden = viewer.selectAll('.photo-wrapper.osc-wrapper.hide').size();
35719
35720         if (isHidden) {
35721             viewer
35722                 .selectAll('.photo-wrapper:not(.osc-wrapper)')
35723                 .classed('hide', true);
35724
35725             viewer
35726                 .selectAll('.photo-wrapper.osc-wrapper')
35727                 .classed('hide', false);
35728         }
35729
35730         return this;
35731     },
35732
35733
35734     hideViewer: function() {
35735         _oscSelectedImage = null;
35736
35737         var viewer = d3_select('#photoviewer');
35738         if (!viewer.empty()) viewer.datum(null);
35739
35740         viewer
35741             .classed('hide', true)
35742             .selectAll('.photo-wrapper')
35743             .classed('hide', true);
35744
35745         d3_selectAll('.viewfield-group, .sequence, .icon-sign')
35746             .classed('selected', false);
35747
35748         return this.setStyles(null, true);
35749     },
35750
35751
35752     updateViewer: function(d) {
35753         var wrap = d3_select('#photoviewer .osc-wrapper');
35754         var imageWrap = wrap.selectAll('.osc-image-wrap');
35755         var attribution = wrap.selectAll('.photo-attribution').html('');
35756
35757         wrap
35758             .transition()
35759             .duration(100)
35760             .call(imgZoom.transform, identity$7);
35761
35762         imageWrap
35763             .selectAll('.osc-image')
35764             .remove();
35765
35766         if (d) {
35767             var sequence = _oscCache.sequences[d.sequence_id];
35768             var r = (sequence && sequence.rotation) || 0;
35769
35770             imageWrap
35771                 .append('img')
35772                 .attr('class', 'osc-image')
35773                 .attr('src', apibase$2 + '/' + d.imagePath)
35774                 .style('transform', 'rotate(' + r + 'deg)');
35775
35776             if (d.captured_by) {
35777                 attribution
35778                     .append('a')
35779                     .attr('class', 'captured_by')
35780                     .attr('target', '_blank')
35781                     .attr('href', 'https://openstreetcam.org/user/' + encodeURIComponent(d.captured_by))
35782                     .text('@' + d.captured_by);
35783
35784                 attribution
35785                     .append('span')
35786                     .text('|');
35787             }
35788
35789             if (d.captured_at) {
35790                 attribution
35791                     .append('span')
35792                     .attr('class', 'captured_at')
35793                     .text(d.captured_at);
35794
35795                 attribution
35796                     .append('span')
35797                     .text('|');
35798             }
35799
35800             attribution
35801                 .append('a')
35802                 .attr('class', 'image_link')
35803                 .attr('target', '_blank')
35804                 .attr('href', 'https://openstreetcam.org/details/' + d.sequence_id + '/' + d.sequence_index)
35805                 .text('openstreetcam.org');
35806         }
35807         return this;
35808     },
35809
35810
35811     selectImage: function(d) {
35812         _oscSelectedImage = d;
35813         var viewer = d3_select('#photoviewer');
35814         if (!viewer.empty()) viewer.datum(d);
35815
35816         this.setStyles(null, true);
35817
35818         d3_selectAll('.icon-sign')
35819             .classed('selected', false);
35820
35821         return this;
35822     },
35823
35824
35825     getSelectedImage: function() {
35826         return _oscSelectedImage;
35827     },
35828
35829
35830     getSequenceKeyForImage: function(d) {
35831         return d && d.sequence_id;
35832     },
35833
35834
35835     setStyles: function(hovered, reset) {
35836         if (reset) {  // reset all layers
35837             d3_selectAll('.viewfield-group')
35838                 .classed('highlighted', false)
35839                 .classed('hovered', false)
35840                 .classed('selected', false);
35841
35842             d3_selectAll('.sequence')
35843                 .classed('highlighted', false)
35844                 .classed('selected', false);
35845         }
35846
35847         var hoveredImageKey = hovered && hovered.key;
35848         var hoveredSequenceKey = this.getSequenceKeyForImage(hovered);
35849         var hoveredSequence = hoveredSequenceKey && _oscCache.sequences[hoveredSequenceKey];
35850         var hoveredImageKeys = (hoveredSequence && hoveredSequence.images.map(function (d) { return d.key; })) || [];
35851
35852         var viewer = d3_select('#photoviewer');
35853         var selected = viewer.empty() ? undefined : viewer.datum();
35854         var selectedImageKey = selected && selected.key;
35855         var selectedSequenceKey = this.getSequenceKeyForImage(selected);
35856         var selectedSequence = selectedSequenceKey && _oscCache.sequences[selectedSequenceKey];
35857         var selectedImageKeys = (selectedSequence && selectedSequence.images.map(function (d) { return d.key; })) || [];
35858
35859         // highlight sibling viewfields on either the selected or the hovered sequences
35860         var highlightedImageKeys = union(hoveredImageKeys, selectedImageKeys);
35861
35862         d3_selectAll('.layer-openstreetcam-images .viewfield-group')
35863             .classed('highlighted', function(d) { return highlightedImageKeys.indexOf(d.key) !== -1; })
35864             .classed('hovered', function(d) { return d.key === hoveredImageKey; })
35865             .classed('selected', function(d) { return d.key === selectedImageKey; });
35866
35867         d3_selectAll('.layer-openstreetcam-images .sequence')
35868             .classed('highlighted', function(d) { return d.properties.key === hoveredSequenceKey; })
35869             .classed('selected', function(d) { return d.properties.key === selectedSequenceKey; });
35870
35871         return this;
35872     },
35873
35874
35875     cache: function() {
35876         return _oscCache;
35877     }
35878
35879 };
35880
35881 /* Built-in method references for those with the same name as other `lodash` methods. */
35882 var nativeCeil = Math.ceil;
35883 var nativeMax$4 = Math.max;
35884
35885 /**
35886  * Creates an array of elements split into groups the length of `size`.
35887  * If `array` can't be split evenly, the final chunk will be the remaining
35888  * elements.
35889  *
35890  * @static
35891  * @memberOf _
35892  * @since 3.0.0
35893  * @category Array
35894  * @param {Array} array The array to process.
35895  * @param {number} [size=1] The length of each chunk
35896  * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
35897  * @returns {Array} Returns the new array of chunks.
35898  * @example
35899  *
35900  * _.chunk(['a', 'b', 'c', 'd'], 2);
35901  * // => [['a', 'b'], ['c', 'd']]
35902  *
35903  * _.chunk(['a', 'b', 'c', 'd'], 3);
35904  * // => [['a', 'b', 'c'], ['d']]
35905  */
35906 function chunk(array, size, guard) {
35907   if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
35908     size = 1;
35909   } else {
35910     size = nativeMax$4(toInteger(size), 0);
35911   }
35912   var length = array == null ? 0 : array.length;
35913   if (!length || size < 1) {
35914     return [];
35915   }
35916   var index = 0,
35917       resIndex = 0,
35918       result = Array(nativeCeil(length / size));
35919
35920   while (index < length) {
35921     result[resIndex++] = baseSlice(array, index, (index += size));
35922   }
35923   return result;
35924 }
35925
35926 var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
35927
35928
35929
35930
35931
35932 function createCommonjsModule(fn, module) {
35933         return module = { exports: {} }, fn(module, module.exports), module.exports;
35934 }
35935
35936 var hashes = createCommonjsModule(function (module, exports) {
35937 /**
35938  * jshashes - https://github.com/h2non/jshashes
35939  * Released under the "New BSD" license
35940  *
35941  * Algorithms specification:
35942  *
35943  * MD5 - http://www.ietf.org/rfc/rfc1321.txt
35944  * RIPEMD-160 - http://homes.esat.kuleuven.be/~bosselae/ripemd160.html
35945  * SHA1   - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
35946  * SHA256 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
35947  * SHA512 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
35948  * HMAC - http://www.ietf.org/rfc/rfc2104.txt
35949  */
35950 (function() {
35951   var Hashes;
35952
35953   function utf8Encode(str) {
35954     var x, y, output = '',
35955       i = -1,
35956       l;
35957
35958     if (str && str.length) {
35959       l = str.length;
35960       while ((i += 1) < l) {
35961         /* Decode utf-16 surrogate pairs */
35962         x = str.charCodeAt(i);
35963         y = i + 1 < l ? str.charCodeAt(i + 1) : 0;
35964         if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) {
35965           x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
35966           i += 1;
35967         }
35968         /* Encode output as utf-8 */
35969         if (x <= 0x7F) {
35970           output += String.fromCharCode(x);
35971         } else if (x <= 0x7FF) {
35972           output += String.fromCharCode(0xC0 | ((x >>> 6) & 0x1F),
35973             0x80 | (x & 0x3F));
35974         } else if (x <= 0xFFFF) {
35975           output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
35976             0x80 | ((x >>> 6) & 0x3F),
35977             0x80 | (x & 0x3F));
35978         } else if (x <= 0x1FFFFF) {
35979           output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
35980             0x80 | ((x >>> 12) & 0x3F),
35981             0x80 | ((x >>> 6) & 0x3F),
35982             0x80 | (x & 0x3F));
35983         }
35984       }
35985     }
35986     return output;
35987   }
35988
35989   function utf8Decode(str) {
35990     var i, ac, c1, c2, c3, arr = [],
35991       l;
35992     i = ac = c1 = c2 = c3 = 0;
35993
35994     if (str && str.length) {
35995       l = str.length;
35996       str += '';
35997
35998       while (i < l) {
35999         c1 = str.charCodeAt(i);
36000         ac += 1;
36001         if (c1 < 128) {
36002           arr[ac] = String.fromCharCode(c1);
36003           i += 1;
36004         } else if (c1 > 191 && c1 < 224) {
36005           c2 = str.charCodeAt(i + 1);
36006           arr[ac] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
36007           i += 2;
36008         } else {
36009           c2 = str.charCodeAt(i + 1);
36010           c3 = str.charCodeAt(i + 2);
36011           arr[ac] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
36012           i += 3;
36013         }
36014       }
36015     }
36016     return arr.join('');
36017   }
36018
36019   /**
36020    * Add integers, wrapping at 2^32. This uses 16-bit operations internally
36021    * to work around bugs in some JS interpreters.
36022    */
36023
36024   function safe_add(x, y) {
36025     var lsw = (x & 0xFFFF) + (y & 0xFFFF),
36026       msw = (x >> 16) + (y >> 16) + (lsw >> 16);
36027     return (msw << 16) | (lsw & 0xFFFF);
36028   }
36029
36030   /**
36031    * Bitwise rotate a 32-bit number to the left.
36032    */
36033
36034   function bit_rol(num, cnt) {
36035     return (num << cnt) | (num >>> (32 - cnt));
36036   }
36037
36038   /**
36039    * Convert a raw string to a hex string
36040    */
36041
36042   function rstr2hex(input, hexcase) {
36043     var hex_tab = hexcase ? '0123456789ABCDEF' : '0123456789abcdef',
36044       output = '',
36045       x, i = 0,
36046       l = input.length;
36047     for (; i < l; i += 1) {
36048       x = input.charCodeAt(i);
36049       output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt(x & 0x0F);
36050     }
36051     return output;
36052   }
36053
36054   /**
36055    * Encode a string as utf-16
36056    */
36057
36058   function binb2rstr(input) {
36059     var i, l = input.length * 32,
36060       output = '';
36061     for (i = 0; i < l; i += 8) {
36062       output += String.fromCharCode((input[i >> 5] >>> (24 - i % 32)) & 0xFF);
36063     }
36064     return output;
36065   }
36066
36067   /**
36068    * Convert an array of little-endian words to a string
36069    */
36070
36071   function binl2rstr(input) {
36072     var i, l = input.length * 32,
36073       output = '';
36074     for (i = 0; i < l; i += 8) {
36075       output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
36076     }
36077     return output;
36078   }
36079
36080   /**
36081    * Convert a raw string to an array of little-endian words
36082    * Characters >255 have their high-byte silently ignored.
36083    */
36084
36085   function rstr2binl(input) {
36086     var i, l = input.length * 8,
36087       output = Array(input.length >> 2),
36088       lo = output.length;
36089     for (i = 0; i < lo; i += 1) {
36090       output[i] = 0;
36091     }
36092     for (i = 0; i < l; i += 8) {
36093       output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32);
36094     }
36095     return output;
36096   }
36097
36098   /**
36099    * Convert a raw string to an array of big-endian words
36100    * Characters >255 have their high-byte silently ignored.
36101    */
36102
36103   function rstr2binb(input) {
36104     var i, l = input.length * 8,
36105       output = Array(input.length >> 2),
36106       lo = output.length;
36107     for (i = 0; i < lo; i += 1) {
36108       output[i] = 0;
36109     }
36110     for (i = 0; i < l; i += 8) {
36111       output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
36112     }
36113     return output;
36114   }
36115
36116   /**
36117    * Convert a raw string to an arbitrary string encoding
36118    */
36119
36120   function rstr2any(input, encoding) {
36121     var divisor = encoding.length,
36122       remainders = Array(),
36123       i, q, x, ld, quotient, dividend, output, full_length;
36124
36125     /* Convert to an array of 16-bit big-endian values, forming the dividend */
36126     dividend = Array(Math.ceil(input.length / 2));
36127     ld = dividend.length;
36128     for (i = 0; i < ld; i += 1) {
36129       dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
36130     }
36131
36132     /**
36133      * Repeatedly perform a long division. The binary array forms the dividend,
36134      * the length of the encoding is the divisor. Once computed, the quotient
36135      * forms the dividend for the next step. We stop when the dividend is zerHashes.
36136      * All remainders are stored for later use.
36137      */
36138     while (dividend.length > 0) {
36139       quotient = Array();
36140       x = 0;
36141       for (i = 0; i < dividend.length; i += 1) {
36142         x = (x << 16) + dividend[i];
36143         q = Math.floor(x / divisor);
36144         x -= q * divisor;
36145         if (quotient.length > 0 || q > 0) {
36146           quotient[quotient.length] = q;
36147         }
36148       }
36149       remainders[remainders.length] = x;
36150       dividend = quotient;
36151     }
36152
36153     /* Convert the remainders to the output string */
36154     output = '';
36155     for (i = remainders.length - 1; i >= 0; i--) {
36156       output += encoding.charAt(remainders[i]);
36157     }
36158
36159     /* Append leading zero equivalents */
36160     full_length = Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2)));
36161     for (i = output.length; i < full_length; i += 1) {
36162       output = encoding[0] + output;
36163     }
36164     return output;
36165   }
36166
36167   /**
36168    * Convert a raw string to a base-64 string
36169    */
36170
36171   function rstr2b64(input, b64pad) {
36172     var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
36173       output = '',
36174       len = input.length,
36175       i, j, triplet;
36176     b64pad = b64pad || '=';
36177     for (i = 0; i < len; i += 3) {
36178       triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0);
36179       for (j = 0; j < 4; j += 1) {
36180         if (i * 8 + j * 6 > input.length * 8) {
36181           output += b64pad;
36182         } else {
36183           output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F);
36184         }
36185       }
36186     }
36187     return output;
36188   }
36189
36190   Hashes = {
36191     /**
36192      * @property {String} version
36193      * @readonly
36194      */
36195     VERSION: '1.0.6',
36196     /**
36197      * @member Hashes
36198      * @class Base64
36199      * @constructor
36200      */
36201     Base64: function() {
36202       // private properties
36203       var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
36204         pad = '=', // default pad according with the RFC standard
36205         url = false, // URL encoding support @todo
36206         utf8 = true; // by default enable UTF-8 support encoding
36207
36208       // public method for encoding
36209       this.encode = function(input) {
36210         var i, j, triplet,
36211           output = '',
36212           len = input.length;
36213
36214         pad = pad || '=';
36215         input = (utf8) ? utf8Encode(input) : input;
36216
36217         for (i = 0; i < len; i += 3) {
36218           triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0);
36219           for (j = 0; j < 4; j += 1) {
36220             if (i * 8 + j * 6 > len * 8) {
36221               output += pad;
36222             } else {
36223               output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F);
36224             }
36225           }
36226         }
36227         return output;
36228       };
36229
36230       // public method for decoding
36231       this.decode = function(input) {
36232         // var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
36233         var i, o1, o2, o3, h1, h2, h3, h4, bits, ac,
36234           dec = '',
36235           arr = [];
36236         if (!input) {
36237           return input;
36238         }
36239
36240         i = ac = 0;
36241         input = input.replace(new RegExp('\\' + pad, 'gi'), ''); // use '='
36242         //input += '';
36243
36244         do { // unpack four hexets into three octets using index points in b64
36245           h1 = tab.indexOf(input.charAt(i += 1));
36246           h2 = tab.indexOf(input.charAt(i += 1));
36247           h3 = tab.indexOf(input.charAt(i += 1));
36248           h4 = tab.indexOf(input.charAt(i += 1));
36249
36250           bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
36251
36252           o1 = bits >> 16 & 0xff;
36253           o2 = bits >> 8 & 0xff;
36254           o3 = bits & 0xff;
36255           ac += 1;
36256
36257           if (h3 === 64) {
36258             arr[ac] = String.fromCharCode(o1);
36259           } else if (h4 === 64) {
36260             arr[ac] = String.fromCharCode(o1, o2);
36261           } else {
36262             arr[ac] = String.fromCharCode(o1, o2, o3);
36263           }
36264         } while (i < input.length);
36265
36266         dec = arr.join('');
36267         dec = (utf8) ? utf8Decode(dec) : dec;
36268
36269         return dec;
36270       };
36271
36272       // set custom pad string
36273       this.setPad = function(str) {
36274         pad = str || pad;
36275         return this;
36276       };
36277       // set custom tab string characters
36278       this.setTab = function(str) {
36279         tab = str || tab;
36280         return this;
36281       };
36282       this.setUTF8 = function(bool) {
36283         if (typeof bool === 'boolean') {
36284           utf8 = bool;
36285         }
36286         return this;
36287       };
36288     },
36289
36290     /**
36291      * CRC-32 calculation
36292      * @member Hashes
36293      * @method CRC32
36294      * @static
36295      * @param {String} str Input String
36296      * @return {String}
36297      */
36298     CRC32: function(str) {
36299       var crc = 0,
36300         x = 0,
36301         y = 0,
36302         table, i, iTop;
36303       str = utf8Encode(str);
36304
36305       table = [
36306         '00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 ',
36307         '79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 ',
36308         '84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F ',
36309         '63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD ',
36310         'A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC ',
36311         '51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 ',
36312         'B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 ',
36313         '06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 ',
36314         'E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 ',
36315         '12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 ',
36316         'D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 ',
36317         '33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 ',
36318         'CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 ',
36319         '9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E ',
36320         '7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D ',
36321         '806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 ',
36322         '60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA ',
36323         'AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 ',
36324         '5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 ',
36325         'B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 ',
36326         '05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 ',
36327         'F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA ',
36328         '11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 ',
36329         'D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F ',
36330         '30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E ',
36331         'C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D'
36332       ].join('');
36333
36334       crc = crc ^ (-1);
36335       for (i = 0, iTop = str.length; i < iTop; i += 1) {
36336         y = (crc ^ str.charCodeAt(i)) & 0xFF;
36337         x = '0x' + table.substr(y * 9, 8);
36338         crc = (crc >>> 8) ^ x;
36339       }
36340       // always return a positive number (that's what >>> 0 does)
36341       return (crc ^ (-1)) >>> 0;
36342     },
36343     /**
36344      * @member Hashes
36345      * @class MD5
36346      * @constructor
36347      * @param {Object} [config]
36348      *
36349      * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
36350      * Digest Algorithm, as defined in RFC 1321.
36351      * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
36352      * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
36353      * See <http://pajhome.org.uk/crypt/md5> for more infHashes.
36354      */
36355     MD5: function(options) {
36356       /**
36357        * Private config properties. You may need to tweak these to be compatible with
36358        * the server-side, but the defaults work in most cases.
36359        * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase}
36360        */
36361       var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase
36362         b64pad = (options && typeof options.pad === 'string') ? options.pad : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance
36363         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding
36364
36365       // privileged (public) methods
36366       this.hex = function(s) {
36367         return rstr2hex(rstr(s, utf8), hexcase);
36368       };
36369       this.b64 = function(s) {
36370         return rstr2b64(rstr(s), b64pad);
36371       };
36372       this.any = function(s, e) {
36373         return rstr2any(rstr(s, utf8), e);
36374       };
36375       this.raw = function(s) {
36376         return rstr(s, utf8);
36377       };
36378       this.hex_hmac = function(k, d) {
36379         return rstr2hex(rstr_hmac(k, d), hexcase);
36380       };
36381       this.b64_hmac = function(k, d) {
36382         return rstr2b64(rstr_hmac(k, d), b64pad);
36383       };
36384       this.any_hmac = function(k, d, e) {
36385         return rstr2any(rstr_hmac(k, d), e);
36386       };
36387       /**
36388        * Perform a simple self-test to see if the VM is working
36389        * @return {String} Hexadecimal hash sample
36390        */
36391       this.vm_test = function() {
36392         return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
36393       };
36394       /**
36395        * Enable/disable uppercase hexadecimal returned string
36396        * @param {Boolean}
36397        * @return {Object} this
36398        */
36399       this.setUpperCase = function(a) {
36400         if (typeof a === 'boolean') {
36401           hexcase = a;
36402         }
36403         return this;
36404       };
36405       /**
36406        * Defines a base64 pad string
36407        * @param {String} Pad
36408        * @return {Object} this
36409        */
36410       this.setPad = function(a) {
36411         b64pad = a || b64pad;
36412         return this;
36413       };
36414       /**
36415        * Defines a base64 pad string
36416        * @param {Boolean}
36417        * @return {Object} [this]
36418        */
36419       this.setUTF8 = function(a) {
36420         if (typeof a === 'boolean') {
36421           utf8 = a;
36422         }
36423         return this;
36424       };
36425
36426       // private methods
36427
36428       /**
36429        * Calculate the MD5 of a raw string
36430        */
36431
36432       function rstr(s) {
36433         s = (utf8) ? utf8Encode(s) : s;
36434         return binl2rstr(binl(rstr2binl(s), s.length * 8));
36435       }
36436
36437       /**
36438        * Calculate the HMAC-MD5, of a key and some data (raw strings)
36439        */
36440
36441       function rstr_hmac(key, data) {
36442         var bkey, ipad, opad, hash, i;
36443
36444         key = (utf8) ? utf8Encode(key) : key;
36445         data = (utf8) ? utf8Encode(data) : data;
36446         bkey = rstr2binl(key);
36447         if (bkey.length > 16) {
36448           bkey = binl(bkey, key.length * 8);
36449         }
36450
36451         ipad = Array(16), opad = Array(16);
36452         for (i = 0; i < 16; i += 1) {
36453           ipad[i] = bkey[i] ^ 0x36363636;
36454           opad[i] = bkey[i] ^ 0x5C5C5C5C;
36455         }
36456         hash = binl(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
36457         return binl2rstr(binl(opad.concat(hash), 512 + 128));
36458       }
36459
36460       /**
36461        * Calculate the MD5 of an array of little-endian words, and a bit length.
36462        */
36463
36464       function binl(x, len) {
36465         var i, olda, oldb, oldc, oldd,
36466           a = 1732584193,
36467           b = -271733879,
36468           c = -1732584194,
36469           d = 271733878;
36470
36471         /* append padding */
36472         x[len >> 5] |= 0x80 << ((len) % 32);
36473         x[(((len + 64) >>> 9) << 4) + 14] = len;
36474
36475         for (i = 0; i < x.length; i += 16) {
36476           olda = a;
36477           oldb = b;
36478           oldc = c;
36479           oldd = d;
36480
36481           a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
36482           d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
36483           c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
36484           b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
36485           a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
36486           d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
36487           c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
36488           b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
36489           a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
36490           d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
36491           c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
36492           b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
36493           a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
36494           d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
36495           c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
36496           b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
36497
36498           a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
36499           d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
36500           c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
36501           b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302);
36502           a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
36503           d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
36504           c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
36505           b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
36506           a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
36507           d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
36508           c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
36509           b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
36510           a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
36511           d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
36512           c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
36513           b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
36514
36515           a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
36516           d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
36517           c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
36518           b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
36519           a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
36520           d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
36521           c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
36522           b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
36523           a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
36524           d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222);
36525           c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
36526           b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
36527           a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
36528           d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
36529           c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
36530           b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
36531
36532           a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844);
36533           d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
36534           c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
36535           b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
36536           a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
36537           d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
36538           c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
36539           b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
36540           a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
36541           d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
36542           c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
36543           b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
36544           a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
36545           d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
36546           c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
36547           b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
36548
36549           a = safe_add(a, olda);
36550           b = safe_add(b, oldb);
36551           c = safe_add(c, oldc);
36552           d = safe_add(d, oldd);
36553         }
36554         return Array(a, b, c, d);
36555       }
36556
36557       /**
36558        * These functions implement the four basic operations the algorithm uses.
36559        */
36560
36561       function md5_cmn(q, a, b, x, s, t) {
36562         return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
36563       }
36564
36565       function md5_ff(a, b, c, d, x, s, t) {
36566         return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
36567       }
36568
36569       function md5_gg(a, b, c, d, x, s, t) {
36570         return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
36571       }
36572
36573       function md5_hh(a, b, c, d, x, s, t) {
36574         return md5_cmn(b ^ c ^ d, a, b, x, s, t);
36575       }
36576
36577       function md5_ii(a, b, c, d, x, s, t) {
36578         return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
36579       }
36580     },
36581     /**
36582      * @member Hashes
36583      * @class Hashes.SHA1
36584      * @param {Object} [config]
36585      * @constructor
36586      *
36587      * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined in FIPS 180-1
36588      * Version 2.2 Copyright Paul Johnston 2000 - 2009.
36589      * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
36590      * See http://pajhome.org.uk/crypt/md5 for details.
36591      */
36592     SHA1: function(options) {
36593       /**
36594        * Private config properties. You may need to tweak these to be compatible with
36595        * the server-side, but the defaults work in most cases.
36596        * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase}
36597        */
36598       var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase
36599         b64pad = (options && typeof options.pad === 'string') ? options.pad : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance
36600         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding
36601
36602       // public methods
36603       this.hex = function(s) {
36604         return rstr2hex(rstr(s, utf8), hexcase);
36605       };
36606       this.b64 = function(s) {
36607         return rstr2b64(rstr(s, utf8), b64pad);
36608       };
36609       this.any = function(s, e) {
36610         return rstr2any(rstr(s, utf8), e);
36611       };
36612       this.raw = function(s) {
36613         return rstr(s, utf8);
36614       };
36615       this.hex_hmac = function(k, d) {
36616         return rstr2hex(rstr_hmac(k, d));
36617       };
36618       this.b64_hmac = function(k, d) {
36619         return rstr2b64(rstr_hmac(k, d), b64pad);
36620       };
36621       this.any_hmac = function(k, d, e) {
36622         return rstr2any(rstr_hmac(k, d), e);
36623       };
36624       /**
36625        * Perform a simple self-test to see if the VM is working
36626        * @return {String} Hexadecimal hash sample
36627        * @public
36628        */
36629       this.vm_test = function() {
36630         return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
36631       };
36632       /**
36633        * @description Enable/disable uppercase hexadecimal returned string
36634        * @param {boolean}
36635        * @return {Object} this
36636        * @public
36637        */
36638       this.setUpperCase = function(a) {
36639         if (typeof a === 'boolean') {
36640           hexcase = a;
36641         }
36642         return this;
36643       };
36644       /**
36645        * @description Defines a base64 pad string
36646        * @param {string} Pad
36647        * @return {Object} this
36648        * @public
36649        */
36650       this.setPad = function(a) {
36651         b64pad = a || b64pad;
36652         return this;
36653       };
36654       /**
36655        * @description Defines a base64 pad string
36656        * @param {boolean}
36657        * @return {Object} this
36658        * @public
36659        */
36660       this.setUTF8 = function(a) {
36661         if (typeof a === 'boolean') {
36662           utf8 = a;
36663         }
36664         return this;
36665       };
36666
36667       // private methods
36668
36669       /**
36670        * Calculate the SHA-512 of a raw string
36671        */
36672
36673       function rstr(s) {
36674         s = (utf8) ? utf8Encode(s) : s;
36675         return binb2rstr(binb(rstr2binb(s), s.length * 8));
36676       }
36677
36678       /**
36679        * Calculate the HMAC-SHA1 of a key and some data (raw strings)
36680        */
36681
36682       function rstr_hmac(key, data) {
36683         var bkey, ipad, opad, i, hash;
36684         key = (utf8) ? utf8Encode(key) : key;
36685         data = (utf8) ? utf8Encode(data) : data;
36686         bkey = rstr2binb(key);
36687
36688         if (bkey.length > 16) {
36689           bkey = binb(bkey, key.length * 8);
36690         }
36691         ipad = Array(16), opad = Array(16);
36692         for (i = 0; i < 16; i += 1) {
36693           ipad[i] = bkey[i] ^ 0x36363636;
36694           opad[i] = bkey[i] ^ 0x5C5C5C5C;
36695         }
36696         hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
36697         return binb2rstr(binb(opad.concat(hash), 512 + 160));
36698       }
36699
36700       /**
36701        * Calculate the SHA-1 of an array of big-endian words, and a bit length
36702        */
36703
36704       function binb(x, len) {
36705         var i, j, t, olda, oldb, oldc, oldd, olde,
36706           w = Array(80),
36707           a = 1732584193,
36708           b = -271733879,
36709           c = -1732584194,
36710           d = 271733878,
36711           e = -1009589776;
36712
36713         /* append padding */
36714         x[len >> 5] |= 0x80 << (24 - len % 32);
36715         x[((len + 64 >> 9) << 4) + 15] = len;
36716
36717         for (i = 0; i < x.length; i += 16) {
36718           olda = a;
36719           oldb = b;
36720           oldc = c;
36721           oldd = d;
36722           olde = e;
36723
36724           for (j = 0; j < 80; j += 1) {
36725             if (j < 16) {
36726               w[j] = x[i + j];
36727             } else {
36728               w[j] = bit_rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
36729             }
36730             t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
36731               safe_add(safe_add(e, w[j]), sha1_kt(j)));
36732             e = d;
36733             d = c;
36734             c = bit_rol(b, 30);
36735             b = a;
36736             a = t;
36737           }
36738
36739           a = safe_add(a, olda);
36740           b = safe_add(b, oldb);
36741           c = safe_add(c, oldc);
36742           d = safe_add(d, oldd);
36743           e = safe_add(e, olde);
36744         }
36745         return Array(a, b, c, d, e);
36746       }
36747
36748       /**
36749        * Perform the appropriate triplet combination function for the current
36750        * iteration
36751        */
36752
36753       function sha1_ft(t, b, c, d) {
36754         if (t < 20) {
36755           return (b & c) | ((~b) & d);
36756         }
36757         if (t < 40) {
36758           return b ^ c ^ d;
36759         }
36760         if (t < 60) {
36761           return (b & c) | (b & d) | (c & d);
36762         }
36763         return b ^ c ^ d;
36764       }
36765
36766       /**
36767        * Determine the appropriate additive constant for the current iteration
36768        */
36769
36770       function sha1_kt(t) {
36771         return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
36772           (t < 60) ? -1894007588 : -899497514;
36773       }
36774     },
36775     /**
36776      * @class Hashes.SHA256
36777      * @param {config}
36778      *
36779      * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined in FIPS 180-2
36780      * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009.
36781      * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
36782      * See http://pajhome.org.uk/crypt/md5 for details.
36783      * Also http://anmar.eu.org/projects/jssha2/
36784      */
36785     SHA256: function(options) {
36786       /**
36787        * Private properties configuration variables. You may need to tweak these to be compatible with
36788        * the server-side, but the defaults work in most cases.
36789        * @see this.setUpperCase() method
36790        * @see this.setPad() method
36791        */
36792       var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase  */
36793         b64pad = (options && typeof options.pad === 'string') ? options.pad : '=',
36794         /* base-64 pad character. Default '=' for strict RFC compliance   */
36795         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
36796         /* enable/disable utf8 encoding */
36797         sha256_K;
36798
36799       /* privileged (public) methods */
36800       this.hex = function(s) {
36801         return rstr2hex(rstr(s, utf8));
36802       };
36803       this.b64 = function(s) {
36804         return rstr2b64(rstr(s, utf8), b64pad);
36805       };
36806       this.any = function(s, e) {
36807         return rstr2any(rstr(s, utf8), e);
36808       };
36809       this.raw = function(s) {
36810         return rstr(s, utf8);
36811       };
36812       this.hex_hmac = function(k, d) {
36813         return rstr2hex(rstr_hmac(k, d));
36814       };
36815       this.b64_hmac = function(k, d) {
36816         return rstr2b64(rstr_hmac(k, d), b64pad);
36817       };
36818       this.any_hmac = function(k, d, e) {
36819         return rstr2any(rstr_hmac(k, d), e);
36820       };
36821       /**
36822        * Perform a simple self-test to see if the VM is working
36823        * @return {String} Hexadecimal hash sample
36824        * @public
36825        */
36826       this.vm_test = function() {
36827         return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
36828       };
36829       /**
36830        * Enable/disable uppercase hexadecimal returned string
36831        * @param {boolean}
36832        * @return {Object} this
36833        * @public
36834        */
36835       this.setUpperCase = function(a) {
36836         if (typeof a === 'boolean') {
36837           hexcase = a;
36838         }
36839         return this;
36840       };
36841       /**
36842        * @description Defines a base64 pad string
36843        * @param {string} Pad
36844        * @return {Object} this
36845        * @public
36846        */
36847       this.setPad = function(a) {
36848         b64pad = a || b64pad;
36849         return this;
36850       };
36851       /**
36852        * Defines a base64 pad string
36853        * @param {boolean}
36854        * @return {Object} this
36855        * @public
36856        */
36857       this.setUTF8 = function(a) {
36858         if (typeof a === 'boolean') {
36859           utf8 = a;
36860         }
36861         return this;
36862       };
36863
36864       // private methods
36865
36866       /**
36867        * Calculate the SHA-512 of a raw string
36868        */
36869
36870       function rstr(s, utf8) {
36871         s = (utf8) ? utf8Encode(s) : s;
36872         return binb2rstr(binb(rstr2binb(s), s.length * 8));
36873       }
36874
36875       /**
36876        * Calculate the HMAC-sha256 of a key and some data (raw strings)
36877        */
36878
36879       function rstr_hmac(key, data) {
36880         key = (utf8) ? utf8Encode(key) : key;
36881         data = (utf8) ? utf8Encode(data) : data;
36882         var hash, i = 0,
36883           bkey = rstr2binb(key),
36884           ipad = Array(16),
36885           opad = Array(16);
36886
36887         if (bkey.length > 16) {
36888           bkey = binb(bkey, key.length * 8);
36889         }
36890
36891         for (; i < 16; i += 1) {
36892           ipad[i] = bkey[i] ^ 0x36363636;
36893           opad[i] = bkey[i] ^ 0x5C5C5C5C;
36894         }
36895
36896         hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
36897         return binb2rstr(binb(opad.concat(hash), 512 + 256));
36898       }
36899
36900       /*
36901        * Main sha256 function, with its support functions
36902        */
36903
36904       function sha256_S(X, n) {
36905         return (X >>> n) | (X << (32 - n));
36906       }
36907
36908       function sha256_R(X, n) {
36909         return (X >>> n);
36910       }
36911
36912       function sha256_Ch(x, y, z) {
36913         return ((x & y) ^ ((~x) & z));
36914       }
36915
36916       function sha256_Maj(x, y, z) {
36917         return ((x & y) ^ (x & z) ^ (y & z));
36918       }
36919
36920       function sha256_Sigma0256(x) {
36921         return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));
36922       }
36923
36924       function sha256_Sigma1256(x) {
36925         return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));
36926       }
36927
36928       function sha256_Gamma0256(x) {
36929         return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));
36930       }
36931
36932       function sha256_Gamma1256(x) {
36933         return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));
36934       }
36935
36936       sha256_K = [
36937         1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993, -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987,
36938         1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522,
36939         264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585,
36940         113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291,
36941         1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885, -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344,
36942         430227734, 506948616, 659060556, 883997877, 958139571, 1322822218,
36943         1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872, -1866530822, -1538233109, -1090935817, -965641998
36944       ];
36945
36946       function binb(m, l) {
36947         var HASH = [1779033703, -1150833019, 1013904242, -1521486534,
36948           1359893119, -1694144372, 528734635, 1541459225
36949         ];
36950         var W = new Array(64);
36951         var a, b, c, d, e, f, g, h;
36952         var i, j, T1, T2;
36953
36954         /* append padding */
36955         m[l >> 5] |= 0x80 << (24 - l % 32);
36956         m[((l + 64 >> 9) << 4) + 15] = l;
36957
36958         for (i = 0; i < m.length; i += 16) {
36959           a = HASH[0];
36960           b = HASH[1];
36961           c = HASH[2];
36962           d = HASH[3];
36963           e = HASH[4];
36964           f = HASH[5];
36965           g = HASH[6];
36966           h = HASH[7];
36967
36968           for (j = 0; j < 64; j += 1) {
36969             if (j < 16) {
36970               W[j] = m[j + i];
36971             } else {
36972               W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]),
36973                 sha256_Gamma0256(W[j - 15])), W[j - 16]);
36974             }
36975
36976             T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)),
36977               sha256_K[j]), W[j]);
36978             T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c));
36979             h = g;
36980             g = f;
36981             f = e;
36982             e = safe_add(d, T1);
36983             d = c;
36984             c = b;
36985             b = a;
36986             a = safe_add(T1, T2);
36987           }
36988
36989           HASH[0] = safe_add(a, HASH[0]);
36990           HASH[1] = safe_add(b, HASH[1]);
36991           HASH[2] = safe_add(c, HASH[2]);
36992           HASH[3] = safe_add(d, HASH[3]);
36993           HASH[4] = safe_add(e, HASH[4]);
36994           HASH[5] = safe_add(f, HASH[5]);
36995           HASH[6] = safe_add(g, HASH[6]);
36996           HASH[7] = safe_add(h, HASH[7]);
36997         }
36998         return HASH;
36999       }
37000
37001     },
37002
37003     /**
37004      * @class Hashes.SHA512
37005      * @param {config}
37006      *
37007      * A JavaScript implementation of the Secure Hash Algorithm, SHA-512, as defined in FIPS 180-2
37008      * Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009.
37009      * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
37010      * See http://pajhome.org.uk/crypt/md5 for details.
37011      */
37012     SHA512: function(options) {
37013       /**
37014        * Private properties configuration variables. You may need to tweak these to be compatible with
37015        * the server-side, but the defaults work in most cases.
37016        * @see this.setUpperCase() method
37017        * @see this.setPad() method
37018        */
37019       var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false,
37020         /* hexadecimal output case format. false - lowercase; true - uppercase  */
37021         b64pad = (options && typeof options.pad === 'string') ? options.pad : '=',
37022         /* base-64 pad character. Default '=' for strict RFC compliance   */
37023         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
37024         /* enable/disable utf8 encoding */
37025         sha512_k;
37026
37027       /* privileged (public) methods */
37028       this.hex = function(s) {
37029         return rstr2hex(rstr(s));
37030       };
37031       this.b64 = function(s) {
37032         return rstr2b64(rstr(s), b64pad);
37033       };
37034       this.any = function(s, e) {
37035         return rstr2any(rstr(s), e);
37036       };
37037       this.raw = function(s) {
37038         return rstr(s, utf8);
37039       };
37040       this.hex_hmac = function(k, d) {
37041         return rstr2hex(rstr_hmac(k, d));
37042       };
37043       this.b64_hmac = function(k, d) {
37044         return rstr2b64(rstr_hmac(k, d), b64pad);
37045       };
37046       this.any_hmac = function(k, d, e) {
37047         return rstr2any(rstr_hmac(k, d), e);
37048       };
37049       /**
37050        * Perform a simple self-test to see if the VM is working
37051        * @return {String} Hexadecimal hash sample
37052        * @public
37053        */
37054       this.vm_test = function() {
37055         return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
37056       };
37057       /**
37058        * @description Enable/disable uppercase hexadecimal returned string
37059        * @param {boolean}
37060        * @return {Object} this
37061        * @public
37062        */
37063       this.setUpperCase = function(a) {
37064         if (typeof a === 'boolean') {
37065           hexcase = a;
37066         }
37067         return this;
37068       };
37069       /**
37070        * @description Defines a base64 pad string
37071        * @param {string} Pad
37072        * @return {Object} this
37073        * @public
37074        */
37075       this.setPad = function(a) {
37076         b64pad = a || b64pad;
37077         return this;
37078       };
37079       /**
37080        * @description Defines a base64 pad string
37081        * @param {boolean}
37082        * @return {Object} this
37083        * @public
37084        */
37085       this.setUTF8 = function(a) {
37086         if (typeof a === 'boolean') {
37087           utf8 = a;
37088         }
37089         return this;
37090       };
37091
37092       /* private methods */
37093
37094       /**
37095        * Calculate the SHA-512 of a raw string
37096        */
37097
37098       function rstr(s) {
37099         s = (utf8) ? utf8Encode(s) : s;
37100         return binb2rstr(binb(rstr2binb(s), s.length * 8));
37101       }
37102       /*
37103        * Calculate the HMAC-SHA-512 of a key and some data (raw strings)
37104        */
37105
37106       function rstr_hmac(key, data) {
37107         key = (utf8) ? utf8Encode(key) : key;
37108         data = (utf8) ? utf8Encode(data) : data;
37109
37110         var hash, i = 0,
37111           bkey = rstr2binb(key),
37112           ipad = Array(32),
37113           opad = Array(32);
37114
37115         if (bkey.length > 32) {
37116           bkey = binb(bkey, key.length * 8);
37117         }
37118
37119         for (; i < 32; i += 1) {
37120           ipad[i] = bkey[i] ^ 0x36363636;
37121           opad[i] = bkey[i] ^ 0x5C5C5C5C;
37122         }
37123
37124         hash = binb(ipad.concat(rstr2binb(data)), 1024 + data.length * 8);
37125         return binb2rstr(binb(opad.concat(hash), 1024 + 512));
37126       }
37127
37128       /**
37129        * Calculate the SHA-512 of an array of big-endian dwords, and a bit length
37130        */
37131
37132       function binb(x, len) {
37133         var j, i, l,
37134           W = new Array(80),
37135           hash = new Array(16),
37136           //Initial hash values
37137           H = [
37138             new int64(0x6a09e667, -205731576),
37139             new int64(-1150833019, -2067093701),
37140             new int64(0x3c6ef372, -23791573),
37141             new int64(-1521486534, 0x5f1d36f1),
37142             new int64(0x510e527f, -1377402159),
37143             new int64(-1694144372, 0x2b3e6c1f),
37144             new int64(0x1f83d9ab, -79577749),
37145             new int64(0x5be0cd19, 0x137e2179)
37146           ],
37147           T1 = new int64(0, 0),
37148           T2 = new int64(0, 0),
37149           a = new int64(0, 0),
37150           b = new int64(0, 0),
37151           c = new int64(0, 0),
37152           d = new int64(0, 0),
37153           e = new int64(0, 0),
37154           f = new int64(0, 0),
37155           g = new int64(0, 0),
37156           h = new int64(0, 0),
37157           //Temporary variables not specified by the document
37158           s0 = new int64(0, 0),
37159           s1 = new int64(0, 0),
37160           Ch = new int64(0, 0),
37161           Maj = new int64(0, 0),
37162           r1 = new int64(0, 0),
37163           r2 = new int64(0, 0),
37164           r3 = new int64(0, 0);
37165
37166         if (sha512_k === undefined) {
37167           //SHA512 constants
37168           sha512_k = [
37169             new int64(0x428a2f98, -685199838), new int64(0x71374491, 0x23ef65cd),
37170             new int64(-1245643825, -330482897), new int64(-373957723, -2121671748),
37171             new int64(0x3956c25b, -213338824), new int64(0x59f111f1, -1241133031),
37172             new int64(-1841331548, -1357295717), new int64(-1424204075, -630357736),
37173             new int64(-670586216, -1560083902), new int64(0x12835b01, 0x45706fbe),
37174             new int64(0x243185be, 0x4ee4b28c), new int64(0x550c7dc3, -704662302),
37175             new int64(0x72be5d74, -226784913), new int64(-2132889090, 0x3b1696b1),
37176             new int64(-1680079193, 0x25c71235), new int64(-1046744716, -815192428),
37177             new int64(-459576895, -1628353838), new int64(-272742522, 0x384f25e3),
37178             new int64(0xfc19dc6, -1953704523), new int64(0x240ca1cc, 0x77ac9c65),
37179             new int64(0x2de92c6f, 0x592b0275), new int64(0x4a7484aa, 0x6ea6e483),
37180             new int64(0x5cb0a9dc, -1119749164), new int64(0x76f988da, -2096016459),
37181             new int64(-1740746414, -295247957), new int64(-1473132947, 0x2db43210),
37182             new int64(-1341970488, -1728372417), new int64(-1084653625, -1091629340),
37183             new int64(-958395405, 0x3da88fc2), new int64(-710438585, -1828018395),
37184             new int64(0x6ca6351, -536640913), new int64(0x14292967, 0xa0e6e70),
37185             new int64(0x27b70a85, 0x46d22ffc), new int64(0x2e1b2138, 0x5c26c926),
37186             new int64(0x4d2c6dfc, 0x5ac42aed), new int64(0x53380d13, -1651133473),
37187             new int64(0x650a7354, -1951439906), new int64(0x766a0abb, 0x3c77b2a8),
37188             new int64(-2117940946, 0x47edaee6), new int64(-1838011259, 0x1482353b),
37189             new int64(-1564481375, 0x4cf10364), new int64(-1474664885, -1136513023),
37190             new int64(-1035236496, -789014639), new int64(-949202525, 0x654be30),
37191             new int64(-778901479, -688958952), new int64(-694614492, 0x5565a910),
37192             new int64(-200395387, 0x5771202a), new int64(0x106aa070, 0x32bbd1b8),
37193             new int64(0x19a4c116, -1194143544), new int64(0x1e376c08, 0x5141ab53),
37194             new int64(0x2748774c, -544281703), new int64(0x34b0bcb5, -509917016),
37195             new int64(0x391c0cb3, -976659869), new int64(0x4ed8aa4a, -482243893),
37196             new int64(0x5b9cca4f, 0x7763e373), new int64(0x682e6ff3, -692930397),
37197             new int64(0x748f82ee, 0x5defb2fc), new int64(0x78a5636f, 0x43172f60),
37198             new int64(-2067236844, -1578062990), new int64(-1933114872, 0x1a6439ec),
37199             new int64(-1866530822, 0x23631e28), new int64(-1538233109, -561857047),
37200             new int64(-1090935817, -1295615723), new int64(-965641998, -479046869),
37201             new int64(-903397682, -366583396), new int64(-779700025, 0x21c0c207),
37202             new int64(-354779690, -840897762), new int64(-176337025, -294727304),
37203             new int64(0x6f067aa, 0x72176fba), new int64(0xa637dc5, -1563912026),
37204             new int64(0x113f9804, -1090974290), new int64(0x1b710b35, 0x131c471b),
37205             new int64(0x28db77f5, 0x23047d84), new int64(0x32caab7b, 0x40c72493),
37206             new int64(0x3c9ebe0a, 0x15c9bebc), new int64(0x431d67c4, -1676669620),
37207             new int64(0x4cc5d4be, -885112138), new int64(0x597f299c, -60457430),
37208             new int64(0x5fcb6fab, 0x3ad6faec), new int64(0x6c44198c, 0x4a475817)
37209           ];
37210         }
37211
37212         for (i = 0; i < 80; i += 1) {
37213           W[i] = new int64(0, 0);
37214         }
37215
37216         // append padding to the source string. The format is described in the FIPS.
37217         x[len >> 5] |= 0x80 << (24 - (len & 0x1f));
37218         x[((len + 128 >> 10) << 5) + 31] = len;
37219         l = x.length;
37220         for (i = 0; i < l; i += 32) { //32 dwords is the block size
37221           int64copy(a, H[0]);
37222           int64copy(b, H[1]);
37223           int64copy(c, H[2]);
37224           int64copy(d, H[3]);
37225           int64copy(e, H[4]);
37226           int64copy(f, H[5]);
37227           int64copy(g, H[6]);
37228           int64copy(h, H[7]);
37229
37230           for (j = 0; j < 16; j += 1) {
37231             W[j].h = x[i + 2 * j];
37232             W[j].l = x[i + 2 * j + 1];
37233           }
37234
37235           for (j = 16; j < 80; j += 1) {
37236             //sigma1
37237             int64rrot(r1, W[j - 2], 19);
37238             int64revrrot(r2, W[j - 2], 29);
37239             int64shr(r3, W[j - 2], 6);
37240             s1.l = r1.l ^ r2.l ^ r3.l;
37241             s1.h = r1.h ^ r2.h ^ r3.h;
37242             //sigma0
37243             int64rrot(r1, W[j - 15], 1);
37244             int64rrot(r2, W[j - 15], 8);
37245             int64shr(r3, W[j - 15], 7);
37246             s0.l = r1.l ^ r2.l ^ r3.l;
37247             s0.h = r1.h ^ r2.h ^ r3.h;
37248
37249             int64add4(W[j], s1, W[j - 7], s0, W[j - 16]);
37250           }
37251
37252           for (j = 0; j < 80; j += 1) {
37253             //Ch
37254             Ch.l = (e.l & f.l) ^ (~e.l & g.l);
37255             Ch.h = (e.h & f.h) ^ (~e.h & g.h);
37256
37257             //Sigma1
37258             int64rrot(r1, e, 14);
37259             int64rrot(r2, e, 18);
37260             int64revrrot(r3, e, 9);
37261             s1.l = r1.l ^ r2.l ^ r3.l;
37262             s1.h = r1.h ^ r2.h ^ r3.h;
37263
37264             //Sigma0
37265             int64rrot(r1, a, 28);
37266             int64revrrot(r2, a, 2);
37267             int64revrrot(r3, a, 7);
37268             s0.l = r1.l ^ r2.l ^ r3.l;
37269             s0.h = r1.h ^ r2.h ^ r3.h;
37270
37271             //Maj
37272             Maj.l = (a.l & b.l) ^ (a.l & c.l) ^ (b.l & c.l);
37273             Maj.h = (a.h & b.h) ^ (a.h & c.h) ^ (b.h & c.h);
37274
37275             int64add5(T1, h, s1, Ch, sha512_k[j], W[j]);
37276             int64add(T2, s0, Maj);
37277
37278             int64copy(h, g);
37279             int64copy(g, f);
37280             int64copy(f, e);
37281             int64add(e, d, T1);
37282             int64copy(d, c);
37283             int64copy(c, b);
37284             int64copy(b, a);
37285             int64add(a, T1, T2);
37286           }
37287           int64add(H[0], H[0], a);
37288           int64add(H[1], H[1], b);
37289           int64add(H[2], H[2], c);
37290           int64add(H[3], H[3], d);
37291           int64add(H[4], H[4], e);
37292           int64add(H[5], H[5], f);
37293           int64add(H[6], H[6], g);
37294           int64add(H[7], H[7], h);
37295         }
37296
37297         //represent the hash as an array of 32-bit dwords
37298         for (i = 0; i < 8; i += 1) {
37299           hash[2 * i] = H[i].h;
37300           hash[2 * i + 1] = H[i].l;
37301         }
37302         return hash;
37303       }
37304
37305       //A constructor for 64-bit numbers
37306
37307       function int64(h, l) {
37308         this.h = h;
37309         this.l = l;
37310         //this.toString = int64toString;
37311       }
37312
37313       //Copies src into dst, assuming both are 64-bit numbers
37314
37315       function int64copy(dst, src) {
37316         dst.h = src.h;
37317         dst.l = src.l;
37318       }
37319
37320       //Right-rotates a 64-bit number by shift
37321       //Won't handle cases of shift>=32
37322       //The function revrrot() is for that
37323
37324       function int64rrot(dst, x, shift) {
37325         dst.l = (x.l >>> shift) | (x.h << (32 - shift));
37326         dst.h = (x.h >>> shift) | (x.l << (32 - shift));
37327       }
37328
37329       //Reverses the dwords of the source and then rotates right by shift.
37330       //This is equivalent to rotation by 32+shift
37331
37332       function int64revrrot(dst, x, shift) {
37333         dst.l = (x.h >>> shift) | (x.l << (32 - shift));
37334         dst.h = (x.l >>> shift) | (x.h << (32 - shift));
37335       }
37336
37337       //Bitwise-shifts right a 64-bit number by shift
37338       //Won't handle shift>=32, but it's never needed in SHA512
37339
37340       function int64shr(dst, x, shift) {
37341         dst.l = (x.l >>> shift) | (x.h << (32 - shift));
37342         dst.h = (x.h >>> shift);
37343       }
37344
37345       //Adds two 64-bit numbers
37346       //Like the original implementation, does not rely on 32-bit operations
37347
37348       function int64add(dst, x, y) {
37349         var w0 = (x.l & 0xffff) + (y.l & 0xffff);
37350         var w1 = (x.l >>> 16) + (y.l >>> 16) + (w0 >>> 16);
37351         var w2 = (x.h & 0xffff) + (y.h & 0xffff) + (w1 >>> 16);
37352         var w3 = (x.h >>> 16) + (y.h >>> 16) + (w2 >>> 16);
37353         dst.l = (w0 & 0xffff) | (w1 << 16);
37354         dst.h = (w2 & 0xffff) | (w3 << 16);
37355       }
37356
37357       //Same, except with 4 addends. Works faster than adding them one by one.
37358
37359       function int64add4(dst, a, b, c, d) {
37360         var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff);
37361         var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (w0 >>> 16);
37362         var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (w1 >>> 16);
37363         var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (w2 >>> 16);
37364         dst.l = (w0 & 0xffff) | (w1 << 16);
37365         dst.h = (w2 & 0xffff) | (w3 << 16);
37366       }
37367
37368       //Same, except with 5 addends
37369
37370       function int64add5(dst, a, b, c, d, e) {
37371         var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff) + (e.l & 0xffff),
37372           w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (e.l >>> 16) + (w0 >>> 16),
37373           w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (e.h & 0xffff) + (w1 >>> 16),
37374           w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (e.h >>> 16) + (w2 >>> 16);
37375         dst.l = (w0 & 0xffff) | (w1 << 16);
37376         dst.h = (w2 & 0xffff) | (w3 << 16);
37377       }
37378     },
37379     /**
37380      * @class Hashes.RMD160
37381      * @constructor
37382      * @param {Object} [config]
37383      *
37384      * A JavaScript implementation of the RIPEMD-160 Algorithm
37385      * Version 2.2 Copyright Jeremy Lin, Paul Johnston 2000 - 2009.
37386      * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
37387      * See http://pajhome.org.uk/crypt/md5 for details.
37388      * Also http://www.ocf.berkeley.edu/~jjlin/jsotp/
37389      */
37390     RMD160: function(options) {
37391       /**
37392        * Private properties configuration variables. You may need to tweak these to be compatible with
37393        * the server-side, but the defaults work in most cases.
37394        * @see this.setUpperCase() method
37395        * @see this.setPad() method
37396        */
37397       var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false,
37398         /* hexadecimal output case format. false - lowercase; true - uppercase  */
37399         b64pad = (options && typeof options.pad === 'string') ? options.pa : '=',
37400         /* base-64 pad character. Default '=' for strict RFC compliance   */
37401         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
37402         /* enable/disable utf8 encoding */
37403         rmd160_r1 = [
37404           0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
37405           7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
37406           3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
37407           1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
37408           4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
37409         ],
37410         rmd160_r2 = [
37411           5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
37412           6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
37413           15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
37414           8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
37415           12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
37416         ],
37417         rmd160_s1 = [
37418           11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
37419           7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
37420           11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
37421           11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
37422           9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
37423         ],
37424         rmd160_s2 = [
37425           8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
37426           9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
37427           9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
37428           15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
37429           8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
37430         ];
37431
37432       /* privileged (public) methods */
37433       this.hex = function(s) {
37434         return rstr2hex(rstr(s, utf8));
37435       };
37436       this.b64 = function(s) {
37437         return rstr2b64(rstr(s, utf8), b64pad);
37438       };
37439       this.any = function(s, e) {
37440         return rstr2any(rstr(s, utf8), e);
37441       };
37442       this.raw = function(s) {
37443         return rstr(s, utf8);
37444       };
37445       this.hex_hmac = function(k, d) {
37446         return rstr2hex(rstr_hmac(k, d));
37447       };
37448       this.b64_hmac = function(k, d) {
37449         return rstr2b64(rstr_hmac(k, d), b64pad);
37450       };
37451       this.any_hmac = function(k, d, e) {
37452         return rstr2any(rstr_hmac(k, d), e);
37453       };
37454       /**
37455        * Perform a simple self-test to see if the VM is working
37456        * @return {String} Hexadecimal hash sample
37457        * @public
37458        */
37459       this.vm_test = function() {
37460         return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
37461       };
37462       /**
37463        * @description Enable/disable uppercase hexadecimal returned string
37464        * @param {boolean}
37465        * @return {Object} this
37466        * @public
37467        */
37468       this.setUpperCase = function(a) {
37469         if (typeof a === 'boolean') {
37470           hexcase = a;
37471         }
37472         return this;
37473       };
37474       /**
37475        * @description Defines a base64 pad string
37476        * @param {string} Pad
37477        * @return {Object} this
37478        * @public
37479        */
37480       this.setPad = function(a) {
37481         if (typeof a !== 'undefined') {
37482           b64pad = a;
37483         }
37484         return this;
37485       };
37486       /**
37487        * @description Defines a base64 pad string
37488        * @param {boolean}
37489        * @return {Object} this
37490        * @public
37491        */
37492       this.setUTF8 = function(a) {
37493         if (typeof a === 'boolean') {
37494           utf8 = a;
37495         }
37496         return this;
37497       };
37498
37499       /* private methods */
37500
37501       /**
37502        * Calculate the rmd160 of a raw string
37503        */
37504
37505       function rstr(s) {
37506         s = (utf8) ? utf8Encode(s) : s;
37507         return binl2rstr(binl(rstr2binl(s), s.length * 8));
37508       }
37509
37510       /**
37511        * Calculate the HMAC-rmd160 of a key and some data (raw strings)
37512        */
37513
37514       function rstr_hmac(key, data) {
37515         key = (utf8) ? utf8Encode(key) : key;
37516         data = (utf8) ? utf8Encode(data) : data;
37517         var i, hash,
37518           bkey = rstr2binl(key),
37519           ipad = Array(16),
37520           opad = Array(16);
37521
37522         if (bkey.length > 16) {
37523           bkey = binl(bkey, key.length * 8);
37524         }
37525
37526         for (i = 0; i < 16; i += 1) {
37527           ipad[i] = bkey[i] ^ 0x36363636;
37528           opad[i] = bkey[i] ^ 0x5C5C5C5C;
37529         }
37530         hash = binl(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
37531         return binl2rstr(binl(opad.concat(hash), 512 + 160));
37532       }
37533
37534       /**
37535        * Convert an array of little-endian words to a string
37536        */
37537
37538       function binl2rstr(input) {
37539         var i, output = '',
37540           l = input.length * 32;
37541         for (i = 0; i < l; i += 8) {
37542           output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
37543         }
37544         return output;
37545       }
37546
37547       /**
37548        * Calculate the RIPE-MD160 of an array of little-endian words, and a bit length.
37549        */
37550
37551       function binl(x, len) {
37552         var T, j, i, l,
37553           h0 = 0x67452301,
37554           h1 = 0xefcdab89,
37555           h2 = 0x98badcfe,
37556           h3 = 0x10325476,
37557           h4 = 0xc3d2e1f0,
37558           A1, B1, C1, D1, E1,
37559           A2, B2, C2, D2, E2;
37560
37561         /* append padding */
37562         x[len >> 5] |= 0x80 << (len % 32);
37563         x[(((len + 64) >>> 9) << 4) + 14] = len;
37564         l = x.length;
37565
37566         for (i = 0; i < l; i += 16) {
37567           A1 = A2 = h0;
37568           B1 = B2 = h1;
37569           C1 = C2 = h2;
37570           D1 = D2 = h3;
37571           E1 = E2 = h4;
37572           for (j = 0; j <= 79; j += 1) {
37573             T = safe_add(A1, rmd160_f(j, B1, C1, D1));
37574             T = safe_add(T, x[i + rmd160_r1[j]]);
37575             T = safe_add(T, rmd160_K1(j));
37576             T = safe_add(bit_rol(T, rmd160_s1[j]), E1);
37577             A1 = E1;
37578             E1 = D1;
37579             D1 = bit_rol(C1, 10);
37580             C1 = B1;
37581             B1 = T;
37582             T = safe_add(A2, rmd160_f(79 - j, B2, C2, D2));
37583             T = safe_add(T, x[i + rmd160_r2[j]]);
37584             T = safe_add(T, rmd160_K2(j));
37585             T = safe_add(bit_rol(T, rmd160_s2[j]), E2);
37586             A2 = E2;
37587             E2 = D2;
37588             D2 = bit_rol(C2, 10);
37589             C2 = B2;
37590             B2 = T;
37591           }
37592
37593           T = safe_add(h1, safe_add(C1, D2));
37594           h1 = safe_add(h2, safe_add(D1, E2));
37595           h2 = safe_add(h3, safe_add(E1, A2));
37596           h3 = safe_add(h4, safe_add(A1, B2));
37597           h4 = safe_add(h0, safe_add(B1, C2));
37598           h0 = T;
37599         }
37600         return [h0, h1, h2, h3, h4];
37601       }
37602
37603       // specific algorithm methods
37604
37605       function rmd160_f(j, x, y, z) {
37606         return (0 <= j && j <= 15) ? (x ^ y ^ z) :
37607           (16 <= j && j <= 31) ? (x & y) | (~x & z) :
37608           (32 <= j && j <= 47) ? (x | ~y) ^ z :
37609           (48 <= j && j <= 63) ? (x & z) | (y & ~z) :
37610           (64 <= j && j <= 79) ? x ^ (y | ~z) :
37611           'rmd160_f: j out of range';
37612       }
37613
37614       function rmd160_K1(j) {
37615         return (0 <= j && j <= 15) ? 0x00000000 :
37616           (16 <= j && j <= 31) ? 0x5a827999 :
37617           (32 <= j && j <= 47) ? 0x6ed9eba1 :
37618           (48 <= j && j <= 63) ? 0x8f1bbcdc :
37619           (64 <= j && j <= 79) ? 0xa953fd4e :
37620           'rmd160_K1: j out of range';
37621       }
37622
37623       function rmd160_K2(j) {
37624         return (0 <= j && j <= 15) ? 0x50a28be6 :
37625           (16 <= j && j <= 31) ? 0x5c4dd124 :
37626           (32 <= j && j <= 47) ? 0x6d703ef3 :
37627           (48 <= j && j <= 63) ? 0x7a6d76e9 :
37628           (64 <= j && j <= 79) ? 0x00000000 :
37629           'rmd160_K2: j out of range';
37630       }
37631     }
37632   };
37633
37634   // exposes Hashes
37635   (function(window, undefined) {
37636     var freeExports = false;
37637     {
37638       freeExports = exports;
37639       if (exports && typeof commonjsGlobal === 'object' && commonjsGlobal && commonjsGlobal === commonjsGlobal.global) {
37640         window = commonjsGlobal;
37641       }
37642     }
37643
37644     if (typeof undefined === 'function' && typeof undefined.amd === 'object' && undefined.amd) {
37645       // define as an anonymous module, so, through path mapping, it can be aliased
37646       undefined(function() {
37647         return Hashes;
37648       });
37649     } else if (freeExports) {
37650       // in Node.js or RingoJS v0.8.0+
37651       if ('object' === 'object' && module && module.exports === freeExports) {
37652         module.exports = Hashes;
37653       }
37654       // in Narwhal or RingoJS v0.7.0-
37655       else {
37656         freeExports.Hashes = Hashes;
37657       }
37658     } else {
37659       // in a browser or Rhino
37660       window.Hashes = Hashes;
37661     }
37662   }(this));
37663 }()); // IIFE
37664 });
37665
37666 var immutable = extend$2;
37667
37668 var hasOwnProperty$16 = Object.prototype.hasOwnProperty;
37669
37670 function extend$2() {
37671     var target = {};
37672
37673     for (var i = 0; i < arguments.length; i++) {
37674         var source = arguments[i];
37675
37676         for (var key in source) {
37677             if (hasOwnProperty$16.call(source, key)) {
37678                 target[key] = source[key];
37679             }
37680         }
37681     }
37682
37683     return target
37684 }
37685
37686 var sha1 = new hashes.SHA1();
37687
37688 var ohauth = {};
37689
37690 ohauth.qsString = function(obj) {
37691     return Object.keys(obj).sort().map(function(key) {
37692         return ohauth.percentEncode(key) + '=' +
37693             ohauth.percentEncode(obj[key]);
37694     }).join('&');
37695 };
37696
37697 ohauth.stringQs = function(str) {
37698     return str.split('&').filter(function (pair) {
37699         return pair !== '';
37700     }).reduce(function(obj, pair){
37701         var parts = pair.split('=');
37702         obj[decodeURIComponent(parts[0])] = (null === parts[1]) ?
37703             '' : decodeURIComponent(parts[1]);
37704         return obj;
37705     }, {});
37706 };
37707
37708 ohauth.rawxhr = function(method, url, data, headers, callback) {
37709     var xhr = new XMLHttpRequest(),
37710         twoHundred = /^20\d$/;
37711     xhr.onreadystatechange = function() {
37712         if (4 === xhr.readyState && 0 !== xhr.status) {
37713             if (twoHundred.test(xhr.status)) callback(null, xhr);
37714             else return callback(xhr, null);
37715         }
37716     };
37717     xhr.onerror = function(e) { return callback(e, null); };
37718     xhr.open(method, url, true);
37719     for (var h in headers) xhr.setRequestHeader(h, headers[h]);
37720     xhr.send(data);
37721     return xhr;
37722 };
37723
37724 ohauth.xhr = function(method, url, auth, data, options, callback) {
37725     var headers = (options && options.header) || {
37726         'Content-Type': 'application/x-www-form-urlencoded'
37727     };
37728     headers.Authorization = 'OAuth ' + ohauth.authHeader(auth);
37729     return ohauth.rawxhr(method, url, data, headers, callback);
37730 };
37731
37732 ohauth.nonce = function() {
37733     for (var o = ''; o.length < 6;) {
37734         o += '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'[Math.floor(Math.random() * 61)];
37735     }
37736     return o;
37737 };
37738
37739 ohauth.authHeader = function(obj) {
37740     return Object.keys(obj).sort().map(function(key) {
37741         return encodeURIComponent(key) + '="' + encodeURIComponent(obj[key]) + '"';
37742     }).join(', ');
37743 };
37744
37745 ohauth.timestamp = function() { return ~~((+new Date()) / 1000); };
37746
37747 ohauth.percentEncode = function(s) {
37748     return encodeURIComponent(s)
37749         .replace(/\!/g, '%21').replace(/\'/g, '%27')
37750         .replace(/\*/g, '%2A').replace(/\(/g, '%28').replace(/\)/g, '%29');
37751 };
37752
37753 ohauth.baseString = function(method, url, params) {
37754     if (params.oauth_signature) delete params.oauth_signature;
37755     return [
37756         method,
37757         ohauth.percentEncode(url),
37758         ohauth.percentEncode(ohauth.qsString(params))].join('&');
37759 };
37760
37761 ohauth.signature = function(oauth_secret, token_secret, baseString) {
37762     return sha1.b64_hmac(
37763         ohauth.percentEncode(oauth_secret) + '&' +
37764         ohauth.percentEncode(token_secret),
37765         baseString);
37766 };
37767
37768 /**
37769  * Takes an options object for configuration (consumer_key,
37770  * consumer_secret, version, signature_method, token, token_secret)
37771  * and returns a function that generates the Authorization header
37772  * for given data.
37773  *
37774  * The returned function takes these parameters:
37775  * - method: GET/POST/...
37776  * - uri: full URI with protocol, port, path and query string
37777  * - extra_params: any extra parameters (that are passed in the POST data),
37778  *   can be an object or a from-urlencoded string.
37779  *
37780  * Returned function returns full OAuth header with "OAuth" string in it.
37781  */
37782
37783 ohauth.headerGenerator = function(options) {
37784     options = options || {};
37785     var consumer_key = options.consumer_key || '',
37786         consumer_secret = options.consumer_secret || '',
37787         signature_method = options.signature_method || 'HMAC-SHA1',
37788         version = options.version || '1.0',
37789         token = options.token || '',
37790         token_secret = options.token_secret || '';
37791
37792     return function(method, uri, extra_params) {
37793         method = method.toUpperCase();
37794         if (typeof extra_params === 'string' && extra_params.length > 0) {
37795             extra_params = ohauth.stringQs(extra_params);
37796         }
37797
37798         var uri_parts = uri.split('?', 2),
37799         base_uri = uri_parts[0];
37800
37801         var query_params = uri_parts.length === 2 ?
37802             ohauth.stringQs(uri_parts[1]) : {};
37803
37804         var oauth_params = {
37805             oauth_consumer_key: consumer_key,
37806             oauth_signature_method: signature_method,
37807             oauth_version: version,
37808             oauth_timestamp: ohauth.timestamp(),
37809             oauth_nonce: ohauth.nonce()
37810         };
37811
37812         if (token) oauth_params.oauth_token = token;
37813
37814         var all_params = immutable({}, oauth_params, query_params, extra_params),
37815             base_str = ohauth.baseString(method, base_uri, all_params);
37816
37817         oauth_params.oauth_signature = ohauth.signature(consumer_secret, token_secret, base_str);
37818
37819         return 'OAuth ' + ohauth.authHeader(oauth_params);
37820     };
37821 };
37822
37823 var ohauth_1 = ohauth;
37824
37825 var resolveUrl = createCommonjsModule(function (module, exports) {
37826 // Copyright 2014 Simon Lydell
37827 // X11 (“MIT”) Licensed. (See LICENSE.)
37828
37829 void (function(root, factory) {
37830   if (typeof undefined === "function" && undefined.amd) {
37831     undefined(factory);
37832   } else {
37833     module.exports = factory();
37834   }
37835 }(commonjsGlobal, function() {
37836
37837   function resolveUrl(/* ...urls */) {
37838     var numUrls = arguments.length;
37839
37840     if (numUrls === 0) {
37841       throw new Error("resolveUrl requires at least one argument; got none.")
37842     }
37843
37844     var base = document.createElement("base");
37845     base.href = arguments[0];
37846
37847     if (numUrls === 1) {
37848       return base.href
37849     }
37850
37851     var head = document.getElementsByTagName("head")[0];
37852     head.insertBefore(base, head.firstChild);
37853
37854     var a = document.createElement("a");
37855     var resolved;
37856
37857     for (var index = 1; index < numUrls; index++) {
37858       a.href = arguments[index];
37859       resolved = a.href;
37860       base.href = resolved;
37861     }
37862
37863     head.removeChild(base);
37864
37865     return resolved
37866   }
37867
37868   return resolveUrl
37869
37870 }));
37871 });
37872
37873 var assign$1 = make_assign();
37874 var create$1 = make_create();
37875 var trim = make_trim();
37876 var Global = (typeof window !== 'undefined' ? window : commonjsGlobal);
37877
37878 var util = {
37879         assign: assign$1,
37880         create: create$1,
37881         trim: trim,
37882         bind: bind,
37883         slice: slice$7,
37884         each: each,
37885         map: map$5,
37886         pluck: pluck,
37887         isList: isList,
37888         isFunction: isFunction$1,
37889         isObject: isObject$1,
37890         Global: Global
37891 };
37892
37893 function make_assign() {
37894         if (Object.assign) {
37895                 return Object.assign
37896         } else {
37897                 return function shimAssign(obj, props1, props2, etc) {
37898                         for (var i = 1; i < arguments.length; i++) {
37899                                 each(Object(arguments[i]), function(val, key) {
37900                                         obj[key] = val;
37901                                 });
37902                         }                       
37903                         return obj
37904                 }
37905         }
37906 }
37907
37908 function make_create() {
37909         if (Object.create) {
37910                 return function create(obj, assignProps1, assignProps2, etc) {
37911                         var assignArgsList = slice$7(arguments, 1);
37912                         return assign$1.apply(this, [Object.create(obj)].concat(assignArgsList))
37913                 }
37914         } else {
37915                 function F() {} // eslint-disable-line no-inner-declarations
37916                 return function create(obj, assignProps1, assignProps2, etc) {
37917                         var assignArgsList = slice$7(arguments, 1);
37918                         F.prototype = obj;
37919                         return assign$1.apply(this, [new F()].concat(assignArgsList))
37920                 }
37921         }
37922 }
37923
37924 function make_trim() {
37925         if (String.prototype.trim) {
37926                 return function trim(str) {
37927                         return String.prototype.trim.call(str)
37928                 }
37929         } else {
37930                 return function trim(str) {
37931                         return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '')
37932                 }
37933         }
37934 }
37935
37936 function bind(obj, fn) {
37937         return function() {
37938                 return fn.apply(obj, Array.prototype.slice.call(arguments, 0))
37939         }
37940 }
37941
37942 function slice$7(arr, index) {
37943         return Array.prototype.slice.call(arr, index || 0)
37944 }
37945
37946 function each(obj, fn) {
37947         pluck(obj, function(val, key) {
37948                 fn(val, key);
37949                 return false
37950         });
37951 }
37952
37953 function map$5(obj, fn) {
37954         var res = (isList(obj) ? [] : {});
37955         pluck(obj, function(v, k) {
37956                 res[k] = fn(v, k);
37957                 return false
37958         });
37959         return res
37960 }
37961
37962 function pluck(obj, fn) {
37963         if (isList(obj)) {
37964                 for (var i=0; i<obj.length; i++) {
37965                         if (fn(obj[i], i)) {
37966                                 return obj[i]
37967                         }
37968                 }
37969         } else {
37970                 for (var key in obj) {
37971                         if (obj.hasOwnProperty(key)) {
37972                                 if (fn(obj[key], key)) {
37973                                         return obj[key]
37974                                 }
37975                         }
37976                 }
37977         }
37978 }
37979
37980 function isList(val) {
37981         return (val != null && typeof val != 'function' && typeof val.length == 'number')
37982 }
37983
37984 function isFunction$1(val) {
37985         return val && {}.toString.call(val) === '[object Function]'
37986 }
37987
37988 function isObject$1(val) {
37989         return val && {}.toString.call(val) === '[object Object]'
37990 }
37991
37992 var slice$8 = util.slice;
37993 var pluck$1 = util.pluck;
37994 var each$1 = util.each;
37995 var bind$1 = util.bind;
37996 var create$2 = util.create;
37997 var isList$1 = util.isList;
37998 var isFunction$2 = util.isFunction;
37999 var isObject$2 = util.isObject;
38000
38001 var storeEngine = {
38002         createStore: createStore
38003 };
38004
38005 var storeAPI = {
38006         version: '2.0.12',
38007         enabled: false,
38008         
38009         // get returns the value of the given key. If that value
38010         // is undefined, it returns optionalDefaultValue instead.
38011         get: function(key, optionalDefaultValue) {
38012                 var data = this.storage.read(this._namespacePrefix + key);
38013                 return this._deserialize(data, optionalDefaultValue)
38014         },
38015
38016         // set will store the given value at key and returns value.
38017         // Calling set with value === undefined is equivalent to calling remove.
38018         set: function(key, value) {
38019                 if (value === undefined) {
38020                         return this.remove(key)
38021                 }
38022                 this.storage.write(this._namespacePrefix + key, this._serialize(value));
38023                 return value
38024         },
38025
38026         // remove deletes the key and value stored at the given key.
38027         remove: function(key) {
38028                 this.storage.remove(this._namespacePrefix + key);
38029         },
38030
38031         // each will call the given callback once for each key-value pair
38032         // in this store.
38033         each: function(callback) {
38034                 var self = this;
38035                 this.storage.each(function(val, namespacedKey) {
38036                         callback.call(self, self._deserialize(val), (namespacedKey || '').replace(self._namespaceRegexp, ''));
38037                 });
38038         },
38039
38040         // clearAll will remove all the stored key-value pairs in this store.
38041         clearAll: function() {
38042                 this.storage.clearAll();
38043         },
38044
38045         // additional functionality that can't live in plugins
38046         // ---------------------------------------------------
38047
38048         // hasNamespace returns true if this store instance has the given namespace.
38049         hasNamespace: function(namespace) {
38050                 return (this._namespacePrefix == '__storejs_'+namespace+'_')
38051         },
38052
38053         // createStore creates a store.js instance with the first
38054         // functioning storage in the list of storage candidates,
38055         // and applies the the given mixins to the instance.
38056         createStore: function() {
38057                 return createStore.apply(this, arguments)
38058         },
38059         
38060         addPlugin: function(plugin) {
38061                 this._addPlugin(plugin);
38062         },
38063         
38064         namespace: function(namespace) {
38065                 return createStore(this.storage, this.plugins, namespace)
38066         }
38067 };
38068
38069 function _warn() {
38070         var _console = (typeof console == 'undefined' ? null : console);
38071         if (!_console) { return }
38072         var fn = (_console.warn ? _console.warn : _console.log);
38073         fn.apply(_console, arguments);
38074 }
38075
38076 function createStore(storages, plugins, namespace) {
38077         if (!namespace) {
38078                 namespace = '';
38079         }
38080         if (storages && !isList$1(storages)) {
38081                 storages = [storages];
38082         }
38083         if (plugins && !isList$1(plugins)) {
38084                 plugins = [plugins];
38085         }
38086
38087         var namespacePrefix = (namespace ? '__storejs_'+namespace+'_' : '');
38088         var namespaceRegexp = (namespace ? new RegExp('^'+namespacePrefix) : null);
38089         var legalNamespaces = /^[a-zA-Z0-9_\-]*$/; // alpha-numeric + underscore and dash
38090         if (!legalNamespaces.test(namespace)) {
38091                 throw new Error('store.js namespaces can only have alphanumerics + underscores and dashes')
38092         }
38093         
38094         var _privateStoreProps = {
38095                 _namespacePrefix: namespacePrefix,
38096                 _namespaceRegexp: namespaceRegexp,
38097
38098                 _testStorage: function(storage) {
38099                         try {
38100                                 var testStr = '__storejs__test__';
38101                                 storage.write(testStr, testStr);
38102                                 var ok = (storage.read(testStr) === testStr);
38103                                 storage.remove(testStr);
38104                                 return ok
38105                         } catch(e) {
38106                                 return false
38107                         }
38108                 },
38109
38110                 _assignPluginFnProp: function(pluginFnProp, propName) {
38111                         var oldFn = this[propName];
38112                         this[propName] = function pluginFn() {
38113                                 var args = slice$8(arguments, 0);
38114                                 var self = this;
38115
38116                                 // super_fn calls the old function which was overwritten by
38117                                 // this mixin.
38118                                 function super_fn() {
38119                                         if (!oldFn) { return }
38120                                         each$1(arguments, function(arg, i) {
38121                                                 args[i] = arg;
38122                                         });
38123                                         return oldFn.apply(self, args)
38124                                 }
38125
38126                                 // Give mixing function access to super_fn by prefixing all mixin function
38127                                 // arguments with super_fn.
38128                                 var newFnArgs = [super_fn].concat(args);
38129
38130                                 return pluginFnProp.apply(self, newFnArgs)
38131                         };
38132                 },
38133
38134                 _serialize: function(obj) {
38135                         return JSON.stringify(obj)
38136                 },
38137
38138                 _deserialize: function(strVal, defaultVal) {
38139                         if (!strVal) { return defaultVal }
38140                         // It is possible that a raw string value has been previously stored
38141                         // in a storage without using store.js, meaning it will be a raw
38142                         // string value instead of a JSON serialized string. By defaulting
38143                         // to the raw string value in case of a JSON parse error, we allow
38144                         // for past stored values to be forwards-compatible with store.js
38145                         var val = '';
38146                         try { val = JSON.parse(strVal); }
38147                         catch(e) { val = strVal; }
38148
38149                         return (val !== undefined ? val : defaultVal)
38150                 },
38151                 
38152                 _addStorage: function(storage) {
38153                         if (this.enabled) { return }
38154                         if (this._testStorage(storage)) {
38155                                 this.storage = storage;
38156                                 this.enabled = true;
38157                         }
38158                 },
38159
38160                 _addPlugin: function(plugin) {
38161                         var self = this;
38162
38163                         // If the plugin is an array, then add all plugins in the array.
38164                         // This allows for a plugin to depend on other plugins.
38165                         if (isList$1(plugin)) {
38166                                 each$1(plugin, function(plugin) {
38167                                         self._addPlugin(plugin);
38168                                 });
38169                                 return
38170                         }
38171
38172                         // Keep track of all plugins we've seen so far, so that we
38173                         // don't add any of them twice.
38174                         var seenPlugin = pluck$1(this.plugins, function(seenPlugin) {
38175                                 return (plugin === seenPlugin)
38176                         });
38177                         if (seenPlugin) {
38178                                 return
38179                         }
38180                         this.plugins.push(plugin);
38181
38182                         // Check that the plugin is properly formed
38183                         if (!isFunction$2(plugin)) {
38184                                 throw new Error('Plugins must be function values that return objects')
38185                         }
38186
38187                         var pluginProperties = plugin.call(this);
38188                         if (!isObject$2(pluginProperties)) {
38189                                 throw new Error('Plugins must return an object of function properties')
38190                         }
38191
38192                         // Add the plugin function properties to this store instance.
38193                         each$1(pluginProperties, function(pluginFnProp, propName) {
38194                                 if (!isFunction$2(pluginFnProp)) {
38195                                         throw new Error('Bad plugin property: '+propName+' from plugin '+plugin.name+'. Plugins should only return functions.')
38196                                 }
38197                                 self._assignPluginFnProp(pluginFnProp, propName);
38198                         });
38199                 },
38200                 
38201                 // Put deprecated properties in the private API, so as to not expose it to accidential
38202                 // discovery through inspection of the store object.
38203                 
38204                 // Deprecated: addStorage
38205                 addStorage: function(storage) {
38206                         _warn('store.addStorage(storage) is deprecated. Use createStore([storages])');
38207                         this._addStorage(storage);
38208                 }
38209         };
38210
38211         var store = create$2(_privateStoreProps, storeAPI, {
38212                 plugins: []
38213         });
38214         store.raw = {};
38215         each$1(store, function(prop, propName) {
38216                 if (isFunction$2(prop)) {
38217                         store.raw[propName] = bind$1(store, prop);                      
38218                 }
38219         });
38220         each$1(storages, function(storage) {
38221                 store._addStorage(storage);
38222         });
38223         each$1(plugins, function(plugin) {
38224                 store._addPlugin(plugin);
38225         });
38226         return store
38227 }
38228
38229 var Global$1 = util.Global;
38230
38231 var localStorage_1 = {
38232         name: 'localStorage',
38233         read: read,
38234         write: write,
38235         each: each$2,
38236         remove: remove$2,
38237         clearAll: clearAll,
38238 };
38239
38240 function localStorage$1() {
38241         return Global$1.localStorage
38242 }
38243
38244 function read(key) {
38245         return localStorage$1().getItem(key)
38246 }
38247
38248 function write(key, data) {
38249         return localStorage$1().setItem(key, data)
38250 }
38251
38252 function each$2(fn) {
38253         for (var i = localStorage$1().length - 1; i >= 0; i--) {
38254                 var key = localStorage$1().key(i);
38255                 fn(read(key), key);
38256         }
38257 }
38258
38259 function remove$2(key) {
38260         return localStorage$1().removeItem(key)
38261 }
38262
38263 function clearAll() {
38264         return localStorage$1().clear()
38265 }
38266
38267 // oldFF-globalStorage provides storage for Firefox
38268 // versions 6 and 7, where no localStorage, etc
38269 // is available.
38270
38271
38272 var Global$2 = util.Global;
38273
38274 var oldFFGlobalStorage = {
38275         name: 'oldFF-globalStorage',
38276         read: read$1,
38277         write: write$1,
38278         each: each$3,
38279         remove: remove$3,
38280         clearAll: clearAll$1,
38281 };
38282
38283 var globalStorage = Global$2.globalStorage;
38284
38285 function read$1(key) {
38286         return globalStorage[key]
38287 }
38288
38289 function write$1(key, data) {
38290         globalStorage[key] = data;
38291 }
38292
38293 function each$3(fn) {
38294         for (var i = globalStorage.length - 1; i >= 0; i--) {
38295                 var key = globalStorage.key(i);
38296                 fn(globalStorage[key], key);
38297         }
38298 }
38299
38300 function remove$3(key) {
38301         return globalStorage.removeItem(key)
38302 }
38303
38304 function clearAll$1() {
38305         each$3(function(key, _) {
38306                 delete globalStorage[key];
38307         });
38308 }
38309
38310 // oldIE-userDataStorage provides storage for Internet Explorer
38311 // versions 6 and 7, where no localStorage, sessionStorage, etc
38312 // is available.
38313
38314
38315 var Global$3 = util.Global;
38316
38317 var oldIEUserDataStorage = {
38318         name: 'oldIE-userDataStorage',
38319         write: write$2,
38320         read: read$2,
38321         each: each$4,
38322         remove: remove$4,
38323         clearAll: clearAll$2,
38324 };
38325
38326 var storageName = 'storejs';
38327 var doc = Global$3.document;
38328 var _withStorageEl = _makeIEStorageElFunction();
38329 var disable = (Global$3.navigator ? Global$3.navigator.userAgent : '').match(/ (MSIE 8|MSIE 9|MSIE 10)\./); // MSIE 9.x, MSIE 10.x
38330
38331 function write$2(unfixedKey, data) {
38332         if (disable) { return }
38333         var fixedKey = fixKey(unfixedKey);
38334         _withStorageEl(function(storageEl) {
38335                 storageEl.setAttribute(fixedKey, data);
38336                 storageEl.save(storageName);
38337         });
38338 }
38339
38340 function read$2(unfixedKey) {
38341         if (disable) { return }
38342         var fixedKey = fixKey(unfixedKey);
38343         var res = null;
38344         _withStorageEl(function(storageEl) {
38345                 res = storageEl.getAttribute(fixedKey);
38346         });
38347         return res
38348 }
38349
38350 function each$4(callback) {
38351         _withStorageEl(function(storageEl) {
38352                 var attributes = storageEl.XMLDocument.documentElement.attributes;
38353                 for (var i=attributes.length-1; i>=0; i--) {
38354                         var attr = attributes[i];
38355                         callback(storageEl.getAttribute(attr.name), attr.name);
38356                 }
38357         });
38358 }
38359
38360 function remove$4(unfixedKey) {
38361         var fixedKey = fixKey(unfixedKey);
38362         _withStorageEl(function(storageEl) {
38363                 storageEl.removeAttribute(fixedKey);
38364                 storageEl.save(storageName);
38365         });
38366 }
38367
38368 function clearAll$2() {
38369         _withStorageEl(function(storageEl) {
38370                 var attributes = storageEl.XMLDocument.documentElement.attributes;
38371                 storageEl.load(storageName);
38372                 for (var i=attributes.length-1; i>=0; i--) {
38373                         storageEl.removeAttribute(attributes[i].name);
38374                 }
38375                 storageEl.save(storageName);
38376         });
38377 }
38378
38379 // Helpers
38380 //////////
38381
38382 // In IE7, keys cannot start with a digit or contain certain chars.
38383 // See https://github.com/marcuswestin/store.js/issues/40
38384 // See https://github.com/marcuswestin/store.js/issues/83
38385 var forbiddenCharsRegex = new RegExp("[!\"#$%&'()*+,/\\\\:;<=>?@[\\]^`{|}~]", "g");
38386 function fixKey(key) {
38387         return key.replace(/^\d/, '___$&').replace(forbiddenCharsRegex, '___')
38388 }
38389
38390 function _makeIEStorageElFunction() {
38391         if (!doc || !doc.documentElement || !doc.documentElement.addBehavior) {
38392                 return null
38393         }
38394         var scriptTag = 'script',
38395                 storageOwner,
38396                 storageContainer,
38397                 storageEl;
38398
38399         // Since #userData storage applies only to specific paths, we need to
38400         // somehow link our data to a specific path.  We choose /favicon.ico
38401         // as a pretty safe option, since all browsers already make a request to
38402         // this URL anyway and being a 404 will not hurt us here.  We wrap an
38403         // iframe pointing to the favicon in an ActiveXObject(htmlfile) object
38404         // (see: http://msdn.microsoft.com/en-us/library/aa752574(v=VS.85).aspx)
38405         // since the iframe access rules appear to allow direct access and
38406         // manipulation of the document element, even for a 404 page.  This
38407         // document can be used instead of the current document (which would
38408         // have been limited to the current path) to perform #userData storage.
38409         try {
38410                 /* global ActiveXObject */
38411                 storageContainer = new ActiveXObject('htmlfile');
38412                 storageContainer.open();
38413                 storageContainer.write('<'+scriptTag+'>document.w=window</'+scriptTag+'><iframe src="/favicon.ico"></iframe>');
38414                 storageContainer.close();
38415                 storageOwner = storageContainer.w.frames[0].document;
38416                 storageEl = storageOwner.createElement('div');
38417         } catch(e) {
38418                 // somehow ActiveXObject instantiation failed (perhaps some special
38419                 // security settings or otherwse), fall back to per-path storage
38420                 storageEl = doc.createElement('div');
38421                 storageOwner = doc.body;
38422         }
38423
38424         return function(storeFunction) {
38425                 var args = [].slice.call(arguments, 0);
38426                 args.unshift(storageEl);
38427                 // See http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx
38428                 // and http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx
38429                 storageOwner.appendChild(storageEl);
38430                 storageEl.addBehavior('#default#userData');
38431                 storageEl.load(storageName);
38432                 storeFunction.apply(this, args);
38433                 storageOwner.removeChild(storageEl);
38434                 return
38435         }
38436 }
38437
38438 // cookieStorage is useful Safari private browser mode, where localStorage
38439 // doesn't work but cookies do. This implementation is adopted from
38440 // https://developer.mozilla.org/en-US/docs/Web/API/Storage/LocalStorage
38441
38442
38443 var Global$4 = util.Global;
38444 var trim$1 = util.trim;
38445
38446 var cookieStorage = {
38447         name: 'cookieStorage',
38448         read: read$3,
38449         write: write$3,
38450         each: each$5,
38451         remove: remove$5,
38452         clearAll: clearAll$3,
38453 };
38454
38455 var doc$1 = Global$4.document;
38456
38457 function read$3(key) {
38458         if (!key || !_has(key)) { return null }
38459         var regexpStr = "(?:^|.*;\\s*)" +
38460                 escape(key).replace(/[\-\.\+\*]/g, "\\$&") +
38461                 "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*";
38462         return unescape(doc$1.cookie.replace(new RegExp(regexpStr), "$1"))
38463 }
38464
38465 function each$5(callback) {
38466         var cookies = doc$1.cookie.split(/; ?/g);
38467         for (var i = cookies.length - 1; i >= 0; i--) {
38468                 if (!trim$1(cookies[i])) {
38469                         continue
38470                 }
38471                 var kvp = cookies[i].split('=');
38472                 var key = unescape(kvp[0]);
38473                 var val = unescape(kvp[1]);
38474                 callback(val, key);
38475         }
38476 }
38477
38478 function write$3(key, data) {
38479         if(!key) { return }
38480         doc$1.cookie = escape(key) + "=" + escape(data) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/";
38481 }
38482
38483 function remove$5(key) {
38484         if (!key || !_has(key)) {
38485                 return
38486         }
38487         doc$1.cookie = escape(key) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
38488 }
38489
38490 function clearAll$3() {
38491         each$5(function(_, key) {
38492                 remove$5(key);
38493         });
38494 }
38495
38496 function _has(key) {
38497         return (new RegExp("(?:^|;\\s*)" + escape(key).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(doc$1.cookie)
38498 }
38499
38500 var Global$5 = util.Global;
38501
38502 var sessionStorage_1 = {
38503         name: 'sessionStorage',
38504         read: read$4,
38505         write: write$4,
38506         each: each$6,
38507         remove: remove$6,
38508         clearAll: clearAll$4
38509 };
38510
38511 function sessionStorage() {
38512         return Global$5.sessionStorage
38513 }
38514
38515 function read$4(key) {
38516         return sessionStorage().getItem(key)
38517 }
38518
38519 function write$4(key, data) {
38520         return sessionStorage().setItem(key, data)
38521 }
38522
38523 function each$6(fn) {
38524         for (var i = sessionStorage().length - 1; i >= 0; i--) {
38525                 var key = sessionStorage().key(i);
38526                 fn(read$4(key), key);
38527         }
38528 }
38529
38530 function remove$6(key) {
38531         return sessionStorage().removeItem(key)
38532 }
38533
38534 function clearAll$4() {
38535         return sessionStorage().clear()
38536 }
38537
38538 // memoryStorage is a useful last fallback to ensure that the store
38539 // is functions (meaning store.get(), store.set(), etc will all function).
38540 // However, stored values will not persist when the browser navigates to
38541 // a new page or reloads the current page.
38542
38543 var memoryStorage_1 = {
38544         name: 'memoryStorage',
38545         read: read$5,
38546         write: write$5,
38547         each: each$7,
38548         remove: remove$7,
38549         clearAll: clearAll$5,
38550 };
38551
38552 var memoryStorage = {};
38553
38554 function read$5(key) {
38555         return memoryStorage[key]
38556 }
38557
38558 function write$5(key, data) {
38559         memoryStorage[key] = data;
38560 }
38561
38562 function each$7(callback) {
38563         for (var key in memoryStorage) {
38564                 if (memoryStorage.hasOwnProperty(key)) {
38565                         callback(memoryStorage[key], key);
38566                 }
38567         }
38568 }
38569
38570 function remove$7(key) {
38571         delete memoryStorage[key];
38572 }
38573
38574 function clearAll$5(key) {
38575         memoryStorage = {};
38576 }
38577
38578 var all$3 = [
38579         // Listed in order of usage preference
38580         localStorage_1,
38581         oldFFGlobalStorage,
38582         oldIEUserDataStorage,
38583         cookieStorage,
38584         sessionStorage_1,
38585         memoryStorage_1
38586 ];
38587
38588 /* eslint-disable */
38589
38590 //  json2.js
38591 //  2016-10-28
38592 //  Public Domain.
38593 //  NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
38594 //  See http://www.JSON.org/js.html
38595 //  This code should be minified before deployment.
38596 //  See http://javascript.crockford.com/jsmin.html
38597
38598 //  USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
38599 //  NOT CONTROL.
38600
38601 //  This file creates a global JSON object containing two methods: stringify
38602 //  and parse. This file provides the ES5 JSON capability to ES3 systems.
38603 //  If a project might run on IE8 or earlier, then this file should be included.
38604 //  This file does nothing on ES5 systems.
38605
38606 //      JSON.stringify(value, replacer, space)
38607 //          value       any JavaScript value, usually an object or array.
38608 //          replacer    an optional parameter that determines how object
38609 //                      values are stringified for objects. It can be a
38610 //                      function or an array of strings.
38611 //          space       an optional parameter that specifies the indentation
38612 //                      of nested structures. If it is omitted, the text will
38613 //                      be packed without extra whitespace. If it is a number,
38614 //                      it will specify the number of spaces to indent at each
38615 //                      level. If it is a string (such as "\t" or "&nbsp;"),
38616 //                      it contains the characters used to indent at each level.
38617 //          This method produces a JSON text from a JavaScript value.
38618 //          When an object value is found, if the object contains a toJSON
38619 //          method, its toJSON method will be called and the result will be
38620 //          stringified. A toJSON method does not serialize: it returns the
38621 //          value represented by the name/value pair that should be serialized,
38622 //          or undefined if nothing should be serialized. The toJSON method
38623 //          will be passed the key associated with the value, and this will be
38624 //          bound to the value.
38625
38626 //          For example, this would serialize Dates as ISO strings.
38627
38628 //              Date.prototype.toJSON = function (key) {
38629 //                  function f(n) {
38630 //                      // Format integers to have at least two digits.
38631 //                      return (n < 10)
38632 //                          ? "0" + n
38633 //                          : n;
38634 //                  }
38635 //                  return this.getUTCFullYear()   + "-" +
38636 //                       f(this.getUTCMonth() + 1) + "-" +
38637 //                       f(this.getUTCDate())      + "T" +
38638 //                       f(this.getUTCHours())     + ":" +
38639 //                       f(this.getUTCMinutes())   + ":" +
38640 //                       f(this.getUTCSeconds())   + "Z";
38641 //              };
38642
38643 //          You can provide an optional replacer method. It will be passed the
38644 //          key and value of each member, with this bound to the containing
38645 //          object. The value that is returned from your method will be
38646 //          serialized. If your method returns undefined, then the member will
38647 //          be excluded from the serialization.
38648
38649 //          If the replacer parameter is an array of strings, then it will be
38650 //          used to select the members to be serialized. It filters the results
38651 //          such that only members with keys listed in the replacer array are
38652 //          stringified.
38653
38654 //          Values that do not have JSON representations, such as undefined or
38655 //          functions, will not be serialized. Such values in objects will be
38656 //          dropped; in arrays they will be replaced with null. You can use
38657 //          a replacer function to replace those with JSON values.
38658
38659 //          JSON.stringify(undefined) returns undefined.
38660
38661 //          The optional space parameter produces a stringification of the
38662 //          value that is filled with line breaks and indentation to make it
38663 //          easier to read.
38664
38665 //          If the space parameter is a non-empty string, then that string will
38666 //          be used for indentation. If the space parameter is a number, then
38667 //          the indentation will be that many spaces.
38668
38669 //          Example:
38670
38671 //          text = JSON.stringify(["e", {pluribus: "unum"}]);
38672 //          // text is '["e",{"pluribus":"unum"}]'
38673
38674 //          text = JSON.stringify(["e", {pluribus: "unum"}], null, "\t");
38675 //          // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
38676
38677 //          text = JSON.stringify([new Date()], function (key, value) {
38678 //              return this[key] instanceof Date
38679 //                  ? "Date(" + this[key] + ")"
38680 //                  : value;
38681 //          });
38682 //          // text is '["Date(---current time---)"]'
38683
38684 //      JSON.parse(text, reviver)
38685 //          This method parses a JSON text to produce an object or array.
38686 //          It can throw a SyntaxError exception.
38687
38688 //          The optional reviver parameter is a function that can filter and
38689 //          transform the results. It receives each of the keys and values,
38690 //          and its return value is used instead of the original value.
38691 //          If it returns what it received, then the structure is not modified.
38692 //          If it returns undefined then the member is deleted.
38693
38694 //          Example:
38695
38696 //          // Parse the text. Values that look like ISO date strings will
38697 //          // be converted to Date objects.
38698
38699 //          myData = JSON.parse(text, function (key, value) {
38700 //              var a;
38701 //              if (typeof value === "string") {
38702 //                  a =
38703 //   /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
38704 //                  if (a) {
38705 //                      return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
38706 //                          +a[5], +a[6]));
38707 //                  }
38708 //              }
38709 //              return value;
38710 //          });
38711
38712 //          myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
38713 //              var d;
38714 //              if (typeof value === "string" &&
38715 //                      value.slice(0, 5) === "Date(" &&
38716 //                      value.slice(-1) === ")") {
38717 //                  d = new Date(value.slice(5, -1));
38718 //                  if (d) {
38719 //                      return d;
38720 //                  }
38721 //              }
38722 //              return value;
38723 //          });
38724
38725 //  This is a reference implementation. You are free to copy, modify, or
38726 //  redistribute.
38727
38728 /*jslint
38729     eval, for, this
38730 */
38731
38732 /*property
38733     JSON, apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
38734     getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
38735     lastIndex, length, parse, prototype, push, replace, slice, stringify,
38736     test, toJSON, toString, valueOf
38737 */
38738
38739
38740 // Create a JSON object only if one does not already exist. We create the
38741 // methods in a closure to avoid creating global variables.
38742
38743 if (typeof JSON !== "object") {
38744     JSON = {};
38745 }
38746
38747 (function () {
38748     var rx_one = /^[\],:{}\s]*$/;
38749     var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
38750     var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
38751     var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
38752     var rx_escapable = /[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
38753     var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
38754
38755     function f(n) {
38756         // Format integers to have at least two digits.
38757         return n < 10
38758             ? "0" + n
38759             : n;
38760     }
38761
38762     function this_value() {
38763         return this.valueOf();
38764     }
38765
38766     if (typeof Date.prototype.toJSON !== "function") {
38767
38768         Date.prototype.toJSON = function () {
38769
38770             return isFinite(this.valueOf())
38771                 ? this.getUTCFullYear() + "-" +
38772                         f(this.getUTCMonth() + 1) + "-" +
38773                         f(this.getUTCDate()) + "T" +
38774                         f(this.getUTCHours()) + ":" +
38775                         f(this.getUTCMinutes()) + ":" +
38776                         f(this.getUTCSeconds()) + "Z"
38777                 : null;
38778         };
38779
38780         Boolean.prototype.toJSON = this_value;
38781         Number.prototype.toJSON = this_value;
38782         String.prototype.toJSON = this_value;
38783     }
38784
38785     var gap;
38786     var indent;
38787     var meta;
38788     var rep;
38789
38790
38791     function quote(string) {
38792
38793 // If the string contains no control characters, no quote characters, and no
38794 // backslash characters, then we can safely slap some quotes around it.
38795 // Otherwise we must also replace the offending characters with safe escape
38796 // sequences.
38797
38798         rx_escapable.lastIndex = 0;
38799         return rx_escapable.test(string)
38800             ? "\"" + string.replace(rx_escapable, function (a) {
38801                 var c = meta[a];
38802                 return typeof c === "string"
38803                     ? c
38804                     : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
38805             }) + "\""
38806             : "\"" + string + "\"";
38807     }
38808
38809
38810     function str(key, holder) {
38811
38812 // Produce a string from holder[key].
38813
38814         var i;          // The loop counter.
38815         var k;          // The member key.
38816         var v;          // The member value.
38817         var length;
38818         var mind = gap;
38819         var partial;
38820         var value = holder[key];
38821
38822 // If the value has a toJSON method, call it to obtain a replacement value.
38823
38824         if (value && typeof value === "object" &&
38825                 typeof value.toJSON === "function") {
38826             value = value.toJSON(key);
38827         }
38828
38829 // If we were called with a replacer function, then call the replacer to
38830 // obtain a replacement value.
38831
38832         if (typeof rep === "function") {
38833             value = rep.call(holder, key, value);
38834         }
38835
38836 // What happens next depends on the value's type.
38837
38838         switch (typeof value) {
38839         case "string":
38840             return quote(value);
38841
38842         case "number":
38843
38844 // JSON numbers must be finite. Encode non-finite numbers as null.
38845
38846             return isFinite(value)
38847                 ? String(value)
38848                 : "null";
38849
38850         case "boolean":
38851         case "null":
38852
38853 // If the value is a boolean or null, convert it to a string. Note:
38854 // typeof null does not produce "null". The case is included here in
38855 // the remote chance that this gets fixed someday.
38856
38857             return String(value);
38858
38859 // If the type is "object", we might be dealing with an object or an array or
38860 // null.
38861
38862         case "object":
38863
38864 // Due to a specification blunder in ECMAScript, typeof null is "object",
38865 // so watch out for that case.
38866
38867             if (!value) {
38868                 return "null";
38869             }
38870
38871 // Make an array to hold the partial results of stringifying this object value.
38872
38873             gap += indent;
38874             partial = [];
38875
38876 // Is the value an array?
38877
38878             if (Object.prototype.toString.apply(value) === "[object Array]") {
38879
38880 // The value is an array. Stringify every element. Use null as a placeholder
38881 // for non-JSON values.
38882
38883                 length = value.length;
38884                 for (i = 0; i < length; i += 1) {
38885                     partial[i] = str(i, value) || "null";
38886                 }
38887
38888 // Join all of the elements together, separated with commas, and wrap them in
38889 // brackets.
38890
38891                 v = partial.length === 0
38892                     ? "[]"
38893                     : gap
38894                         ? "[\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "]"
38895                         : "[" + partial.join(",") + "]";
38896                 gap = mind;
38897                 return v;
38898             }
38899
38900 // If the replacer is an array, use it to select the members to be stringified.
38901
38902             if (rep && typeof rep === "object") {
38903                 length = rep.length;
38904                 for (i = 0; i < length; i += 1) {
38905                     if (typeof rep[i] === "string") {
38906                         k = rep[i];
38907                         v = str(k, value);
38908                         if (v) {
38909                             partial.push(quote(k) + (
38910                                 gap
38911                                     ? ": "
38912                                     : ":"
38913                             ) + v);
38914                         }
38915                     }
38916                 }
38917             } else {
38918
38919 // Otherwise, iterate through all of the keys in the object.
38920
38921                 for (k in value) {
38922                     if (Object.prototype.hasOwnProperty.call(value, k)) {
38923                         v = str(k, value);
38924                         if (v) {
38925                             partial.push(quote(k) + (
38926                                 gap
38927                                     ? ": "
38928                                     : ":"
38929                             ) + v);
38930                         }
38931                     }
38932                 }
38933             }
38934
38935 // Join all of the member texts together, separated with commas,
38936 // and wrap them in braces.
38937
38938             v = partial.length === 0
38939                 ? "{}"
38940                 : gap
38941                     ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}"
38942                     : "{" + partial.join(",") + "}";
38943             gap = mind;
38944             return v;
38945         }
38946     }
38947
38948 // If the JSON object does not yet have a stringify method, give it one.
38949
38950     if (typeof JSON.stringify !== "function") {
38951         meta = {    // table of character substitutions
38952             "\b": "\\b",
38953             "\t": "\\t",
38954             "\n": "\\n",
38955             "\f": "\\f",
38956             "\r": "\\r",
38957             "\"": "\\\"",
38958             "\\": "\\\\"
38959         };
38960         JSON.stringify = function (value, replacer, space) {
38961
38962 // The stringify method takes a value and an optional replacer, and an optional
38963 // space parameter, and returns a JSON text. The replacer can be a function
38964 // that can replace values, or an array of strings that will select the keys.
38965 // A default replacer method can be provided. Use of the space parameter can
38966 // produce text that is more easily readable.
38967
38968             var i;
38969             gap = "";
38970             indent = "";
38971
38972 // If the space parameter is a number, make an indent string containing that
38973 // many spaces.
38974
38975             if (typeof space === "number") {
38976                 for (i = 0; i < space; i += 1) {
38977                     indent += " ";
38978                 }
38979
38980 // If the space parameter is a string, it will be used as the indent string.
38981
38982             } else if (typeof space === "string") {
38983                 indent = space;
38984             }
38985
38986 // If there is a replacer, it must be a function or an array.
38987 // Otherwise, throw an error.
38988
38989             rep = replacer;
38990             if (replacer && typeof replacer !== "function" &&
38991                     (typeof replacer !== "object" ||
38992                     typeof replacer.length !== "number")) {
38993                 throw new Error("JSON.stringify");
38994             }
38995
38996 // Make a fake root object containing our value under the key of "".
38997 // Return the result of stringifying the value.
38998
38999             return str("", {"": value});
39000         };
39001     }
39002
39003
39004 // If the JSON object does not yet have a parse method, give it one.
39005
39006     if (typeof JSON.parse !== "function") {
39007         JSON.parse = function (text, reviver) {
39008
39009 // The parse method takes a text and an optional reviver function, and returns
39010 // a JavaScript value if the text is a valid JSON text.
39011
39012             var j;
39013
39014             function walk(holder, key) {
39015
39016 // The walk method is used to recursively walk the resulting structure so
39017 // that modifications can be made.
39018
39019                 var k;
39020                 var v;
39021                 var value = holder[key];
39022                 if (value && typeof value === "object") {
39023                     for (k in value) {
39024                         if (Object.prototype.hasOwnProperty.call(value, k)) {
39025                             v = walk(value, k);
39026                             if (v !== undefined) {
39027                                 value[k] = v;
39028                             } else {
39029                                 delete value[k];
39030                             }
39031                         }
39032                     }
39033                 }
39034                 return reviver.call(holder, key, value);
39035             }
39036
39037
39038 // Parsing happens in four stages. In the first stage, we replace certain
39039 // Unicode characters with escape sequences. JavaScript handles many characters
39040 // incorrectly, either silently deleting them, or treating them as line endings.
39041
39042             text = String(text);
39043             rx_dangerous.lastIndex = 0;
39044             if (rx_dangerous.test(text)) {
39045                 text = text.replace(rx_dangerous, function (a) {
39046                     return "\\u" +
39047                             ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
39048                 });
39049             }
39050
39051 // In the second stage, we run the text against regular expressions that look
39052 // for non-JSON patterns. We are especially concerned with "()" and "new"
39053 // because they can cause invocation, and "=" because it can cause mutation.
39054 // But just to be safe, we want to reject all unexpected forms.
39055
39056 // We split the second stage into 4 regexp operations in order to work around
39057 // crippling inefficiencies in IE's and Safari's regexp engines. First we
39058 // replace the JSON backslash pairs with "@" (a non-JSON character). Second, we
39059 // replace all simple value tokens with "]" characters. Third, we delete all
39060 // open brackets that follow a colon or comma or that begin the text. Finally,
39061 // we look to see that the remaining characters are only whitespace or "]" or
39062 // "," or ":" or "{" or "}". If that is so, then the text is safe for eval.
39063
39064             if (
39065                 rx_one.test(
39066                     text
39067                         .replace(rx_two, "@")
39068                         .replace(rx_three, "]")
39069                         .replace(rx_four, "")
39070                 )
39071             ) {
39072
39073 // In the third stage we use the eval function to compile the text into a
39074 // JavaScript structure. The "{" operator is subject to a syntactic ambiguity
39075 // in JavaScript: it can begin a block or an object literal. We wrap the text
39076 // in parens to eliminate the ambiguity.
39077
39078                 j = eval("(" + text + ")");
39079
39080 // In the optional fourth stage, we recursively walk the new structure, passing
39081 // each name/value pair to a reviver function for possible transformation.
39082
39083                 return (typeof reviver === "function")
39084                     ? walk({"": j}, "")
39085                     : j;
39086             }
39087
39088 // If the text is not JSON parseable, then a SyntaxError is thrown.
39089
39090             throw new SyntaxError("JSON.parse");
39091         };
39092     }
39093 }());
39094
39095 var json2$1 = json2Plugin;
39096
39097 function json2Plugin() {
39098         
39099         return {}
39100 }
39101
39102 var plugins = [json2$1];
39103
39104 var store_legacy = storeEngine.createStore(all$3, plugins);
39105
39106 // # osm-auth
39107 //
39108 // This code is only compatible with IE10+ because the [XDomainRequest](http://bit.ly/LfO7xo)
39109 // object, IE<10's idea of [CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing),
39110 // does not support custom headers, which this uses everywhere.
39111 var osmAuth = function(o) {
39112
39113     var oauth = {};
39114
39115     // authenticated users will also have a request token secret, but it's
39116     // not used in transactions with the server
39117     oauth.authenticated = function() {
39118         return !!(token('oauth_token') && token('oauth_token_secret'));
39119     };
39120
39121     oauth.logout = function() {
39122         token('oauth_token', '');
39123         token('oauth_token_secret', '');
39124         token('oauth_request_token_secret', '');
39125         return oauth;
39126     };
39127
39128     // TODO: detect lack of click event
39129     oauth.authenticate = function(callback) {
39130         if (oauth.authenticated()) return callback();
39131
39132         oauth.logout();
39133
39134         // ## Getting a request token
39135         var params = timenonce(getAuth(o)),
39136             url = o.url + '/oauth/request_token';
39137
39138         params.oauth_signature = ohauth_1.signature(
39139             o.oauth_secret, '',
39140             ohauth_1.baseString('POST', url, params));
39141
39142         if (!o.singlepage) {
39143             // Create a 600x550 popup window in the center of the screen
39144             var w = 600, h = 550,
39145                 settings = [
39146                     ['width', w], ['height', h],
39147                     ['left', screen.width / 2 - w / 2],
39148                     ['top', screen.height / 2 - h / 2]].map(function(x) {
39149                         return x.join('=');
39150                     }).join(','),
39151                 popup = window.open('about:blank', 'oauth_window', settings);
39152         }
39153
39154         // Request a request token. When this is complete, the popup
39155         // window is redirected to OSM's authorization page.
39156         ohauth_1.xhr('POST', url, params, null, {}, reqTokenDone);
39157         o.loading();
39158
39159         function reqTokenDone(err, xhr) {
39160             o.done();
39161             if (err) return callback(err);
39162             var resp = ohauth_1.stringQs(xhr.response);
39163             token('oauth_request_token_secret', resp.oauth_token_secret);
39164             var authorize_url = o.url + '/oauth/authorize?' + ohauth_1.qsString({
39165                 oauth_token: resp.oauth_token,
39166                 oauth_callback: resolveUrl(o.landing)
39167             });
39168
39169             if (o.singlepage) {
39170                 location.href = authorize_url;
39171             } else {
39172                 popup.location = authorize_url;
39173             }
39174         }
39175
39176         // Called by a function in a landing page, in the popup window. The
39177         // window closes itself.
39178         window.authComplete = function(token) {
39179             var oauth_token = ohauth_1.stringQs(token.split('?')[1]);
39180             get_access_token(oauth_token.oauth_token);
39181             delete window.authComplete;
39182         };
39183
39184         // ## Getting an request token
39185         //
39186         // At this point we have an `oauth_token`, brought in from a function
39187         // call on a landing page popup.
39188         function get_access_token(oauth_token) {
39189             var url = o.url + '/oauth/access_token',
39190                 params = timenonce(getAuth(o)),
39191                 request_token_secret = token('oauth_request_token_secret');
39192             params.oauth_token = oauth_token;
39193             params.oauth_signature = ohauth_1.signature(
39194                 o.oauth_secret,
39195                 request_token_secret,
39196                 ohauth_1.baseString('POST', url, params));
39197
39198             // ## Getting an access token
39199             //
39200             // The final token required for authentication. At this point
39201             // we have a `request token secret`
39202             ohauth_1.xhr('POST', url, params, null, {}, accessTokenDone);
39203             o.loading();
39204         }
39205
39206         function accessTokenDone(err, xhr) {
39207             o.done();
39208             if (err) return callback(err);
39209             var access_token = ohauth_1.stringQs(xhr.response);
39210             token('oauth_token', access_token.oauth_token);
39211             token('oauth_token_secret', access_token.oauth_token_secret);
39212             callback(null, oauth);
39213         }
39214     };
39215
39216     oauth.bootstrapToken = function(oauth_token, callback) {
39217         // ## Getting an request token
39218         // At this point we have an `oauth_token`, brought in from a function
39219         // call on a landing page popup.
39220         function get_access_token(oauth_token) {
39221             var url = o.url + '/oauth/access_token',
39222                 params = timenonce(getAuth(o)),
39223                 request_token_secret = token('oauth_request_token_secret');
39224             params.oauth_token = oauth_token;
39225             params.oauth_signature = ohauth_1.signature(
39226                 o.oauth_secret,
39227                 request_token_secret,
39228                 ohauth_1.baseString('POST', url, params));
39229
39230             // ## Getting an access token
39231             // The final token required for authentication. At this point
39232             // we have a `request token secret`
39233             ohauth_1.xhr('POST', url, params, null, {}, accessTokenDone);
39234             o.loading();
39235         }
39236
39237         function accessTokenDone(err, xhr) {
39238             o.done();
39239             if (err) return callback(err);
39240             var access_token = ohauth_1.stringQs(xhr.response);
39241             token('oauth_token', access_token.oauth_token);
39242             token('oauth_token_secret', access_token.oauth_token_secret);
39243             callback(null, oauth);
39244         }
39245
39246         get_access_token(oauth_token);
39247     };
39248
39249     // # xhr
39250     //
39251     // A single XMLHttpRequest wrapper that does authenticated calls if the
39252     // user has logged in.
39253     oauth.xhr = function(options, callback) {
39254         if (!oauth.authenticated()) {
39255             if (o.auto) {
39256                 return oauth.authenticate(run);
39257             } else {
39258                 callback('not authenticated', null);
39259                 return;
39260             }
39261         } else {
39262             return run();
39263         }
39264
39265         function run() {
39266             var params = timenonce(getAuth(o)),
39267                 oauth_token_secret = token('oauth_token_secret'),
39268                 url = (options.prefix !== false) ? o.url + options.path : options.path,
39269                 url_parts = url.replace(/#.*$/, '').split('?', 2),
39270                 base_url = url_parts[0],
39271                 query = (url_parts.length === 2) ? url_parts[1] : '';
39272
39273             // https://tools.ietf.org/html/rfc5849#section-3.4.1.3.1
39274             if ((!options.options || !options.options.header ||
39275                 options.options.header['Content-Type'] === 'application/x-www-form-urlencoded') &&
39276                 options.content) {
39277                 params = immutable(params, ohauth_1.stringQs(options.content));
39278             }
39279
39280             params.oauth_token = token('oauth_token');
39281             params.oauth_signature = ohauth_1.signature(
39282                 o.oauth_secret,
39283                 oauth_token_secret,
39284                 ohauth_1.baseString(options.method, base_url, immutable(params, ohauth_1.stringQs(query)))
39285             );
39286
39287             return ohauth_1.xhr(options.method, url, params, options.content, options.options, done);
39288         }
39289
39290         function done(err, xhr) {
39291             if (err) return callback(err);
39292             else if (xhr.responseXML) return callback(err, xhr.responseXML);
39293             else return callback(err, xhr.response);
39294         }
39295     };
39296
39297     // pre-authorize this object, if we can just get a token and token_secret
39298     // from the start
39299     oauth.preauth = function(c) {
39300         if (!c) return;
39301         if (c.oauth_token) token('oauth_token', c.oauth_token);
39302         if (c.oauth_token_secret) token('oauth_token_secret', c.oauth_token_secret);
39303         return oauth;
39304     };
39305
39306     oauth.options = function(_) {
39307         if (!arguments.length) return o;
39308
39309         o = _;
39310         o.url = o.url || 'https://www.openstreetmap.org';
39311         o.landing = o.landing || 'land.html';
39312         o.singlepage = o.singlepage || false;
39313
39314         // Optional loading and loading-done functions for nice UI feedback.
39315         // by default, no-ops
39316         o.loading = o.loading || function() {};
39317         o.done = o.done || function() {};
39318
39319         return oauth.preauth(o);
39320     };
39321
39322     // 'stamp' an authentication object from `getAuth()`
39323     // with a [nonce](http://en.wikipedia.org/wiki/Cryptographic_nonce)
39324     // and timestamp
39325     function timenonce(o) {
39326         o.oauth_timestamp = ohauth_1.timestamp();
39327         o.oauth_nonce = ohauth_1.nonce();
39328         return o;
39329     }
39330
39331     // get/set tokens. These are prefixed with the base URL so that `osm-auth`
39332     // can be used with multiple APIs and the keys in `localStorage`
39333     // will not clash
39334     var token;
39335
39336     if (store_legacy.enabled) {
39337         token = function (x, y) {
39338             if (arguments.length === 1) return store_legacy.get(o.url + x);
39339             else if (arguments.length === 2) return store_legacy.set(o.url + x, y);
39340         };
39341     } else {
39342         var storage = {};
39343         token = function (x, y) {
39344             if (arguments.length === 1) return storage[o.url + x];
39345             else if (arguments.length === 2) return storage[o.url + x] = y;
39346         };
39347     }
39348
39349     // Get an authentication object. If you just add and remove properties
39350     // from a single object, you'll need to use `delete` to make sure that
39351     // it doesn't contain undesired properties for authentication
39352     function getAuth(o) {
39353         return {
39354             oauth_consumer_key: o.oauth_consumer_key,
39355             oauth_signature_method: 'HMAC-SHA1'
39356         };
39357     }
39358
39359     // potentially pre-authorize
39360     oauth.options(o);
39361
39362     return oauth;
39363 };
39364
39365 var JXON = new (function () {
39366   var
39367     sValueProp = 'keyValue', sAttributesProp = 'keyAttributes', sAttrPref = '@', /* you can customize these values */
39368     aCache = [], rIsNull = /^\s*$/, rIsBool = /^(?:true|false)$/i;
39369
39370   function parseText (sValue) {
39371     if (rIsNull.test(sValue)) { return null; }
39372     if (rIsBool.test(sValue)) { return sValue.toLowerCase() === 'true'; }
39373     if (isFinite(sValue)) { return parseFloat(sValue); }
39374     if (isFinite(Date.parse(sValue))) { return new Date(sValue); }
39375     return sValue;
39376   }
39377
39378   function EmptyTree () { }
39379   EmptyTree.prototype.toString = function () { return 'null'; };
39380   EmptyTree.prototype.valueOf = function () { return null; };
39381
39382   function objectify (vValue) {
39383     return vValue === null ? new EmptyTree() : vValue instanceof Object ? vValue : new vValue.constructor(vValue);
39384   }
39385
39386   function createObjTree (oParentNode, nVerb, bFreeze, bNesteAttr) {
39387     var
39388       nLevelStart = aCache.length, bChildren = oParentNode.hasChildNodes(),
39389       bAttributes = oParentNode.hasAttributes(), bHighVerb = Boolean(nVerb & 2);
39390
39391     var
39392       sProp, vContent, nLength = 0, sCollectedTxt = '',
39393       vResult = bHighVerb ? {} : /* put here the default value for empty nodes: */ true;
39394
39395     if (bChildren) {
39396       for (var oNode, nItem = 0; nItem < oParentNode.childNodes.length; nItem++) {
39397         oNode = oParentNode.childNodes.item(nItem);
39398         if (oNode.nodeType === 4) { sCollectedTxt += oNode.nodeValue; } /* nodeType is 'CDATASection' (4) */
39399         else if (oNode.nodeType === 3) { sCollectedTxt += oNode.nodeValue.trim(); } /* nodeType is 'Text' (3) */
39400         else if (oNode.nodeType === 1 && !oNode.prefix) { aCache.push(oNode); } /* nodeType is 'Element' (1) */
39401       }
39402     }
39403
39404     var nLevelEnd = aCache.length, vBuiltVal = parseText(sCollectedTxt);
39405
39406     if (!bHighVerb && (bChildren || bAttributes)) { vResult = nVerb === 0 ? objectify(vBuiltVal) : {}; }
39407
39408     for (var nElId = nLevelStart; nElId < nLevelEnd; nElId++) {
39409       sProp = aCache[nElId].nodeName.toLowerCase();
39410       vContent = createObjTree(aCache[nElId], nVerb, bFreeze, bNesteAttr);
39411       if (vResult.hasOwnProperty(sProp)) {
39412         if (vResult[sProp].constructor !== Array) { vResult[sProp] = [vResult[sProp]]; }
39413         vResult[sProp].push(vContent);
39414       } else {
39415         vResult[sProp] = vContent;
39416         nLength++;
39417       }
39418     }
39419
39420     if (bAttributes) {
39421       var
39422         nAttrLen = oParentNode.attributes.length,
39423         sAPrefix = bNesteAttr ? '' : sAttrPref, oAttrParent = bNesteAttr ? {} : vResult;
39424
39425       for (var oAttrib, nAttrib = 0; nAttrib < nAttrLen; nLength++, nAttrib++) {
39426         oAttrib = oParentNode.attributes.item(nAttrib);
39427         oAttrParent[sAPrefix + oAttrib.name.toLowerCase()] = parseText(oAttrib.value.trim());
39428       }
39429
39430       if (bNesteAttr) {
39431         if (bFreeze) { Object.freeze(oAttrParent); }
39432         vResult[sAttributesProp] = oAttrParent;
39433         nLength -= nAttrLen - 1;
39434       }
39435     }
39436
39437     if (nVerb === 3 || (nVerb === 2 || nVerb === 1 && nLength > 0) && sCollectedTxt) {
39438       vResult[sValueProp] = vBuiltVal;
39439     } else if (!bHighVerb && nLength === 0 && sCollectedTxt) {
39440       vResult = vBuiltVal;
39441     }
39442
39443     if (bFreeze && (bHighVerb || nLength > 0)) { Object.freeze(vResult); }
39444
39445     aCache.length = nLevelStart;
39446
39447     return vResult;
39448   }
39449
39450   function loadObjTree (oXMLDoc, oParentEl, oParentObj) {
39451     var vValue, oChild;
39452
39453     if (oParentObj instanceof String || oParentObj instanceof Number || oParentObj instanceof Boolean) {
39454       oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toString())); /* verbosity level is 0 */
39455     } else if (oParentObj.constructor === Date) {
39456       oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toGMTString()));    
39457     }
39458
39459     for (var sName in oParentObj) {
39460       vValue = oParentObj[sName];
39461       if (isFinite(sName) || vValue instanceof Function) { continue; } /* verbosity level is 0 */
39462       if (sName === sValueProp) {
39463         if (vValue !== null && vValue !== true) { oParentEl.appendChild(oXMLDoc.createTextNode(vValue.constructor === Date ? vValue.toGMTString() : String(vValue))); }
39464       } else if (sName === sAttributesProp) { /* verbosity level is 3 */
39465         for (var sAttrib in vValue) { oParentEl.setAttribute(sAttrib, vValue[sAttrib]); }
39466       } else if (sName.charAt(0) === sAttrPref) {
39467         oParentEl.setAttribute(sName.slice(1), vValue);
39468       } else if (vValue.constructor === Array) {
39469         for (var nItem = 0; nItem < vValue.length; nItem++) {
39470           oChild = oXMLDoc.createElement(sName);
39471           loadObjTree(oXMLDoc, oChild, vValue[nItem]);
39472           oParentEl.appendChild(oChild);
39473         }
39474       } else {
39475         oChild = oXMLDoc.createElement(sName);
39476         if (vValue instanceof Object) {
39477           loadObjTree(oXMLDoc, oChild, vValue);
39478         } else if (vValue !== null && vValue !== true) {
39479           oChild.appendChild(oXMLDoc.createTextNode(vValue.toString()));
39480         }
39481         oParentEl.appendChild(oChild);
39482      }
39483    }
39484   }
39485
39486   this.build = function (oXMLParent, nVerbosity /* optional */, bFreeze /* optional */, bNesteAttributes /* optional */) {
39487     var _nVerb = arguments.length > 1 && typeof nVerbosity === 'number' ? nVerbosity & 3 : /* put here the default verbosity level: */ 1;
39488     return createObjTree(oXMLParent, _nVerb, bFreeze || false, arguments.length > 3 ? bNesteAttributes : _nVerb === 3);    
39489   };
39490
39491   this.unbuild = function (oObjTree) {    
39492     var oNewDoc = document.implementation.createDocument('', '', null);
39493     loadObjTree(oNewDoc, oNewDoc, oObjTree);
39494     return oNewDoc;
39495   };
39496
39497   this.stringify = function (oObjTree) {
39498     return (new XMLSerializer()).serializeToString(JXON.unbuild(oObjTree));
39499   };
39500 })();
39501
39502 // var myObject = JXON.build(doc);
39503 // we got our javascript object! try: alert(JSON.stringify(myObject));
39504
39505 // var newDoc = JXON.unbuild(myObject);
39506 // we got our Document instance! try: alert((new XMLSerializer()).serializeToString(newDoc));
39507
39508 var dispatch$3 = dispatch('authLoading', 'authDone', 'change', 'loading', 'loaded');
39509 var urlroot = 'https://www.openstreetmap.org';
39510 var oauth = osmAuth({
39511     url: urlroot,
39512     oauth_consumer_key: '5A043yRSEugj4DJ5TljuapfnrflWDte8jTOcWLlT',
39513     oauth_secret: 'aB3jKq1TRsCOUrfOIZ6oQMEDmv2ptV76PA54NGLL',
39514     loading: authLoading,
39515     done: authDone
39516 });
39517
39518 var _blacklists = ['.*\.google(apis)?\..*/(vt|kh)[\?/].*([xyz]=.*){3}.*'];
39519 var _tiles = { loaded: {}, inflight: {} };
39520 var _changeset = {};
39521 var _entityCache = {};
39522 var _connectionID = 1;
39523 var _tileZoom = 16;
39524 var _rateLimitError;
39525 var _userChangesets;
39526 var _userDetails;
39527 var _off;
39528
39529
39530 function authLoading() {
39531     dispatch$3.call('authLoading');
39532 }
39533
39534
39535 function authDone() {
39536     dispatch$3.call('authDone');
39537 }
39538
39539
39540 function abortRequest$2(i) {
39541     if (i) {
39542         i.abort();
39543     }
39544 }
39545
39546
39547 function getLoc(attrs) {
39548     var lon = attrs.lon && attrs.lon.value;
39549     var lat = attrs.lat && attrs.lat.value;
39550     return [parseFloat(lon), parseFloat(lat)];
39551 }
39552
39553
39554 function getNodes(obj) {
39555     var elems = obj.getElementsByTagName('nd');
39556     var nodes = new Array(elems.length);
39557     for (var i = 0, l = elems.length; i < l; i++) {
39558         nodes[i] = 'n' + elems[i].attributes.ref.value;
39559     }
39560     return nodes;
39561 }
39562
39563
39564 function getTags(obj) {
39565     var elems = obj.getElementsByTagName('tag');
39566     var tags = {};
39567     for (var i = 0, l = elems.length; i < l; i++) {
39568         var attrs = elems[i].attributes;
39569         tags[attrs.k.value] = attrs.v.value;
39570     }
39571
39572     return tags;
39573 }
39574
39575
39576 function getMembers(obj) {
39577     var elems = obj.getElementsByTagName('member');
39578     var members = new Array(elems.length);
39579     for (var i = 0, l = elems.length; i < l; i++) {
39580         var attrs = elems[i].attributes;
39581         members[i] = {
39582             id: attrs.type.value[0] + attrs.ref.value,
39583             type: attrs.type.value,
39584             role: attrs.role.value
39585         };
39586     }
39587     return members;
39588 }
39589
39590
39591 function getVisible(attrs) {
39592     return (!attrs.visible || attrs.visible.value !== 'false');
39593 }
39594
39595
39596 var parsers = {
39597     node: function nodeData(obj, uid) {
39598         var attrs = obj.attributes;
39599         return new osmNode({
39600             id:uid,
39601             visible: getVisible(attrs),
39602             version: attrs.version.value,
39603             changeset: attrs.changeset && attrs.changeset.value,
39604             timestamp: attrs.timestamp && attrs.timestamp.value,
39605             user: attrs.user && attrs.user.value,
39606             uid: attrs.uid && attrs.uid.value,
39607             loc: getLoc(attrs),
39608             tags: getTags(obj)
39609         });
39610     },
39611
39612     way: function wayData(obj, uid) {
39613         var attrs = obj.attributes;
39614         return new osmWay({
39615             id: uid,
39616             visible: getVisible(attrs),
39617             version: attrs.version.value,
39618             changeset: attrs.changeset && attrs.changeset.value,
39619             timestamp: attrs.timestamp && attrs.timestamp.value,
39620             user: attrs.user && attrs.user.value,
39621             uid: attrs.uid && attrs.uid.value,
39622             tags: getTags(obj),
39623             nodes: getNodes(obj),
39624         });
39625     },
39626
39627     relation: function relationData(obj, uid) {
39628         var attrs = obj.attributes;
39629         return new osmRelation({
39630             id: uid,
39631             visible: getVisible(attrs),
39632             version: attrs.version.value,
39633             changeset: attrs.changeset && attrs.changeset.value,
39634             timestamp: attrs.timestamp && attrs.timestamp.value,
39635             user: attrs.user && attrs.user.value,
39636             uid: attrs.uid && attrs.uid.value,
39637             tags: getTags(obj),
39638             members: getMembers(obj)
39639         });
39640     }
39641 };
39642
39643
39644 function parse(xml$$1, callback, options) {
39645     options = assignIn({ cache: true }, options);
39646     if (!xml$$1 || !xml$$1.childNodes) return;
39647
39648     var root = xml$$1.childNodes[0];
39649     var children = root.childNodes;
39650
39651     function parseChild(child) {
39652         var parser = parsers[child.nodeName];
39653         if (parser) {
39654             var uid = osmEntity.id.fromOSM(child.nodeName, child.attributes.id.value);
39655             if (options.cache && _entityCache[uid]) {
39656                 return null;
39657             }
39658             return parser(child, uid);
39659         }
39660     }
39661
39662     utilIdleWorker(children, parseChild, callback);
39663 }
39664
39665
39666 var serviceOsm = {
39667
39668     init: function() {
39669         utilRebind(this, dispatch$3, 'on');
39670     },
39671
39672
39673     reset: function() {
39674         _connectionID++;
39675         _userChangesets = undefined;
39676         _userDetails = undefined;
39677         _rateLimitError = undefined;
39678         forEach(_tiles.inflight, abortRequest$2);
39679         if (_changeset.inflight) abortRequest$2(_changeset.inflight);
39680         _tiles = { loaded: {}, inflight: {} };
39681         _changeset = {};
39682         _entityCache = {};
39683         return this;
39684     },
39685
39686
39687     getConnectionId: function() {
39688         return _connectionID;
39689     },
39690
39691
39692     changesetURL: function(changesetId) {
39693         return urlroot + '/changeset/' + changesetId;
39694     },
39695
39696
39697     changesetsURL: function(center, zoom) {
39698         var precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2));
39699         return urlroot + '/history#map=' +
39700             Math.floor(zoom) + '/' +
39701             center[1].toFixed(precision) + '/' +
39702             center[0].toFixed(precision);
39703     },
39704
39705
39706     entityURL: function(entity) {
39707         return urlroot + '/' + entity.type + '/' + entity.osmId();
39708     },
39709
39710
39711     historyURL: function(entity) {
39712         return urlroot + '/' + entity.type + '/' + entity.osmId() + '/history';
39713     },
39714
39715
39716     userURL: function(username) {
39717         return urlroot + '/user/' + username;
39718     },
39719
39720
39721     loadFromAPI: function(path, callback, options) {
39722         options = assignIn({ cache: true }, options);
39723         var that = this;
39724         var cid = _connectionID;
39725
39726         function done(err, xml$$1) {
39727             if (that.getConnectionId() !== cid) {
39728                 if (callback) callback({ message: 'Connection Switched', status: -1 });
39729                 return;
39730             }
39731
39732             var isAuthenticated = that.authenticated();
39733
39734             // 400 Bad Request, 401 Unauthorized, 403 Forbidden
39735             // Logout and retry the request..
39736             if (isAuthenticated && err && (err.status === 400 || err.status === 401 || err.status === 403)) {
39737                 that.logout();
39738                 that.loadFromAPI(path, callback);
39739
39740             // else, no retry..
39741             } else {
39742                 // 509 Bandwidth Limit Exceeded, 429 Too Many Requests
39743                 // Set the rateLimitError flag and trigger a warning..
39744                 if (!isAuthenticated && !_rateLimitError && err &&
39745                         (err.status === 509 || err.status === 429)) {
39746                     _rateLimitError = err;
39747                     dispatch$3.call('change');
39748                 }
39749
39750                 if (callback) {
39751                     if (err) return callback(err, null);
39752                     parse(xml$$1, function (entities) {
39753                         if (options.cache) {
39754                             for (var i in entities) {
39755                                 _entityCache[entities[i].id] = true;
39756                             }
39757                         }
39758                         callback(null, entities);
39759                     }, options);
39760                 }
39761             }
39762         }
39763
39764         if (this.authenticated()) {
39765             return oauth.xhr({ method: 'GET', path: path }, done);
39766         } else {
39767             var url = urlroot + path;
39768             return d3_xml(url).get(done);
39769         }
39770     },
39771
39772
39773     loadEntity: function(id, callback) {
39774         var type = osmEntity.id.type(id);
39775         var osmID = osmEntity.id.toOSM(id);
39776         var options = { cache: false };
39777
39778         this.loadFromAPI(
39779             '/api/0.6/' + type + '/' + osmID + (type !== 'node' ? '/full' : ''),
39780             function(err, entities) {
39781                 if (callback) callback(err, { data: entities });
39782             },
39783             options
39784         );
39785     },
39786
39787
39788     loadEntityVersion: function(id, version, callback) {
39789         var type = osmEntity.id.type(id);
39790         var osmID = osmEntity.id.toOSM(id);
39791         var options = { cache: false };
39792
39793         this.loadFromAPI(
39794             '/api/0.6/' + type + '/' + osmID + '/' + version,
39795             function(err, entities) {
39796                 if (callback) callback(err, { data: entities });
39797             },
39798             options
39799         );
39800     },
39801
39802
39803     loadMultiple: function(ids, callback) {
39804         var that = this;
39805
39806         forEach(groupBy(uniq(ids), osmEntity.id.type), function(v, k) {
39807             var type = k + 's';
39808             var osmIDs = map$4(v, osmEntity.id.toOSM);
39809             var options = { cache: false };
39810
39811             forEach(chunk(osmIDs, 150), function(arr) {
39812                 that.loadFromAPI(
39813                     '/api/0.6/' + type + '?' + type + '=' + arr.join(),
39814                     function(err, entities) {
39815                         if (callback) callback(err, { data: entities });
39816                     },
39817                     options
39818                 );
39819             });
39820         });
39821     },
39822
39823
39824     authenticated: function() {
39825         return oauth.authenticated();
39826     },
39827
39828
39829     putChangeset: function(changeset, changes, callback) {
39830         if (_changeset.inflight) {
39831             return callback({ message: 'Changeset already inflight', status: -2 }, changeset);
39832         }
39833
39834         var that = this;
39835         var cid = _connectionID;
39836
39837         if (_changeset.open) {   // reuse existing open changeset..
39838             createdChangeset(null, _changeset.open);
39839         } else {                 // open a new changeset..
39840             _changeset.inflight = oauth.xhr({
39841                 method: 'PUT',
39842                 path: '/api/0.6/changeset/create',
39843                 options: { header: { 'Content-Type': 'text/xml' } },
39844                 content: JXON.stringify(changeset.asJXON())
39845             }, createdChangeset);
39846         }
39847
39848
39849         function createdChangeset(err, changesetID) {
39850             _changeset.inflight = null;
39851
39852             if (err) {
39853                 // 400 Bad Request, 401 Unauthorized, 403 Forbidden..
39854                 if (err.status === 400 || err.status === 401 || err.status === 403) {
39855                     that.logout();
39856                 }
39857                 return callback(err, changeset);
39858             }
39859             if (that.getConnectionId() !== cid) {
39860                 return callback({ message: 'Connection Switched', status: -1 }, changeset);
39861             }
39862
39863             _changeset.open = changesetID;
39864             changeset = changeset.update({ id: changesetID });
39865
39866             // Upload the changeset..
39867             _changeset.inflight = oauth.xhr({
39868                 method: 'POST',
39869                 path: '/api/0.6/changeset/' + changesetID + '/upload',
39870                 options: { header: { 'Content-Type': 'text/xml' } },
39871                 content: JXON.stringify(changeset.osmChangeJXON(changes))
39872             }, uploadedChangeset);
39873         }
39874
39875
39876         function uploadedChangeset(err) {
39877             _changeset.inflight = null;
39878
39879             if (err) return callback(err, changeset);
39880
39881             // Upload was successful, safe to call the callback.
39882             // Add delay to allow for postgres replication #1646 #2678
39883             window.setTimeout(function() {
39884                 callback(null, changeset);
39885             }, 2500);
39886
39887             _changeset.open = null;
39888
39889             // At this point, we don't really care if the connection was switched..
39890             // Only try to close the changeset if we're still talking to the same server.
39891             if (that.getConnectionId() === cid) {
39892                 // Still attempt to close changeset, but ignore response because #2667
39893                 oauth.xhr({
39894                     method: 'PUT',
39895                     path: '/api/0.6/changeset/' + changeset.id + '/close',
39896                     options: { header: { 'Content-Type': 'text/xml' } }
39897                 }, function() { return true; });
39898             }
39899         }
39900     },
39901
39902
39903     userDetails: function(callback) {
39904         if (_userDetails) {
39905             callback(undefined, _userDetails);
39906             return;
39907         }
39908
39909         var that = this;
39910         var cid = _connectionID;
39911
39912         function done(err, user_details) {
39913             if (err) {
39914                 // 400 Bad Request, 401 Unauthorized, 403 Forbidden..
39915                 if (err.status === 400 || err.status === 401 || err.status === 403) {
39916                     that.logout();
39917                 }
39918                 return callback(err);
39919             }
39920             if (that.getConnectionId() !== cid) {
39921                 return callback({ message: 'Connection Switched', status: -1 });
39922             }
39923
39924
39925             var u = user_details.getElementsByTagName('user')[0];
39926             var img = u.getElementsByTagName('img');
39927             var image_url = '';
39928
39929             if (img && img[0] && img[0].getAttribute('href')) {
39930                 image_url = img[0].getAttribute('href');
39931             }
39932
39933             var changesets = u.getElementsByTagName('changesets');
39934             var changesets_count = 0;
39935
39936             if (changesets && changesets[0] && changesets[0].getAttribute('count')) {
39937                 changesets_count = changesets[0].getAttribute('count');
39938             }
39939
39940             _userDetails = {
39941                 id: u.attributes.id.value,
39942                 display_name: u.attributes.display_name.value,
39943                 image_url: image_url,
39944                 changesets_count: changesets_count
39945             };
39946
39947             callback(undefined, _userDetails);
39948         }
39949
39950         oauth.xhr({ method: 'GET', path: '/api/0.6/user/details' }, done);
39951     },
39952
39953
39954     userChangesets: function(callback) {
39955         if (_userChangesets) {
39956             callback(undefined, _userChangesets);
39957             return;
39958         }
39959
39960         var that = this;
39961         var cid = _connectionID;
39962
39963         this.userDetails(function(err, user) {
39964             if (err) {
39965                 return callback(err);
39966             }
39967             if (that.getConnectionId() !== cid) {
39968                 return callback({ message: 'Connection Switched', status: -1 });
39969             }
39970
39971             function done(err, changesets) {
39972                 if (err) {
39973                     // 400 Bad Request, 401 Unauthorized, 403 Forbidden..
39974                     if (err.status === 400 || err.status === 401 || err.status === 403) {
39975                         that.logout();
39976                     }
39977                     return callback(err);
39978                 }
39979                 if (that.getConnectionId() !== cid) {
39980                     return callback({ message: 'Connection Switched', status: -1 });
39981                 }
39982
39983                 _userChangesets = Array.prototype.map.call(
39984                     changesets.getElementsByTagName('changeset'),
39985                     function (changeset) {
39986                         return { tags: getTags(changeset) };
39987                     }
39988                 ).filter(function (changeset) {
39989                     var comment = changeset.tags.comment;
39990                     return comment && comment !== '';
39991                 });
39992
39993                 callback(undefined, _userChangesets);
39994             }
39995
39996             oauth.xhr({ method: 'GET', path: '/api/0.6/changesets?user=' + user.id }, done);
39997         });
39998     },
39999
40000
40001     status: function(callback) {
40002         var that = this;
40003         var cid = _connectionID;
40004
40005         function done(xml$$1) {
40006             if (that.getConnectionId() !== cid) {
40007                 return callback({ message: 'Connection Switched', status: -1 }, 'connectionSwitched');
40008             }
40009
40010             // update blacklists
40011             var elements = xml$$1.getElementsByTagName('blacklist');
40012             var regexes = [];
40013             for (var i = 0; i < elements.length; i++) {
40014                 var regex = elements[i].getAttribute('regex');  // needs unencode?
40015                 if (regex) {
40016                     regexes.push(regex);
40017                 }
40018             }
40019             if (regexes.length) {
40020                 _blacklists = regexes;
40021             }
40022
40023
40024             if (_rateLimitError) {
40025                 callback(_rateLimitError, 'rateLimited');
40026             } else {
40027                 var apiStatus = xml$$1.getElementsByTagName('status');
40028                 var val = apiStatus[0].getAttribute('api');
40029
40030                 callback(undefined, val);
40031             }
40032         }
40033
40034         d3_xml(urlroot + '/api/capabilities').get()
40035             .on('load', done)
40036             .on('error', callback);
40037     },
40038
40039
40040     imageryBlacklists: function() {
40041         return _blacklists;
40042     },
40043
40044
40045     tileZoom: function(_) {
40046         if (!arguments.length) return _tileZoom;
40047         _tileZoom = _;
40048         return this;
40049     },
40050
40051
40052     loadTiles: function(projection, dimensions, callback) {
40053         if (_off) return;
40054
40055         var that = this;
40056         var s = projection.scale() * 2 * Math.PI;
40057         var z = Math.max(Math.log(s) / Math.log(2) - 8, 0);
40058         var ts = 256 * Math.pow(2, z - _tileZoom);
40059         var origin = [
40060             s / 2 - projection.translate()[0],
40061             s / 2 - projection.translate()[1]
40062         ];
40063
40064         var tiles = d3geoTile()
40065             .scaleExtent([_tileZoom, _tileZoom])
40066             .scale(s)
40067             .size(dimensions)
40068             .translate(projection.translate())()
40069             .map(function(tile) {
40070                 var x = tile[0] * ts - origin[0];
40071                 var y = tile[1] * ts - origin[1];
40072
40073                 return {
40074                     id: tile.toString(),
40075                     extent: geoExtent(
40076                         projection.invert([x, y + ts]),
40077                         projection.invert([x + ts, y]))
40078                 };
40079             });
40080
40081         filter(_tiles.inflight, function(v, i) {
40082             var wanted = find$1(tiles, function(tile) {
40083                 return i === tile.id;
40084             });
40085             if (!wanted) delete _tiles.inflight[i];
40086             return !wanted;
40087         }).map(abortRequest$2);
40088
40089         tiles.forEach(function(tile) {
40090             var id = tile.id;
40091
40092             if (_tiles.loaded[id] || _tiles.inflight[id]) return;
40093
40094             if (isEmpty(_tiles.inflight)) {
40095                 dispatch$3.call('loading');
40096             }
40097
40098             _tiles.inflight[id] = that.loadFromAPI(
40099                 '/api/0.6/map?bbox=' + tile.extent.toParam(),
40100                 function(err, parsed) {
40101                     delete _tiles.inflight[id];
40102                     if (!err) {
40103                         _tiles.loaded[id] = true;
40104                     }
40105
40106                     if (callback) {
40107                         callback(err, assignIn({ data: parsed }, tile));
40108                     }
40109
40110                     if (isEmpty(_tiles.inflight)) {
40111                         dispatch$3.call('loaded');
40112                     }
40113                 }
40114             );
40115         });
40116     },
40117
40118
40119     switch: function(options) {
40120         urlroot = options.urlroot;
40121
40122         oauth.options(assignIn({
40123             url: urlroot,
40124             loading: authLoading,
40125             done: authDone
40126         }, options));
40127
40128         this.reset();
40129         this.userChangesets(function() {});  // eagerly load user details/changesets
40130         dispatch$3.call('change');
40131         return this;
40132     },
40133
40134
40135     toggle: function(_) {
40136         _off = !_;
40137         return this;
40138     },
40139
40140
40141     loadedTiles: function(_) {
40142         if (!arguments.length) return _tiles.loaded;
40143         _tiles.loaded = _;
40144         return this;
40145     },
40146
40147
40148     logout: function() {
40149         _userChangesets = undefined;
40150         _userDetails = undefined;
40151         oauth.logout();
40152         dispatch$3.call('change');
40153         return this;
40154     },
40155
40156
40157     authenticate: function(callback) {
40158         var that = this;
40159         var cid = _connectionID;
40160         _userChangesets = undefined;
40161         _userDetails = undefined;
40162
40163         function done(err, res) {
40164             if (err) {
40165                 if (callback) callback(err);
40166                 return;
40167             }
40168             if (that.getConnectionId() !== cid) {
40169                 if (callback) callback({ message: 'Connection Switched', status: -1 });
40170                 return;
40171             }
40172             _rateLimitError = undefined;
40173             dispatch$3.call('change');
40174             if (callback) callback(err, res);
40175             that.userChangesets(function() {});  // eagerly load user details/changesets
40176         }
40177
40178         return oauth.authenticate(done);
40179     }
40180 };
40181
40182 var apibase$3 = 'https://taginfo.openstreetmap.org/api/4/';
40183 var inflight$1 = {};
40184 var popularKeys = {};
40185 var taginfoCache = {};
40186 var tag_sorts = {
40187         point: 'count_nodes',
40188         vertex: 'count_nodes',
40189         area: 'count_ways',
40190         line: 'count_ways'
40191     };
40192 var tag_sort_members = {
40193         point: 'count_node_members',
40194         vertex: 'count_node_members',
40195         area: 'count_way_members',
40196         line: 'count_way_members',
40197         relation: 'count_relation_members'
40198     };
40199 var tag_filters = {
40200         point: 'nodes',
40201         vertex: 'nodes',
40202         area: 'ways',
40203         line: 'ways'
40204     };
40205 var tag_members_fractions = {
40206         point: 'count_node_members_fraction',
40207         vertex: 'count_node_members_fraction',
40208         area: 'count_way_members_fraction',
40209         line: 'count_way_members_fraction',
40210         relation: 'count_relation_members_fraction'
40211     };
40212
40213
40214 function sets(params, n, o) {
40215     if (params.geometry && o[params.geometry]) {
40216         params[n] = o[params.geometry];
40217     }
40218     return params;
40219 }
40220
40221
40222 function setFilter(params) {
40223     return sets(params, 'filter', tag_filters);
40224 }
40225
40226
40227 function setSort(params) {
40228     return sets(params, 'sortname', tag_sorts);
40229 }
40230
40231
40232 function setSortMembers(params) {
40233     return sets(params, 'sortname', tag_sort_members);
40234 }
40235
40236
40237 function clean(params) {
40238     return omit(params, ['geometry', 'debounce']);
40239 }
40240
40241
40242 function filterKeys(type) {
40243     var count_type = type ? 'count_' + type : 'count_all';
40244     return function(d) {
40245         return parseFloat(d[count_type]) > 2500 || d.in_wiki;
40246     };
40247 }
40248
40249
40250 function filterMultikeys(prefix) {
40251     return function(d) {
40252         // d.key begins with prefix, and d.key contains no additional ':'s
40253         var re = new RegExp('^' + prefix + '(.*)$');
40254         var matches = d.key.match(re) || [];
40255         return (matches.length === 2 && matches[1].indexOf(':') === -1);
40256     };
40257 }
40258
40259
40260 function filterValues(allowUpperCase) {
40261     return function(d) {
40262         if (d.value.match(/[;,]/) !== null) return false;  // exclude some punctuation
40263         if (!allowUpperCase && d.value.match(/[A-Z*]/) !== null) return false;  // exclude uppercase letters
40264         return parseFloat(d.fraction) > 0.0 || d.in_wiki;
40265     };
40266 }
40267
40268
40269 function filterRoles(geometry) {
40270     return function(d) {
40271         if (d.role === '') return false; // exclude empty role
40272         if (d.role.match(/[A-Z*;,]/) !== null) return false;  // exclude uppercase letters and some punctuation
40273         return parseFloat(d[tag_members_fractions[geometry]]) > 0.0;
40274     };
40275 }
40276
40277
40278 function valKey(d) {
40279     return {
40280         value: d.key,
40281         title: d.key
40282     };
40283 }
40284
40285
40286 function valKeyDescription(d) {
40287     return {
40288         value: d.value,
40289         title: d.description || d.value
40290     };
40291 }
40292
40293
40294 function roleKey(d) {
40295     return {
40296         value: d.role,
40297         title: d.role
40298     };
40299 }
40300
40301
40302 // sort keys with ':' lower than keys without ':'
40303 function sortKeys(a, b) {
40304     return (a.key.indexOf(':') === -1 && b.key.indexOf(':') !== -1) ? -1
40305         : (a.key.indexOf(':') !== -1 && b.key.indexOf(':') === -1) ? 1
40306         : 0;
40307 }
40308
40309
40310 var debouncedRequest = debounce(request, 500, { leading: false });
40311
40312 function request(url, params, exactMatch, callback, loaded) {
40313     if (inflight$1[url]) return;
40314
40315     if (checkCache(url, params, exactMatch, callback)) return;
40316
40317     inflight$1[url] = d3_json(url, function (err, data) {
40318         delete inflight$1[url];
40319         loaded(err, data);
40320     });
40321 }
40322
40323
40324 function checkCache(url, params, exactMatch, callback) {
40325     var rp = params.rp || 25,
40326         testQuery = params.query || '',
40327         testUrl = url;
40328
40329     do {
40330         var hit = taginfoCache[testUrl];
40331
40332         // exact match, or shorter match yielding fewer than max results (rp)
40333         if (hit && (url === testUrl || hit.length < rp)) {
40334             callback(null, hit);
40335             return true;
40336         }
40337
40338         // don't try to shorten the query
40339         if (exactMatch || !testQuery.length) return false;
40340
40341         // do shorten the query to see if we already have a cached result
40342         // that has returned fewer than max results (rp)
40343         testQuery = testQuery.slice(0, -1);
40344         testUrl = url.replace(/&query=(.*?)&/, '&query=' + testQuery + '&');
40345     } while (testQuery.length >= 0);
40346
40347     return false;
40348 }
40349
40350
40351 var serviceTaginfo = {
40352
40353     init: function() {
40354         inflight$1 = {};
40355         taginfoCache = {};
40356         popularKeys = {};
40357
40358         // Fetch popular keys.  We'll exclude these from `values`
40359         // lookups because they stress taginfo, and they aren't likely
40360         // to yield meaningful autocomplete results.. see #3955
40361         var params = { rp: 100, sortname: 'values_all', sortorder: 'desc', page: 1, debounce: false };
40362         this.keys(params, function(err, data) {
40363             if (err) return;
40364             data.forEach(function(d) {
40365                 if (d.value === 'opening_hours') return;  // exception
40366                 popularKeys[d.value] = true;
40367             });
40368         });
40369     },
40370
40371
40372     reset: function() {
40373         forEach(inflight$1, function(req) { req.abort(); });
40374         inflight$1 = {};
40375     },
40376
40377
40378     keys: function(params, callback) {
40379         var doRequest = params.debounce ? debouncedRequest : request;
40380         params = clean(setSort(params));
40381         params = assignIn({ rp: 10, sortname: 'count_all', sortorder: 'desc', page: 1 }, params);
40382
40383         var url = apibase$3 + 'keys/all?' + utilQsString(params);
40384         doRequest(url, params, false, callback, function(err, d) {
40385             if (err) {
40386                 callback(err);
40387             } else {
40388                 var f = filterKeys(params.filter);
40389                 var result = d.data.filter(f).sort(sortKeys).map(valKey);
40390                 taginfoCache[url] = result;
40391                 callback(null, result);
40392             }
40393         });
40394     },
40395
40396
40397     multikeys: function(params, callback) {
40398         var doRequest = params.debounce ? debouncedRequest : request;
40399         params = clean(setSort(params));
40400         params = assignIn({ rp: 25, sortname: 'count_all', sortorder: 'desc', page: 1 }, params);
40401         var prefix = params.query;
40402
40403         var url = apibase$3 + 'keys/all?' + utilQsString(params);
40404         doRequest(url, params, true, callback, function(err, d) {
40405             if (err) {
40406                 callback(err);
40407             } else {
40408                 var f = filterMultikeys(prefix);
40409                 var result = d.data.filter(f).map(valKey);
40410                 taginfoCache[url] = result;
40411                 callback(null, result);
40412             }
40413         });
40414     },
40415
40416
40417     values: function(params, callback) {
40418         // Exclude popular keys from values lookups.. see #3955
40419         var key = params.key;
40420         if (key && popularKeys[key]) {
40421             callback(null, []);
40422             return;
40423         }
40424
40425         var doRequest = params.debounce ? debouncedRequest : request;
40426         params = clean(setSort(setFilter(params)));
40427         params = assignIn({ rp: 25, sortname: 'count_all', sortorder: 'desc', page: 1 }, params);
40428
40429         var url = apibase$3 + 'key/values?' + utilQsString(params);
40430         doRequest(url, params, false, callback, function(err, d) {
40431             if (err) {
40432                 callback(err);
40433             } else {
40434                 // In most cases we prefer taginfo value results with lowercase letters.
40435                 // A few OSM keys expect values to contain uppercase values (see #3377).
40436                 // This is not an exhaustive list (e.g. `name` also has uppercase values)
40437                 // but these are the fields where taginfo value lookup is most useful.
40438                 var re = /network|taxon|genus|species|brand|grape_variety|rating|:output|_hours|_times/;
40439                 var allowUpperCase = (params.key.match(re) !== null);
40440                 var f = filterValues(allowUpperCase);
40441
40442                 var result = d.data.filter(f).map(valKeyDescription);
40443                 taginfoCache[url] = result;
40444                 callback(null, result);
40445             }
40446         });
40447     },
40448
40449
40450     roles: function(params, callback) {
40451         var doRequest = params.debounce ? debouncedRequest : request;
40452         var geometry = params.geometry;
40453         params = clean(setSortMembers(params));
40454         params = assignIn({ rp: 25, sortname: 'count_all_members', sortorder: 'desc', page: 1 }, params);
40455
40456         var url = apibase$3 + 'relation/roles?' + utilQsString(params);
40457         doRequest(url, params, true, callback, function(err, d) {
40458             if (err) {
40459                 callback(err);
40460             } else {
40461                 var f = filterRoles(geometry);
40462                 var result = d.data.filter(f).map(roleKey);
40463                 taginfoCache[url] = result;
40464                 callback(null, result);
40465             }
40466         });
40467     },
40468
40469
40470     docs: function(params, callback) {
40471         var doRequest = params.debounce ? debouncedRequest : request;
40472         params = clean(setSort(params));
40473
40474         var path = 'key/wiki_pages?';
40475         if (params.value) path = 'tag/wiki_pages?';
40476         else if (params.rtype) path = 'relation/wiki_pages?';
40477
40478         var url = apibase$3 + path + utilQsString(params);
40479         doRequest(url, params, true, callback, function(err, d) {
40480             if (err) {
40481                 callback(err);
40482             } else {
40483                 taginfoCache[url] = d.data;
40484                 callback(null, d.data);
40485             }
40486         });
40487     },
40488
40489
40490     apibase: function(_) {
40491         if (!arguments.length) return apibase$3;
40492         apibase$3 = _;
40493         return this;
40494     }
40495
40496 };
40497
40498 var jsonpCache = {};
40499 window.jsonpCache = jsonpCache;
40500
40501 function jsonpRequest(url, callback) {
40502
40503   if (window.JSONP_FIX) {
40504     if (window.JSONP_DELAY === 0) {
40505       callback(window.JSONP_FIX);
40506     } else {
40507       setTimeout(function() {
40508         callback(window.JSONP_FIX);
40509       }, window.JSONP_DELAY || 0);
40510     }
40511     return;
40512   }
40513
40514   function rand() {
40515     var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
40516       c = '', i = -1;
40517     while (++i < 15) c += chars.charAt(Math.floor(Math.random() * 52));
40518     return c;
40519   }
40520
40521   function create(url) {
40522     var e = url.match(/callback=(\w+)/),
40523       c = e ? e[1] : rand();
40524     jsonpCache[c] = function(data) {
40525       callback(data);
40526       delete jsonpCache[c];
40527       script.remove();
40528     };
40529     return 'jsonpCache.' + c;
40530   }
40531
40532   var cb = create(url),
40533     script = d3_select('head')
40534     .append('script')
40535     .attr('type', 'text/javascript')
40536     .attr('src', url.replace(/(\{|%7B)callback(\}|%7D)/, cb));
40537 }
40538
40539 var endpoint = 'https://www.wikidata.org/w/api.php?';
40540
40541 var serviceWikidata = {
40542
40543     init: function() {},
40544     reset: function() {},
40545
40546
40547     // Given a Wikipedia language and article title, return an array of
40548     // corresponding Wikidata entities.
40549     itemsByTitle: function(lang, title, callback) {
40550         if (!title) {
40551             callback('', {});
40552             return;
40553         }
40554
40555         lang = lang || 'en';
40556         jsonpRequest(endpoint + utilQsString({
40557             action: 'wbgetentities',
40558             format: 'json',
40559             sites: lang.replace(/-/g, '_') + 'wiki',
40560             titles: title,
40561             languages: 'en', // shrink response by filtering to one language
40562             callback: '{callback}'
40563         }), function(data) {
40564             if (!data || data.error) {
40565                 callback('', {});
40566             } else {
40567                 callback(title, data.entities || {});
40568             }
40569         });
40570     }
40571
40572 };
40573
40574 var endpoint$1 = 'https://en.wikipedia.org/w/api.php?';
40575
40576 var serviceWikipedia = {
40577
40578     init: function() {},
40579     reset: function() {},
40580
40581
40582     search: function(lang, query, callback) {
40583         if (!query) {
40584             callback('', []);
40585             return;
40586         }
40587
40588         lang = lang || 'en';
40589         jsonpRequest(endpoint$1.replace('en', lang) +
40590             utilQsString({
40591                 action: 'query',
40592                 list: 'search',
40593                 srlimit: '10',
40594                 srinfo: 'suggestion',
40595                 format: 'json',
40596                 callback: '{callback}',
40597                 srsearch: query
40598             }), function(data) {
40599                 if (!data || !data.query || !data.query.search || data.error) {
40600                     callback('', []);
40601                 } else {
40602                     var results = data.query.search.map(function(d) { return d.title; });
40603                     callback(query, results);
40604                 }
40605             }
40606         );
40607     },
40608
40609
40610     suggestions: function(lang, query, callback) {
40611         if (!query) {
40612             callback('', []);
40613             return;
40614         }
40615
40616         lang = lang || 'en';
40617         jsonpRequest(endpoint$1.replace('en', lang) +
40618             utilQsString({
40619                 action: 'opensearch',
40620                 namespace: 0,
40621                 suggest: '',
40622                 format: 'json',
40623                 callback: '{callback}',
40624                 search: query
40625             }), function(data) {
40626                 if (!data || data.error) {
40627                     callback('', []);
40628                 } else {
40629                     callback(data[0], data[1] || []);
40630                 }
40631             }
40632         );
40633     },
40634
40635
40636     translations: function(lang, title, callback) {
40637         if (!title) {
40638             callback({});
40639             return;
40640         }
40641
40642         jsonpRequest(endpoint$1.replace('en', lang) +
40643             utilQsString({
40644                 action: 'query',
40645                 prop: 'langlinks',
40646                 format: 'json',
40647                 callback: '{callback}',
40648                 lllimit: 500,
40649                 titles: title
40650             }), function(data) {
40651                 if (!data || !data.query || !data.query.pages || data.error) {
40652                     callback({});
40653                 } else {
40654                     var list = data.query.pages[Object.keys(data.query.pages)[0]],
40655                         translations = {};
40656                     if (list && list.langlinks) {
40657                         list.langlinks.forEach(function(d) {
40658                             translations[d.lang] = d['*'];
40659                         });
40660                     }
40661                     callback(translations);
40662                 }
40663             }
40664         );
40665     }
40666
40667 };
40668
40669 var services = {
40670     geocoder: serviceNominatim,
40671     mapillary: serviceMapillary,
40672     openstreetcam: serviceOpenstreetcam,
40673     osm: serviceOsm,
40674     taginfo: serviceTaginfo,
40675     wikidata: serviceWikidata,
40676     wikipedia: serviceWikipedia
40677 };
40678
40679 function svgAreas(projection, context) {
40680     // Patterns only work in Firefox when set directly on element.
40681     // (This is not a bug: https://bugzilla.mozilla.org/show_bug.cgi?id=750632)
40682     var patterns = {
40683         beach: 'beach',
40684         cemetery: 'cemetery',
40685         construction: 'construction',
40686         farm: 'farmland',
40687         farmland: 'farmland',
40688         grave_yard: 'cemetery',
40689         meadow: 'meadow',
40690         military: 'construction',
40691         orchard: 'orchard',
40692         sand: 'beach',
40693         scrub: 'scrub',
40694         wetland: 'wetland',
40695     };
40696
40697     var patternKeys = ['landuse', 'natural', 'amenity'];
40698
40699
40700     function setPattern(d) {
40701         for (var i = 0; i < patternKeys.length; i++) {
40702             if (d.tags.building && d.tags.building !== 'no') continue;
40703
40704             if (patterns.hasOwnProperty(d.tags[patternKeys[i]])) {
40705                 this.style.fill = this.style.stroke = 'url("#pattern-' + patterns[d.tags[patternKeys[i]]] + '")';
40706                 return;
40707             }
40708         }
40709         this.style.fill = this.style.stroke = '';
40710     }
40711
40712
40713     function drawTargets(selection, graph, entities, filter) {
40714         var targetClass = context.getDebug('target') ? 'pink ' : 'nocolor ';
40715         var nopeClass = context.getDebug('target') ? 'red ' : 'nocolor ';
40716         var getPath = svgPath(projection).geojson;
40717         var activeID = context.activeID();
40718
40719         // The targets and nopes will be MultiLineString sub-segments of the ways
40720         var data = { targets: [], nopes: [] };
40721
40722         entities.forEach(function(way) {
40723             var features = svgSegmentWay(way, graph, activeID);
40724             data.targets.push.apply(data.targets, features.passive);
40725             data.nopes.push.apply(data.nopes, features.active);
40726         });
40727
40728
40729         // Targets allow hover and vertex snapping
40730         var targets = selection.selectAll('.area.target-allowed')
40731             .filter(function(d) { return filter(d.properties.entity); })
40732             .data(data.targets, function key(d) { return d.id; });
40733
40734         // exit
40735         targets.exit()
40736             .remove();
40737
40738         // enter/update
40739         targets.enter()
40740             .append('path')
40741             .merge(targets)
40742             .attr('d', getPath)
40743             .attr('class', function(d) { return 'way area target target-allowed ' + targetClass + d.id; });
40744
40745
40746         // NOPE
40747         var nopes = selection.selectAll('.area.target-nope')
40748             .filter(function(d) { return filter(d.properties.entity); })
40749             .data(data.nopes, function key(d) { return d.id; });
40750
40751         // exit
40752         nopes.exit()
40753             .remove();
40754
40755         // enter/update
40756         nopes.enter()
40757             .append('path')
40758             .merge(nopes)
40759             .attr('d', getPath)
40760             .attr('class', function(d) { return 'way area target target-nope ' + nopeClass + d.id; });
40761     }
40762
40763
40764
40765     function drawAreas(selection, graph, entities, filter) {
40766         var path = svgPath(projection, graph, true),
40767             areas = {},
40768             multipolygon;
40769
40770         for (var i = 0; i < entities.length; i++) {
40771             var entity = entities[i];
40772             if (entity.geometry(graph) !== 'area') continue;
40773
40774             multipolygon = osmIsSimpleMultipolygonOuterMember(entity, graph);
40775             if (multipolygon) {
40776                 areas[multipolygon.id] = {
40777                     entity: multipolygon.mergeTags(entity.tags),
40778                     area: Math.abs(entity.area(graph))
40779                 };
40780             } else if (!areas[entity.id]) {
40781                 areas[entity.id] = {
40782                     entity: entity,
40783                     area: Math.abs(entity.area(graph))
40784                 };
40785             }
40786         }
40787
40788         areas = values$1(areas).filter(function hasPath(a) { return path(a.entity); });
40789         areas.sort(function areaSort(a, b) { return b.area - a.area; });
40790         areas = map$4(areas, 'entity');
40791
40792         var strokes = areas.filter(function(area) {
40793             return area.type === 'way';
40794         });
40795
40796         var data = {
40797             clip: areas,
40798             shadow: strokes,
40799             stroke: strokes,
40800             fill: areas
40801         };
40802
40803         var clipPaths = context.surface().selectAll('defs').selectAll('.clipPath')
40804            .filter(filter)
40805            .data(data.clip, osmEntity.key);
40806
40807         clipPaths.exit()
40808            .remove();
40809
40810         var clipPathsEnter = clipPaths.enter()
40811            .append('clipPath')
40812            .attr('class', 'clipPath')
40813            .attr('id', function(entity) { return entity.id + '-clippath'; });
40814
40815         clipPathsEnter
40816            .append('path');
40817
40818         clipPaths.merge(clipPathsEnter)
40819            .selectAll('path')
40820            .attr('d', path);
40821
40822
40823         var layer = selection.selectAll('.layer-areas .layer-areas-areas');
40824
40825         var areagroup = layer
40826             .selectAll('g.areagroup')
40827             .data(['fill', 'shadow', 'stroke']);
40828
40829         areagroup = areagroup.enter()
40830             .append('g')
40831             .attr('class', function(d) { return 'areagroup area-' + d; })
40832             .merge(areagroup);
40833
40834         var paths = areagroup
40835             .selectAll('path')
40836             .filter(filter)
40837             .data(function(layer) { return data[layer]; }, osmEntity.key);
40838
40839         paths.exit()
40840             .remove();
40841
40842         var fills = selection.selectAll('.area-fill path.area').nodes();
40843
40844         var bisect = d3_bisector(function(node) {
40845             return -node.__data__.area(graph);
40846         }).left;
40847
40848         function sortedByArea(entity) {
40849             if (this._parent.__data__ === 'fill') {
40850                 return fills[bisect(fills, -entity.area(graph))];
40851             }
40852         }
40853
40854         paths = paths.enter()
40855             .insert('path', sortedByArea)
40856             .merge(paths)
40857             .each(function(entity) {
40858                 var layer = this.parentNode.__data__;
40859
40860                 this.setAttribute('class', entity.type + ' area ' + layer + ' ' + entity.id);
40861
40862                 if (layer === 'fill') {
40863                     this.setAttribute('clip-path', 'url(#' + entity.id + '-clippath)');
40864                     setPattern.apply(this, arguments);
40865                 }
40866             })
40867             .call(svgTagClasses())
40868             .attr('d', path);
40869
40870
40871         // touch targets
40872         selection.selectAll('.layer-areas .layer-areas-targets')
40873             .call(drawTargets, graph, data.stroke, filter);
40874     }
40875
40876     return drawAreas;
40877 }
40878
40879 function svgDebug(projection, context) {
40880
40881     function multipolygons(imagery) {
40882         return imagery.map(function(data$$1) {
40883             return {
40884                 type: 'MultiPolygon',
40885                 coordinates: [ data$$1.polygon ]
40886             };
40887         });
40888     }
40889
40890     function drawDebug(selection) {
40891         var showsTile = context.getDebug('tile');
40892         var showsCollision = context.getDebug('collision');
40893         var showsImagery = context.getDebug('imagery');
40894         var showsImperial = context.getDebug('imperial');
40895         var showsDriveLeft = context.getDebug('driveLeft');
40896         var showsTouchTargets = context.getDebug('target');
40897
40898         var debugData = [];
40899         if (showsTile) {
40900             debugData.push({ class: 'red', label: 'tile' });
40901         }
40902         if (showsCollision) {
40903             debugData.push({ class: 'yellow', label: 'collision' });
40904         }
40905         if (showsImagery) {
40906             debugData.push({ class: 'orange', label: 'imagery' });
40907         }
40908         if (showsImperial) {
40909             debugData.push({ class: 'cyan', label: 'imperial' });
40910         }
40911         if (showsDriveLeft) {
40912             debugData.push({ class: 'green', label: 'driveLeft' });
40913         }
40914         if (showsTouchTargets) {
40915             debugData.push({ class: 'pink', label: 'touchTargets' });
40916         }
40917
40918
40919         var legend = d3_select('#content')
40920             .selectAll('.debug-legend')
40921             .data(debugData.length ? [0] : []);
40922
40923         legend.exit()
40924             .remove();
40925
40926         legend = legend.enter()
40927             .append('div')
40928             .attr('class', 'fillD debug-legend')
40929             .merge(legend);
40930
40931
40932         var legendItems = legend.selectAll('.debug-legend-item')
40933             .data(debugData, function(d) { return d.label; });
40934
40935         legendItems.exit()
40936             .remove();
40937
40938         legendItems.enter()
40939             .append('span')
40940             .attr('class', function(d) { return 'debug-legend-item ' + d.class; })
40941             .text(function(d) { return d.label; });
40942
40943
40944         var layer = selection.selectAll('.layer-debug')
40945             .data(showsImagery || showsImperial || showsDriveLeft ? [0] : []);
40946
40947         layer.exit()
40948             .remove();
40949
40950         layer = layer.enter()
40951             .append('g')
40952             .attr('class', 'layer-debug')
40953             .merge(layer);
40954
40955
40956         var extent = context.map().extent();
40957         var dataImagery = data.imagery || [];
40958         var availableImagery = showsImagery && multipolygons(dataImagery.filter(function(source) {
40959             if (!source.polygon) return false;
40960             return source.polygon.some(function(polygon) {
40961                 return geoPolygonIntersectsPolygon(polygon, extent, true);
40962             });
40963         }));
40964
40965         var imagery = layer.selectAll('path.debug-imagery')
40966             .data(showsImagery ? availableImagery : []);
40967
40968         imagery.exit()
40969             .remove();
40970
40971         imagery.enter()
40972             .append('path')
40973             .attr('class', 'debug-imagery debug orange');
40974
40975
40976         var imperial = layer
40977             .selectAll('path.debug-imperial')
40978             .data(showsImperial ? [dataImperial] : []);
40979
40980         imperial.exit()
40981             .remove();
40982
40983         imperial.enter()
40984             .append('path')
40985             .attr('class', 'debug-imperial debug cyan');
40986
40987
40988         var driveLeft = layer
40989             .selectAll('path.debug-drive-left')
40990             .data(showsDriveLeft ? [dataDriveLeft] : []);
40991
40992         driveLeft.exit()
40993             .remove();
40994
40995         driveLeft.enter()
40996             .append('path')
40997             .attr('class', 'debug-drive-left debug green');
40998
40999
41000         // update
41001         layer.selectAll('path')
41002             .attr('d', svgPath(projection).geojson);
41003     }
41004
41005
41006     // This looks strange because `enabled` methods on other layers are
41007     // chainable getter/setters, and this one is just a getter.
41008     drawDebug.enabled = function() {
41009         if (!arguments.length) {
41010             return context.getDebug('tile') ||
41011                 context.getDebug('collision') ||
41012                 context.getDebug('imagery') ||
41013                 context.getDebug('imperial') ||
41014                 context.getDebug('driveLeft') ||
41015                 context.getDebug('target');
41016         } else {
41017             return this;
41018         }
41019     };
41020
41021
41022     return drawDebug;
41023 }
41024
41025 /*
41026     A standalone SVG element that contains only a `defs` sub-element. To be
41027     used once globally, since defs IDs must be unique within a document.
41028 */
41029 function svgDefs(context) {
41030
41031     function SVGSpriteDefinition(id, href) {
41032         return function(defs) {
41033             d3_request(href)
41034                 .mimeType('image/svg+xml')
41035                 .response(function(xhr) { return xhr.responseXML; })
41036                 .get(function(err, svg) {
41037                     if (err) return;
41038                     defs.node().appendChild(
41039                         d3_select(svg.documentElement).attr('id', id).node()
41040                     );
41041                 });
41042         };
41043     }
41044
41045
41046     return function drawDefs(selection) {
41047         var defs = selection.append('defs');
41048
41049         // markers
41050         defs
41051             .append('marker')
41052             .attr('id', 'oneway-marker')
41053             .attr('viewBox', '0 0 10 5')
41054             .attr('refX', 2.5)
41055             .attr('refY', 2.5)
41056             .attr('markerWidth', 2)
41057             .attr('markerHeight', 2)
41058             .attr('markerUnits', 'strokeWidth')
41059             .attr('orient', 'auto')
41060             .append('path')
41061             .attr('class', 'oneway-marker-path')
41062             .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')
41063             .attr('stroke', 'none')
41064             .attr('fill', '#000')
41065             .attr('opacity', '0.75');
41066
41067         defs
41068             .append('marker')
41069             .attr('id', 'viewfield-marker')
41070             .attr('viewBox', '0 0 16 16')
41071             .attr('refX', 8)
41072             .attr('refY', 16)
41073             .attr('markerWidth', 4)
41074             .attr('markerHeight', 4)
41075             .attr('markerUnits', 'strokeWidth')
41076             .attr('orient', 'auto')
41077             .append('path')
41078             .attr('class', 'viewfield-marker-path')
41079             .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')
41080             .attr('fill', '#333')
41081             .attr('fill-opacity', '0.75')
41082             .attr('stroke', '#fff')
41083             .attr('stroke-width', '0.5px')
41084             .attr('stroke-opacity', '0.75');
41085
41086         defs
41087             .append('marker')
41088             .attr('id', 'viewfield-marker-wireframe')
41089             .attr('viewBox', '0 0 16 16')
41090             .attr('refX', 8)
41091             .attr('refY', 16)
41092             .attr('markerWidth', 4)
41093             .attr('markerHeight', 4)
41094             .attr('markerUnits', 'strokeWidth')
41095             .attr('orient', 'auto')
41096             .append('path')
41097             .attr('class', 'viewfield-marker-path')
41098             .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')
41099             .attr('fill', 'none')
41100             .attr('stroke', '#fff')
41101             .attr('stroke-width', '0.5px')
41102             .attr('stroke-opacity', '0.75');
41103
41104         // patterns
41105         var patterns = defs.selectAll('pattern')
41106             .data([
41107                 // pattern name, pattern image name
41108                 ['wetland', 'wetland'],
41109                 ['construction', 'construction'],
41110                 ['cemetery', 'cemetery'],
41111                 ['orchard', 'orchard'],
41112                 ['farmland', 'farmland'],
41113                 ['beach', 'dots'],
41114                 ['scrub', 'dots'],
41115                 ['meadow', 'dots']
41116             ])
41117             .enter()
41118             .append('pattern')
41119             .attr('id', function (d) { return 'pattern-' + d[0]; })
41120             .attr('width', 32)
41121             .attr('height', 32)
41122             .attr('patternUnits', 'userSpaceOnUse');
41123
41124         patterns
41125             .append('rect')
41126             .attr('x', 0)
41127             .attr('y', 0)
41128             .attr('width', 32)
41129             .attr('height', 32)
41130             .attr('class', function (d) { return 'pattern-color-' + d[0]; });
41131
41132         patterns
41133             .append('image')
41134             .attr('x', 0)
41135             .attr('y', 0)
41136             .attr('width', 32)
41137             .attr('height', 32)
41138             .attr('xlink:href', function (d) {
41139                 return context.imagePath('pattern/' + d[1] + '.png');
41140             });
41141
41142         // clip paths
41143         defs.selectAll('clipPath')
41144             .data([12, 18, 20, 32, 45])
41145             .enter()
41146             .append('clipPath')
41147             .attr('id', function (d) { return 'clip-square-' + d; })
41148             .append('rect')
41149             .attr('x', 0)
41150             .attr('y', 0)
41151             .attr('width', function (d) { return d; })
41152             .attr('height', function (d) { return d; });
41153
41154         // symbol spritesheets
41155         defs
41156             .call(SVGSpriteDefinition('iD-sprite', context.imagePath('iD-sprite.svg')))
41157             .call(SVGSpriteDefinition('maki-sprite', context.imagePath('maki-sprite.svg')));
41158     };
41159 }
41160
41161 /**
41162  * Checks if `value` is `undefined`.
41163  *
41164  * @static
41165  * @since 0.1.0
41166  * @memberOf _
41167  * @category Lang
41168  * @param {*} value The value to check.
41169  * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
41170  * @example
41171  *
41172  * _.isUndefined(void 0);
41173  * // => true
41174  *
41175  * _.isUndefined(null);
41176  * // => false
41177  */
41178 function isUndefined(value) {
41179   return value === undefined;
41180 }
41181
41182 //[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]
41183 //[4a]          NameChar           ::=          NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
41184 //[5]           Name       ::=          NameStartChar (NameChar)*
41185 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
41186 var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\\u00B7\\u0300-\\u036F\\u203F-\\u2040]");
41187 var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$');
41188 //var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/
41189 //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(',')
41190
41191 //S_TAG,        S_ATTR, S_EQ,   S_ATTR_NOQUOT_VALUE
41192 //S_ATTR_SPACE, S_ATTR_END,     S_TAG_SPACE, S_TAG_CLOSE
41193 var S_TAG = 0;//tag name offerring
41194 var S_ATTR = 1;//attr name offerring 
41195 var S_ATTR_SPACE=2;//attr name end and space offer
41196 var S_EQ = 3;//=space?
41197 var S_ATTR_NOQUOT_VALUE = 4;//attr value(no quot value only)
41198 var S_ATTR_END = 5;//attr value end and no space(quot end)
41199 var S_TAG_SPACE = 6;//(attr value end || tag end ) && (space offer)
41200 var S_TAG_CLOSE = 7;//closed el<el />
41201
41202 function XMLReader(){
41203         
41204 }
41205
41206 XMLReader.prototype = {
41207         parse:function(source,defaultNSMap,entityMap){
41208                 var domBuilder = this.domBuilder;
41209                 domBuilder.startDocument();
41210                 _copy(defaultNSMap ,defaultNSMap = {});
41211                 parse$1(source,defaultNSMap,entityMap,
41212                                 domBuilder,this.errorHandler);
41213                 domBuilder.endDocument();
41214         }
41215 };
41216 function parse$1(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){
41217         function fixedFromCharCode(code) {
41218                 // String.prototype.fromCharCode does not supports
41219                 // > 2 bytes unicode chars directly
41220                 if (code > 0xffff) {
41221                         code -= 0x10000;
41222                         var surrogate1 = 0xd800 + (code >> 10)
41223                                 , surrogate2 = 0xdc00 + (code & 0x3ff);
41224
41225                         return String.fromCharCode(surrogate1, surrogate2);
41226                 } else {
41227                         return String.fromCharCode(code);
41228                 }
41229         }
41230         function entityReplacer(a){
41231                 var k = a.slice(1,-1);
41232                 if(k in entityMap){
41233                         return entityMap[k]; 
41234                 }else if(k.charAt(0) === '#'){
41235                         return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x')))
41236                 }else{
41237                         errorHandler.error('entity not found:'+a);
41238                         return a;
41239                 }
41240         }
41241         function appendText(end){//has some bugs
41242                 if(end>start){
41243                         var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer);
41244                         locator&&position(start);
41245                         domBuilder.characters(xt,0,end-start);
41246                         start = end;
41247                 }
41248         }
41249         function position(p,m){
41250                 while(p>=lineEnd && (m = linePattern.exec(source))){
41251                         lineStart = m.index;
41252                         lineEnd = lineStart + m[0].length;
41253                         locator.lineNumber++;
41254                         //console.log('line++:',locator,startPos,endPos)
41255                 }
41256                 locator.columnNumber = p-lineStart+1;
41257         }
41258         var lineStart = 0;
41259         var lineEnd = 0;
41260         var linePattern = /.*(?:\r\n?|\n)|.*$/g;
41261         var locator = domBuilder.locator;
41262         
41263         var parseStack = [{currentNSMap:defaultNSMapCopy}];
41264         var closeMap = {};
41265         var start = 0;
41266         while(true){
41267                 try{
41268                         var tagStart = source.indexOf('<',start);
41269                         if(tagStart<0){
41270                                 if(!source.substr(start).match(/^\s*$/)){
41271                                         var doc = domBuilder.doc;
41272                                 var text = doc.createTextNode(source.substr(start));
41273                                 doc.appendChild(text);
41274                                 domBuilder.currentElement = text;
41275                                 }
41276                                 return;
41277                         }
41278                         if(tagStart>start){
41279                                 appendText(tagStart);
41280                         }
41281                         switch(source.charAt(tagStart+1)){
41282                         case '/':
41283                                 var end = source.indexOf('>',tagStart+3);
41284                                 var tagName = source.substring(tagStart+2,end);
41285                                 var config = parseStack.pop();
41286                                 if(end<0){
41287                                         
41288                                 tagName = source.substring(tagStart+2).replace(/[\s<].*/,'');
41289                                 //console.error('#@@@@@@'+tagName)
41290                                 errorHandler.error("end tag name: "+tagName+' is not complete:'+config.tagName);
41291                                 end = tagStart+1+tagName.length;
41292                         }else if(tagName.match(/\s</)){
41293                                 tagName = tagName.replace(/[\s<].*/,'');
41294                                 errorHandler.error("end tag name: "+tagName+' maybe not complete');
41295                                 end = tagStart+1+tagName.length;
41296                                 }
41297                                 //console.error(parseStack.length,parseStack)
41298                                 //console.error(config);
41299                                 var localNSMap = config.localNSMap;
41300                                 var endMatch = config.tagName == tagName;
41301                                 var endIgnoreCaseMach = endMatch || config.tagName&&config.tagName.toLowerCase() == tagName.toLowerCase();
41302                         if(endIgnoreCaseMach){
41303                                 domBuilder.endElement(config.uri,config.localName,tagName);
41304                                         if(localNSMap){
41305                                                 for(var prefix in localNSMap){
41306                                                         domBuilder.endPrefixMapping(prefix) ;
41307                                                 }
41308                                         }
41309                                         if(!endMatch){
41310                                 errorHandler.fatalError("end tag name: "+tagName+' is not match the current start tagName:'+config.tagName );
41311                                         }
41312                         }else{
41313                                 parseStack.push(config);
41314                         }
41315                                 
41316                                 end++;
41317                                 break;
41318                                 // end elment
41319                         case '?':// <?...?>
41320                                 locator&&position(tagStart);
41321                                 end = parseInstruction(source,tagStart,domBuilder);
41322                                 break;
41323                         case '!':// <!doctype,<![CDATA,<!--
41324                                 locator&&position(tagStart);
41325                                 end = parseDCC(source,tagStart,domBuilder,errorHandler);
41326                                 break;
41327                         default:
41328                                 locator&&position(tagStart);
41329                                 var el = new ElementAttributes();
41330                                 var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
41331                                 //elStartEnd
41332                                 var end = parseElementStartPart(source,tagStart,el,currentNSMap,entityReplacer,errorHandler);
41333                                 var len = el.length;
41334                                 
41335                                 
41336                                 if(!el.closed && fixSelfClosed(source,end,el.tagName,closeMap)){
41337                                         el.closed = true;
41338                                         if(!entityMap.nbsp){
41339                                                 errorHandler.warning('unclosed xml attribute');
41340                                         }
41341                                 }
41342                                 if(locator && len){
41343                                         var locator2 = copyLocator(locator,{});
41344                                         //try{//attribute position fixed
41345                                         for(var i = 0;i<len;i++){
41346                                                 var a = el[i];
41347                                                 position(a.offset);
41348                                                 a.locator = copyLocator(locator,{});
41349                                         }
41350                                         //}catch(e){console.error('@@@@@'+e)}
41351                                         domBuilder.locator = locator2;
41352                                         if(appendElement(el,domBuilder,currentNSMap)){
41353                                                 parseStack.push(el);
41354                                         }
41355                                         domBuilder.locator = locator;
41356                                 }else{
41357                                         if(appendElement(el,domBuilder,currentNSMap)){
41358                                                 parseStack.push(el);
41359                                         }
41360                                 }
41361                                 
41362                                 
41363                                 
41364                                 if(el.uri === 'http://www.w3.org/1999/xhtml' && !el.closed){
41365                                         end = parseHtmlSpecialContent(source,end,el.tagName,entityReplacer,domBuilder);
41366                                 }else{
41367                                         end++;
41368                                 }
41369                         }
41370                 }catch(e){
41371                         errorHandler.error('element parse error: '+e);
41372                         //errorHandler.error('element parse error: '+e);
41373                         end = -1;
41374                         //throw e;
41375                 }
41376                 if(end>start){
41377                         start = end;
41378                 }else{
41379                         //TODO: 这里有可能sax回退,有位置错误风险
41380                         appendText(Math.max(tagStart,start)+1);
41381                 }
41382         }
41383 }
41384 function copyLocator(f,t){
41385         t.lineNumber = f.lineNumber;
41386         t.columnNumber = f.columnNumber;
41387         return t;
41388 }
41389
41390 /**
41391  * @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack);
41392  * @return end of the elementStartPart(end of elementEndPart for selfClosed el)
41393  */
41394 function parseElementStartPart(source,start,el,currentNSMap,entityReplacer,errorHandler){
41395         var attrName;
41396         var value;
41397         var p = ++start;
41398         var s = S_TAG;//status
41399         while(true){
41400                 var c = source.charAt(p);
41401                 switch(c){
41402                 case '=':
41403                         if(s === S_ATTR){//attrName
41404                                 attrName = source.slice(start,p);
41405                                 s = S_EQ;
41406                         }else if(s === S_ATTR_SPACE){
41407                                 s = S_EQ;
41408                         }else{
41409                                 //fatalError: equal must after attrName or space after attrName
41410                                 throw new Error('attribute equal must after attrName');
41411                         }
41412                         break;
41413                 case '\'':
41414                 case '"':
41415                         if(s === S_EQ || s === S_ATTR //|| s == S_ATTR_SPACE
41416                                 ){//equal
41417                                 if(s === S_ATTR){
41418                                         errorHandler.warning('attribute value must after "="');
41419                                         attrName = source.slice(start,p);
41420                                 }
41421                                 start = p+1;
41422                                 p = source.indexOf(c,start);
41423                                 if(p>0){
41424                                         value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
41425                                         el.add(attrName,value,start-1);
41426                                         s = S_ATTR_END;
41427                                 }else{
41428                                         //fatalError: no end quot match
41429                                         throw new Error('attribute value no end \''+c+'\' match');
41430                                 }
41431                         }else if(s == S_ATTR_NOQUOT_VALUE){
41432                                 value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
41433                                 //console.log(attrName,value,start,p)
41434                                 el.add(attrName,value,start);
41435                                 //console.dir(el)
41436                                 errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!');
41437                                 start = p+1;
41438                                 s = S_ATTR_END;
41439                         }else{
41440                                 //fatalError: no equal before
41441                                 throw new Error('attribute value must after "="');
41442                         }
41443                         break;
41444                 case '/':
41445                         switch(s){
41446                         case S_TAG:
41447                                 el.setTagName(source.slice(start,p));
41448                         case S_ATTR_END:
41449                         case S_TAG_SPACE:
41450                         case S_TAG_CLOSE:
41451                                 s =S_TAG_CLOSE;
41452                                 el.closed = true;
41453                         case S_ATTR_NOQUOT_VALUE:
41454                         case S_ATTR:
41455                         case S_ATTR_SPACE:
41456                                 break;
41457                         //case S_EQ:
41458                         default:
41459                                 throw new Error("attribute invalid close char('/')")
41460                         }
41461                         break;
41462                 case ''://end document
41463                         //throw new Error('unexpected end of input')
41464                         errorHandler.error('unexpected end of input');
41465                         if(s == S_TAG){
41466                                 el.setTagName(source.slice(start,p));
41467                         }
41468                         return p;
41469                 case '>':
41470                         switch(s){
41471                         case S_TAG:
41472                                 el.setTagName(source.slice(start,p));
41473                         case S_ATTR_END:
41474                         case S_TAG_SPACE:
41475                         case S_TAG_CLOSE:
41476                                 break;//normal
41477                         case S_ATTR_NOQUOT_VALUE://Compatible state
41478                         case S_ATTR:
41479                                 value = source.slice(start,p);
41480                                 if(value.slice(-1) === '/'){
41481                                         el.closed  = true;
41482                                         value = value.slice(0,-1);
41483                                 }
41484                         case S_ATTR_SPACE:
41485                                 if(s === S_ATTR_SPACE){
41486                                         value = attrName;
41487                                 }
41488                                 if(s == S_ATTR_NOQUOT_VALUE){
41489                                         errorHandler.warning('attribute "'+value+'" missed quot(")!!');
41490                                         el.add(attrName,value.replace(/&#?\w+;/g,entityReplacer),start);
41491                                 }else{
41492                                         if(currentNSMap[''] !== 'http://www.w3.org/1999/xhtml' || !value.match(/^(?:disabled|checked|selected)$/i)){
41493                                                 errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!');
41494                                         }
41495                                         el.add(value,value,start);
41496                                 }
41497                                 break;
41498                         case S_EQ:
41499                                 throw new Error('attribute value missed!!');
41500                         }
41501 //                      console.log(tagName,tagNamePattern,tagNamePattern.test(tagName))
41502                         return p;
41503                 /*xml space '\x20' | #x9 | #xD | #xA; */
41504                 case '\u0080':
41505                         c = ' ';
41506                 default:
41507                         if(c<= ' '){//space
41508                                 switch(s){
41509                                 case S_TAG:
41510                                         el.setTagName(source.slice(start,p));//tagName
41511                                         s = S_TAG_SPACE;
41512                                         break;
41513                                 case S_ATTR:
41514                                         attrName = source.slice(start,p);
41515                                         s = S_ATTR_SPACE;
41516                                         break;
41517                                 case S_ATTR_NOQUOT_VALUE:
41518                                         var value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
41519                                         errorHandler.warning('attribute "'+value+'" missed quot(")!!');
41520                                         el.add(attrName,value,start);
41521                                 case S_ATTR_END:
41522                                         s = S_TAG_SPACE;
41523                                         break;
41524                                 //case S_TAG_SPACE:
41525                                 //case S_EQ:
41526                                 //case S_ATTR_SPACE:
41527                                 //      void();break;
41528                                 //case S_TAG_CLOSE:
41529                                         //ignore warning
41530                                 }
41531                         }else{//not space
41532 //S_TAG,        S_ATTR, S_EQ,   S_ATTR_NOQUOT_VALUE
41533 //S_ATTR_SPACE, S_ATTR_END,     S_TAG_SPACE, S_TAG_CLOSE
41534                                 switch(s){
41535                                 //case S_TAG:void();break;
41536                                 //case S_ATTR:void();break;
41537                                 //case S_ATTR_NOQUOT_VALUE:void();break;
41538                                 case S_ATTR_SPACE:
41539                                         var tagName =  el.tagName;
41540                                         if(currentNSMap[''] !== 'http://www.w3.org/1999/xhtml' || !attrName.match(/^(?:disabled|checked|selected)$/i)){
41541                                                 errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead2!!');
41542                                         }
41543                                         el.add(attrName,attrName,start);
41544                                         start = p;
41545                                         s = S_ATTR;
41546                                         break;
41547                                 case S_ATTR_END:
41548                                         errorHandler.warning('attribute space is required"'+attrName+'"!!');
41549                                 case S_TAG_SPACE:
41550                                         s = S_ATTR;
41551                                         start = p;
41552                                         break;
41553                                 case S_EQ:
41554                                         s = S_ATTR_NOQUOT_VALUE;
41555                                         start = p;
41556                                         break;
41557                                 case S_TAG_CLOSE:
41558                                         throw new Error("elements closed character '/' and '>' must be connected to");
41559                                 }
41560                         }
41561                 }//end outer switch
41562                 //console.log('p++',p)
41563                 p++;
41564         }
41565 }
41566 /**
41567  * @return true if has new namespace define
41568  */
41569 function appendElement(el,domBuilder,currentNSMap){
41570         var tagName = el.tagName;
41571         var localNSMap = null;
41572         //var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
41573         var i = el.length;
41574         while(i--){
41575                 var a = el[i];
41576                 var qName = a.qName;
41577                 var value = a.value;
41578                 var nsp = qName.indexOf(':');
41579                 if(nsp>0){
41580                         var prefix = a.prefix = qName.slice(0,nsp);
41581                         var localName = qName.slice(nsp+1);
41582                         var nsPrefix = prefix === 'xmlns' && localName;
41583                 }else{
41584                         localName = qName;
41585                         prefix = null;
41586                         nsPrefix = qName === 'xmlns' && '';
41587                 }
41588                 //can not set prefix,because prefix !== ''
41589                 a.localName = localName ;
41590                 //prefix == null for no ns prefix attribute 
41591                 if(nsPrefix !== false){//hack!!
41592                         if(localNSMap == null){
41593                                 localNSMap = {};
41594                                 //console.log(currentNSMap,0)
41595                                 _copy(currentNSMap,currentNSMap={});
41596                                 //console.log(currentNSMap,1)
41597                         }
41598                         currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
41599                         a.uri = 'http://www.w3.org/2000/xmlns/';
41600                         domBuilder.startPrefixMapping(nsPrefix, value); 
41601                 }
41602         }
41603         var i = el.length;
41604         while(i--){
41605                 a = el[i];
41606                 var prefix = a.prefix;
41607                 if(prefix){//no prefix attribute has no namespace
41608                         if(prefix === 'xml'){
41609                                 a.uri = 'http://www.w3.org/XML/1998/namespace';
41610                         }if(prefix !== 'xmlns'){
41611                                 a.uri = currentNSMap[prefix || ''];
41612                                 
41613                                 //{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)}
41614                         }
41615                 }
41616         }
41617         var nsp = tagName.indexOf(':');
41618         if(nsp>0){
41619                 prefix = el.prefix = tagName.slice(0,nsp);
41620                 localName = el.localName = tagName.slice(nsp+1);
41621         }else{
41622                 prefix = null;//important!!
41623                 localName = el.localName = tagName;
41624         }
41625         //no prefix element has default namespace
41626         var ns = el.uri = currentNSMap[prefix || ''];
41627         domBuilder.startElement(ns,localName,tagName,el);
41628         //endPrefixMapping and startPrefixMapping have not any help for dom builder
41629         //localNSMap = null
41630         if(el.closed){
41631                 domBuilder.endElement(ns,localName,tagName);
41632                 if(localNSMap){
41633                         for(prefix in localNSMap){
41634                                 domBuilder.endPrefixMapping(prefix); 
41635                         }
41636                 }
41637         }else{
41638                 el.currentNSMap = currentNSMap;
41639                 el.localNSMap = localNSMap;
41640                 //parseStack.push(el);
41641                 return true;
41642         }
41643 }
41644 function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){
41645         if(/^(?:script|textarea)$/i.test(tagName)){
41646                 var elEndStart =  source.indexOf('</'+tagName+'>',elStartEnd);
41647                 var text = source.substring(elStartEnd+1,elEndStart);
41648                 if(/[&<]/.test(text)){
41649                         if(/^script$/i.test(tagName)){
41650                                 //if(!/\]\]>/.test(text)){
41651                                         //lexHandler.startCDATA();
41652                                         domBuilder.characters(text,0,text.length);
41653                                         //lexHandler.endCDATA();
41654                                         return elEndStart;
41655                                 //}
41656                         }//}else{//text area
41657                                 text = text.replace(/&#?\w+;/g,entityReplacer);
41658                                 domBuilder.characters(text,0,text.length);
41659                                 return elEndStart;
41660                         //}
41661                         
41662                 }
41663         }
41664         return elStartEnd+1;
41665 }
41666 function fixSelfClosed(source,elStartEnd,tagName,closeMap){
41667         //if(tagName in closeMap){
41668         var pos = closeMap[tagName];
41669         if(pos == null){
41670                 //console.log(tagName)
41671                 pos =  source.lastIndexOf('</'+tagName+'>');
41672                 if(pos<elStartEnd){//忘记闭合
41673                         pos = source.lastIndexOf('</'+tagName);
41674                 }
41675                 closeMap[tagName] =pos;
41676         }
41677         return pos<elStartEnd;
41678         //} 
41679 }
41680 function _copy(source,target){
41681         for(var n in source){target[n] = source[n];}
41682 }
41683 function parseDCC(source,start,domBuilder,errorHandler){//sure start with '<!'
41684         var next= source.charAt(start+2);
41685         switch(next){
41686         case '-':
41687                 if(source.charAt(start + 3) === '-'){
41688                         var end = source.indexOf('-->',start+4);
41689                         //append comment source.substring(4,end)//<!--
41690                         if(end>start){
41691                                 domBuilder.comment(source,start+4,end-start-4);
41692                                 return end+3;
41693                         }else{
41694                                 errorHandler.error("Unclosed comment");
41695                                 return -1;
41696                         }
41697                 }else{
41698                         //error
41699                         return -1;
41700                 }
41701         default:
41702                 if(source.substr(start+3,6) == 'CDATA['){
41703                         var end = source.indexOf(']]>',start+9);
41704                         domBuilder.startCDATA();
41705                         domBuilder.characters(source,start+9,end-start-9);
41706                         domBuilder.endCDATA(); 
41707                         return end+3;
41708                 }
41709                 //<!DOCTYPE
41710                 //startDTD(java.lang.String name, java.lang.String publicId, java.lang.String systemId) 
41711                 var matchs = split(source,start);
41712                 var len = matchs.length;
41713                 if(len>1 && /!doctype/i.test(matchs[0][0])){
41714                         var name = matchs[1][0];
41715                         var pubid = len>3 && /^public$/i.test(matchs[2][0]) && matchs[3][0];
41716                         var sysid = len>4 && matchs[4][0];
41717                         var lastMatch = matchs[len-1];
41718                         domBuilder.startDTD(name,pubid && pubid.replace(/^(['"])(.*?)\1$/,'$2'),
41719                                         sysid && sysid.replace(/^(['"])(.*?)\1$/,'$2'));
41720                         domBuilder.endDTD();
41721                         
41722                         return lastMatch.index+lastMatch[0].length
41723                 }
41724         }
41725         return -1;
41726 }
41727
41728
41729
41730 function parseInstruction(source,start,domBuilder){
41731         var end = source.indexOf('?>',start);
41732         if(end){
41733                 var match = source.substring(start,end).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);
41734                 if(match){
41735                         var len = match[0].length;
41736                         domBuilder.processingInstruction(match[1], match[2]) ;
41737                         return end+2;
41738                 }else{//error
41739                         return -1;
41740                 }
41741         }
41742         return -1;
41743 }
41744
41745 /**
41746  * @param source
41747  */
41748 function ElementAttributes(source){
41749         
41750 }
41751 ElementAttributes.prototype = {
41752         setTagName:function(tagName){
41753                 if(!tagNamePattern.test(tagName)){
41754                         throw new Error('invalid tagName:'+tagName)
41755                 }
41756                 this.tagName = tagName;
41757         },
41758         add:function(qName,value,offset){
41759                 if(!tagNamePattern.test(qName)){
41760                         throw new Error('invalid attribute:'+qName)
41761                 }
41762                 this[this.length++] = {qName:qName,value:value,offset:offset};
41763         },
41764         length:0,
41765         getLocalName:function(i){return this[i].localName},
41766         getLocator:function(i){return this[i].locator},
41767         getQName:function(i){return this[i].qName},
41768         getURI:function(i){return this[i].uri},
41769         getValue:function(i){return this[i].value}
41770 //      ,getIndex:function(uri, localName)){
41771 //              if(localName){
41772 //                      
41773 //              }else{
41774 //                      var qName = uri
41775 //              }
41776 //      },
41777 //      getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))},
41778 //      getType:function(uri,localName){}
41779 //      getType:function(i){},
41780 };
41781
41782
41783
41784
41785 function _set_proto_(thiz,parent){
41786         thiz.__proto__ = parent;
41787         return thiz;
41788 }
41789 if(!(_set_proto_({},_set_proto_.prototype) instanceof _set_proto_)){
41790         _set_proto_ = function(thiz,parent){
41791                 function p(){}
41792                 p.prototype = parent;
41793                 p = new p();
41794                 for(parent in thiz){
41795                         p[parent] = thiz[parent];
41796                 }
41797                 return p;
41798         };
41799 }
41800
41801 function split(source,start){
41802         var match;
41803         var buf = [];
41804         var reg = /'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;
41805         reg.lastIndex = start;
41806         reg.exec(source);//skip <
41807         while(match = reg.exec(source)){
41808                 buf.push(match);
41809                 if(match[1])return buf;
41810         }
41811 }
41812
41813 var XMLReader_1 = XMLReader;
41814
41815 var sax = {
41816         XMLReader: XMLReader_1
41817 };
41818
41819 /*
41820  * DOM Level 2
41821  * Object DOMException
41822  * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html
41823  * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html
41824  */
41825
41826 function copy$1(src,dest){
41827         for(var p in src){
41828                 dest[p] = src[p];
41829         }
41830 }
41831 /**
41832 ^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));?
41833 ^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));?
41834  */
41835 function _extends(Class,Super){
41836         var pt = Class.prototype;
41837         if(Object.create){
41838                 var ppt = Object.create(Super.prototype);
41839                 pt.__proto__ = ppt;
41840         }
41841         if(!(pt instanceof Super)){
41842                 function t(){}
41843                 t.prototype = Super.prototype;
41844                 t = new t();
41845                 copy$1(pt,t);
41846                 Class.prototype = pt = t;
41847         }
41848         if(pt.constructor != Class){
41849                 if(typeof Class != 'function'){
41850                         console.error("unknow Class:"+Class);
41851                 }
41852                 pt.constructor = Class;
41853         }
41854 }
41855 var htmlns = 'http://www.w3.org/1999/xhtml';
41856 // Node Types
41857 var NodeType = {};
41858 var ELEMENT_NODE                = NodeType.ELEMENT_NODE                = 1;
41859 var ATTRIBUTE_NODE              = NodeType.ATTRIBUTE_NODE              = 2;
41860 var TEXT_NODE                   = NodeType.TEXT_NODE                   = 3;
41861 var CDATA_SECTION_NODE          = NodeType.CDATA_SECTION_NODE          = 4;
41862 var ENTITY_REFERENCE_NODE       = NodeType.ENTITY_REFERENCE_NODE       = 5;
41863 var ENTITY_NODE                 = NodeType.ENTITY_NODE                 = 6;
41864 var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7;
41865 var COMMENT_NODE                = NodeType.COMMENT_NODE                = 8;
41866 var DOCUMENT_NODE               = NodeType.DOCUMENT_NODE               = 9;
41867 var DOCUMENT_TYPE_NODE          = NodeType.DOCUMENT_TYPE_NODE          = 10;
41868 var DOCUMENT_FRAGMENT_NODE      = NodeType.DOCUMENT_FRAGMENT_NODE      = 11;
41869 var NOTATION_NODE               = NodeType.NOTATION_NODE               = 12;
41870
41871 // ExceptionCode
41872 var ExceptionCode = {};
41873 var ExceptionMessage = {};
41874 var INDEX_SIZE_ERR              = ExceptionCode.INDEX_SIZE_ERR              = (ExceptionMessage[1]="Index size error", 1);
41875 var DOMSTRING_SIZE_ERR          = ExceptionCode.DOMSTRING_SIZE_ERR          = (ExceptionMessage[2]="DOMString size error", 2);
41876 var HIERARCHY_REQUEST_ERR       = ExceptionCode.HIERARCHY_REQUEST_ERR       = (ExceptionMessage[3]="Hierarchy request error", 3);
41877 var WRONG_DOCUMENT_ERR          = ExceptionCode.WRONG_DOCUMENT_ERR          = (ExceptionMessage[4]="Wrong document", 4);
41878 var INVALID_CHARACTER_ERR       = ExceptionCode.INVALID_CHARACTER_ERR       = (ExceptionMessage[5]="Invalid character", 5);
41879 var NO_DATA_ALLOWED_ERR         = ExceptionCode.NO_DATA_ALLOWED_ERR         = (ExceptionMessage[6]="No data allowed", 6);
41880 var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = (ExceptionMessage[7]="No modification allowed", 7);
41881 var NOT_FOUND_ERR               = ExceptionCode.NOT_FOUND_ERR               = (ExceptionMessage[8]="Not found", 8);
41882 var NOT_SUPPORTED_ERR           = ExceptionCode.NOT_SUPPORTED_ERR           = (ExceptionMessage[9]="Not supported", 9);
41883 var INUSE_ATTRIBUTE_ERR         = ExceptionCode.INUSE_ATTRIBUTE_ERR         = (ExceptionMessage[10]="Attribute in use", 10);
41884 //level2
41885 var INVALID_STATE_ERR           = ExceptionCode.INVALID_STATE_ERR               = (ExceptionMessage[11]="Invalid state", 11);
41886 var SYNTAX_ERR                  = ExceptionCode.SYNTAX_ERR                      = (ExceptionMessage[12]="Syntax error", 12);
41887 var INVALID_MODIFICATION_ERR    = ExceptionCode.INVALID_MODIFICATION_ERR        = (ExceptionMessage[13]="Invalid modification", 13);
41888 var NAMESPACE_ERR               = ExceptionCode.NAMESPACE_ERR                   = (ExceptionMessage[14]="Invalid namespace", 14);
41889 var INVALID_ACCESS_ERR          = ExceptionCode.INVALID_ACCESS_ERR              = (ExceptionMessage[15]="Invalid access", 15);
41890
41891
41892 function DOMException(code, message) {
41893         if(message instanceof Error){
41894                 var error = message;
41895         }else{
41896                 error = this;
41897                 Error.call(this, ExceptionMessage[code]);
41898                 this.message = ExceptionMessage[code];
41899                 if(Error.captureStackTrace) Error.captureStackTrace(this, DOMException);
41900         }
41901         error.code = code;
41902         if(message) this.message = this.message + ": " + message;
41903         return error;
41904 }
41905 DOMException.prototype = Error.prototype;
41906 copy$1(ExceptionCode,DOMException);
41907 /**
41908  * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177
41909  * 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.
41910  * The items in the NodeList are accessible via an integral index, starting from 0.
41911  */
41912 function NodeList() {
41913 }
41914 NodeList.prototype = {
41915         /**
41916          * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive.
41917          * @standard level1
41918          */
41919         length:0, 
41920         /**
41921          * 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.
41922          * @standard level1
41923          * @param index  unsigned long 
41924          *   Index into the collection.
41925          * @return Node
41926          *      The node at the indexth position in the NodeList, or null if that is not a valid index. 
41927          */
41928         item: function(index) {
41929                 return this[index] || null;
41930         },
41931         toString:function(isHTML,nodeFilter){
41932                 for(var buf = [], i = 0;i<this.length;i++){
41933                         serializeToString(this[i],buf,isHTML,nodeFilter);
41934                 }
41935                 return buf.join('');
41936         }
41937 };
41938 function LiveNodeList(node,refresh){
41939         this._node = node;
41940         this._refresh = refresh;
41941         _updateLiveList(this);
41942 }
41943 function _updateLiveList(list){
41944         var inc = list._node._inc || list._node.ownerDocument._inc;
41945         if(list._inc != inc){
41946                 var ls = list._refresh(list._node);
41947                 //console.log(ls.length)
41948                 __set__(list,'length',ls.length);
41949                 copy$1(ls,list);
41950                 list._inc = inc;
41951         }
41952 }
41953 LiveNodeList.prototype.item = function(i){
41954         _updateLiveList(this);
41955         return this[i];
41956 };
41957
41958 _extends(LiveNodeList,NodeList);
41959 /**
41960  * 
41961  * 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.
41962  * NamedNodeMap objects in the DOM are live.
41963  * used for attributes or DocumentType entities 
41964  */
41965 function NamedNodeMap() {
41966 }
41967
41968 function _findNodeIndex(list,node){
41969         var i = list.length;
41970         while(i--){
41971                 if(list[i] === node){return i}
41972         }
41973 }
41974
41975 function _addNamedNode(el,list,newAttr,oldAttr){
41976         if(oldAttr){
41977                 list[_findNodeIndex(list,oldAttr)] = newAttr;
41978         }else{
41979                 list[list.length++] = newAttr;
41980         }
41981         if(el){
41982                 newAttr.ownerElement = el;
41983                 var doc = el.ownerDocument;
41984                 if(doc){
41985                         oldAttr && _onRemoveAttribute(doc,el,oldAttr);
41986                         _onAddAttribute(doc,el,newAttr);
41987                 }
41988         }
41989 }
41990 function _removeNamedNode(el,list,attr){
41991         //console.log('remove attr:'+attr)
41992         var i = _findNodeIndex(list,attr);
41993         if(i>=0){
41994                 var lastIndex = list.length-1;
41995                 while(i<lastIndex){
41996                         list[i] = list[++i];
41997                 }
41998                 list.length = lastIndex;
41999                 if(el){
42000                         var doc = el.ownerDocument;
42001                         if(doc){
42002                                 _onRemoveAttribute(doc,el,attr);
42003                                 attr.ownerElement = null;
42004                         }
42005                 }
42006         }else{
42007                 throw DOMException(NOT_FOUND_ERR,new Error(el.tagName+'@'+attr))
42008         }
42009 }
42010 NamedNodeMap.prototype = {
42011         length:0,
42012         item:NodeList.prototype.item,
42013         getNamedItem: function(key) {
42014 //              if(key.indexOf(':')>0 || key == 'xmlns'){
42015 //                      return null;
42016 //              }
42017                 //console.log()
42018                 var i = this.length;
42019                 while(i--){
42020                         var attr = this[i];
42021                         //console.log(attr.nodeName,key)
42022                         if(attr.nodeName == key){
42023                                 return attr;
42024                         }
42025                 }
42026         },
42027         setNamedItem: function(attr) {
42028                 var el = attr.ownerElement;
42029                 if(el && el!=this._ownerElement){
42030                         throw new DOMException(INUSE_ATTRIBUTE_ERR);
42031                 }
42032                 var oldAttr = this.getNamedItem(attr.nodeName);
42033                 _addNamedNode(this._ownerElement,this,attr,oldAttr);
42034                 return oldAttr;
42035         },
42036         /* returns Node */
42037         setNamedItemNS: function(attr) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR
42038                 var el = attr.ownerElement, oldAttr;
42039                 if(el && el!=this._ownerElement){
42040                         throw new DOMException(INUSE_ATTRIBUTE_ERR);
42041                 }
42042                 oldAttr = this.getNamedItemNS(attr.namespaceURI,attr.localName);
42043                 _addNamedNode(this._ownerElement,this,attr,oldAttr);
42044                 return oldAttr;
42045         },
42046
42047         /* returns Node */
42048         removeNamedItem: function(key) {
42049                 var attr = this.getNamedItem(key);
42050                 _removeNamedNode(this._ownerElement,this,attr);
42051                 return attr;
42052                 
42053                 
42054         },// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR
42055         
42056         //for level2
42057         removeNamedItemNS:function(namespaceURI,localName){
42058                 var attr = this.getNamedItemNS(namespaceURI,localName);
42059                 _removeNamedNode(this._ownerElement,this,attr);
42060                 return attr;
42061         },
42062         getNamedItemNS: function(namespaceURI, localName) {
42063                 var i = this.length;
42064                 while(i--){
42065                         var node = this[i];
42066                         if(node.localName == localName && node.namespaceURI == namespaceURI){
42067                                 return node;
42068                         }
42069                 }
42070                 return null;
42071         }
42072 };
42073 /**
42074  * @see http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490
42075  */
42076 function DOMImplementation(/* Object */ features) {
42077         this._features = {};
42078         if (features) {
42079                 for (var feature in features) {
42080                          this._features = features[feature];
42081                 }
42082         }
42083 }
42084
42085 DOMImplementation.prototype = {
42086         hasFeature: function(/* string */ feature, /* string */ version) {
42087                 var versions = this._features[feature.toLowerCase()];
42088                 if (versions && (!version || version in versions)) {
42089                         return true;
42090                 } else {
42091                         return false;
42092                 }
42093         },
42094         // Introduced in DOM Level 2:
42095         createDocument:function(namespaceURI,  qualifiedName, doctype){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR,WRONG_DOCUMENT_ERR
42096                 var doc = new Document();
42097                 doc.implementation = this;
42098                 doc.childNodes = new NodeList();
42099                 doc.doctype = doctype;
42100                 if(doctype){
42101                         doc.appendChild(doctype);
42102                 }
42103                 if(qualifiedName){
42104                         var root = doc.createElementNS(namespaceURI,qualifiedName);
42105                         doc.appendChild(root);
42106                 }
42107                 return doc;
42108         },
42109         // Introduced in DOM Level 2:
42110         createDocumentType:function(qualifiedName, publicId, systemId){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR
42111                 var node = new DocumentType();
42112                 node.name = qualifiedName;
42113                 node.nodeName = qualifiedName;
42114                 node.publicId = publicId;
42115                 node.systemId = systemId;
42116                 // Introduced in DOM Level 2:
42117                 //readonly attribute DOMString        internalSubset;
42118                 
42119                 //TODO:..
42120                 //  readonly attribute NamedNodeMap     entities;
42121                 //  readonly attribute NamedNodeMap     notations;
42122                 return node;
42123         }
42124 };
42125
42126
42127 /**
42128  * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247
42129  */
42130
42131 function Node$2() {
42132 }
42133
42134 Node$2.prototype = {
42135         firstChild : null,
42136         lastChild : null,
42137         previousSibling : null,
42138         nextSibling : null,
42139         attributes : null,
42140         parentNode : null,
42141         childNodes : null,
42142         ownerDocument : null,
42143         nodeValue : null,
42144         namespaceURI : null,
42145         prefix : null,
42146         localName : null,
42147         // Modified in DOM Level 2:
42148         insertBefore:function(newChild, refChild){//raises 
42149                 return _insertBefore(this,newChild,refChild);
42150         },
42151         replaceChild:function(newChild, oldChild){//raises 
42152                 this.insertBefore(newChild,oldChild);
42153                 if(oldChild){
42154                         this.removeChild(oldChild);
42155                 }
42156         },
42157         removeChild:function(oldChild){
42158                 return _removeChild(this,oldChild);
42159         },
42160         appendChild:function(newChild){
42161                 return this.insertBefore(newChild,null);
42162         },
42163         hasChildNodes:function(){
42164                 return this.firstChild != null;
42165         },
42166         cloneNode:function(deep){
42167                 return cloneNode(this.ownerDocument||this,this,deep);
42168         },
42169         // Modified in DOM Level 2:
42170         normalize:function(){
42171                 var child = this.firstChild;
42172                 while(child){
42173                         var next = child.nextSibling;
42174                         if(next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE){
42175                                 this.removeChild(next);
42176                                 child.appendData(next.data);
42177                         }else{
42178                                 child.normalize();
42179                                 child = next;
42180                         }
42181                 }
42182         },
42183         // Introduced in DOM Level 2:
42184         isSupported:function(feature, version){
42185                 return this.ownerDocument.implementation.hasFeature(feature,version);
42186         },
42187     // Introduced in DOM Level 2:
42188     hasAttributes:function(){
42189         return this.attributes.length>0;
42190     },
42191     lookupPrefix:function(namespaceURI){
42192         var el = this;
42193         while(el){
42194                 var map = el._nsMap;
42195                 //console.dir(map)
42196                 if(map){
42197                         for(var n in map){
42198                                 if(map[n] == namespaceURI){
42199                                         return n;
42200                                 }
42201                         }
42202                 }
42203                 el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode;
42204         }
42205         return null;
42206     },
42207     // Introduced in DOM Level 3:
42208     lookupNamespaceURI:function(prefix){
42209         var el = this;
42210         while(el){
42211                 var map = el._nsMap;
42212                 //console.dir(map)
42213                 if(map){
42214                         if(prefix in map){
42215                                 return map[prefix] ;
42216                         }
42217                 }
42218                 el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode;
42219         }
42220         return null;
42221     },
42222     // Introduced in DOM Level 3:
42223     isDefaultNamespace:function(namespaceURI){
42224         var prefix = this.lookupPrefix(namespaceURI);
42225         return prefix == null;
42226     }
42227 };
42228
42229
42230 function _xmlEncoder(c){
42231         return c == '<' && '&lt;' ||
42232          c == '>' && '&gt;' ||
42233          c == '&' && '&amp;' ||
42234          c == '"' && '&quot;' ||
42235          '&#'+c.charCodeAt()+';'
42236 }
42237
42238
42239 copy$1(NodeType,Node$2);
42240 copy$1(NodeType,Node$2.prototype);
42241
42242 /**
42243  * @param callback return true for continue,false for break
42244  * @return boolean true: break visit;
42245  */
42246 function _visitNode(node,callback){
42247         if(callback(node)){
42248                 return true;
42249         }
42250         if(node = node.firstChild){
42251                 do{
42252                         if(_visitNode(node,callback)){return true}
42253         }while(node=node.nextSibling)
42254     }
42255 }
42256
42257
42258
42259 function Document(){
42260 }
42261 function _onAddAttribute(doc,el,newAttr){
42262         doc && doc._inc++;
42263         var ns = newAttr.namespaceURI;
42264         if(ns == 'http://www.w3.org/2000/xmlns/'){
42265                 //update namespace
42266                 el._nsMap[newAttr.prefix?newAttr.localName:''] = newAttr.value;
42267         }
42268 }
42269 function _onRemoveAttribute(doc,el,newAttr,remove){
42270         doc && doc._inc++;
42271         var ns = newAttr.namespaceURI;
42272         if(ns == 'http://www.w3.org/2000/xmlns/'){
42273                 //update namespace
42274                 delete el._nsMap[newAttr.prefix?newAttr.localName:''];
42275         }
42276 }
42277 function _onUpdateChild(doc,el,newChild){
42278         if(doc && doc._inc){
42279                 doc._inc++;
42280                 //update childNodes
42281                 var cs = el.childNodes;
42282                 if(newChild){
42283                         cs[cs.length++] = newChild;
42284                 }else{
42285                         //console.log(1)
42286                         var child = el.firstChild;
42287                         var i = 0;
42288                         while(child){
42289                                 cs[i++] = child;
42290                                 child =child.nextSibling;
42291                         }
42292                         cs.length = i;
42293                 }
42294         }
42295 }
42296
42297 /**
42298  * attributes;
42299  * children;
42300  * 
42301  * writeable properties:
42302  * nodeValue,Attr:value,CharacterData:data
42303  * prefix
42304  */
42305 function _removeChild(parentNode,child){
42306         var previous = child.previousSibling;
42307         var next = child.nextSibling;
42308         if(previous){
42309                 previous.nextSibling = next;
42310         }else{
42311                 parentNode.firstChild = next;
42312         }
42313         if(next){
42314                 next.previousSibling = previous;
42315         }else{
42316                 parentNode.lastChild = previous;
42317         }
42318         _onUpdateChild(parentNode.ownerDocument,parentNode);
42319         return child;
42320 }
42321 /**
42322  * preformance key(refChild == null)
42323  */
42324 function _insertBefore(parentNode,newChild,nextChild){
42325         var cp = newChild.parentNode;
42326         if(cp){
42327                 cp.removeChild(newChild);//remove and update
42328         }
42329         if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
42330                 var newFirst = newChild.firstChild;
42331                 if (newFirst == null) {
42332                         return newChild;
42333                 }
42334                 var newLast = newChild.lastChild;
42335         }else{
42336                 newFirst = newLast = newChild;
42337         }
42338         var pre = nextChild ? nextChild.previousSibling : parentNode.lastChild;
42339
42340         newFirst.previousSibling = pre;
42341         newLast.nextSibling = nextChild;
42342         
42343         
42344         if(pre){
42345                 pre.nextSibling = newFirst;
42346         }else{
42347                 parentNode.firstChild = newFirst;
42348         }
42349         if(nextChild == null){
42350                 parentNode.lastChild = newLast;
42351         }else{
42352                 nextChild.previousSibling = newLast;
42353         }
42354         do{
42355                 newFirst.parentNode = parentNode;
42356         }while(newFirst !== newLast && (newFirst= newFirst.nextSibling))
42357         _onUpdateChild(parentNode.ownerDocument||parentNode,parentNode);
42358         //console.log(parentNode.lastChild.nextSibling == null)
42359         if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) {
42360                 newChild.firstChild = newChild.lastChild = null;
42361         }
42362         return newChild;
42363 }
42364 function _appendSingleChild(parentNode,newChild){
42365         var cp = newChild.parentNode;
42366         if(cp){
42367                 var pre = parentNode.lastChild;
42368                 cp.removeChild(newChild);//remove and update
42369                 var pre = parentNode.lastChild;
42370         }
42371         var pre = parentNode.lastChild;
42372         newChild.parentNode = parentNode;
42373         newChild.previousSibling = pre;
42374         newChild.nextSibling = null;
42375         if(pre){
42376                 pre.nextSibling = newChild;
42377         }else{
42378                 parentNode.firstChild = newChild;
42379         }
42380         parentNode.lastChild = newChild;
42381         _onUpdateChild(parentNode.ownerDocument,parentNode,newChild);
42382         return newChild;
42383         //console.log("__aa",parentNode.lastChild.nextSibling == null)
42384 }
42385 Document.prototype = {
42386         //implementation : null,
42387         nodeName :  '#document',
42388         nodeType :  DOCUMENT_NODE,
42389         doctype :  null,
42390         documentElement :  null,
42391         _inc : 1,
42392         
42393         insertBefore :  function(newChild, refChild){//raises 
42394                 if(newChild.nodeType == DOCUMENT_FRAGMENT_NODE){
42395                         var child = newChild.firstChild;
42396                         while(child){
42397                                 var next = child.nextSibling;
42398                                 this.insertBefore(child,refChild);
42399                                 child = next;
42400                         }
42401                         return newChild;
42402                 }
42403                 if(this.documentElement == null && newChild.nodeType == ELEMENT_NODE){
42404                         this.documentElement = newChild;
42405                 }
42406                 
42407                 return _insertBefore(this,newChild,refChild), newChild.ownerDocument = this, newChild;
42408         },
42409         removeChild :  function(oldChild){
42410                 if(this.documentElement == oldChild){
42411                         this.documentElement = null;
42412                 }
42413                 return _removeChild(this,oldChild);
42414         },
42415         // Introduced in DOM Level 2:
42416         importNode : function(importedNode,deep){
42417                 return importNode(this,importedNode,deep);
42418         },
42419         // Introduced in DOM Level 2:
42420         getElementById :        function(id){
42421                 var rtv = null;
42422                 _visitNode(this.documentElement,function(node){
42423                         if(node.nodeType == ELEMENT_NODE){
42424                                 if(node.getAttribute('id') == id){
42425                                         rtv = node;
42426                                         return true;
42427                                 }
42428                         }
42429                 });
42430                 return rtv;
42431         },
42432         
42433         //document factory method:
42434         createElement : function(tagName){
42435                 var node = new Element();
42436                 node.ownerDocument = this;
42437                 node.nodeName = tagName;
42438                 node.tagName = tagName;
42439                 node.childNodes = new NodeList();
42440                 var attrs       = node.attributes = new NamedNodeMap();
42441                 attrs._ownerElement = node;
42442                 return node;
42443         },
42444         createDocumentFragment :        function(){
42445                 var node = new DocumentFragment();
42446                 node.ownerDocument = this;
42447                 node.childNodes = new NodeList();
42448                 return node;
42449         },
42450         createTextNode :        function(data){
42451                 var node = new Text();
42452                 node.ownerDocument = this;
42453                 node.appendData(data);
42454                 return node;
42455         },
42456         createComment : function(data){
42457                 var node = new Comment();
42458                 node.ownerDocument = this;
42459                 node.appendData(data);
42460                 return node;
42461         },
42462         createCDATASection :    function(data){
42463                 var node = new CDATASection();
42464                 node.ownerDocument = this;
42465                 node.appendData(data);
42466                 return node;
42467         },
42468         createProcessingInstruction :   function(target,data){
42469                 var node = new ProcessingInstruction();
42470                 node.ownerDocument = this;
42471                 node.tagName = node.target = target;
42472                 node.nodeValue= node.data = data;
42473                 return node;
42474         },
42475         createAttribute :       function(name){
42476                 var node = new Attr();
42477                 node.ownerDocument      = this;
42478                 node.name = name;
42479                 node.nodeName   = name;
42480                 node.localName = name;
42481                 node.specified = true;
42482                 return node;
42483         },
42484         createEntityReference : function(name){
42485                 var node = new EntityReference();
42486                 node.ownerDocument      = this;
42487                 node.nodeName   = name;
42488                 return node;
42489         },
42490         // Introduced in DOM Level 2:
42491         createElementNS :       function(namespaceURI,qualifiedName){
42492                 var node = new Element();
42493                 var pl = qualifiedName.split(':');
42494                 var attrs       = node.attributes = new NamedNodeMap();
42495                 node.childNodes = new NodeList();
42496                 node.ownerDocument = this;
42497                 node.nodeName = qualifiedName;
42498                 node.tagName = qualifiedName;
42499                 node.namespaceURI = namespaceURI;
42500                 if(pl.length == 2){
42501                         node.prefix = pl[0];
42502                         node.localName = pl[1];
42503                 }else{
42504                         //el.prefix = null;
42505                         node.localName = qualifiedName;
42506                 }
42507                 attrs._ownerElement = node;
42508                 return node;
42509         },
42510         // Introduced in DOM Level 2:
42511         createAttributeNS :     function(namespaceURI,qualifiedName){
42512                 var node = new Attr();
42513                 var pl = qualifiedName.split(':');
42514                 node.ownerDocument = this;
42515                 node.nodeName = qualifiedName;
42516                 node.name = qualifiedName;
42517                 node.namespaceURI = namespaceURI;
42518                 node.specified = true;
42519                 if(pl.length == 2){
42520                         node.prefix = pl[0];
42521                         node.localName = pl[1];
42522                 }else{
42523                         //el.prefix = null;
42524                         node.localName = qualifiedName;
42525                 }
42526                 return node;
42527         }
42528 };
42529 _extends(Document,Node$2);
42530
42531
42532 function Element() {
42533         this._nsMap = {};
42534 }
42535 Element.prototype = {
42536         nodeType : ELEMENT_NODE,
42537         hasAttribute : function(name){
42538                 return this.getAttributeNode(name)!=null;
42539         },
42540         getAttribute : function(name){
42541                 var attr = this.getAttributeNode(name);
42542                 return attr && attr.value || '';
42543         },
42544         getAttributeNode : function(name){
42545                 return this.attributes.getNamedItem(name);
42546         },
42547         setAttribute : function(name, value){
42548                 var attr = this.ownerDocument.createAttribute(name);
42549                 attr.value = attr.nodeValue = "" + value;
42550                 this.setAttributeNode(attr);
42551         },
42552         removeAttribute : function(name){
42553                 var attr = this.getAttributeNode(name);
42554                 attr && this.removeAttributeNode(attr);
42555         },
42556         
42557         //four real opeartion method
42558         appendChild:function(newChild){
42559                 if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
42560                         return this.insertBefore(newChild,null);
42561                 }else{
42562                         return _appendSingleChild(this,newChild);
42563                 }
42564         },
42565         setAttributeNode : function(newAttr){
42566                 return this.attributes.setNamedItem(newAttr);
42567         },
42568         setAttributeNodeNS : function(newAttr){
42569                 return this.attributes.setNamedItemNS(newAttr);
42570         },
42571         removeAttributeNode : function(oldAttr){
42572                 //console.log(this == oldAttr.ownerElement)
42573                 return this.attributes.removeNamedItem(oldAttr.nodeName);
42574         },
42575         //get real attribute name,and remove it by removeAttributeNode
42576         removeAttributeNS : function(namespaceURI, localName){
42577                 var old = this.getAttributeNodeNS(namespaceURI, localName);
42578                 old && this.removeAttributeNode(old);
42579         },
42580         
42581         hasAttributeNS : function(namespaceURI, localName){
42582                 return this.getAttributeNodeNS(namespaceURI, localName)!=null;
42583         },
42584         getAttributeNS : function(namespaceURI, localName){
42585                 var attr = this.getAttributeNodeNS(namespaceURI, localName);
42586                 return attr && attr.value || '';
42587         },
42588         setAttributeNS : function(namespaceURI, qualifiedName, value){
42589                 var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
42590                 attr.value = attr.nodeValue = "" + value;
42591                 this.setAttributeNode(attr);
42592         },
42593         getAttributeNodeNS : function(namespaceURI, localName){
42594                 return this.attributes.getNamedItemNS(namespaceURI, localName);
42595         },
42596         
42597         getElementsByTagName : function(tagName){
42598                 return new LiveNodeList(this,function(base){
42599                         var ls = [];
42600                         _visitNode(base,function(node){
42601                                 if(node !== base && node.nodeType == ELEMENT_NODE && (tagName === '*' || node.tagName == tagName)){
42602                                         ls.push(node);
42603                                 }
42604                         });
42605                         return ls;
42606                 });
42607         },
42608         getElementsByTagNameNS : function(namespaceURI, localName){
42609                 return new LiveNodeList(this,function(base){
42610                         var ls = [];
42611                         _visitNode(base,function(node){
42612                                 if(node !== base && node.nodeType === ELEMENT_NODE && (namespaceURI === '*' || node.namespaceURI === namespaceURI) && (localName === '*' || node.localName == localName)){
42613                                         ls.push(node);
42614                                 }
42615                         });
42616                         return ls;
42617                         
42618                 });
42619         }
42620 };
42621 Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName;
42622 Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS;
42623
42624
42625 _extends(Element,Node$2);
42626 function Attr() {
42627 }
42628 Attr.prototype.nodeType = ATTRIBUTE_NODE;
42629 _extends(Attr,Node$2);
42630
42631
42632 function CharacterData() {
42633 }
42634 CharacterData.prototype = {
42635         data : '',
42636         substringData : function(offset, count) {
42637                 return this.data.substring(offset, offset+count);
42638         },
42639         appendData: function(text) {
42640                 text = this.data+text;
42641                 this.nodeValue = this.data = text;
42642                 this.length = text.length;
42643         },
42644         insertData: function(offset,text) {
42645                 this.replaceData(offset,0,text);
42646         
42647         },
42648         appendChild:function(newChild){
42649                 throw new Error(ExceptionMessage[HIERARCHY_REQUEST_ERR])
42650         },
42651         deleteData: function(offset, count) {
42652                 this.replaceData(offset,count,"");
42653         },
42654         replaceData: function(offset, count, text) {
42655                 var start = this.data.substring(0,offset);
42656                 var end = this.data.substring(offset+count);
42657                 text = start + text + end;
42658                 this.nodeValue = this.data = text;
42659                 this.length = text.length;
42660         }
42661 };
42662 _extends(CharacterData,Node$2);
42663 function Text() {
42664 }
42665 Text.prototype = {
42666         nodeName : "#text",
42667         nodeType : TEXT_NODE,
42668         splitText : function(offset) {
42669                 var text = this.data;
42670                 var newText = text.substring(offset);
42671                 text = text.substring(0, offset);
42672                 this.data = this.nodeValue = text;
42673                 this.length = text.length;
42674                 var newNode = this.ownerDocument.createTextNode(newText);
42675                 if(this.parentNode){
42676                         this.parentNode.insertBefore(newNode, this.nextSibling);
42677                 }
42678                 return newNode;
42679         }
42680 };
42681 _extends(Text,CharacterData);
42682 function Comment() {
42683 }
42684 Comment.prototype = {
42685         nodeName : "#comment",
42686         nodeType : COMMENT_NODE
42687 };
42688 _extends(Comment,CharacterData);
42689
42690 function CDATASection() {
42691 }
42692 CDATASection.prototype = {
42693         nodeName : "#cdata-section",
42694         nodeType : CDATA_SECTION_NODE
42695 };
42696 _extends(CDATASection,CharacterData);
42697
42698
42699 function DocumentType() {
42700 }
42701 DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE;
42702 _extends(DocumentType,Node$2);
42703
42704 function Notation() {
42705 }
42706 Notation.prototype.nodeType = NOTATION_NODE;
42707 _extends(Notation,Node$2);
42708
42709 function Entity() {
42710 }
42711 Entity.prototype.nodeType = ENTITY_NODE;
42712 _extends(Entity,Node$2);
42713
42714 function EntityReference() {
42715 }
42716 EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE;
42717 _extends(EntityReference,Node$2);
42718
42719 function DocumentFragment() {
42720 }
42721 DocumentFragment.prototype.nodeName =   "#document-fragment";
42722 DocumentFragment.prototype.nodeType =   DOCUMENT_FRAGMENT_NODE;
42723 _extends(DocumentFragment,Node$2);
42724
42725
42726 function ProcessingInstruction() {
42727 }
42728 ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE;
42729 _extends(ProcessingInstruction,Node$2);
42730 function XMLSerializer$1(){}
42731 XMLSerializer$1.prototype.serializeToString = function(node,isHtml,nodeFilter){
42732         return nodeSerializeToString.call(node,isHtml,nodeFilter);
42733 };
42734 Node$2.prototype.toString = nodeSerializeToString;
42735 function nodeSerializeToString(isHtml,nodeFilter){
42736         var buf = [];
42737         var refNode = this.nodeType == 9?this.documentElement:this;
42738         var prefix = refNode.prefix;
42739         var uri = refNode.namespaceURI;
42740         
42741         if(uri && prefix == null){
42742                 //console.log(prefix)
42743                 var prefix = refNode.lookupPrefix(uri);
42744                 if(prefix == null){
42745                         //isHTML = true;
42746                         var visibleNamespaces=[
42747                         {namespace:uri,prefix:null}
42748                         //{namespace:uri,prefix:''}
42749                         ];
42750                 }
42751         }
42752         serializeToString(this,buf,isHtml,nodeFilter,visibleNamespaces);
42753         //console.log('###',this.nodeType,uri,prefix,buf.join(''))
42754         return buf.join('');
42755 }
42756 function needNamespaceDefine(node,isHTML, visibleNamespaces) {
42757         var prefix = node.prefix||'';
42758         var uri = node.namespaceURI;
42759         if (!prefix && !uri){
42760                 return false;
42761         }
42762         if (prefix === "xml" && uri === "http://www.w3.org/XML/1998/namespace" 
42763                 || uri == 'http://www.w3.org/2000/xmlns/'){
42764                 return false;
42765         }
42766         
42767         var i = visibleNamespaces.length; 
42768         //console.log('@@@@',node.tagName,prefix,uri,visibleNamespaces)
42769         while (i--) {
42770                 var ns = visibleNamespaces[i];
42771                 // get namespace prefix
42772                 //console.log(node.nodeType,node.tagName,ns.prefix,prefix)
42773                 if (ns.prefix == prefix){
42774                         return ns.namespace != uri;
42775                 }
42776         }
42777         //console.log(isHTML,uri,prefix=='')
42778         //if(isHTML && prefix ==null && uri == 'http://www.w3.org/1999/xhtml'){
42779         //      return false;
42780         //}
42781         //node.flag = '11111'
42782         //console.error(3,true,node.flag,node.prefix,node.namespaceURI)
42783         return true;
42784 }
42785 function serializeToString(node,buf,isHTML,nodeFilter,visibleNamespaces){
42786         if(nodeFilter){
42787                 node = nodeFilter(node);
42788                 if(node){
42789                         if(typeof node == 'string'){
42790                                 buf.push(node);
42791                                 return;
42792                         }
42793                 }else{
42794                         return;
42795                 }
42796                 //buf.sort.apply(attrs, attributeSorter);
42797         }
42798         switch(node.nodeType){
42799         case ELEMENT_NODE:
42800                 if (!visibleNamespaces) visibleNamespaces = [];
42801                 var startVisibleNamespaces = visibleNamespaces.length;
42802                 var attrs = node.attributes;
42803                 var len = attrs.length;
42804                 var child = node.firstChild;
42805                 var nodeName = node.tagName;
42806                 
42807                 isHTML =  (htmlns === node.namespaceURI) ||isHTML; 
42808                 buf.push('<',nodeName);
42809                 
42810                 
42811                 
42812                 for(var i=0;i<len;i++){
42813                         // add namespaces for attributes
42814                         var attr = attrs.item(i);
42815                         if (attr.prefix == 'xmlns') {
42816                                 visibleNamespaces.push({ prefix: attr.localName, namespace: attr.value });
42817                         }else if(attr.nodeName == 'xmlns'){
42818                                 visibleNamespaces.push({ prefix: '', namespace: attr.value });
42819                         }
42820                 }
42821                 for(var i=0;i<len;i++){
42822                         var attr = attrs.item(i);
42823                         if (needNamespaceDefine(attr,isHTML, visibleNamespaces)) {
42824                                 var prefix = attr.prefix||'';
42825                                 var uri = attr.namespaceURI;
42826                                 var ns = prefix ? ' xmlns:' + prefix : " xmlns";
42827                                 buf.push(ns, '="' , uri , '"');
42828                                 visibleNamespaces.push({ prefix: prefix, namespace:uri });
42829                         }
42830                         serializeToString(attr,buf,isHTML,nodeFilter,visibleNamespaces);
42831                 }
42832                 // add namespace for current node               
42833                 if (needNamespaceDefine(node,isHTML, visibleNamespaces)) {
42834                         var prefix = node.prefix||'';
42835                         var uri = node.namespaceURI;
42836                         var ns = prefix ? ' xmlns:' + prefix : " xmlns";
42837                         buf.push(ns, '="' , uri , '"');
42838                         visibleNamespaces.push({ prefix: prefix, namespace:uri });
42839                 }
42840                 
42841                 if(child || isHTML && !/^(?:meta|link|img|br|hr|input)$/i.test(nodeName)){
42842                         buf.push('>');
42843                         //if is cdata child node
42844                         if(isHTML && /^script$/i.test(nodeName)){
42845                                 while(child){
42846                                         if(child.data){
42847                                                 buf.push(child.data);
42848                                         }else{
42849                                                 serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces);
42850                                         }
42851                                         child = child.nextSibling;
42852                                 }
42853                         }else
42854                         {
42855                                 while(child){
42856                                         serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces);
42857                                         child = child.nextSibling;
42858                                 }
42859                         }
42860                         buf.push('</',nodeName,'>');
42861                 }else{
42862                         buf.push('/>');
42863                 }
42864                 // remove added visible namespaces
42865                 //visibleNamespaces.length = startVisibleNamespaces;
42866                 return;
42867         case DOCUMENT_NODE:
42868         case DOCUMENT_FRAGMENT_NODE:
42869                 var child = node.firstChild;
42870                 while(child){
42871                         serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces);
42872                         child = child.nextSibling;
42873                 }
42874                 return;
42875         case ATTRIBUTE_NODE:
42876                 return buf.push(' ',node.name,'="',node.value.replace(/[<&"]/g,_xmlEncoder),'"');
42877         case TEXT_NODE:
42878                 return buf.push(node.data.replace(/[<&]/g,_xmlEncoder));
42879         case CDATA_SECTION_NODE:
42880                 return buf.push( '<![CDATA[',node.data,']]>');
42881         case COMMENT_NODE:
42882                 return buf.push( "<!--",node.data,"-->");
42883         case DOCUMENT_TYPE_NODE:
42884                 var pubid = node.publicId;
42885                 var sysid = node.systemId;
42886                 buf.push('<!DOCTYPE ',node.name);
42887                 if(pubid){
42888                         buf.push(' PUBLIC "',pubid);
42889                         if (sysid && sysid!='.') {
42890                                 buf.push( '" "',sysid);
42891                         }
42892                         buf.push('">');
42893                 }else if(sysid && sysid!='.'){
42894                         buf.push(' SYSTEM "',sysid,'">');
42895                 }else{
42896                         var sub = node.internalSubset;
42897                         if(sub){
42898                                 buf.push(" [",sub,"]");
42899                         }
42900                         buf.push(">");
42901                 }
42902                 return;
42903         case PROCESSING_INSTRUCTION_NODE:
42904                 return buf.push( "<?",node.target," ",node.data,"?>");
42905         case ENTITY_REFERENCE_NODE:
42906                 return buf.push( '&',node.nodeName,';');
42907         //case ENTITY_NODE:
42908         //case NOTATION_NODE:
42909         default:
42910                 buf.push('??',node.nodeName);
42911         }
42912 }
42913 function importNode(doc,node,deep){
42914         var node2;
42915         switch (node.nodeType) {
42916         case ELEMENT_NODE:
42917                 node2 = node.cloneNode(false);
42918                 node2.ownerDocument = doc;
42919                 //var attrs = node2.attributes;
42920                 //var len = attrs.length;
42921                 //for(var i=0;i<len;i++){
42922                         //node2.setAttributeNodeNS(importNode(doc,attrs.item(i),deep));
42923                 //}
42924         case DOCUMENT_FRAGMENT_NODE:
42925                 break;
42926         case ATTRIBUTE_NODE:
42927                 deep = true;
42928                 break;
42929         //case ENTITY_REFERENCE_NODE:
42930         //case PROCESSING_INSTRUCTION_NODE:
42931         ////case TEXT_NODE:
42932         //case CDATA_SECTION_NODE:
42933         //case COMMENT_NODE:
42934         //      deep = false;
42935         //      break;
42936         //case DOCUMENT_NODE:
42937         //case DOCUMENT_TYPE_NODE:
42938         //cannot be imported.
42939         //case ENTITY_NODE:
42940         //case NOTATION_NODE:
42941         //can not hit in level3
42942         //default:throw e;
42943         }
42944         if(!node2){
42945                 node2 = node.cloneNode(false);//false
42946         }
42947         node2.ownerDocument = doc;
42948         node2.parentNode = null;
42949         if(deep){
42950                 var child = node.firstChild;
42951                 while(child){
42952                         node2.appendChild(importNode(doc,child,deep));
42953                         child = child.nextSibling;
42954                 }
42955         }
42956         return node2;
42957 }
42958 //
42959 //var _relationMap = {firstChild:1,lastChild:1,previousSibling:1,nextSibling:1,
42960 //                                      attributes:1,childNodes:1,parentNode:1,documentElement:1,doctype,};
42961 function cloneNode(doc,node,deep){
42962         var node2 = new node.constructor();
42963         for(var n in node){
42964                 var v = node[n];
42965                 if(typeof v != 'object' ){
42966                         if(v != node2[n]){
42967                                 node2[n] = v;
42968                         }
42969                 }
42970         }
42971         if(node.childNodes){
42972                 node2.childNodes = new NodeList();
42973         }
42974         node2.ownerDocument = doc;
42975         switch (node2.nodeType) {
42976         case ELEMENT_NODE:
42977                 var attrs       = node.attributes;
42978                 var attrs2      = node2.attributes = new NamedNodeMap();
42979                 var len = attrs.length;
42980                 attrs2._ownerElement = node2;
42981                 for(var i=0;i<len;i++){
42982                         node2.setAttributeNode(cloneNode(doc,attrs.item(i),true));
42983                 }
42984                 break;;
42985         case ATTRIBUTE_NODE:
42986                 deep = true;
42987         }
42988         if(deep){
42989                 var child = node.firstChild;
42990                 while(child){
42991                         node2.appendChild(cloneNode(doc,child,deep));
42992                         child = child.nextSibling;
42993                 }
42994         }
42995         return node2;
42996 }
42997
42998 function __set__(object,key,value){
42999         object[key] = value;
43000 }
43001 //do dynamic
43002 try{
43003         if(Object.defineProperty){
43004                 Object.defineProperty(LiveNodeList.prototype,'length',{
43005                         get:function(){
43006                                 _updateLiveList(this);
43007                                 return this.$$length;
43008                         }
43009                 });
43010                 Object.defineProperty(Node$2.prototype,'textContent',{
43011                         get:function(){
43012                                 return getTextContent(this);
43013                         },
43014                         set:function(data){
43015                                 switch(this.nodeType){
43016                                 case ELEMENT_NODE:
43017                                 case DOCUMENT_FRAGMENT_NODE:
43018                                         while(this.firstChild){
43019                                                 this.removeChild(this.firstChild);
43020                                         }
43021                                         if(data || String(data)){
43022                                                 this.appendChild(this.ownerDocument.createTextNode(data));
43023                                         }
43024                                         break;
43025                                 default:
43026                                         //TODO:
43027                                         this.data = data;
43028                                         this.value = data;
43029                                         this.nodeValue = data;
43030                                 }
43031                         }
43032                 });
43033                 
43034                 function getTextContent(node){
43035                         switch(node.nodeType){
43036                         case ELEMENT_NODE:
43037                         case DOCUMENT_FRAGMENT_NODE:
43038                                 var buf = [];
43039                                 node = node.firstChild;
43040                                 while(node){
43041                                         if(node.nodeType!==7 && node.nodeType !==8){
43042                                                 buf.push(getTextContent(node));
43043                                         }
43044                                         node = node.nextSibling;
43045                                 }
43046                                 return buf.join('');
43047                         default:
43048                                 return node.nodeValue;
43049                         }
43050                 }
43051                 __set__ = function(object,key,value){
43052                         //console.log(value)
43053                         object['$$'+key] = value;
43054                 };
43055         }
43056 }catch(e){//ie8
43057 }
43058
43059 //if(typeof require == 'function'){
43060         var DOMImplementation_1 = DOMImplementation;
43061         var XMLSerializer_1 = XMLSerializer$1;
43062 //}
43063
43064 var dom = {
43065         DOMImplementation: DOMImplementation_1,
43066         XMLSerializer: XMLSerializer_1
43067 };
43068
43069 var domParser = createCommonjsModule(function (module, exports) {
43070 function DOMParser(options){
43071         this.options = options ||{locator:{}};
43072         
43073 }
43074 DOMParser.prototype.parseFromString = function(source,mimeType){
43075         var options = this.options;
43076         var sax$$1 =  new XMLReader();
43077         var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler
43078         var errorHandler = options.errorHandler;
43079         var locator = options.locator;
43080         var defaultNSMap = options.xmlns||{};
43081         var entityMap = {'lt':'<','gt':'>','amp':'&','quot':'"','apos':"'"};
43082         if(locator){
43083                 domBuilder.setDocumentLocator(locator);
43084         }
43085         
43086         sax$$1.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator);
43087         sax$$1.domBuilder = options.domBuilder || domBuilder;
43088         if(/\/x?html?$/.test(mimeType)){
43089                 entityMap.nbsp = '\xa0';
43090                 entityMap.copy = '\xa9';
43091                 defaultNSMap['']= 'http://www.w3.org/1999/xhtml';
43092         }
43093         defaultNSMap.xml = defaultNSMap.xml || 'http://www.w3.org/XML/1998/namespace';
43094         if(source){
43095                 sax$$1.parse(source,defaultNSMap,entityMap);
43096         }else{
43097                 sax$$1.errorHandler.error("invalid doc source");
43098         }
43099         return domBuilder.doc;
43100 };
43101 function buildErrorHandler(errorImpl,domBuilder,locator){
43102         if(!errorImpl){
43103                 if(domBuilder instanceof DOMHandler){
43104                         return domBuilder;
43105                 }
43106                 errorImpl = domBuilder ;
43107         }
43108         var errorHandler = {};
43109         var isCallback = errorImpl instanceof Function;
43110         locator = locator||{};
43111         function build(key){
43112                 var fn = errorImpl[key];
43113                 if(!fn && isCallback){
43114                         fn = errorImpl.length == 2?function(msg){errorImpl(key,msg);}:errorImpl;
43115                 }
43116                 errorHandler[key] = fn && function(msg){
43117                         fn('[xmldom '+key+']\t'+msg+_locator(locator));
43118                 }||function(){};
43119         }
43120         build('warning');
43121         build('error');
43122         build('fatalError');
43123         return errorHandler;
43124 }
43125
43126 //console.log('#\n\n\n\n\n\n\n####')
43127 /**
43128  * +ContentHandler+ErrorHandler
43129  * +LexicalHandler+EntityResolver2
43130  * -DeclHandler-DTDHandler 
43131  * 
43132  * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler
43133  * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2
43134  * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html
43135  */
43136 function DOMHandler() {
43137     this.cdata = false;
43138 }
43139 function position(locator,node){
43140         node.lineNumber = locator.lineNumber;
43141         node.columnNumber = locator.columnNumber;
43142 }
43143 /**
43144  * @see org.xml.sax.ContentHandler#startDocument
43145  * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
43146  */ 
43147 DOMHandler.prototype = {
43148         startDocument : function() {
43149         this.doc = new DOMImplementation().createDocument(null, null, null);
43150         if (this.locator) {
43151                 this.doc.documentURI = this.locator.systemId;
43152         }
43153         },
43154         startElement:function(namespaceURI, localName, qName, attrs) {
43155                 var doc = this.doc;
43156             var el = doc.createElementNS(namespaceURI, qName||localName);
43157             var len = attrs.length;
43158             appendElement(this, el);
43159             this.currentElement = el;
43160             
43161                 this.locator && position(this.locator,el);
43162             for (var i = 0 ; i < len; i++) {
43163                 var namespaceURI = attrs.getURI(i);
43164                 var value = attrs.getValue(i);
43165                 var qName = attrs.getQName(i);
43166                         var attr = doc.createAttributeNS(namespaceURI, qName);
43167                         this.locator &&position(attrs.getLocator(i),attr);
43168                         attr.value = attr.nodeValue = value;
43169                         el.setAttributeNode(attr);
43170             }
43171         },
43172         endElement:function(namespaceURI, localName, qName) {
43173                 var current = this.currentElement;
43174                 var tagName = current.tagName;
43175                 this.currentElement = current.parentNode;
43176         },
43177         startPrefixMapping:function(prefix, uri) {
43178         },
43179         endPrefixMapping:function(prefix) {
43180         },
43181         processingInstruction:function(target, data) {
43182             var ins = this.doc.createProcessingInstruction(target, data);
43183             this.locator && position(this.locator,ins);
43184             appendElement(this, ins);
43185         },
43186         ignorableWhitespace:function(ch, start, length) {
43187         },
43188         characters:function(chars, start, length) {
43189                 chars = _toString.apply(this,arguments);
43190                 //console.log(chars)
43191                 if(chars){
43192                         if (this.cdata) {
43193                                 var charNode = this.doc.createCDATASection(chars);
43194                         } else {
43195                                 var charNode = this.doc.createTextNode(chars);
43196                         }
43197                         if(this.currentElement){
43198                                 this.currentElement.appendChild(charNode);
43199                         }else if(/^\s*$/.test(chars)){
43200                                 this.doc.appendChild(charNode);
43201                                 //process xml
43202                         }
43203                         this.locator && position(this.locator,charNode);
43204                 }
43205         },
43206         skippedEntity:function(name) {
43207         },
43208         endDocument:function() {
43209                 this.doc.normalize();
43210         },
43211         setDocumentLocator:function (locator) {
43212             if(this.locator = locator){// && !('lineNumber' in locator)){
43213                 locator.lineNumber = 0;
43214             }
43215         },
43216         //LexicalHandler
43217         comment:function(chars, start, length) {
43218                 chars = _toString.apply(this,arguments);
43219             var comm = this.doc.createComment(chars);
43220             this.locator && position(this.locator,comm);
43221             appendElement(this, comm);
43222         },
43223         
43224         startCDATA:function() {
43225             //used in characters() methods
43226             this.cdata = true;
43227         },
43228         endCDATA:function() {
43229             this.cdata = false;
43230         },
43231         
43232         startDTD:function(name, publicId, systemId) {
43233                 var impl = this.doc.implementation;
43234             if (impl && impl.createDocumentType) {
43235                 var dt = impl.createDocumentType(name, publicId, systemId);
43236                 this.locator && position(this.locator,dt);
43237                 appendElement(this, dt);
43238             }
43239         },
43240         /**
43241          * @see org.xml.sax.ErrorHandler
43242          * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
43243          */
43244         warning:function(error) {
43245                 console.warn('[xmldom warning]\t'+error,_locator(this.locator));
43246         },
43247         error:function(error) {
43248                 console.error('[xmldom error]\t'+error,_locator(this.locator));
43249         },
43250         fatalError:function(error) {
43251                 console.error('[xmldom fatalError]\t'+error,_locator(this.locator));
43252             throw error;
43253         }
43254 };
43255 function _locator(l){
43256         if(l){
43257                 return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']'
43258         }
43259 }
43260 function _toString(chars,start,length){
43261         if(typeof chars == 'string'){
43262                 return chars.substr(start,length)
43263         }else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)")
43264                 if(chars.length >= start+length || start){
43265                         return new java.lang.String(chars,start,length)+'';
43266                 }
43267                 return chars;
43268         }
43269 }
43270
43271 /*
43272  * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html
43273  * used method of org.xml.sax.ext.LexicalHandler:
43274  *  #comment(chars, start, length)
43275  *  #startCDATA()
43276  *  #endCDATA()
43277  *  #startDTD(name, publicId, systemId)
43278  *
43279  *
43280  * IGNORED method of org.xml.sax.ext.LexicalHandler:
43281  *  #endDTD()
43282  *  #startEntity(name)
43283  *  #endEntity(name)
43284  *
43285  *
43286  * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html
43287  * IGNORED method of org.xml.sax.ext.DeclHandler
43288  *      #attributeDecl(eName, aName, type, mode, value)
43289  *  #elementDecl(name, model)
43290  *  #externalEntityDecl(name, publicId, systemId)
43291  *  #internalEntityDecl(name, value)
43292  * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html
43293  * IGNORED method of org.xml.sax.EntityResolver2
43294  *  #resolveEntity(String name,String publicId,String baseURI,String systemId)
43295  *  #resolveEntity(publicId, systemId)
43296  *  #getExternalSubset(name, baseURI)
43297  * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html
43298  * IGNORED method of org.xml.sax.DTDHandler
43299  *  #notationDecl(name, publicId, systemId) {};
43300  *  #unparsedEntityDecl(name, publicId, systemId, notationName) {};
43301  */
43302 "endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){
43303         DOMHandler.prototype[key] = function(){return null};
43304 });
43305
43306 /* 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 */
43307 function appendElement (hander,node) {
43308     if (!hander.currentElement) {
43309         hander.doc.appendChild(node);
43310     } else {
43311         hander.currentElement.appendChild(node);
43312     }
43313 }//appendChild and setAttributeNS are preformance key
43314
43315 //if(typeof require == 'function'){
43316         var XMLReader = sax.XMLReader;
43317         var DOMImplementation = exports.DOMImplementation = dom.DOMImplementation;
43318         exports.XMLSerializer = dom.XMLSerializer ;
43319         exports.DOMParser = DOMParser;
43320 //}
43321 });
43322
43323 var domParser_1 = domParser.DOMImplementation;
43324 var domParser_2 = domParser.XMLSerializer;
43325 var domParser_3 = domParser.DOMParser;
43326
43327 var togeojson = createCommonjsModule(function (module, exports) {
43328 var toGeoJSON = (function() {
43329     var removeSpace = /\s*/g,
43330         trimSpace = /^\s*|\s*$/g,
43331         splitSpace = /\s+/;
43332     // generate a short, numeric hash of a string
43333     function okhash(x) {
43334         if (!x || !x.length) return 0;
43335         for (var i = 0, h = 0; i < x.length; i++) {
43336             h = ((h << 5) - h) + x.charCodeAt(i) | 0;
43337         } return h;
43338     }
43339     // all Y children of X
43340     function get(x, y) { return x.getElementsByTagName(y); }
43341     function attr(x, y) { return x.getAttribute(y); }
43342     function attrf(x, y) { return parseFloat(attr(x, y)); }
43343     // one Y child of X, if any, otherwise null
43344     function get1(x, y) { var n = get(x, y); return n.length ? n[0] : null; }
43345     // https://developer.mozilla.org/en-US/docs/Web/API/Node.normalize
43346     function norm(el) { if (el.normalize) { el.normalize(); } return el; }
43347     // cast array x into numbers
43348     function numarray(x) {
43349         for (var j = 0, o = []; j < x.length; j++) { o[j] = parseFloat(x[j]); }
43350         return o;
43351     }
43352     // get the content of a text node, if any
43353     function nodeVal(x) {
43354         if (x) { norm(x); }
43355         return (x && x.textContent) || '';
43356     }
43357     // get the contents of multiple text nodes, if present
43358     function getMulti(x, ys) {
43359         var o = {}, n, k;
43360         for (k = 0; k < ys.length; k++) {
43361             n = get1(x, ys[k]);
43362             if (n) o[ys[k]] = nodeVal(n);
43363         }
43364         return o;
43365     }
43366     // add properties of Y to X, overwriting if present in both
43367     function extend(x, y) { for (var k in y) x[k] = y[k]; }
43368     // get one coordinate from a coordinate array, if any
43369     function coord1(v) { return numarray(v.replace(removeSpace, '').split(',')); }
43370     // get all coordinates from a coordinate array as [[],[]]
43371     function coord(v) {
43372         var coords = v.replace(trimSpace, '').split(splitSpace),
43373             o = [];
43374         for (var i = 0; i < coords.length; i++) {
43375             o.push(coord1(coords[i]));
43376         }
43377         return o;
43378     }
43379     function coordPair(x) {
43380         var ll = [attrf(x, 'lon'), attrf(x, 'lat')],
43381             ele = get1(x, 'ele'),
43382             // handle namespaced attribute in browser
43383             heartRate = get1(x, 'gpxtpx:hr') || get1(x, 'hr'),
43384             time = get1(x, 'time'),
43385             e;
43386         if (ele) {
43387             e = parseFloat(nodeVal(ele));
43388             if (!isNaN(e)) {
43389                 ll.push(e);
43390             }
43391         }
43392         return {
43393             coordinates: ll,
43394             time: time ? nodeVal(time) : null,
43395             heartRate: heartRate ? parseFloat(nodeVal(heartRate)) : null
43396         };
43397     }
43398
43399     // create a new feature collection parent object
43400     function fc() {
43401         return {
43402             type: 'FeatureCollection',
43403             features: []
43404         };
43405     }
43406
43407     var serializer;
43408     if (typeof XMLSerializer !== 'undefined') {
43409         /* istanbul ignore next */
43410         serializer = new XMLSerializer();
43411     // only require xmldom in a node environment
43412     } else if ('object' === 'object' && typeof process === 'object' && !process.browser) {
43413         serializer = new (domParser.XMLSerializer)();
43414     }
43415     function xml2str(str) {
43416         // IE9 will create a new XMLSerializer but it'll crash immediately.
43417         // This line is ignored because we don't run coverage tests in IE9
43418         /* istanbul ignore next */
43419         if (str.xml !== undefined) return str.xml;
43420         return serializer.serializeToString(str);
43421     }
43422
43423     var t = {
43424         kml: function(doc) {
43425
43426             var gj = fc(),
43427                 // styleindex keeps track of hashed styles in order to match features
43428                 styleIndex = {}, styleByHash = {},
43429                 // stylemapindex keeps track of style maps to expose in properties
43430                 styleMapIndex = {},
43431                 // atomic geospatial types supported by KML - MultiGeometry is
43432                 // handled separately
43433                 geotypes = ['Polygon', 'LineString', 'Point', 'Track', 'gx:Track'],
43434                 // all root placemarks in the file
43435                 placemarks = get(doc, 'Placemark'),
43436                 styles = get(doc, 'Style'),
43437                 styleMaps = get(doc, 'StyleMap');
43438
43439             for (var k = 0; k < styles.length; k++) {
43440                 var hash = okhash(xml2str(styles[k])).toString(16);
43441                 styleIndex['#' + attr(styles[k], 'id')] = hash;
43442                 styleByHash[hash] = styles[k];
43443             }
43444             for (var l = 0; l < styleMaps.length; l++) {
43445                 styleIndex['#' + attr(styleMaps[l], 'id')] = okhash(xml2str(styleMaps[l])).toString(16);
43446                 var pairs = get(styleMaps[l], 'Pair');
43447                 var pairsMap = {};
43448                 for (var m = 0; m < pairs.length; m++) {
43449                     pairsMap[nodeVal(get1(pairs[m], 'key'))] = nodeVal(get1(pairs[m], 'styleUrl'));
43450                 }
43451                 styleMapIndex['#' + attr(styleMaps[l], 'id')] = pairsMap;
43452
43453             }
43454             for (var j = 0; j < placemarks.length; j++) {
43455                 gj.features = gj.features.concat(getPlacemark(placemarks[j]));
43456             }
43457             function kmlColor(v) {
43458                 var color, opacity;
43459                 v = v || '';
43460                 if (v.substr(0, 1) === '#') { v = v.substr(1); }
43461                 if (v.length === 6 || v.length === 3) { color = v; }
43462                 if (v.length === 8) {
43463                     opacity = parseInt(v.substr(0, 2), 16) / 255;
43464                     color = '#' + v.substr(6, 2) +
43465                         v.substr(4, 2) +
43466                         v.substr(2, 2);
43467                 }
43468                 return [color, isNaN(opacity) ? undefined : opacity];
43469             }
43470             function gxCoord(v) { return numarray(v.split(' ')); }
43471             function gxCoords(root) {
43472                 var elems = get(root, 'coord', 'gx'), coords = [], times = [];
43473                 if (elems.length === 0) elems = get(root, 'gx:coord');
43474                 for (var i = 0; i < elems.length; i++) coords.push(gxCoord(nodeVal(elems[i])));
43475                 var timeElems = get(root, 'when');
43476                 for (var j = 0; j < timeElems.length; j++) times.push(nodeVal(timeElems[j]));
43477                 return {
43478                     coords: coords,
43479                     times: times
43480                 };
43481             }
43482             function getGeometry(root) {
43483                 var geomNode, geomNodes, i, j, k, geoms = [], coordTimes = [];
43484                 if (get1(root, 'MultiGeometry')) { return getGeometry(get1(root, 'MultiGeometry')); }
43485                 if (get1(root, 'MultiTrack')) { return getGeometry(get1(root, 'MultiTrack')); }
43486                 if (get1(root, 'gx:MultiTrack')) { return getGeometry(get1(root, 'gx:MultiTrack')); }
43487                 for (i = 0; i < geotypes.length; i++) {
43488                     geomNodes = get(root, geotypes[i]);
43489                     if (geomNodes) {
43490                         for (j = 0; j < geomNodes.length; j++) {
43491                             geomNode = geomNodes[j];
43492                             if (geotypes[i] === 'Point') {
43493                                 geoms.push({
43494                                     type: 'Point',
43495                                     coordinates: coord1(nodeVal(get1(geomNode, 'coordinates')))
43496                                 });
43497                             } else if (geotypes[i] === 'LineString') {
43498                                 geoms.push({
43499                                     type: 'LineString',
43500                                     coordinates: coord(nodeVal(get1(geomNode, 'coordinates')))
43501                                 });
43502                             } else if (geotypes[i] === 'Polygon') {
43503                                 var rings = get(geomNode, 'LinearRing'),
43504                                     coords = [];
43505                                 for (k = 0; k < rings.length; k++) {
43506                                     coords.push(coord(nodeVal(get1(rings[k], 'coordinates'))));
43507                                 }
43508                                 geoms.push({
43509                                     type: 'Polygon',
43510                                     coordinates: coords
43511                                 });
43512                             } else if (geotypes[i] === 'Track' ||
43513                                 geotypes[i] === 'gx:Track') {
43514                                 var track = gxCoords(geomNode);
43515                                 geoms.push({
43516                                     type: 'LineString',
43517                                     coordinates: track.coords
43518                                 });
43519                                 if (track.times.length) coordTimes.push(track.times);
43520                             }
43521                         }
43522                     }
43523                 }
43524                 return {
43525                     geoms: geoms,
43526                     coordTimes: coordTimes
43527                 };
43528             }
43529             function getPlacemark(root) {
43530                 var geomsAndTimes = getGeometry(root), i, properties = {},
43531                     name = nodeVal(get1(root, 'name')),
43532                     address = nodeVal(get1(root, 'address')),
43533                     styleUrl = nodeVal(get1(root, 'styleUrl')),
43534                     description = nodeVal(get1(root, 'description')),
43535                     timeSpan = get1(root, 'TimeSpan'),
43536                     timeStamp = get1(root, 'TimeStamp'),
43537                     extendedData = get1(root, 'ExtendedData'),
43538                     lineStyle = get1(root, 'LineStyle'),
43539                     polyStyle = get1(root, 'PolyStyle'),
43540                     visibility = get1(root, 'visibility');
43541
43542                 if (!geomsAndTimes.geoms.length) return [];
43543                 if (name) properties.name = name;
43544                 if (address) properties.address = address;
43545                 if (styleUrl) {
43546                     if (styleUrl[0] !== '#') {
43547                         styleUrl = '#' + styleUrl;
43548                     }
43549
43550                     properties.styleUrl = styleUrl;
43551                     if (styleIndex[styleUrl]) {
43552                         properties.styleHash = styleIndex[styleUrl];
43553                     }
43554                     if (styleMapIndex[styleUrl]) {
43555                         properties.styleMapHash = styleMapIndex[styleUrl];
43556                         properties.styleHash = styleIndex[styleMapIndex[styleUrl].normal];
43557                     }
43558                     // Try to populate the lineStyle or polyStyle since we got the style hash
43559                     var style = styleByHash[properties.styleHash];
43560                     if (style) {
43561                         if (!lineStyle) lineStyle = get1(style, 'LineStyle');
43562                         if (!polyStyle) polyStyle = get1(style, 'PolyStyle');
43563                     }
43564                 }
43565                 if (description) properties.description = description;
43566                 if (timeSpan) {
43567                     var begin = nodeVal(get1(timeSpan, 'begin'));
43568                     var end = nodeVal(get1(timeSpan, 'end'));
43569                     properties.timespan = { begin: begin, end: end };
43570                 }
43571                 if (timeStamp) {
43572                     properties.timestamp = nodeVal(get1(timeStamp, 'when'));
43573                 }
43574                 if (lineStyle) {
43575                     var linestyles = kmlColor(nodeVal(get1(lineStyle, 'color'))),
43576                         color = linestyles[0],
43577                         opacity = linestyles[1],
43578                         width = parseFloat(nodeVal(get1(lineStyle, 'width')));
43579                     if (color) properties.stroke = color;
43580                     if (!isNaN(opacity)) properties['stroke-opacity'] = opacity;
43581                     if (!isNaN(width)) properties['stroke-width'] = width;
43582                 }
43583                 if (polyStyle) {
43584                     var polystyles = kmlColor(nodeVal(get1(polyStyle, 'color'))),
43585                         pcolor = polystyles[0],
43586                         popacity = polystyles[1],
43587                         fill = nodeVal(get1(polyStyle, 'fill')),
43588                         outline = nodeVal(get1(polyStyle, 'outline'));
43589                     if (pcolor) properties.fill = pcolor;
43590                     if (!isNaN(popacity)) properties['fill-opacity'] = popacity;
43591                     if (fill) properties['fill-opacity'] = fill === '1' ? properties['fill-opacity'] || 1 : 0;
43592                     if (outline) properties['stroke-opacity'] = outline === '1' ? properties['stroke-opacity'] || 1 : 0;
43593                 }
43594                 if (extendedData) {
43595                     var datas = get(extendedData, 'Data'),
43596                         simpleDatas = get(extendedData, 'SimpleData');
43597
43598                     for (i = 0; i < datas.length; i++) {
43599                         properties[datas[i].getAttribute('name')] = nodeVal(get1(datas[i], 'value'));
43600                     }
43601                     for (i = 0; i < simpleDatas.length; i++) {
43602                         properties[simpleDatas[i].getAttribute('name')] = nodeVal(simpleDatas[i]);
43603                     }
43604                 }
43605                 if (visibility) {
43606                     properties.visibility = nodeVal(visibility);
43607                 }
43608                 if (geomsAndTimes.coordTimes.length) {
43609                     properties.coordTimes = (geomsAndTimes.coordTimes.length === 1) ?
43610                         geomsAndTimes.coordTimes[0] : geomsAndTimes.coordTimes;
43611                 }
43612                 var feature = {
43613                     type: 'Feature',
43614                     geometry: (geomsAndTimes.geoms.length === 1) ? geomsAndTimes.geoms[0] : {
43615                         type: 'GeometryCollection',
43616                         geometries: geomsAndTimes.geoms
43617                     },
43618                     properties: properties
43619                 };
43620                 if (attr(root, 'id')) feature.id = attr(root, 'id');
43621                 return [feature];
43622             }
43623             return gj;
43624         },
43625         gpx: function(doc) {
43626             var i,
43627                 tracks = get(doc, 'trk'),
43628                 routes = get(doc, 'rte'),
43629                 waypoints = get(doc, 'wpt'),
43630                 // a feature collection
43631                 gj = fc(),
43632                 feature;
43633             for (i = 0; i < tracks.length; i++) {
43634                 feature = getTrack(tracks[i]);
43635                 if (feature) gj.features.push(feature);
43636             }
43637             for (i = 0; i < routes.length; i++) {
43638                 feature = getRoute(routes[i]);
43639                 if (feature) gj.features.push(feature);
43640             }
43641             for (i = 0; i < waypoints.length; i++) {
43642                 gj.features.push(getPoint(waypoints[i]));
43643             }
43644             function getPoints(node, pointname) {
43645                 var pts = get(node, pointname),
43646                     line = [],
43647                     times = [],
43648                     heartRates = [],
43649                     l = pts.length;
43650                 if (l < 2) return {};  // Invalid line in GeoJSON
43651                 for (var i = 0; i < l; i++) {
43652                     var c = coordPair(pts[i]);
43653                     line.push(c.coordinates);
43654                     if (c.time) times.push(c.time);
43655                     if (c.heartRate) heartRates.push(c.heartRate);
43656                 }
43657                 return {
43658                     line: line,
43659                     times: times,
43660                     heartRates: heartRates
43661                 };
43662             }
43663             function getTrack(node) {
43664                 var segments = get(node, 'trkseg'),
43665                     track = [],
43666                     times = [],
43667                     heartRates = [],
43668                     line;
43669                 for (var i = 0; i < segments.length; i++) {
43670                     line = getPoints(segments[i], 'trkpt');
43671                     if (line) {
43672                         if (line.line) track.push(line.line);
43673                         if (line.times && line.times.length) times.push(line.times);
43674                         if (line.heartRates && line.heartRates.length) heartRates.push(line.heartRates);
43675                     }
43676                 }
43677                 if (track.length === 0) return;
43678                 var properties = getProperties(node);
43679                 extend(properties, getLineStyle(get1(node, 'extensions')));
43680                 if (times.length) properties.coordTimes = track.length === 1 ? times[0] : times;
43681                 if (heartRates.length) properties.heartRates = track.length === 1 ? heartRates[0] : heartRates;
43682                 return {
43683                     type: 'Feature',
43684                     properties: properties,
43685                     geometry: {
43686                         type: track.length === 1 ? 'LineString' : 'MultiLineString',
43687                         coordinates: track.length === 1 ? track[0] : track
43688                     }
43689                 };
43690             }
43691             function getRoute(node) {
43692                 var line = getPoints(node, 'rtept');
43693                 if (!line.line) return;
43694                 var prop = getProperties(node);
43695                 extend(prop, getLineStyle(get1(node, 'extensions')));
43696                 var routeObj = {
43697                     type: 'Feature',
43698                     properties: prop,
43699                     geometry: {
43700                         type: 'LineString',
43701                         coordinates: line.line
43702                     }
43703                 };
43704                 return routeObj;
43705             }
43706             function getPoint(node) {
43707                 var prop = getProperties(node);
43708                 extend(prop, getMulti(node, ['sym']));
43709                 return {
43710                     type: 'Feature',
43711                     properties: prop,
43712                     geometry: {
43713                         type: 'Point',
43714                         coordinates: coordPair(node).coordinates
43715                     }
43716                 };
43717             }
43718             function getLineStyle(extensions) {
43719                 var style = {};
43720                 if (extensions) {
43721                     var lineStyle = get1(extensions, 'line');
43722                     if (lineStyle) {
43723                         var color = nodeVal(get1(lineStyle, 'color')),
43724                             opacity = parseFloat(nodeVal(get1(lineStyle, 'opacity'))),
43725                             width = parseFloat(nodeVal(get1(lineStyle, 'width')));
43726                         if (color) style.stroke = color;
43727                         if (!isNaN(opacity)) style['stroke-opacity'] = opacity;
43728                         // GPX width is in mm, convert to px with 96 px per inch
43729                         if (!isNaN(width)) style['stroke-width'] = width * 96 / 25.4;
43730                     }
43731                 }
43732                 return style;
43733             }
43734             function getProperties(node) {
43735                 var prop = getMulti(node, ['name', 'cmt', 'desc', 'type', 'time', 'keywords']),
43736                     links = get(node, 'link');
43737                 if (links.length) prop.links = [];
43738                 for (var i = 0, link; i < links.length; i++) {
43739                     link = { href: attr(links[i], 'href') };
43740                     extend(link, getMulti(links[i], ['text', 'type']));
43741                     prop.links.push(link);
43742                 }
43743                 return prop;
43744             }
43745             return gj;
43746         }
43747     };
43748     return t;
43749 })();
43750
43751 module.exports = toGeoJSON;
43752 });
43753
43754 function svgGpx(projection, context, dispatch) {
43755     var showLabels = true,
43756         detected = utilDetect(),
43757         layer,
43758         src;
43759
43760
43761     function init() {
43762         if (svgGpx.initialized) return;  // run once
43763
43764         svgGpx.geojson = {};
43765         svgGpx.enabled = true;
43766
43767         function over() {
43768             event.stopPropagation();
43769             event.preventDefault();
43770             event.dataTransfer.dropEffect = 'copy';
43771         }
43772
43773         d3_select('body')
43774             .attr('dropzone', 'copy')
43775             .on('drop.localgpx', function() {
43776                 event.stopPropagation();
43777                 event.preventDefault();
43778                 if (!detected.filedrop) return;
43779                 drawGpx.files(event.dataTransfer.files);
43780             })
43781             .on('dragenter.localgpx', over)
43782             .on('dragexit.localgpx', over)
43783             .on('dragover.localgpx', over);
43784
43785         svgGpx.initialized = true;
43786     }
43787
43788
43789     function drawGpx(selection) {
43790         var geojson = svgGpx.geojson,
43791             enabled = svgGpx.enabled;
43792
43793         layer = selection.selectAll('.layer-gpx')
43794             .data(enabled ? [0] : []);
43795
43796         layer.exit()
43797             .remove();
43798
43799         layer = layer.enter()
43800             .append('g')
43801             .attr('class', 'layer-gpx')
43802             .merge(layer);
43803
43804
43805         var paths = layer
43806             .selectAll('path')
43807             .data([geojson]);
43808
43809         paths.exit()
43810             .remove();
43811
43812         paths = paths.enter()
43813             .append('path')
43814             .attr('class', 'gpx')
43815             .merge(paths);
43816
43817
43818         var path = d3_geoPath(projection);
43819
43820         paths
43821             .attr('d', path);
43822
43823
43824         var labels = layer.selectAll('text')
43825             .data(showLabels && geojson.features ? geojson.features : []);
43826
43827         labels.exit()
43828             .remove();
43829
43830         labels = labels.enter()
43831             .append('text')
43832             .attr('class', 'gpx')
43833             .merge(labels);
43834
43835         labels
43836             .text(function(d) {
43837                 return d.properties.desc || d.properties.name;
43838             })
43839             .attr('x', function(d) {
43840                 var centroid = path.centroid(d);
43841                 return centroid[0] + 7;
43842             })
43843             .attr('y', function(d) {
43844                 var centroid = path.centroid(d);
43845                 return centroid[1];
43846             });
43847
43848     }
43849
43850
43851     function toDom(x) {
43852         return (new DOMParser()).parseFromString(x, 'text/xml');
43853     }
43854
43855
43856     function getExtension(fileName) {
43857         if (isUndefined(fileName)) {
43858             return '';
43859         }
43860
43861         var lastDotIndex = fileName.lastIndexOf('.');
43862         if (lastDotIndex < 0) {
43863             return '';
43864         }
43865
43866         return fileName.substr(lastDotIndex);
43867     }
43868
43869
43870     function parseSaveAndZoom(extension, data) {
43871         switch (extension) {
43872             default:
43873                 drawGpx.geojson(togeojson.gpx(toDom(data))).fitZoom();
43874                 break;
43875             case '.kml':
43876                 drawGpx.geojson(togeojson.kml(toDom(data))).fitZoom();
43877                 break;
43878             case '.geojson':
43879             case '.json':
43880                 drawGpx.geojson(JSON.parse(data)).fitZoom();
43881                 break;
43882         }
43883     }
43884
43885
43886     drawGpx.showLabels = function(_) {
43887         if (!arguments.length) return showLabels;
43888         showLabels = _;
43889         return this;
43890     };
43891
43892
43893     drawGpx.enabled = function(_) {
43894         if (!arguments.length) return svgGpx.enabled;
43895         svgGpx.enabled = _;
43896         dispatch.call('change');
43897         return this;
43898     };
43899
43900
43901     drawGpx.hasGpx = function() {
43902         var geojson = svgGpx.geojson;
43903         return (!(isEmpty(geojson) || isEmpty(geojson.features)));
43904     };
43905
43906
43907     drawGpx.geojson = function(gj) {
43908         if (!arguments.length) return svgGpx.geojson;
43909         if (isEmpty(gj) || isEmpty(gj.features)) return this;
43910         svgGpx.geojson = gj;
43911         dispatch.call('change');
43912         return this;
43913     };
43914
43915
43916     drawGpx.url = function(url) {
43917         d3_text(url, function(err, data) {
43918             if (!err) {
43919                 src = url;
43920
43921                 var extension = getExtension(url);
43922                 parseSaveAndZoom(extension, data);
43923             }
43924         });
43925         return this;
43926     };
43927
43928
43929     drawGpx.files = function(fileList) {
43930         if (!fileList.length) return this;
43931         var f = fileList[0],
43932             reader = new FileReader();
43933
43934         reader.onload = (function(file) {
43935             src = file.name;
43936
43937             var extension = getExtension(file.name);
43938
43939             return function (e) {
43940                 parseSaveAndZoom(extension, e.target.result);
43941             };
43942         })(f);
43943
43944         reader.readAsText(f);
43945         return this;
43946     };
43947
43948     drawGpx.getSrc = function () {
43949       return src;
43950     };
43951
43952     drawGpx.fitZoom = function() {
43953         if (!this.hasGpx()) return this;
43954         var geojson = svgGpx.geojson;
43955
43956         var map = context.map(),
43957             viewport = map.trimmedExtent().polygon(),
43958             coords = reduce(geojson.features, function(coords, feature) {
43959                 var c = feature.geometry.coordinates;
43960
43961                 /* eslint-disable no-fallthrough */
43962                 switch (feature.geometry.type) {
43963                     case 'Point':
43964                         c = [c];
43965                     case 'MultiPoint':
43966                     case 'LineString':
43967                         break;
43968
43969                     case 'MultiPolygon':
43970                         c = flatten(c);
43971                     case 'Polygon':
43972                     case 'MultiLineString':
43973                         c = flatten(c);
43974                         break;
43975                 }
43976                 /* eslint-enable no-fallthrough */
43977
43978                 return union(coords, c);
43979             }, []);
43980
43981         if (!geoPolygonIntersectsPolygon(viewport, coords, true)) {
43982             var extent = geoExtent(d3_geoBounds({ type: 'LineString', coordinates: coords }));
43983             map.centerZoom(extent.center(), map.trimmedExtentZoom(extent));
43984         }
43985
43986         return this;
43987     };
43988
43989
43990     init();
43991     return drawGpx;
43992 }
43993
43994 function svgIcon(name, svgklass, useklass) {
43995     return function drawIcon(selection) {
43996         selection.selectAll('svg')
43997             .data([0])
43998             .enter()
43999             .append('svg')
44000             .attr('class', 'icon ' + (svgklass || ''))
44001             .append('use')
44002             .attr('xlink:href', name)
44003             .attr('class', useklass);
44004     };
44005 }
44006
44007 function svgLabels(projection, context) {
44008     var path = d3_geoPath(projection);
44009     var detected = utilDetect();
44010     var baselineHack = (detected.ie || detected.browser.toLowerCase() === 'edge');
44011     var _rdrawn = rbush_1();
44012     var _rskipped = rbush_1();
44013     var _textWidthCache = {};
44014     var _entitybboxes = {};
44015
44016     // Listed from highest to lowest priority
44017     var labelStack = [
44018         ['line', 'aeroway', '*', 12],
44019         ['line', 'highway', 'motorway', 12],
44020         ['line', 'highway', 'trunk', 12],
44021         ['line', 'highway', 'primary', 12],
44022         ['line', 'highway', 'secondary', 12],
44023         ['line', 'highway', 'tertiary', 12],
44024         ['line', 'highway', '*', 12],
44025         ['line', 'railway', '*', 12],
44026         ['line', 'waterway', '*', 12],
44027         ['area', 'aeroway', '*', 12],
44028         ['area', 'amenity', '*', 12],
44029         ['area', 'building', '*', 12],
44030         ['area', 'historic', '*', 12],
44031         ['area', 'leisure', '*', 12],
44032         ['area', 'man_made', '*', 12],
44033         ['area', 'natural', '*', 12],
44034         ['area', 'shop', '*', 12],
44035         ['area', 'tourism', '*', 12],
44036         ['area', 'camp_site', '*', 12],
44037         ['point', 'aeroway', '*', 10],
44038         ['point', 'amenity', '*', 10],
44039         ['point', 'building', '*', 10],
44040         ['point', 'historic', '*', 10],
44041         ['point', 'leisure', '*', 10],
44042         ['point', 'man_made', '*', 10],
44043         ['point', 'natural', '*', 10],
44044         ['point', 'shop', '*', 10],
44045         ['point', 'tourism', '*', 10],
44046         ['point', 'camp_site', '*', 10],
44047         ['line', 'name', '*', 12],
44048         ['area', 'name', '*', 12],
44049         ['point', 'name', '*', 10]
44050     ];
44051
44052
44053     function blacklisted(preset) {
44054         var noIcons = ['building', 'landuse', 'natural'];
44055         return some(noIcons, function(s) {
44056             return preset.id.indexOf(s) >= 0;
44057         });
44058     }
44059
44060
44061     function get(array, prop) {
44062         return function(d, i) { return array[i][prop]; };
44063     }
44064
44065
44066     function textWidth(text, size, elem) {
44067         var c = _textWidthCache[size];
44068         if (!c) c = _textWidthCache[size] = {};
44069
44070         if (c[text]) {
44071             return c[text];
44072
44073         } else if (elem) {
44074             c[text] = elem.getComputedTextLength();
44075             return c[text];
44076
44077         } else {
44078             var str = encodeURIComponent(text).match(/%[CDEFcdef]/g);
44079             if (str === null) {
44080                 return size / 3 * 2 * text.length;
44081             } else {
44082                 return size / 3 * (2 * text.length + str.length);
44083             }
44084         }
44085     }
44086
44087
44088     function drawLinePaths(selection, entities, filter, classes, labels) {
44089         var paths = selection.selectAll('path')
44090             .filter(filter)
44091             .data(entities, osmEntity.key);
44092
44093         // exit
44094         paths.exit()
44095             .remove();
44096
44097         // enter/update
44098         paths.enter()
44099             .append('path')
44100             .style('stroke-width', get(labels, 'font-size'))
44101             .attr('id', function(d) { return 'labelpath-' + d.id; })
44102             .attr('class', classes)
44103             .merge(paths)
44104             .attr('d', get(labels, 'lineString'));
44105     }
44106
44107
44108     function drawLineLabels(selection, entities, filter, classes, labels) {
44109         var texts = selection.selectAll('text.' + classes)
44110             .filter(filter)
44111             .data(entities, osmEntity.key);
44112
44113         // exit
44114         texts.exit()
44115             .remove();
44116
44117         // enter
44118         texts.enter()
44119             .append('text')
44120             .attr('class', function(d, i) { return classes + ' ' + labels[i].classes + ' ' + d.id; })
44121             .attr('dy', baselineHack ? '0.35em' : null)
44122             .append('textPath')
44123             .attr('class', 'textpath');
44124
44125         // update
44126         selection.selectAll('text.' + classes).selectAll('.textpath')
44127             .filter(filter)
44128             .data(entities, osmEntity.key)
44129             .attr('startOffset', '50%')
44130             .attr('xlink:href', function(d) { return '#labelpath-' + d.id; })
44131             .text(utilDisplayNameForPath);
44132     }
44133
44134
44135     function drawPointLabels(selection, entities, filter, classes, labels) {
44136         var texts = selection.selectAll('text.' + classes)
44137             .filter(filter)
44138             .data(entities, osmEntity.key);
44139
44140         // exit
44141         texts.exit()
44142             .remove();
44143
44144         // enter/update
44145         texts.enter()
44146             .append('text')
44147             .attr('class', function(d, i) {
44148                 return classes + ' ' + labels[i].classes + ' ' + d.id;
44149             })
44150             .merge(texts)
44151             .attr('x', get(labels, 'x'))
44152             .attr('y', get(labels, 'y'))
44153             .style('text-anchor', get(labels, 'textAnchor'))
44154             .text(utilDisplayName)
44155             .each(function(d, i) {
44156                 textWidth(utilDisplayName(d), labels[i].height, this);
44157             });
44158     }
44159
44160
44161     function drawAreaLabels(selection, entities, filter, classes, labels) {
44162         entities = entities.filter(hasText);
44163         labels = labels.filter(hasText);
44164         drawPointLabels(selection, entities, filter, classes, labels);
44165
44166         function hasText(d, i) {
44167             return labels[i].hasOwnProperty('x') && labels[i].hasOwnProperty('y');
44168         }
44169     }
44170
44171
44172     function drawAreaIcons(selection, entities, filter, classes, labels) {
44173         var icons = selection.selectAll('use.' + classes)
44174             .filter(filter)
44175             .data(entities, osmEntity.key);
44176
44177         // exit
44178         icons.exit()
44179             .remove();
44180
44181         // enter/update
44182         icons.enter()
44183             .append('use')
44184             .attr('class', 'icon ' + classes)
44185             .attr('width', '17px')
44186             .attr('height', '17px')
44187             .merge(icons)
44188             .attr('transform', get(labels, 'transform'))
44189             .attr('xlink:href', function(d) {
44190                 var preset = context.presets().match(d, context.graph());
44191                 var picon = preset && preset.icon;
44192
44193                 if (!picon) {
44194                     return '';
44195                 } else {
44196                     var isMaki = dataFeatureIcons.indexOf(picon) !== -1;
44197                     return '#' + picon + (isMaki ? '-15' : '');
44198                 }
44199             });
44200     }
44201
44202
44203     function drawCollisionBoxes(selection, rtree, which) {
44204         var classes = 'debug ' + which + ' ' + (which === 'debug-skipped' ? 'orange' : 'yellow');
44205
44206         var gj = [];
44207         if (context.getDebug('collision')) {
44208             gj = rtree.all().map(function(d) {
44209                 return { type: 'Polygon', coordinates: [[
44210                     [d.minX, d.minY],
44211                     [d.maxX, d.minY],
44212                     [d.maxX, d.maxY],
44213                     [d.minX, d.maxY],
44214                     [d.minX, d.minY]
44215                 ]]};
44216             });
44217         }
44218
44219         var boxes = selection.selectAll('.' + which)
44220             .data(gj);
44221
44222         // exit
44223         boxes.exit()
44224             .remove();
44225
44226         // enter/update
44227         boxes.enter()
44228             .append('path')
44229             .attr('class', classes)
44230             .merge(boxes)
44231             .attr('d', d3_geoPath());
44232     }
44233
44234
44235     function drawLabels(selection, graph, entities, filter, dimensions, fullRedraw) {
44236         var wireframe = context.surface().classed('fill-wireframe');
44237         var zoom = geoScaleToZoom(projection.scale());
44238
44239         var labelable = [];
44240         var renderNodeAs = {};
44241         var i, j, k, entity, geometry;
44242
44243         for (i = 0; i < labelStack.length; i++) {
44244             labelable.push([]);
44245         }
44246
44247         if (fullRedraw) {
44248             _rdrawn.clear();
44249             _rskipped.clear();
44250             _entitybboxes = {};
44251
44252         } else {
44253             for (i = 0; i < entities.length; i++) {
44254                 entity = entities[i];
44255                 var toRemove = []
44256                     .concat(_entitybboxes[entity.id] || [])
44257                     .concat(_entitybboxes[entity.id + 'I'] || []);
44258
44259                 for (j = 0; j < toRemove.length; j++) {
44260                     _rdrawn.remove(toRemove[j]);
44261                     _rskipped.remove(toRemove[j]);
44262                 }
44263             }
44264         }
44265
44266         // Loop through all the entities to do some preprocessing
44267         for (i = 0; i < entities.length; i++) {
44268             entity = entities[i];
44269             geometry = entity.geometry(graph);
44270
44271             // Insert collision boxes around interesting points/vertices
44272             if (geometry === 'point' || (geometry === 'vertex' && isInterestingVertex(entity))) {
44273                 var hasDirections = entity.directions(graph, projection).length;
44274                 var markerPadding;
44275
44276                 if (!wireframe && geometry === 'point' && !(zoom >= 18 && hasDirections)) {
44277                     renderNodeAs[entity.id] = 'point';
44278                     markerPadding = 20;   // extra y for marker height
44279                 } else {
44280                     renderNodeAs[entity.id] = 'vertex';
44281                     markerPadding = 0;
44282                 }
44283
44284                 var coord = projection(entity.loc);
44285                 var nodePadding = 10;
44286                 var bbox = {
44287                     minX: coord[0] - nodePadding,
44288                     minY: coord[1] - nodePadding - markerPadding,
44289                     maxX: coord[0] + nodePadding,
44290                     maxY: coord[1] + nodePadding
44291                 };
44292
44293                 doInsert(bbox, entity.id + 'P');
44294             }
44295
44296             // From here on, treat vertices like points
44297             if (geometry === 'vertex') {
44298                 geometry = 'point';
44299             }
44300
44301             // Determine which entities are label-able
44302             var preset = geometry === 'area' && context.presets().match(entity, graph);
44303             var icon = preset && !blacklisted(preset) && preset.icon;
44304
44305             if (!icon && !utilDisplayName(entity))
44306                 continue;
44307
44308             for (k = 0; k < labelStack.length; k++) {
44309                 var matchGeom = labelStack[k][0];
44310                 var matchKey = labelStack[k][1];
44311                 var matchVal = labelStack[k][2];
44312                 var hasVal = entity.tags[matchKey];
44313
44314                 if (geometry === matchGeom && hasVal && (matchVal === '*' || matchVal === hasVal)) {
44315                     labelable[k].push(entity);
44316                     break;
44317                 }
44318             }
44319         }
44320
44321         var positions = {
44322             point: [],
44323             line: [],
44324             area: []
44325         };
44326
44327         var labelled = {
44328             point: [],
44329             line: [],
44330             area: []
44331         };
44332
44333         // Try and find a valid label for labellable entities
44334         for (k = 0; k < labelable.length; k++) {
44335             var fontSize = labelStack[k][3];
44336
44337             for (i = 0; i < labelable[k].length; i++) {
44338                 entity = labelable[k][i];
44339                 geometry = entity.geometry(graph);
44340
44341                 var getName = (geometry === 'line') ? utilDisplayNameForPath : utilDisplayName;
44342                 var name = getName(entity);
44343                 var width = name && textWidth(name, fontSize);
44344                 var p = null;
44345
44346                 if (geometry === 'point' || geometry === 'vertex') {
44347                     // no point or vertex labels in wireframe mode
44348                     // no vertex labels at low zooms (vertices have no icons)
44349                     if (wireframe) continue;
44350                     var renderAs = renderNodeAs[entity.id];
44351                     if (renderAs === 'vertex' && zoom < 17) continue;
44352
44353                     p = getPointLabel(entity, width, fontSize, renderAs);
44354
44355                 } else if (geometry === 'line') {
44356                     p = getLineLabel(entity, width, fontSize);
44357
44358                 } else if (geometry === 'area') {
44359                     p = getAreaLabel(entity, width, fontSize);
44360                 }
44361
44362                 if (p) {
44363                     if (geometry === 'vertex') { geometry = 'point'; }  // treat vertex like point
44364                     p.classes = geometry + ' tag-' + labelStack[k][1];
44365                     positions[geometry].push(p);
44366                     labelled[geometry].push(entity);
44367                 }
44368             }
44369         }
44370
44371
44372         function isInterestingVertex(entity) {
44373             var selectedIDs = context.selectedIDs();
44374
44375             return entity.hasInterestingTags() ||
44376                 entity.isEndpoint(graph) ||
44377                 entity.isConnected(graph) ||
44378                 selectedIDs.indexOf(entity.id) !== -1 ||
44379                 some(graph.parentWays(entity), function(parent) {
44380                     return selectedIDs.indexOf(parent.id) !== -1;
44381                 });
44382         }
44383
44384
44385         function getPointLabel(entity, width, height, geometry) {
44386             var y = (geometry === 'point' ? -12 : 0);
44387             var pointOffsets = {
44388                 ltr: [15, y, 'start'],
44389                 rtl: [-15, y, 'end']
44390             };
44391
44392             var coord = projection(entity.loc);
44393             var textPadding = 2;
44394             var offset = pointOffsets[textDirection];
44395             var p = {
44396                 height: height,
44397                 width: width,
44398                 x: coord[0] + offset[0],
44399                 y: coord[1] + offset[1],
44400                 textAnchor: offset[2]
44401             };
44402
44403             // insert a collision box for the text label..
44404             var bbox;
44405             if (textDirection === 'rtl') {
44406                 bbox = {
44407                     minX: p.x - width - textPadding,
44408                     minY: p.y - (height / 2) - textPadding,
44409                     maxX: p.x + textPadding,
44410                     maxY: p.y + (height / 2) + textPadding
44411                 };
44412             } else {
44413                 bbox = {
44414                     minX: p.x - textPadding,
44415                     minY: p.y - (height / 2) - textPadding,
44416                     maxX: p.x + width + textPadding,
44417                     maxY: p.y + (height / 2) + textPadding
44418                 };
44419             }
44420
44421             if (tryInsert([bbox], entity.id, true)) {
44422                 return p;
44423             }
44424         }
44425
44426
44427         function getLineLabel(entity, width, height) {
44428             var viewport = geoExtent(context.projection.clipExtent()).polygon();
44429             var points = map$4(graph.childNodes(entity), 'loc').map(projection);
44430             var length = geoPathLength(points);
44431
44432             if (length < width + 20) return;
44433
44434             // todo: properly clip points to viewport
44435
44436             // % along the line to attempt to place the label
44437             var lineOffsets = [50, 45, 55, 40, 60, 35, 65, 30, 70,
44438                                25, 75, 20, 80, 15, 95, 10, 90, 5, 95];
44439             var padding = 3;
44440
44441             for (var i = 0; i < lineOffsets.length; i++) {
44442                 var offset = lineOffsets[i];
44443                 var middle = offset / 100 * length;
44444                 var start = middle - width / 2;
44445
44446                 if (start < 0 || start + width > length) continue;
44447
44448                 // generate subpath and ignore paths that are invalid or don't cross viewport.
44449                 var sub = subpath(points, start, start + width);
44450                 if (!sub || !geoPolygonIntersectsPolygon(viewport, sub, true)) {
44451                     continue;
44452                 }
44453
44454                 var isReverse = reverse(sub);
44455                 if (isReverse) {
44456                     sub = sub.reverse();
44457                 }
44458
44459                 var bboxes = [];
44460                 var boxsize = (height + 2) / 2;
44461
44462                 for (var j = 0; j < sub.length - 1; j++) {
44463                     var a = sub[j];
44464                     var b = sub[j + 1];
44465
44466                     // split up the text into small collision boxes
44467                     var num = Math.max(1, Math.floor(geoVecLength(a, b) / boxsize / 2));
44468
44469                     for (var box = 0; box < num; box++) {
44470                         var p = geoVecInterp(a, b, box / num);
44471                         var x0 = p[0] - boxsize - padding;
44472                         var y0 = p[1] - boxsize - padding;
44473                         var x1 = p[0] + boxsize + padding;
44474                         var y1 = p[1] + boxsize + padding;
44475
44476                         bboxes.push({
44477                             minX: Math.min(x0, x1),
44478                             minY: Math.min(y0, y1),
44479                             maxX: Math.max(x0, x1),
44480                             maxY: Math.max(y0, y1)
44481                         });
44482                     }
44483                 }
44484
44485                 if (tryInsert(bboxes, entity.id, false)) {   // accept this one
44486                     return {
44487                         'font-size': height + 2,
44488                         lineString: lineString(sub),
44489                         startOffset: offset + '%'
44490                     };
44491                 }
44492             }
44493
44494             function reverse(p) {
44495                 var angle = Math.atan2(p[1][1] - p[0][1], p[1][0] - p[0][0]);
44496                 return !(p[0][0] < p[p.length - 1][0] && angle < Math.PI/2 && angle > -Math.PI/2);
44497             }
44498
44499             function lineString(points) {
44500                 return 'M' + points.join('L');
44501             }
44502
44503             function subpath(points, from, to) {
44504                 var sofar = 0;
44505                 var start, end, i0, i1;
44506
44507                 for (var i = 0; i < points.length - 1; i++) {
44508                     var a = points[i];
44509                     var b = points[i + 1];
44510                     var current = geoVecLength(a, b);
44511                     var portion;
44512                     if (!start && sofar + current >= from) {
44513                         portion = (from - sofar) / current;
44514                         start = [
44515                             a[0] + portion * (b[0] - a[0]),
44516                             a[1] + portion * (b[1] - a[1])
44517                         ];
44518                         i0 = i + 1;
44519                     }
44520                     if (!end && sofar + current >= to) {
44521                         portion = (to - sofar) / current;
44522                         end = [
44523                             a[0] + portion * (b[0] - a[0]),
44524                             a[1] + portion * (b[1] - a[1])
44525                         ];
44526                         i1 = i + 1;
44527                     }
44528                     sofar += current;
44529                 }
44530
44531                 var result = points.slice(i0, i1);
44532                 result.unshift(start);
44533                 result.push(end);
44534                 return result;
44535             }
44536         }
44537
44538
44539         function getAreaLabel(entity, width, height) {
44540             var centroid = path.centroid(entity.asGeoJSON(graph, true));
44541             var extent = entity.extent(graph);
44542             var areaWidth = projection(extent[1])[0] - projection(extent[0])[0];
44543
44544             if (isNaN(centroid[0]) || areaWidth < 20) return;
44545
44546             var preset = context.presets().match(entity, context.graph());
44547             var picon = preset && preset.icon;
44548             var iconSize = 17;
44549             var padding = 2;
44550             var p = {};
44551
44552             if (picon) {  // icon and label..
44553                 if (addIcon()) {
44554                     addLabel(iconSize + padding);
44555                     return p;
44556                 }
44557             } else {   // label only..
44558                 if (addLabel(0)) {
44559                     return p;
44560                 }
44561             }
44562
44563
44564             function addIcon() {
44565                 var iconX = centroid[0] - (iconSize / 2);
44566                 var iconY = centroid[1] - (iconSize / 2);
44567                 var bbox = {
44568                     minX: iconX,
44569                     minY: iconY,
44570                     maxX: iconX + iconSize,
44571                     maxY: iconY + iconSize
44572                 };
44573
44574                 if (tryInsert([bbox], entity.id + 'I', true)) {
44575                     p.transform = 'translate(' + iconX + ',' + iconY + ')';
44576                     return true;
44577                 }
44578                 return false;
44579             }
44580
44581             function addLabel(yOffset) {
44582                 if (width && areaWidth >= width + 20) {
44583                     var labelX = centroid[0];
44584                     var labelY = centroid[1] + yOffset;
44585                     var bbox = {
44586                         minX: labelX - (width / 2) - padding,
44587                         minY: labelY - (height / 2) - padding,
44588                         maxX: labelX + (width / 2) + padding,
44589                         maxY: labelY + (height / 2) + padding
44590                     };
44591
44592                     if (tryInsert([bbox], entity.id, true)) {
44593                         p.x = labelX;
44594                         p.y = labelY;
44595                         p.textAnchor = 'middle';
44596                         p.height = height;
44597                         return true;
44598                     }
44599                 }
44600                 return false;
44601             }
44602         }
44603
44604
44605         // force insert a singular bounding box
44606         // singular box only, no array, id better be unique
44607         function doInsert(bbox, id) {
44608             bbox.id = id;
44609
44610             var oldbox = _entitybboxes[id];
44611             if (oldbox) {
44612                 _rdrawn.remove(oldbox);
44613             }
44614             _entitybboxes[id] = bbox;
44615             _rdrawn.insert(bbox);
44616         }
44617
44618
44619         function tryInsert(bboxes, id, saveSkipped) {
44620             var skipped = false;
44621
44622             for (var i = 0; i < bboxes.length; i++) {
44623                 var bbox = bboxes[i];
44624                 bbox.id = id;
44625
44626                 // Check that label is visible
44627                 if (bbox.minX < 0 || bbox.minY < 0 || bbox.maxX > dimensions[0] || bbox.maxY > dimensions[1]) {
44628                     skipped = true;
44629                     break;
44630                 }
44631                 if (_rdrawn.collides(bbox)) {
44632                     skipped = true;
44633                     break;
44634                 }
44635             }
44636
44637             _entitybboxes[id] = bboxes;
44638
44639             if (skipped) {
44640                 if (saveSkipped) {
44641                     _rskipped.load(bboxes);
44642                 }
44643             } else {
44644                 _rdrawn.load(bboxes);
44645             }
44646
44647             return !skipped;
44648         }
44649
44650
44651         var layer = selection.selectAll('.layer-labels');
44652         var halo = layer.selectAll('.layer-labels-halo');
44653         var label = layer.selectAll('.layer-labels-label');
44654         var debug = layer.selectAll('.layer-labels-debug');
44655
44656         // points
44657         drawPointLabels(label, labelled.point, filter, 'pointlabel', positions.point);
44658         drawPointLabels(halo, labelled.point, filter, 'pointlabel-halo', positions.point);
44659
44660         // lines
44661         drawLinePaths(halo, labelled.line, filter, '', positions.line);
44662         drawLineLabels(label, labelled.line, filter, 'linelabel', positions.line);
44663         drawLineLabels(halo, labelled.line, filter, 'linelabel-halo', positions.line);
44664
44665         // areas
44666         drawAreaLabels(label, labelled.area, filter, 'arealabel', positions.area);
44667         drawAreaLabels(halo, labelled.area, filter, 'arealabel-halo', positions.area);
44668         drawAreaIcons(label, labelled.area, filter, 'areaicon', positions.area);
44669         drawAreaIcons(halo, labelled.area, filter, 'areaicon-halo', positions.area);
44670
44671         // debug
44672         drawCollisionBoxes(debug, _rskipped, 'debug-skipped');
44673         drawCollisionBoxes(debug, _rdrawn, 'debug-drawn');
44674
44675         layer.call(filterLabels);
44676     }
44677
44678
44679     function filterLabels(selection) {
44680         var layers = selection
44681             .selectAll('.layer-labels-label, .layer-labels-halo');
44682
44683         layers.selectAll('.nolabel')
44684             .classed('nolabel', false);
44685
44686         var mouse = context.mouse();
44687         var graph = context.graph();
44688         var selectedIDs = context.selectedIDs();
44689         var ids = [];
44690         var pad, bbox;
44691
44692         // hide labels near the mouse
44693         if (mouse) {
44694             pad = 20;
44695             bbox = { minX: mouse[0] - pad, minY: mouse[1] - pad, maxX: mouse[0] + pad, maxY: mouse[1] + pad };
44696             ids.push.apply(ids, map$4(_rdrawn.search(bbox), 'id'));
44697         }
44698
44699         // hide labels on selected nodes (they look weird when dragging / haloed)
44700         for (var i = 0; i < selectedIDs.length; i++) {
44701             var entity = graph.hasEntity(selectedIDs[i]);
44702             if (entity && entity.type === 'node') {
44703                 ids.push(selectedIDs[i]);
44704             }
44705         }
44706
44707         layers.selectAll(utilEntitySelector(ids))
44708             .classed('nolabel', true);
44709
44710
44711         // draw the mouse bbox if debugging is on..
44712         var debug = selection.selectAll('.layer-labels-debug');
44713         var gj = [];
44714         if (context.getDebug('collision')) {
44715             gj = bbox ? [{
44716                 type: 'Polygon',
44717                 coordinates: [[
44718                     [bbox.minX, bbox.minY],
44719                     [bbox.maxX, bbox.minY],
44720                     [bbox.maxX, bbox.maxY],
44721                     [bbox.minX, bbox.maxY],
44722                     [bbox.minX, bbox.minY]
44723                 ]]
44724             }] : [];
44725         }
44726
44727         var box = debug.selectAll('.debug-mouse')
44728             .data(gj);
44729
44730         // exit
44731         box.exit()
44732             .remove();
44733
44734         // enter/update
44735         box.enter()
44736             .append('path')
44737             .attr('class', 'debug debug-mouse yellow')
44738             .merge(box)
44739             .attr('d', d3_geoPath());
44740     }
44741
44742
44743     var throttleFilterLabels = throttle(utilCallWhenIdle(filterLabels), 100);
44744
44745
44746     drawLabels.observe = function(selection) {
44747         var listener = function() { throttleFilterLabels(selection); };
44748         selection.on('mousemove.hidelabels', listener);
44749         context.on('enter.hidelabels', listener);
44750     };
44751
44752
44753     drawLabels.off = function(selection) {
44754         throttleFilterLabels.cancel();
44755         selection.on('mousemove.hidelabels', null);
44756         context.on('enter.hidelabels', null);
44757     };
44758
44759
44760     return drawLabels;
44761 }
44762
44763 function svgMapillaryImages(projection, context, dispatch) {
44764     var throttledRedraw = throttle(function () { dispatch.call('change'); }, 1000);
44765     var minZoom = 12;
44766     var minMarkerZoom = 16;
44767     var minViewfieldZoom = 18;
44768     var layer = d3_select(null);
44769     var _mapillary;
44770
44771
44772     function init() {
44773         if (svgMapillaryImages.initialized) return;  // run once
44774         svgMapillaryImages.enabled = false;
44775         svgMapillaryImages.initialized = true;
44776     }
44777
44778
44779     function getService() {
44780         if (services.mapillary && !_mapillary) {
44781             _mapillary = services.mapillary;
44782             _mapillary.event.on('loadedImages', throttledRedraw);
44783         } else if (!services.mapillary && _mapillary) {
44784             _mapillary = null;
44785         }
44786
44787         return _mapillary;
44788     }
44789
44790
44791     function showLayer() {
44792         var service = getService();
44793         if (!service) return;
44794
44795         service.loadViewer(context);
44796         editOn();
44797
44798         layer
44799             .style('opacity', 0)
44800             .transition()
44801             .duration(250)
44802             .style('opacity', 1)
44803             .on('end', function () { dispatch.call('change'); });
44804     }
44805
44806
44807     function hideLayer() {
44808         var service = getService();
44809         if (service) {
44810             service.hideViewer();
44811         }
44812
44813         throttledRedraw.cancel();
44814
44815         layer
44816             .transition()
44817             .duration(250)
44818             .style('opacity', 0)
44819             .on('end', editOff);
44820     }
44821
44822
44823     function editOn() {
44824         layer.style('display', 'block');
44825     }
44826
44827
44828     function editOff() {
44829         layer.selectAll('.viewfield-group').remove();
44830         layer.style('display', 'none');
44831     }
44832
44833
44834     function click(d) {
44835         var service = getService();
44836         if (!service) return;
44837
44838         service
44839             .selectImage(d)
44840             .updateViewer(d.key, context)
44841             .showViewer();
44842
44843         context.map().centerEase(d.loc);
44844     }
44845
44846
44847     function mouseover(d) {
44848         var service = getService();
44849         if (service) service.setStyles(d);
44850     }
44851
44852
44853     function mouseout() {
44854         var service = getService();
44855         if (service) service.setStyles(null);
44856     }
44857
44858
44859     function transform(d) {
44860         var t = svgPointTransform(projection)(d);
44861         if (d.ca) {
44862             t += ' rotate(' + Math.floor(d.ca) + ',0,0)';
44863         }
44864         return t;
44865     }
44866
44867
44868     function update() {
44869         var viewer = d3_select('#photoviewer');
44870         var selected = viewer.empty() ? undefined : viewer.datum();
44871
44872         var z = ~~context.map().zoom();
44873         var showMarkers = (z >= minMarkerZoom);
44874         var showViewfields = (z >= minViewfieldZoom);
44875
44876         var service = getService();
44877         var sequences = (service ? service.sequences(projection) : []);
44878         var images = (service && showMarkers ? service.images(projection) : []);
44879
44880         var traces = layer.selectAll('.sequences').selectAll('.sequence')
44881             .data(sequences, function(d) { return d.properties.key; });
44882
44883         // exit
44884         traces.exit()
44885             .remove();
44886
44887         // enter/update
44888         traces = traces.enter()
44889             .append('path')
44890             .attr('class', 'sequence')
44891             .merge(traces)
44892             .attr('d', svgPath(projection).geojson);
44893
44894
44895         var groups = layer.selectAll('.markers').selectAll('.viewfield-group')
44896             .data(images, function(d) { return d.key; });
44897
44898         // exit
44899         groups.exit()
44900             .remove();
44901
44902         // enter
44903         var groupsEnter = groups.enter()
44904             .append('g')
44905             .attr('class', 'viewfield-group')
44906             .on('mouseover', mouseover)
44907             .on('mouseout', mouseout)
44908             .on('click', click);
44909
44910         groupsEnter
44911             .append('g')
44912             .attr('class', 'viewfield-scale');
44913
44914         // update
44915         var markers = groups
44916             .merge(groupsEnter)
44917             .sort(function(a, b) {
44918                 return (a === selected) ? 1
44919                     : (b === selected) ? -1
44920                     : b.loc[1] - a.loc[1];  // sort Y
44921             })
44922             .attr('transform', transform)
44923             .select('.viewfield-scale');
44924
44925
44926         markers.selectAll('circle')
44927             .data([0])
44928             .enter()
44929             .append('circle')
44930             .attr('dx', '0')
44931             .attr('dy', '0')
44932             .attr('r', '6');
44933
44934         var viewfields = markers.selectAll('.viewfield')
44935             .data(showViewfields ? [0] : []);
44936
44937         viewfields.exit()
44938             .remove();
44939
44940         viewfields.enter()               // viewfields may or may not be drawn...
44941             .insert('path', 'circle')    // but if they are, draw below the circles
44942             .attr('class', 'viewfield')
44943             .attr('transform', 'scale(1.5,1.5),translate(-8, -13)')
44944             .attr('d', viewfieldPath);
44945
44946         function viewfieldPath() {
44947             var d = this.parentNode.__data__;
44948             if (d.pano) {
44949                 return 'M 8,13 m -10,0 a 10,10 0 1,0 20,0 a 10,10 0 1,0 -20,0';
44950             } else {
44951                 return 'M 6,9 C 8,8.4 8,8.4 10,9 L 16,-2 C 12,-5 4,-5 0,-2 z';
44952             }
44953         }
44954     }
44955
44956
44957     function drawImages(selection) {
44958         var enabled = svgMapillaryImages.enabled,
44959             service = getService();
44960
44961         layer = selection.selectAll('.layer-mapillary-images')
44962             .data(service ? [0] : []);
44963
44964         layer.exit()
44965             .remove();
44966
44967         var layerEnter = layer.enter()
44968             .append('g')
44969             .attr('class', 'layer-mapillary-images')
44970             .style('display', enabled ? 'block' : 'none');
44971
44972         layerEnter
44973             .append('g')
44974             .attr('class', 'sequences');
44975
44976         layerEnter
44977             .append('g')
44978             .attr('class', 'markers');
44979
44980         layer = layerEnter
44981             .merge(layer);
44982
44983         if (enabled) {
44984             if (service && ~~context.map().zoom() >= minZoom) {
44985                 editOn();
44986                 update();
44987                 service.loadImages(projection);
44988             } else {
44989                 editOff();
44990             }
44991         }
44992     }
44993
44994
44995     drawImages.enabled = function(_) {
44996         if (!arguments.length) return svgMapillaryImages.enabled;
44997         svgMapillaryImages.enabled = _;
44998         if (svgMapillaryImages.enabled) {
44999             showLayer();
45000         } else {
45001             hideLayer();
45002         }
45003         dispatch.call('change');
45004         return this;
45005     };
45006
45007
45008     drawImages.supported = function() {
45009         return !!getService();
45010     };
45011
45012
45013     init();
45014     return drawImages;
45015 }
45016
45017 function svgMapillarySigns(projection, context, dispatch) {
45018     var throttledRedraw = throttle(function () { dispatch.call('change'); }, 1000);
45019     var minZoom = 12;
45020     var layer = d3_select(null);
45021     var _mapillary;
45022
45023
45024     function init() {
45025         if (svgMapillarySigns.initialized) return;  // run once
45026         svgMapillarySigns.enabled = false;
45027         svgMapillarySigns.initialized = true;
45028     }
45029
45030
45031     function getService() {
45032         if (services.mapillary && !_mapillary) {
45033             _mapillary = services.mapillary;
45034             _mapillary.event.on('loadedSigns', throttledRedraw);
45035         } else if (!services.mapillary && _mapillary) {
45036             _mapillary = null;
45037         }
45038         return _mapillary;
45039     }
45040
45041
45042     function showLayer() {
45043         var service = getService();
45044         if (!service) return;
45045
45046         service.loadViewer(context);
45047         editOn();
45048     }
45049
45050
45051     function hideLayer() {
45052         throttledRedraw.cancel();
45053         editOff();
45054     }
45055
45056
45057     function editOn() {
45058         layer.style('display', 'block');
45059     }
45060
45061
45062     function editOff() {
45063         layer.selectAll('.icon-sign').remove();
45064         layer.style('display', 'none');
45065     }
45066
45067
45068     function click(d) {
45069         var service = getService();
45070         if (!service) return;
45071
45072         context.map().centerEase(d.loc);
45073
45074         var selected = service.getSelectedImage();
45075         var selectedImageKey = selected && selected.key;
45076         var imageKey;
45077
45078         // Pick one of the images the sign was detected in,
45079         // preference given to an image already selected.
45080         d.detections.forEach(function(detection) {
45081             if (!imageKey || selectedImageKey === detection.image_key) {
45082                 imageKey = detection.image_key;
45083             }
45084         });
45085
45086         service
45087             .selectImage(null, imageKey)
45088             .updateViewer(imageKey, context)
45089             .showViewer();
45090     }
45091
45092
45093     function update() {
45094         var service = getService();
45095         var data = (service ? service.signs(projection) : []);
45096         var viewer = d3_select('#photoviewer');
45097         var selected = viewer.empty() ? undefined : viewer.datum();
45098         var selectedImageKey = selected && selected.key;
45099
45100         var signs = layer.selectAll('.icon-sign')
45101             .data(data, function(d) { return d.key; });
45102
45103         signs.exit()
45104             .remove();
45105
45106         var enter = signs.enter()
45107             .append('foreignObject')
45108             .attr('class', 'icon-sign')
45109             .attr('width', '24px')      // for Firefox
45110             .attr('height', '24px')     // for Firefox
45111             .classed('selected', function(d) {
45112                 return some(d.detections, function(detection) {
45113                     return detection.image_key === selectedImageKey;
45114                 });
45115             })
45116             .on('click', click);
45117
45118         enter
45119             .append('xhtml:body')
45120             .attr('class', 'icon-sign-body')
45121             .html(service.signHTML);
45122
45123         signs
45124             .merge(enter)
45125             .attr('x', function(d) { return projection(d.loc)[0] - 12; })   // offset by -12px to
45126             .attr('y', function(d) { return projection(d.loc)[1] - 12; });  // center signs on loc
45127     }
45128
45129
45130     function drawSigns(selection) {
45131         var enabled = svgMapillarySigns.enabled,
45132             service = getService();
45133
45134         layer = selection.selectAll('.layer-mapillary-signs')
45135             .data(service ? [0] : []);
45136
45137         layer.exit()
45138             .remove();
45139
45140         layer = layer.enter()
45141             .append('g')
45142             .attr('class', 'layer-mapillary-signs')
45143             .style('display', enabled ? 'block' : 'none')
45144             .merge(layer);
45145
45146         if (enabled) {
45147             if (service && ~~context.map().zoom() >= minZoom) {
45148                 editOn();
45149                 update();
45150                 service.loadSigns(context, projection);
45151             } else {
45152                 editOff();
45153             }
45154         }
45155     }
45156
45157
45158     drawSigns.enabled = function(_) {
45159         if (!arguments.length) return svgMapillarySigns.enabled;
45160         svgMapillarySigns.enabled = _;
45161         if (svgMapillarySigns.enabled) {
45162             showLayer();
45163         } else {
45164             hideLayer();
45165         }
45166         dispatch.call('change');
45167         return this;
45168     };
45169
45170
45171     drawSigns.supported = function() {
45172         var service = getService();
45173         return (service && service.signsSupported());
45174     };
45175
45176
45177     init();
45178     return drawSigns;
45179 }
45180
45181 function svgOpenstreetcamImages(projection, context, dispatch) {
45182     var throttledRedraw = throttle(function () { dispatch.call('change'); }, 1000);
45183     var minZoom = 12;
45184     var minMarkerZoom = 16;
45185     var minViewfieldZoom = 18;
45186     var layer = d3_select(null);
45187     var _openstreetcam;
45188
45189
45190     function init() {
45191         if (svgOpenstreetcamImages.initialized) return;  // run once
45192         svgOpenstreetcamImages.enabled = false;
45193         svgOpenstreetcamImages.initialized = true;
45194     }
45195
45196
45197     function getService() {
45198         if (services.openstreetcam && !_openstreetcam) {
45199             _openstreetcam = services.openstreetcam;
45200             _openstreetcam.event.on('loadedImages', throttledRedraw);
45201         } else if (!services.openstreetcam && _openstreetcam) {
45202             _openstreetcam = null;
45203         }
45204
45205         return _openstreetcam;
45206     }
45207
45208
45209     function showLayer() {
45210         var service = getService();
45211         if (!service) return;
45212
45213         service.loadViewer(context);
45214         editOn();
45215
45216         layer
45217             .style('opacity', 0)
45218             .transition()
45219             .duration(250)
45220             .style('opacity', 1)
45221             .on('end', function () { dispatch.call('change'); });
45222     }
45223
45224
45225     function hideLayer() {
45226         var service = getService();
45227         if (service) {
45228             service.hideViewer();
45229         }
45230
45231         throttledRedraw.cancel();
45232
45233         layer
45234             .transition()
45235             .duration(250)
45236             .style('opacity', 0)
45237             .on('end', editOff);
45238     }
45239
45240
45241     function editOn() {
45242         layer.style('display', 'block');
45243     }
45244
45245
45246     function editOff() {
45247         layer.selectAll('.viewfield-group').remove();
45248         layer.style('display', 'none');
45249     }
45250
45251
45252     function click(d) {
45253         var service = getService();
45254         if (!service) return;
45255
45256         service
45257             .selectImage(d)
45258             .updateViewer(d)
45259             .showViewer();
45260
45261         context.map().centerEase(d.loc);
45262     }
45263
45264
45265     function mouseover(d) {
45266         var service = getService();
45267         if (service) service.setStyles(d);
45268     }
45269
45270
45271     function mouseout() {
45272         var service = getService();
45273         if (service) service.setStyles(null);
45274     }
45275
45276
45277     function transform(d) {
45278         var t = svgPointTransform(projection)(d);
45279         if (d.ca) {
45280             t += ' rotate(' + Math.floor(d.ca) + ',0,0)';
45281         }
45282         return t;
45283     }
45284
45285
45286     function update() {
45287         var viewer = d3_select('#photoviewer');
45288         var selected = viewer.empty() ? undefined : viewer.datum();
45289
45290         var z = ~~context.map().zoom();
45291         var showMarkers = (z >= minMarkerZoom);
45292         var showViewfields = (z >= minViewfieldZoom);
45293
45294         var service = getService();
45295         var sequences = (service ? service.sequences(projection) : []);
45296         var images = (service && showMarkers ? service.images(projection) : []);
45297
45298         var traces = layer.selectAll('.sequences').selectAll('.sequence')
45299             .data(sequences, function(d) { return d.properties.key; });
45300
45301         // exit
45302         traces.exit()
45303             .remove();
45304
45305         // enter/update
45306         traces = traces.enter()
45307             .append('path')
45308             .attr('class', 'sequence')
45309             .merge(traces)
45310             .attr('d', svgPath(projection).geojson);
45311
45312
45313         var groups = layer.selectAll('.markers').selectAll('.viewfield-group')
45314             .data(images, function(d) { return d.key; });
45315
45316         // exit
45317         groups.exit()
45318             .remove();
45319
45320         // enter
45321         var groupsEnter = groups.enter()
45322             .append('g')
45323             .attr('class', 'viewfield-group')
45324             .on('mouseover', mouseover)
45325             .on('mouseout', mouseout)
45326             .on('click', click);
45327
45328         groupsEnter
45329             .append('g')
45330             .attr('class', 'viewfield-scale');
45331
45332         // update
45333         var markers = groups
45334             .merge(groupsEnter)
45335             .sort(function(a, b) {
45336                 return (a === selected) ? 1
45337                     : (b === selected) ? -1
45338                     : b.loc[1] - a.loc[1];  // sort Y
45339             })
45340             .attr('transform', transform)
45341             .select('.viewfield-scale');
45342
45343
45344         markers.selectAll('circle')
45345             .data([0])
45346             .enter()
45347             .append('circle')
45348             .attr('dx', '0')
45349             .attr('dy', '0')
45350             .attr('r', '6');
45351
45352         var viewfields = markers.selectAll('.viewfield')
45353             .data(showViewfields ? [0] : []);
45354
45355         viewfields.exit()
45356             .remove();
45357
45358         viewfields.enter()               // viewfields may or may not be drawn...
45359             .insert('path', 'circle')    // but if they are, draw below the circles
45360             .attr('class', 'viewfield')
45361             .attr('transform', 'scale(1.5,1.5),translate(-8, -13)')
45362             .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');
45363     }
45364
45365
45366     function drawImages(selection) {
45367         var enabled = svgOpenstreetcamImages.enabled,
45368             service = getService();
45369
45370         layer = selection.selectAll('.layer-openstreetcam-images')
45371             .data(service ? [0] : []);
45372
45373         layer.exit()
45374             .remove();
45375
45376         var layerEnter = layer.enter()
45377             .append('g')
45378             .attr('class', 'layer-openstreetcam-images')
45379             .style('display', enabled ? 'block' : 'none');
45380
45381         layerEnter
45382             .append('g')
45383             .attr('class', 'sequences');
45384
45385         layerEnter
45386             .append('g')
45387             .attr('class', 'markers');
45388
45389         layer = layerEnter
45390             .merge(layer);
45391
45392         if (enabled) {
45393             if (service && ~~context.map().zoom() >= minZoom) {
45394                 editOn();
45395                 update();
45396                 service.loadImages(projection);
45397             } else {
45398                 editOff();
45399             }
45400         }
45401     }
45402
45403
45404     drawImages.enabled = function(_) {
45405         if (!arguments.length) return svgOpenstreetcamImages.enabled;
45406         svgOpenstreetcamImages.enabled = _;
45407         if (svgOpenstreetcamImages.enabled) {
45408             showLayer();
45409         } else {
45410             hideLayer();
45411         }
45412         dispatch.call('change');
45413         return this;
45414     };
45415
45416
45417     drawImages.supported = function() {
45418         return !!getService();
45419     };
45420
45421
45422     init();
45423     return drawImages;
45424 }
45425
45426 function svgOsm(projection, context, dispatch) {
45427     var enabled = true;
45428
45429
45430     function drawOsm(selection) {
45431         selection.selectAll('.layer-osm')
45432             .data(['areas', 'lines', 'points', 'labels'])
45433             .enter()
45434             .append('g')
45435             .attr('class', function(d) { return 'layer-osm layer-' + d; });
45436
45437         selection.selectAll('.layer-areas').selectAll('.layer-areas-group')
45438             .data(['areas', 'targets'])
45439             .enter()
45440             .append('g')
45441             .attr('class', function(d) { return 'layer-areas-group layer-areas-' + d; });
45442
45443         selection.selectAll('.layer-lines').selectAll('.layer-lines-group')
45444             .data(['lines', 'targets'])
45445             .enter()
45446             .append('g')
45447             .attr('class', function(d) { return 'layer-lines-group layer-lines-' + d; });
45448
45449         selection.selectAll('.layer-points').selectAll('.layer-points-group')
45450             .data(['points', 'midpoints', 'vertices', 'turns', 'targets'])
45451             .enter()
45452             .append('g')
45453             .attr('class', function(d) { return 'layer-points-group layer-points-' + d; });
45454
45455         selection.selectAll('.layer-labels').selectAll('.layer-labels-group')
45456             .data(['halo', 'label', 'debug'])
45457             .enter()
45458             .append('g')
45459             .attr('class', function(d) { return 'layer-labels-group layer-labels-' + d; });
45460     }
45461
45462
45463     function showLayer() {
45464         var layer = context.surface().selectAll('.data-layer-osm');
45465         layer.interrupt();
45466
45467         layer
45468             .classed('disabled', false)
45469             .style('opacity', 0)
45470             .transition()
45471             .duration(250)
45472             .style('opacity', 1)
45473             .on('end interrupt', function () {
45474                 dispatch.call('change');
45475             });
45476     }
45477
45478
45479     function hideLayer() {
45480         var layer = context.surface().selectAll('.data-layer-osm');
45481         layer.interrupt();
45482
45483         layer
45484             .transition()
45485             .duration(250)
45486             .style('opacity', 0)
45487             .on('end interrupt', function () {
45488                 layer.classed('disabled', true);
45489                 dispatch.call('change');
45490             });
45491     }
45492
45493
45494     drawOsm.enabled = function(_) {
45495         if (!arguments.length) return enabled;
45496         enabled = _;
45497
45498         if (enabled) {
45499             showLayer();
45500         } else {
45501             hideLayer();
45502         }
45503
45504         dispatch.call('change');
45505         return this;
45506     };
45507
45508
45509     return drawOsm;
45510 }
45511
45512 function svgLayers(projection, context) {
45513     var dispatch$$1 = dispatch('change'),
45514         svg = d3_select(null),
45515         layers = [
45516             { id: 'osm', layer: svgOsm(projection, context, dispatch$$1) },
45517             { id: 'gpx', layer: svgGpx(projection, context, dispatch$$1) },
45518             { id: 'mapillary-images', layer: svgMapillaryImages(projection, context, dispatch$$1) },
45519             { id: 'mapillary-signs',  layer: svgMapillarySigns(projection, context, dispatch$$1) },
45520             { id: 'openstreetcam-images', layer: svgOpenstreetcamImages(projection, context, dispatch$$1) },
45521             { id: 'debug', layer: svgDebug(projection, context, dispatch$$1) }
45522         ];
45523
45524
45525     function drawLayers(selection) {
45526         svg = selection.selectAll('.surface')
45527             .data([0]);
45528
45529         svg = svg.enter()
45530             .append('svg')
45531             .attr('class', 'surface')
45532             .merge(svg);
45533
45534         var defs = svg.selectAll('.surface-defs')
45535             .data([0]);
45536
45537         defs.enter()
45538             .append('defs')
45539             .attr('class', 'surface-defs');
45540
45541         var groups = svg.selectAll('.data-layer')
45542             .data(layers);
45543
45544         groups.exit()
45545             .remove();
45546
45547         groups.enter()
45548             .append('g')
45549             .attr('class', function(d) { return 'data-layer data-layer-' + d.id; })
45550             .merge(groups)
45551             .each(function(d) { d3_select(this).call(d.layer); });
45552     }
45553
45554
45555     drawLayers.all = function() {
45556         return layers;
45557     };
45558
45559
45560     drawLayers.layer = function(id) {
45561         var obj = find$1(layers, function(o) {return o.id === id;});
45562         return obj && obj.layer;
45563     };
45564
45565
45566     drawLayers.only = function(what) {
45567         var arr = [].concat(what);
45568         drawLayers.remove(difference(map$4(layers, 'id'), arr));
45569         return this;
45570     };
45571
45572
45573     drawLayers.remove = function(what) {
45574         var arr = [].concat(what);
45575         arr.forEach(function(id) {
45576             layers = reject(layers, function(o) {return o.id === id;});
45577         });
45578         dispatch$$1.call('change');
45579         return this;
45580     };
45581
45582
45583     drawLayers.add = function(what) {
45584         var arr = [].concat(what);
45585         arr.forEach(function(obj) {
45586             if ('id' in obj && 'layer' in obj) {
45587                 layers.push(obj);
45588             }
45589         });
45590         dispatch$$1.call('change');
45591         return this;
45592     };
45593
45594
45595     drawLayers.dimensions = function(_) {
45596         if (!arguments.length) return utilGetDimensions(svg);
45597         utilSetDimensions(svg, _);
45598         return this;
45599     };
45600
45601
45602     return utilRebind(drawLayers, dispatch$$1, 'on');
45603 }
45604
45605 function svgLines(projection, context) {
45606     var detected = utilDetect();
45607
45608     var highway_stack = {
45609         motorway: 0,
45610         motorway_link: 1,
45611         trunk: 2,
45612         trunk_link: 3,
45613         primary: 4,
45614         primary_link: 5,
45615         secondary: 6,
45616         tertiary: 7,
45617         unclassified: 8,
45618         residential: 9,
45619         service: 10,
45620         footway: 11
45621     };
45622
45623
45624     function drawTargets(selection, graph, entities, filter$$1) {
45625         var targetClass = context.getDebug('target') ? 'pink ' : 'nocolor ';
45626         var nopeClass = context.getDebug('target') ? 'red ' : 'nocolor ';
45627         var getPath = svgPath(projection).geojson;
45628         var activeID = context.activeID();
45629
45630         // The targets and nopes will be MultiLineString sub-segments of the ways
45631         var data = { targets: [], nopes: [] };
45632
45633         entities.forEach(function(way) {
45634             var features = svgSegmentWay(way, graph, activeID);
45635             data.targets.push.apply(data.targets, features.passive);
45636             data.nopes.push.apply(data.nopes, features.active);
45637         });
45638
45639
45640         // Targets allow hover and vertex snapping
45641         var targets = selection.selectAll('.line.target-allowed')
45642             .filter(function(d) { return filter$$1(d.properties.entity); })
45643             .data(data.targets, function key(d) { return d.id; });
45644
45645         // exit
45646         targets.exit()
45647             .remove();
45648
45649         // enter/update
45650         targets.enter()
45651             .append('path')
45652             .merge(targets)
45653             .attr('d', getPath)
45654             .attr('class', function(d) { return 'way line target target-allowed ' + targetClass + d.id; });
45655
45656
45657         // NOPE
45658         var nopes = selection.selectAll('.line.target-nope')
45659             .filter(function(d) { return filter$$1(d.properties.entity); })
45660             .data(data.nopes, function key(d) { return d.id; });
45661
45662         // exit
45663         nopes.exit()
45664             .remove();
45665
45666         // enter/update
45667         nopes.enter()
45668             .append('path')
45669             .merge(nopes)
45670             .attr('d', getPath)
45671             .attr('class', function(d) { return 'way line target target-nope ' + nopeClass + d.id; });
45672     }
45673
45674
45675     function drawLines(selection, graph, entities, filter$$1) {
45676
45677         function waystack(a, b) {
45678             var selected = context.selectedIDs();
45679             var scoreA = selected.indexOf(a.id) !== -1 ? 20 : 0;
45680             var scoreB = selected.indexOf(b.id) !== -1 ? 20 : 0;
45681
45682             if (a.tags.highway) { scoreA -= highway_stack[a.tags.highway]; }
45683             if (b.tags.highway) { scoreB -= highway_stack[b.tags.highway]; }
45684             return scoreA - scoreB;
45685         }
45686
45687
45688         function drawLineGroup(selection, klass, isSelected) {
45689             // Note: Don't add `.selected` class in draw modes
45690             var mode = context.mode();
45691             var isDrawing = mode && /^draw/.test(mode.id);
45692             var selectedClass = (!isDrawing && isSelected) ? 'selected ' : '';
45693
45694             var lines = selection
45695                 .selectAll('path')
45696                 .filter(filter$$1)
45697                 .data(getPathData(isSelected), osmEntity.key);
45698
45699             lines.exit()
45700                 .remove();
45701
45702             // Optimization: Call expensive TagClasses only on enter selection. This
45703             // works because osmEntity.key is defined to include the entity v attribute.
45704             lines.enter()
45705                 .append('path')
45706                 .attr('class', function(d) {
45707                     var oldMPClass = oldMultiPolygonOuters[d.id] ? 'old-multipolygon ' : '';
45708                     return 'way line ' + klass + ' ' + selectedClass + oldMPClass + d.id;
45709                 })
45710                 .call(svgTagClasses())
45711                 .merge(lines)
45712                 .sort(waystack)
45713                 .attr('d', getPath)
45714                 .call(svgTagClasses().tags(svgRelationMemberTags(graph)));
45715
45716             return selection;
45717         }
45718
45719
45720         function getPathData(isSelected) {
45721             return function() {
45722                 var layer = this.parentNode.__data__;
45723                 var data = pathdata[layer] || [];
45724                 return data.filter(function(d) {
45725                     if (isSelected)
45726                         return context.selectedIDs().indexOf(d.id) !== -1;
45727                     else
45728                         return context.selectedIDs().indexOf(d.id) === -1;
45729                 });
45730             };
45731         }
45732
45733
45734         var getPath = svgPath(projection, graph);
45735         var ways = [];
45736         var pathdata = {};
45737         var onewaydata = {};
45738         var oldMultiPolygonOuters = {};
45739
45740         for (var i = 0; i < entities.length; i++) {
45741             var entity = entities[i];
45742             var outer = osmSimpleMultipolygonOuterMember(entity, graph);
45743             if (outer) {
45744                 ways.push(entity.mergeTags(outer.tags));
45745                 oldMultiPolygonOuters[outer.id] = true;
45746             } else if (entity.geometry(graph) === 'line') {
45747                 ways.push(entity);
45748             }
45749         }
45750
45751         ways = ways.filter(getPath);
45752         pathdata = groupBy(ways, function(way) { return way.layer(); });
45753
45754         forOwn(pathdata, function(v, k) {
45755             var arr = filter(v, function(d) { return d.isOneWay(); });
45756             onewaydata[k] = flatten(map$4(arr, svgOneWaySegments(projection, graph, 35)));
45757         });
45758
45759
45760         var layer = selection.selectAll('.layer-lines .layer-lines-lines');
45761
45762         var layergroup = layer
45763             .selectAll('g.layergroup')
45764             .data(d3_range(-10, 11));
45765
45766         layergroup = layergroup.enter()
45767             .append('g')
45768             .attr('class', function(d) { return 'layergroup layer' + String(d); })
45769             .merge(layergroup);
45770
45771         layergroup
45772             .selectAll('g.linegroup')
45773             .data(['shadow', 'casing', 'stroke', 'shadow-highlighted', 'casing-highlighted', 'stroke-highlighted'])
45774             .enter()
45775             .append('g')
45776             .attr('class', function(d) { return 'linegroup line-' + d; });
45777
45778
45779         layergroup.selectAll('g.line-shadow')
45780             .call(drawLineGroup, 'shadow', false);
45781         layergroup.selectAll('g.line-casing')
45782             .call(drawLineGroup, 'casing', false);
45783         layergroup.selectAll('g.line-stroke')
45784             .call(drawLineGroup, 'stroke', false);
45785
45786         layergroup.selectAll('g.line-shadow-highlighted')
45787             .call(drawLineGroup, 'shadow', true);
45788         layergroup.selectAll('g.line-casing-highlighted')
45789             .call(drawLineGroup, 'casing', true);
45790         layergroup.selectAll('g.line-stroke-highlighted')
45791             .call(drawLineGroup, 'stroke', true);
45792
45793
45794         var onewaygroup = layergroup
45795             .selectAll('g.onewaygroup')
45796             .data(['oneway']);
45797
45798         onewaygroup = onewaygroup.enter()
45799             .append('g')
45800             .attr('class', 'onewaygroup')
45801             .merge(onewaygroup);
45802
45803         var oneways = onewaygroup
45804             .selectAll('path')
45805             .filter(filter$$1)
45806             .data(
45807                 function data() { return onewaydata[this.parentNode.__data__] || []; },
45808                 function key(d) { return [d.id, d.index]; }
45809             );
45810
45811         oneways.exit()
45812             .remove();
45813
45814         oneways = oneways.enter()
45815             .append('path')
45816             .attr('class', 'oneway')
45817             .attr('marker-mid', 'url(#oneway-marker)')
45818             .merge(oneways)
45819             .attr('d', function(d) { return d.d; });
45820
45821         if (detected.ie) {
45822             oneways.each(function() { this.parentNode.insertBefore(this, this); });
45823         }
45824
45825
45826         // touch targets
45827         selection.selectAll('.layer-lines .layer-lines-targets')
45828             .call(drawTargets, graph, ways, filter$$1);
45829     }
45830
45831
45832     return drawLines;
45833 }
45834
45835 function svgMidpoints(projection, context) {
45836     var targetRadius = 8;
45837
45838     function drawTargets(selection, graph, entities, filter) {
45839         var fillClass = context.getDebug('target') ? 'pink ' : 'nocolor ';
45840         var getTransform = svgPointTransform(projection).geojson;
45841
45842         var data = entities.map(function(midpoint) {
45843             return {
45844                 type: 'Feature',
45845                 id: midpoint.id,
45846                 properties: {
45847                     target: true,
45848                     entity: midpoint
45849                 },
45850                 geometry: {
45851                     type: 'Point',
45852                     coordinates: midpoint.loc
45853                 }
45854             };
45855         });
45856
45857         var targets = selection.selectAll('.midpoint.target')
45858             .filter(function(d) { return filter(d.properties.entity); })
45859             .data(data, function key(d) { return d.id; });
45860
45861         // exit
45862         targets.exit()
45863             .remove();
45864
45865         // enter/update
45866         targets.enter()
45867             .append('circle')
45868             .attr('r', targetRadius)
45869             .merge(targets)
45870             .attr('class', function(d) { return 'node midpoint target ' + fillClass + d.id; })
45871             .attr('transform', getTransform);
45872     }
45873
45874
45875     function drawMidpoints(selection, graph, entities, filter, extent) {
45876         var layer = selection.selectAll('.layer-points .layer-points-midpoints');
45877
45878         var mode = context.mode();
45879         if (mode && mode.id !== 'select') {
45880             layer.selectAll('g.midpoint')
45881                 .remove();
45882
45883             selection.selectAll('.layer-points .layer-points-targets .midpoint.target')
45884                 .remove();
45885
45886             return;
45887         }
45888
45889         var poly = extent.polygon();
45890         var midpoints = {};
45891
45892         for (var i = 0; i < entities.length; i++) {
45893             var entity = entities[i];
45894
45895             if (entity.type !== 'way')
45896                 continue;
45897             if (!filter(entity))
45898                 continue;
45899             if (context.selectedIDs().indexOf(entity.id) < 0)
45900                 continue;
45901
45902             var nodes = graph.childNodes(entity);
45903             for (var j = 0; j < nodes.length - 1; j++) {
45904
45905                 var a = nodes[j];
45906                 var b = nodes[j + 1];
45907                 var id = [a.id, b.id].sort().join('-');
45908
45909                 if (midpoints[id]) {
45910                     midpoints[id].parents.push(entity);
45911                 } else {
45912                     if (geoVecLength(projection(a.loc), projection(b.loc)) > 40) {
45913                         var point = geoVecInterp(a.loc, b.loc, 0.5);
45914                         var loc = null;
45915
45916                         if (extent.intersects(point)) {
45917                             loc = point;
45918                         } else {
45919                             for (var k = 0; k < 4; k++) {
45920                                 point = geoLineIntersection([a.loc, b.loc], [poly[k], poly[k + 1]]);
45921                                 if (point &&
45922                                     geoVecLength(projection(a.loc), projection(point)) > 20 &&
45923                                     geoVecLength(projection(b.loc), projection(point)) > 20)
45924                                 {
45925                                     loc = point;
45926                                     break;
45927                                 }
45928                             }
45929                         }
45930
45931                         if (loc) {
45932                             midpoints[id] = {
45933                                 type: 'midpoint',
45934                                 id: id,
45935                                 loc: loc,
45936                                 edge: [a.id, b.id],
45937                                 parents: [entity]
45938                             };
45939                         }
45940                     }
45941                 }
45942             }
45943         }
45944
45945
45946         function midpointFilter(d) {
45947             if (midpoints[d.id])
45948                 return true;
45949
45950             for (var i = 0; i < d.parents.length; i++) {
45951                 if (filter(d.parents[i])) {
45952                     return true;
45953                 }
45954             }
45955
45956             return false;
45957         }
45958
45959
45960         var groups = layer
45961             .selectAll('g.midpoint')
45962             .filter(midpointFilter)
45963             .data(values$1(midpoints), function(d) { return d.id; });
45964
45965         groups.exit()
45966             .remove();
45967
45968         var enter = groups.enter()
45969             .insert('g', ':first-child')
45970             .attr('class', 'midpoint');
45971
45972         enter
45973             .append('polygon')
45974             .attr('points', '-6,8 10,0 -6,-8')
45975             .attr('class', 'shadow');
45976
45977         enter
45978             .append('polygon')
45979             .attr('points', '-3,4 5,0 -3,-4')
45980             .attr('class', 'fill');
45981
45982         groups = groups
45983             .merge(enter)
45984             .attr('transform', function(d) {
45985                 var translate = svgPointTransform(projection);
45986                 var a = graph.entity(d.edge[0]);
45987                 var b = graph.entity(d.edge[1]);
45988                 var angle = geoAngle(a, b, projection) * (180 / Math.PI);
45989                 return translate(d) + ' rotate(' + angle + ')';
45990             })
45991             .call(svgTagClasses().tags(
45992                 function(d) { return d.parents[0].tags; }
45993             ));
45994
45995         // Propagate data bindings.
45996         groups.select('polygon.shadow');
45997         groups.select('polygon.fill');
45998
45999
46000         // Draw touch targets..
46001         selection.selectAll('.layer-points .layer-points-targets')
46002             .call(drawTargets, graph, values$1(midpoints), midpointFilter);
46003     }
46004
46005     return drawMidpoints;
46006 }
46007
46008 // Touch targets control which other vertices we can drag a vertex onto.
46009 //
46010 // - the activeID - nope
46011 // - 1 away (adjacent) to the activeID - yes (vertices will be merged)
46012 // - 2 away from the activeID - nope (would create a self intersecting segment)
46013 // - all others on a linear way - yes
46014 // - all others on a closed way - nope (would create a self intersecting polygon)
46015 //
46016 // returns
46017 // 0 = active vertex - no touch/connect
46018 // 1 = passive vertex - yes touch/connect
46019 // 2 = adjacent vertex - yes but pay attention segmenting a line here
46020 //
46021 function svgPassiveVertex(node, graph, activeID) {
46022     if (!activeID) return 1;
46023     if (activeID === node.id) return 0;
46024
46025     var parents = graph.parentWays(node);
46026
46027     for (var i = 0; i < parents.length; i++) {
46028         var nodes = parents[i].nodes;
46029         var isClosed = parents[i].isClosed();
46030         for (var j = 0; j < nodes.length; j++) {   // find this vertex, look nearby
46031             if (nodes[j] === node.id) {
46032                 var ix1 = j - 2;
46033                 var ix2 = j - 1;
46034                 var ix3 = j + 1;
46035                 var ix4 = j + 2;
46036
46037                 if (isClosed) {  // wraparound if needed
46038                     var max = nodes.length - 1;
46039                     if (ix1 < 0)   ix1 = max + ix1;
46040                     if (ix2 < 0)   ix2 = max + ix2;
46041                     if (ix3 > max) ix3 = ix3 - max;
46042                     if (ix4 > max) ix4 = ix4 - max;
46043                 }
46044
46045                 if (nodes[ix1] === activeID) return 0;        // no - prevent self intersect
46046                 else if (nodes[ix2] === activeID) return 2;   // ok - adjacent
46047                 else if (nodes[ix3] === activeID) return 2;   // ok - adjacent
46048                 else if (nodes[ix4] === activeID) return 0;   // no - prevent self intersect
46049                 else if (isClosed && nodes.indexOf(activeID) !== -1) return 0;  // no - prevent self intersect
46050             }
46051         }
46052     }
46053
46054     return 1;   // ok
46055 }
46056
46057
46058 function svgOneWaySegments(projection, graph, dt) {
46059     return function(entity) {
46060         var i = 0;
46061         var offset = dt;
46062         var segments = [];
46063         var clip = d3_geoIdentity().clipExtent(projection.clipExtent()).stream;
46064         var coordinates = graph.childNodes(entity).map(function(n) { return n.loc; });
46065         var a, b;
46066
46067         if (entity.tags.oneway === '-1') {
46068             coordinates.reverse();
46069         }
46070
46071         var isReversible = (entity.tags.oneway === 'reversible' || entity.tags.oneway === 'alternating');
46072
46073         d3_geoStream({
46074             type: 'LineString',
46075             coordinates: coordinates
46076         }, projection.stream(clip({
46077             lineStart: function() {},
46078             lineEnd: function() { a = null; },
46079             point: function(x, y) {
46080                 b = [x, y];
46081
46082                 if (a) {
46083                     var span = geoVecLength(a, b) - offset;
46084
46085                     if (span >= 0) {
46086                         var heading = geoVecAngle(a, b);
46087                         var dx = dt * Math.cos(heading);
46088                         var dy = dt * Math.sin(heading);
46089                         var p = [
46090                             a[0] + offset * Math.cos(heading),
46091                             a[1] + offset * Math.sin(heading)
46092                         ];
46093
46094                         // gather coordinates
46095                         var coord = [a, p];
46096                         for (span -= dt; span >= 0; span -= dt) {
46097                             p = geoVecAdd(p, [dx, dy]);
46098                             coord.push(p);
46099                         }
46100                         coord.push(b);
46101
46102                         // generate svg paths
46103                         var segment = '';
46104                         var j;
46105
46106                         for (j = 0; j < coord.length; j++) {
46107                             segment += (j === 0 ? 'M' : 'L') + coord[j][0] + ',' + coord[j][1];
46108                         }
46109                         segments.push({ id: entity.id, index: i++, d: segment });
46110
46111                         if (isReversible) {
46112                             segment = '';
46113                             for (j = coord.length - 1; j >= 0; j--) {
46114                                 segment += (j === coord.length - 1 ? 'M' : 'L') + coord[j][0] + ',' + coord[j][1];
46115                             }
46116                             segments.push({ id: entity.id, index: i++, d: segment });
46117                         }
46118                     }
46119
46120                     offset = -span;
46121                 }
46122
46123                 a = b;
46124             }
46125         })));
46126
46127         return segments;
46128     };
46129 }
46130
46131
46132 function svgPath(projection, graph, isArea) {
46133
46134     // Explanation of magic numbers:
46135     // "padding" here allows space for strokes to extend beyond the viewport,
46136     // so that the stroke isn't drawn along the edge of the viewport when
46137     // the shape is clipped.
46138     //
46139     // When drawing lines, pad viewport by 5px.
46140     // When drawing areas, pad viewport by 65px in each direction to allow
46141     // for 60px area fill stroke (see ".fill-partial path.fill" css rule)
46142
46143     var cache = {};
46144     var padding = isArea ? 65 : 5;
46145     var viewport = projection.clipExtent();
46146     var paddedExtent = [
46147         [viewport[0][0] - padding, viewport[0][1] - padding],
46148         [viewport[1][0] + padding, viewport[1][1] + padding]
46149     ];
46150     var clip = d3_geoIdentity().clipExtent(paddedExtent).stream;
46151     var project = projection.stream;
46152     var path = d3_geoPath()
46153         .projection({stream: function(output) { return project(clip(output)); }});
46154
46155     var svgpath = function(entity) {
46156         if (entity.id in cache) {
46157             return cache[entity.id];
46158         } else {
46159             return cache[entity.id] = path(entity.asGeoJSON(graph));
46160         }
46161     };
46162
46163     svgpath.geojson = path;
46164
46165     return svgpath;
46166 }
46167
46168
46169 function svgPointTransform(projection) {
46170     var svgpoint = function(entity) {
46171         // http://jsperf.com/short-array-join
46172         var pt = projection(entity.loc);
46173         return 'translate(' + pt[0] + ',' + pt[1] + ')';
46174     };
46175
46176     svgpoint.geojson = function(d) {
46177         return svgpoint(d.properties.entity);
46178     };
46179
46180     return svgpoint;
46181 }
46182
46183
46184 function svgRelationMemberTags(graph) {
46185     return function(entity) {
46186         var tags = entity.tags;
46187         graph.parentRelations(entity).forEach(function(relation) {
46188             var type = relation.tags.type;
46189             if (type === 'multipolygon' || type === 'boundary') {
46190                 tags = assignIn({}, relation.tags, tags);
46191             }
46192         });
46193         return tags;
46194     };
46195 }
46196
46197
46198 function svgSegmentWay(way, graph, activeID) {
46199     var isActiveWay = (way.nodes.indexOf(activeID) !== -1);
46200     var features = { passive: [], active: [] };
46201     var start = {};
46202     var end = {};
46203     var node, type;
46204
46205     for (var i = 0; i < way.nodes.length; i++) {
46206         node = graph.entity(way.nodes[i]);
46207         type = svgPassiveVertex(node, graph, activeID);
46208         end = { node: node, type: type };
46209
46210         if (start.type !== undefined) {
46211             if (start.node.id === activeID || end.node.id === activeID) {
46212                 // push nothing
46213             } else if (isActiveWay && (start.type === 2 || end.type === 2)) {   // one adjacent vertex
46214                 pushActive(start, end, i);
46215             } else if (start.type === 0 && end.type === 0) {   // both active vertices
46216                 pushActive(start, end, i);
46217             } else {
46218                 pushPassive(start, end, i);
46219             }
46220         }
46221
46222         start = end;
46223     }
46224
46225     return features;
46226
46227
46228     function pushActive(start, end, index) {
46229         features.active.push({
46230             type: 'Feature',
46231             id: way.id + '-' + index + '-nope',
46232             properties: {
46233                 nope: true,
46234                 target: true,
46235                 entity: way,
46236                 nodes: [start.node, end.node],
46237                 index: index
46238             },
46239             geometry: {
46240                 type: 'LineString',
46241                 coordinates: [start.node.loc, end.node.loc]
46242             }
46243         });
46244     }
46245
46246     function pushPassive(start, end, index) {
46247         features.passive.push({
46248             type: 'Feature',
46249             id: way.id + '-' + index,
46250             properties: {
46251                 target: true,
46252                 entity: way,
46253                 nodes: [start.node, end.node],
46254                 index: index
46255             },
46256             geometry: {
46257                 type: 'LineString',
46258                 coordinates: [start.node.loc, end.node.loc]
46259             }
46260         });
46261     }
46262 }
46263
46264 function svgPoints(projection, context) {
46265
46266     function markerPath(selection, klass) {
46267         selection
46268             .attr('class', klass)
46269             .attr('transform', 'translate(-8, -23)')
46270             .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');
46271     }
46272
46273     function sortY(a, b) {
46274         return b.loc[1] - a.loc[1];
46275     }
46276
46277
46278     // Avoid exit/enter if we're just moving stuff around.
46279     // The node will get a new version but we only need to run the update selection.
46280     function fastEntityKey(d) {
46281         var mode = context.mode();
46282         var isMoving = mode && /^(add|draw|drag|move|rotate)/.test(mode.id);
46283         return isMoving ? d.id : osmEntity.key(d);
46284     }
46285
46286
46287     function drawTargets(selection, graph, entities, filter) {
46288         var fillClass = context.getDebug('target') ? 'pink ' : 'nocolor ';
46289         var getTransform = svgPointTransform(projection).geojson;
46290         var activeID = context.activeID();
46291         var data$$1 = [];
46292
46293         entities.forEach(function(node) {
46294             if (activeID === node.id) return;   // draw no target on the activeID
46295
46296             data$$1.push({
46297                 type: 'Feature',
46298                 id: node.id,
46299                 properties: {
46300                     target: true,
46301                     entity: node
46302                 },
46303                 geometry: node.asGeoJSON()
46304             });
46305         });
46306
46307         var targets = selection.selectAll('.point.target')
46308             .filter(function(d) { return filter(d.properties.entity); })
46309             .data(data$$1, function key(d) { return d.id; });
46310
46311         // exit
46312         targets.exit()
46313             .remove();
46314
46315         // enter/update
46316         targets.enter()
46317             .append('rect')
46318             .attr('x', -10)
46319             .attr('y', -26)
46320             .attr('width', 20)
46321             .attr('height', 30)
46322             .merge(targets)
46323             .attr('class', function(d) { return 'node point target ' + fillClass + d.id; })
46324             .attr('transform', getTransform);
46325     }
46326
46327
46328     function drawPoints(selection, graph, entities, filter) {
46329         var wireframe = context.surface().classed('fill-wireframe');
46330         var zoom = geoScaleToZoom(projection.scale());
46331
46332         // points with a direction will render as vertices at higher zooms
46333         function renderAsPoint(entity) {
46334             return entity.geometry(graph) === 'point' &&
46335                 !(zoom >= 18 && entity.directions(graph, projection).length);
46336         }
46337
46338         // all points will render as vertices in wireframe mode too
46339         var points = wireframe ? [] : entities.filter(renderAsPoint);
46340
46341         points.sort(sortY);
46342
46343
46344         var layer = selection.selectAll('.layer-points .layer-points-points');
46345
46346         var groups = layer.selectAll('g.point')
46347             .filter(filter)
46348             .data(points, fastEntityKey);
46349
46350         groups.exit()
46351             .remove();
46352
46353         var enter = groups.enter()
46354             .append('g')
46355             .attr('class', function(d) { return 'node point ' + d.id; })
46356             .order();
46357
46358         enter
46359             .append('path')
46360             .call(markerPath, 'shadow');
46361
46362         enter
46363             .append('ellipse')
46364             .attr('cx', 0.5)
46365             .attr('cy', 1)
46366             .attr('rx', 6.5)
46367             .attr('ry', 3)
46368             .attr('class', 'stroke');
46369
46370         enter
46371             .append('path')
46372             .call(markerPath, 'stroke');
46373
46374         enter
46375             .append('use')
46376             .attr('transform', 'translate(-5, -19)')
46377             .attr('class', 'icon')
46378             .attr('width', '11px')
46379             .attr('height', '11px');
46380
46381         groups = groups
46382             .merge(enter)
46383             .attr('transform', svgPointTransform(projection))
46384             .call(svgTagClasses());
46385
46386         // Selecting the following implicitly
46387         // sets the data (point entity) on the element
46388         groups.select('.shadow');
46389         groups.select('.stroke');
46390         groups.select('.icon')
46391             .attr('xlink:href', function(entity) {
46392                 var preset = context.presets().match(entity, graph);
46393                 var picon = preset && preset.icon;
46394
46395                 if (!picon)
46396                     return '';
46397                 else {
46398                     var isMaki = dataFeatureIcons.indexOf(picon) !== -1;
46399                     return '#' + picon + (isMaki ? '-11' : '');
46400                 }
46401             });
46402
46403
46404         // touch targets
46405         selection.selectAll('.layer-points .layer-points-targets')
46406             .call(drawTargets, graph, points, filter);
46407     }
46408
46409
46410     return drawPoints;
46411 }
46412
46413 function svgTagClasses() {
46414     var primaries = [
46415             'building', 'highway', 'railway', 'waterway', 'aeroway',
46416             'motorway', 'boundary', 'power', 'amenity', 'natural', 'landuse',
46417             'leisure', 'military', 'place'
46418         ],
46419         statuses = [
46420             'proposed', 'construction', 'disused', 'abandoned', 'dismantled',
46421             'razed', 'demolished', 'obliterated', 'intermittent'
46422         ],
46423         secondaries = [
46424             'oneway', 'bridge', 'tunnel', 'embankment', 'cutting', 'barrier',
46425             'surface', 'tracktype', 'crossing', 'service', 'sport'
46426         ],
46427         tagClassRe = /^tag-/,
46428         tags = function(entity) { return entity.tags; };
46429
46430
46431     var tagClasses = function(selection) {
46432         selection.each(function tagClassesEach(entity) {
46433             var value = this.className,
46434                 classes, primary, status;
46435
46436             if (value.baseVal !== undefined) value = value.baseVal;
46437
46438             classes = value.trim().split(/\s+/).filter(function(name) {
46439                 return name.length && !tagClassRe.test(name);
46440             }).join(' ');
46441
46442             var t = tags(entity), i, k, v;
46443
46444             // pick at most one primary classification tag..
46445             for (i = 0; i < primaries.length; i++) {
46446                 k = primaries[i];
46447                 v = t[k];
46448                 if (!v || v === 'no') continue;
46449
46450                 primary = k;
46451                 if (statuses.indexOf(v) !== -1) {   // e.g. `railway=abandoned`
46452                     status = v;
46453                     classes += ' tag-' + k;
46454                 } else {
46455                     classes += ' tag-' + k + ' tag-' + k + '-' + v;
46456                 }
46457
46458                 break;
46459             }
46460
46461             // add at most one status tag, only if relates to primary tag..
46462             if (!status) {
46463                 for (i = 0; i < statuses.length; i++) {
46464                     k = statuses[i];
46465                     v = t[k];
46466                     if (!v || v === 'no') continue;
46467
46468                     if (v === 'yes') {   // e.g. `railway=rail + abandoned=yes`
46469                         status = k;
46470                     }
46471                     else if (primary && primary === v) {  // e.g. `railway=rail + abandoned=railway`
46472                         status = k;
46473                     } else if (!primary && primaries.indexOf(v) !== -1) {  // e.g. `abandoned=railway`
46474                         status = k;
46475                         primary = v;
46476                         classes += ' tag-' + v;
46477                     }  // else ignore e.g.  `highway=path + abandoned=railway`
46478
46479                     if (status) break;
46480                 }
46481             }
46482
46483             if (status) {
46484                 classes += ' tag-status tag-status-' + status;
46485             }
46486
46487             // add any secondary (structure) tags
46488             for (i = 0; i < secondaries.length; i++) {
46489                 k = secondaries[i];
46490                 v = t[k];
46491                 if (!v || v === 'no') continue;
46492                 classes += ' tag-' + k + ' tag-' + k + '-' + v;
46493             }
46494
46495             // For highways, look for surface tagging..
46496             if (primary === 'highway') {
46497                 var paved = (t.highway !== 'track');
46498                 for (k in t) {
46499                     v = t[k];
46500                     if (k in osmPavedTags) {
46501                         paved = !!osmPavedTags[k][v];
46502                         break;
46503                     }
46504                 }
46505                 if (!paved) {
46506                     classes += ' tag-unpaved';
46507                 }
46508             }
46509
46510             classes = classes.trim();
46511
46512             if (classes !== value) {
46513                 d3_select(this).attr('class', classes);
46514             }
46515         });
46516     };
46517
46518
46519     tagClasses.tags = function(_) {
46520         if (!arguments.length) return tags;
46521         tags = _;
46522         return tagClasses;
46523     };
46524
46525     return tagClasses;
46526 }
46527
46528 function svgTurns(projection) {
46529
46530     return function drawTurns(selection, graph, turns) {
46531
46532         function key(turn) {
46533             return [turn.from.node + turn.via.node + turn.to.node].join('-');
46534         }
46535
46536         function icon(turn) {
46537             var u = turn.u ? '-u' : '';
46538             if (!turn.restriction)
46539                 return '#turn-yes' + u;
46540             var restriction = graph.entity(turn.restriction).tags.restriction;
46541             return '#turn-' +
46542                 (!turn.indirect_restriction && /^only_/.test(restriction) ? 'only' : 'no') + u;
46543         }
46544
46545         var layer = selection.selectAll('.layer-points .layer-points-turns');
46546         var groups = layer.selectAll('g.turn')
46547             .data(turns, key);
46548
46549         groups.exit()
46550             .remove();
46551
46552
46553         var enter = groups.enter()
46554             .append('g')
46555             .attr('class', 'turn');
46556
46557         var nEnter = enter
46558             .filter(function (turn) { return !turn.u; });
46559
46560         nEnter.append('rect')
46561             .attr('transform', 'translate(-22, -12)')
46562             .attr('width', '44')
46563             .attr('height', '24');
46564
46565         nEnter.append('use')
46566             .attr('transform', 'translate(-22, -12)')
46567             .attr('width', '44')
46568             .attr('height', '24');
46569
46570
46571         var uEnter = enter
46572             .filter(function (turn) { return turn.u; });
46573
46574         uEnter.append('circle')
46575             .attr('r', '16');
46576
46577         uEnter.append('use')
46578             .attr('transform', 'translate(-16, -16)')
46579             .attr('width', '32')
46580             .attr('height', '32');
46581
46582
46583         groups = groups
46584             .merge(enter);
46585
46586         groups
46587             .attr('transform', function (turn) {
46588                 var v = graph.entity(turn.via.node),
46589                     t = graph.entity(turn.to.node),
46590                     a = geoAngle(v, t, projection),
46591                     p = projection(v.loc),
46592                     r = turn.u ? 0 : 60;
46593
46594                 return 'translate(' + (r * Math.cos(a) + p[0]) + ',' + (r * Math.sin(a) + p[1]) + ') ' +
46595                     'rotate(' + a * 180 / Math.PI + ')';
46596             });
46597
46598         groups.select('use')
46599             .attr('xlink:href', icon);
46600
46601         groups.select('rect');
46602         groups.select('circle');
46603
46604         return this;
46605     };
46606 }
46607
46608 function svgVertices(projection, context) {
46609     var radiuses = {
46610         //       z16-, z17,   z18+,  w/icon
46611         shadow: [6,    7.5,   7.5,   12],
46612         stroke: [2.5,  3.5,   3.5,   8],
46613         fill:   [1,    1.5,   1.5,   1.5]
46614     };
46615
46616     var _currHoverTarget;
46617     var _currPersistent = {};
46618     var _currHover = {};
46619     var _prevHover = {};
46620     var _currSelected = {};
46621     var _prevSelected = {};
46622     var _radii = {};
46623
46624
46625     function sortY(a, b) {
46626         return b.loc[1] - a.loc[1];
46627     }
46628
46629     // Avoid exit/enter if we're just moving stuff around.
46630     // The node will get a new version but we only need to run the update selection.
46631     function fastEntityKey(d) {
46632         var mode = context.mode();
46633         var isMoving = mode && /^(add|draw|drag|move|rotate)/.test(mode.id);
46634         return isMoving ? d.id : osmEntity.key(d);
46635     }
46636
46637
46638     function draw(selection, graph, vertices, sets, filter) {
46639         sets = sets || { selected: {}, important: {}, hovered: {} };
46640
46641         var icons = {};
46642         var directions = {};
46643         var wireframe = context.surface().classed('fill-wireframe');
46644         var zoom = geoScaleToZoom(projection.scale());
46645         var z = (zoom < 17 ? 0 : zoom < 18 ? 1 : 2);
46646
46647
46648         function getIcon(entity) {
46649             if (entity.id in icons) return icons[entity.id];
46650
46651             icons[entity.id] =
46652                 entity.hasInterestingTags() &&
46653                 context.presets().match(entity, graph).icon;
46654             return icons[entity.id];
46655         }
46656
46657
46658         // memoize directions results, return false for empty arrays (for use in filter)
46659         function getDirections(entity) {
46660             if (entity.id in directions) return directions[entity.id];
46661
46662             var angles = entity.directions(graph, projection);
46663             directions[entity.id] = angles.length ? angles : false;
46664             return angles;
46665         }
46666
46667
46668         function updateAttributes(selection) {
46669             ['shadow', 'stroke', 'fill'].forEach(function(klass) {
46670                 var rads = radiuses[klass];
46671                 selection.selectAll('.' + klass)
46672                     .each(function(entity) {
46673                         var i = z && getIcon(entity);
46674                         var r = rads[i ? 3 : z];
46675
46676                         // slightly increase the size of unconnected endpoints #3775
46677                         if (entity.isEndpoint(graph) && !entity.isConnected(graph)) {
46678                             r += 1.5;
46679                         }
46680
46681                         if (klass === 'shadow') {   // remember this value, so we don't need to
46682                             _radii[entity.id] = r;  // recompute it when we draw the touch targets
46683                         }
46684
46685                         d3_select(this)
46686                             .attr('r', r)
46687                             .attr('visibility', (i && klass === 'fill') ? 'hidden' : null);
46688                     });
46689             });
46690
46691             selection.selectAll('use')
46692                 .attr('visibility', (z === 0 ? 'hidden' : null));
46693         }
46694
46695         vertices.sort(sortY);
46696
46697         var groups = selection.selectAll('g.vertex')
46698             .filter(filter)
46699             .data(vertices, fastEntityKey);
46700
46701         // exit
46702         groups.exit()
46703             .remove();
46704
46705         // enter
46706         var enter = groups.enter()
46707             .append('g')
46708             .attr('class', function(d) { return 'node vertex ' + d.id; })
46709             .order();
46710
46711         enter
46712             .append('circle')
46713             .attr('class', 'shadow');
46714
46715         enter
46716             .append('circle')
46717             .attr('class', 'stroke');
46718
46719         // Vertices with icons get a `use`.
46720         enter.filter(function(d) { return getIcon(d); })
46721             .append('use')
46722             .attr('class', 'icon')
46723             .attr('width', '11px')
46724             .attr('height', '11px')
46725             .attr('transform', 'translate(-5.5, -5.5)')
46726             .attr('xlink:href', function(d) {
46727                 var picon = getIcon(d);
46728                 var isMaki = dataFeatureIcons.indexOf(picon) !== -1;
46729                 return '#' + picon + (isMaki ? '-11' : '');
46730             });
46731
46732         // Vertices with tags get a fill.
46733         enter.filter(function(d) { return d.hasInterestingTags(); })
46734             .append('circle')
46735             .attr('class', 'fill');
46736
46737         // update
46738         groups = groups
46739             .merge(enter)
46740             .attr('transform', svgPointTransform(projection))
46741             .classed('sibling', function(d) { return d.id in sets.selected; })
46742             .classed('shared', function(d) { return graph.isShared(d); })
46743             .classed('endpoint', function(d) { return d.isEndpoint(graph); })
46744             .call(updateAttributes);
46745
46746
46747         // Directional vertices get viewfields
46748         var dgroups = groups.filter(function(d) { return getDirections(d); })
46749             .selectAll('.viewfieldgroup')
46750             .data(function data$$1(d) { return zoom >= 18 ? [d] : []; }, osmEntity.key);
46751
46752         // exit
46753         dgroups.exit()
46754             .remove();
46755
46756         // enter/update
46757         dgroups = dgroups.enter()
46758             .insert('g', '.shadow')
46759             .attr('class', 'viewfieldgroup')
46760             .merge(dgroups);
46761
46762         var viewfields = dgroups.selectAll('.viewfield')
46763             .data(getDirections, function key(d) { return d; });
46764
46765         // exit
46766         viewfields.exit()
46767             .remove();
46768
46769         // enter/update
46770         viewfields.enter()
46771             .append('path')
46772             .attr('class', 'viewfield')
46773             .attr('d', 'M0,0H0')
46774             .merge(viewfields)
46775             .attr('marker-start', 'url(#viewfield-marker' + (wireframe ? '-wireframe' : '') + ')')
46776             .attr('transform', function(d) { return 'rotate(' + d + ')'; });
46777     }
46778
46779
46780     function drawTargets(selection, graph, entities, filter) {
46781         var targetClass = context.getDebug('target') ? 'pink ' : 'nocolor ';
46782         var nopeClass = context.getDebug('target') ? 'red ' : 'nocolor ';
46783         var getTransform = svgPointTransform(projection).geojson;
46784         var activeID = context.activeID();
46785         var data$$1 = { targets: [], nopes: [] };
46786
46787         entities.forEach(function(node) {
46788             if (activeID === node.id) return;   // draw no target on the activeID
46789
46790             var vertexType = svgPassiveVertex(node, graph, activeID);
46791             if (vertexType !== 0) {     // passive or adjacent - allow to connect
46792                 data$$1.targets.push({
46793                     type: 'Feature',
46794                     id: node.id,
46795                     properties: {
46796                         target: true,
46797                         entity: node
46798                     },
46799                     geometry: node.asGeoJSON()
46800                 });
46801             } else {
46802                 data$$1.nopes.push({
46803                     type: 'Feature',
46804                     id: node.id + '-nope',
46805                     properties: {
46806                         nope: true,
46807                         target: true,
46808                         entity: node
46809                     },
46810                     geometry: node.asGeoJSON()
46811                 });
46812             }
46813         });
46814
46815
46816         // Targets allow hover and vertex snapping
46817         var targets = selection.selectAll('.vertex.target-allowed')
46818             .filter(function(d) { return filter(d.properties.entity); })
46819             .data(data$$1.targets, function key(d) { return d.id; });
46820
46821         // exit
46822         targets.exit()
46823             .remove();
46824
46825         // enter/update
46826         targets.enter()
46827             .append('circle')
46828             .attr('r', function(d) { return (_radii[d.id] || radiuses.shadow[3]); })
46829             .merge(targets)
46830             .attr('class', function(d) { return 'node vertex target target-allowed ' + targetClass + d.id; })
46831             .attr('transform', getTransform);
46832
46833
46834         // NOPE
46835         var nopes = selection.selectAll('.vertex.target-nope')
46836             .filter(function(d) { return filter(d.properties.entity); })
46837             .data(data$$1.nopes, function key(d) { return d.id; });
46838
46839         // exit
46840         nopes.exit()
46841             .remove();
46842
46843         // enter/update
46844         nopes.enter()
46845             .append('circle')
46846             .attr('r', function(d) { return (_radii[d.properties.entity.id] || radiuses.shadow[3]); })
46847             .merge(nopes)
46848             .attr('class', function(d) { return 'node vertex target target-nope ' + nopeClass + d.id; })
46849             .attr('transform', getTransform);
46850     }
46851
46852
46853     // Points can also render as vertices:
46854     // 1. in wireframe mode or
46855     // 2. at higher zooms if they have a direction
46856     function renderAsVertex(entity, graph, wireframe, zoom) {
46857         var geometry = entity.geometry(graph);
46858         return geometry === 'vertex' || (geometry === 'point' && (
46859             wireframe || (zoom >= 18 && entity.directions(graph, projection).length)
46860         ));
46861     }
46862
46863
46864     function getSiblingAndChildVertices(ids, graph, wireframe, zoom) {
46865         var results = {};
46866
46867         function addChildVertices(entity) {
46868             var geometry = entity.geometry(graph);
46869             if (!context.features().isHiddenFeature(entity, graph, geometry)) {
46870                 var i;
46871                 if (entity.type === 'way') {
46872                     for (i = 0; i < entity.nodes.length; i++) {
46873                         var child = graph.hasEntity(entity.nodes[i]);
46874                         if (child) {
46875                             addChildVertices(child);
46876                         }
46877                     }
46878                 } else if (entity.type === 'relation') {
46879                     for (i = 0; i < entity.members.length; i++) {
46880                         var member = graph.hasEntity(entity.members[i].id);
46881                         if (member) {
46882                             addChildVertices(member);
46883                         }
46884                     }
46885                 } else if (renderAsVertex(entity, graph, wireframe, zoom)) {
46886                     results[entity.id] = entity;
46887                 }
46888             }
46889         }
46890
46891         ids.forEach(function(id) {
46892             var entity = graph.hasEntity(id);
46893             if (!entity) return;
46894
46895             if (entity.type === 'node') {
46896                 if (renderAsVertex(entity, graph, wireframe, zoom)) {
46897                     results[entity.id] = entity;
46898                     graph.parentWays(entity).forEach(function(entity) {
46899                         addChildVertices(entity);
46900                     });
46901                 }
46902             } else {  // way, relation
46903                 addChildVertices(entity);
46904             }
46905         });
46906
46907         return results;
46908     }
46909
46910
46911     function drawVertices(selection, graph, entities, filter, extent, fullRedraw) {
46912         var wireframe = context.surface().classed('fill-wireframe');
46913         var zoom = geoScaleToZoom(projection.scale());
46914         var mode = context.mode();
46915         var isMoving = mode && /^(add|draw|drag|move|rotate)/.test(mode.id);
46916
46917         if (fullRedraw) {
46918             _currPersistent = {};
46919             _radii = {};
46920         }
46921
46922         // Collect important vertices from the `entities` list..
46923         // (during a paritial redraw, it will not contain everything)
46924         for (var i = 0; i < entities.length; i++) {
46925             var entity = entities[i];
46926             var geometry = entity.geometry(graph);
46927             var keep = false;
46928
46929             // a point that looks like a vertex..
46930             if ((geometry === 'point') && renderAsVertex(entity, graph, wireframe, zoom)) {
46931                 _currPersistent[entity.id] = entity;
46932                 keep = true;
46933
46934             // a vertex of some importance..
46935             } else if (geometry === 'vertex' &&
46936                 (entity.hasInterestingTags() || entity.isEndpoint(graph) || entity.isConnected(graph))) {
46937                 _currPersistent[entity.id] = entity;
46938                 keep = true;
46939             }
46940
46941             // whatever this is, it's not a persistent vertex..
46942             if (!keep && !fullRedraw) {
46943                 delete _currPersistent[entity.id];
46944             }
46945         }
46946
46947         // 3 sets of vertices to consider:
46948         var sets = {
46949             persistent: _currPersistent,  // persistent = important vertices (render always)
46950             selected: _currSelected,      // selected + siblings of selected (render always)
46951             hovered: _currHover           // hovered + siblings of hovered (render only in draw modes)
46952         };
46953
46954         var all = assign({}, (isMoving ? _currHover : {}), _currSelected, _currPersistent);
46955
46956         // Draw the vertices..
46957         // The filter function controls the scope of what objects d3 will touch (exit/enter/update)
46958         // Adjust the filter function to expand the scope beyond whatever entities were passed in.
46959         var filterRendered = function(d) {
46960             return d.id in _currPersistent || d.id in _currSelected || d.id in _currHover || filter(d);
46961         };
46962         selection.selectAll('.layer-points .layer-points-vertices')
46963             .call(draw, graph, currentVisible(all), sets, filterRendered);
46964
46965         // Draw touch targets..
46966         // When drawing, render all targets (not just those affected by a partial redraw)
46967         var filterTouch = function(d) {
46968             return isMoving ? true : filterRendered(d);
46969         };
46970         selection.selectAll('.layer-points .layer-points-targets')
46971             .call(drawTargets, graph, currentVisible(all), filterTouch);
46972
46973
46974         function currentVisible(which) {
46975             return Object.keys(which)
46976                 .map(graph.hasEntity, graph)     // the current version of this entity
46977                 .filter(function (entity) { return entity && entity.intersects(extent, graph); });
46978         }
46979     }
46980
46981
46982     // partial redraw - only update the selected items..
46983     drawVertices.drawSelected = function(selection, graph, extent) {
46984         var wireframe = context.surface().classed('fill-wireframe');
46985         var zoom = geoScaleToZoom(projection.scale());
46986
46987         _prevSelected = _currSelected || {};
46988         _currSelected = getSiblingAndChildVertices(context.selectedIDs(), graph, wireframe, zoom);
46989
46990         // note that drawVertices will add `_currSelected` automatically if needed..
46991         var filter = function(d) { return d.id in _prevSelected; };
46992         drawVertices(selection, graph, values$1(_prevSelected), filter, extent, false);
46993     };
46994
46995
46996     // partial redraw - only update the hovered items..
46997     drawVertices.drawHover = function(selection, graph, target, extent) {
46998         if (target === _currHoverTarget) return;  // continue only if something changed
46999
47000         var wireframe = context.surface().classed('fill-wireframe');
47001         var zoom = geoScaleToZoom(projection.scale());
47002
47003         _prevHover = _currHover || {};
47004         _currHoverTarget = target;
47005         var entity = target && target.properties && target.properties.entity;
47006
47007         if (entity) {
47008             _currHover = getSiblingAndChildVertices([entity.id], graph, wireframe, zoom);
47009         } else {
47010             _currHover = {};
47011         }
47012
47013         // note that drawVertices will add `_currHover` automatically if needed..
47014         var filter = function(d) { return d.id in _prevHover; };
47015         drawVertices(selection, graph, values$1(_prevHover), filter, extent, false);
47016     };
47017
47018     return drawVertices;
47019 }
47020
47021 function uiAccount(context) {
47022     var osm = context.connection();
47023
47024
47025     function update(selection) {
47026         if (!osm) return;
47027
47028         if (!osm.authenticated()) {
47029             selection.selectAll('#userLink, #logoutLink')
47030                 .classed('hide', true);
47031             return;
47032         }
47033
47034         osm.userDetails(function(err, details) {
47035             var userLink = selection.select('#userLink'),
47036                 logoutLink = selection.select('#logoutLink');
47037
47038             userLink.html('');
47039             logoutLink.html('');
47040
47041             if (err) return;
47042
47043             selection.selectAll('#userLink, #logoutLink')
47044                 .classed('hide', false);
47045
47046             // Link
47047             userLink.append('a')
47048                 .attr('href', osm.userURL(details.display_name))
47049                 .attr('target', '_blank');
47050
47051             // Add thumbnail or dont
47052             if (details.image_url) {
47053                 userLink.append('img')
47054                     .attr('class', 'icon pre-text user-icon')
47055                     .attr('src', details.image_url);
47056             } else {
47057                 userLink
47058                     .call(svgIcon('#icon-avatar', 'pre-text light'));
47059             }
47060
47061             // Add user name
47062             userLink.append('span')
47063                 .attr('class', 'label')
47064                 .text(details.display_name);
47065
47066             logoutLink.append('a')
47067                 .attr('class', 'logout')
47068                 .attr('href', '#')
47069                 .text(t('logout'))
47070                 .on('click.logout', function() {
47071                     event.preventDefault();
47072                     osm.logout();
47073                 });
47074         });
47075     }
47076
47077
47078     return function(selection) {
47079         selection.append('li')
47080             .attr('id', 'logoutLink')
47081             .classed('hide', true);
47082
47083         selection.append('li')
47084             .attr('id', 'userLink')
47085             .classed('hide', true);
47086
47087         if (osm) {
47088             osm.on('change.account', function() { update(selection); });
47089             update(selection);
47090         }
47091     };
47092 }
47093
47094 function uiAttribution(context) {
47095     var selection;
47096
47097
47098     function attribution(data, klass) {
47099         var div = selection.selectAll('.' + klass)
47100             .data([0]);
47101
47102         div = div.enter()
47103             .append('div')
47104             .attr('class', klass)
47105             .merge(div);
47106
47107
47108         var background = div.selectAll('.attribution')
47109             .data(data, function(d) { return d.name(); });
47110
47111         background.exit()
47112             .remove();
47113
47114         background = background.enter()
47115             .append('span')
47116             .attr('class', 'attribution')
47117             .each(function(d) {
47118                 if (d.terms_html) {
47119                     d3_select(this)
47120                         .html(d.terms_html);
47121                     return;
47122                 }
47123
47124                 var selection;
47125                 if (d.terms_url) {
47126                     selection = d3_select(this)
47127                         .append('a')
47128                         .attr('href', d.terms_url)
47129                         .attr('target', '_blank');
47130                 } else {
47131                     selection = d3_select(this);
47132                 }
47133
47134
47135                 var id_safe = d.id.replace('.', '<TX_DOT>');
47136                 var terms_text = t('imagery.' + id_safe + '.attribution.text',
47137                     { default: d.terms_text || d.id || d.name() }
47138                 );
47139
47140                 if (d.icon && !d.overlay) {
47141                     selection
47142                         .append('img')
47143                         .attr('class', 'source-image')
47144                         .attr('src', d.icon);
47145                 }
47146
47147                 selection
47148                     .append('span')
47149                     .attr('class', 'attribution-text')
47150                     .text(terms_text);
47151             })
47152             .merge(background);
47153
47154
47155         var copyright = background.selectAll('.copyright-notice')
47156             .data(function(d) {
47157                 var notice = d.copyrightNotices(context.map().zoom(), context.map().extent());
47158                 return notice ? [notice] : [];
47159             });
47160
47161         copyright.exit()
47162             .remove();
47163
47164         copyright = copyright.enter()
47165             .append('span')
47166             .attr('class', 'copyright-notice')
47167             .merge(copyright);
47168
47169         copyright
47170             .text(String);
47171     }
47172
47173
47174     function update() {
47175         attribution([context.background().baseLayerSource()], 'base-layer-attribution');
47176         attribution(context.background().overlayLayerSources().filter(function (s) {
47177             return s.validZoom(context.map().zoom());
47178         }), 'overlay-layer-attribution');
47179     }
47180
47181
47182     return function(select$$1) {
47183         selection = select$$1;
47184
47185         context.background()
47186             .on('change.attribution', update);
47187
47188         context.map()
47189             .on('move.attribution', throttle(update, 400, {leading: false}));
47190
47191         update();
47192     };
47193 }
47194
47195 // toggles the visibility of ui elements, using a combination of the
47196 // hide class, which sets display=none, and a d3 transition for opacity.
47197 // this will cause blinking when called repeatedly, so check that the
47198 // value actually changes between calls.
47199 function uiToggle(show, callback) {
47200     return function(selection) {
47201         selection
47202             .style('opacity', show ? 0 : 1)
47203             .classed('hide', false)
47204             .transition()
47205             .style('opacity', show ? 1 : 0)
47206             .on('end', function() {
47207                 d3_select(this)
47208                     .classed('hide', !show)
47209                     .style('opacity', null);
47210                 if (callback) callback.apply(this);
47211             });
47212     };
47213 }
47214
47215 function uiDisclosure(context, key, expandedDefault) {
47216     var dispatch$$1 = dispatch('toggled'),
47217         _preference = (context.storage('disclosure.' + key + '.expanded')),
47218         _expanded = (_preference === null ? !!expandedDefault : (_preference === 'true')),
47219         _title,
47220         _updatePreference = true,
47221         _content = function () {};
47222
47223
47224     var disclosure = function(selection) {
47225         var hideToggle = selection.selectAll('.hide-toggle-' + key)
47226             .data([0]);
47227
47228         // enter
47229         var hideToggleEnter = hideToggle.enter()
47230             .append('a')
47231             .attr('href', '#')
47232             .attr('class', 'hide-toggle hide-toggle-' + key)
47233             .call(svgIcon('', 'pre-text', 'hide-toggle-icon'));
47234
47235         hideToggleEnter
47236             .append('span')
47237             .attr('class', 'hide-toggle-text');
47238
47239         // update
47240         hideToggle = hideToggleEnter
47241             .merge(hideToggle);
47242
47243         hideToggle
47244             .on('click', toggle)
47245             .classed('expanded', _expanded);
47246
47247         hideToggle.selectAll('.hide-toggle-text')
47248             .text(_title);
47249
47250         hideToggle.selectAll('.hide-toggle-icon')
47251             .attr('xlink:href', _expanded ? '#icon-down'
47252                 : (textDirection === 'rtl') ? '#icon-backward' : '#icon-forward'
47253             );
47254
47255
47256         var wrap = selection.selectAll('.disclosure-wrap')
47257             .data([0]);
47258
47259         wrap = wrap.enter()
47260             .append('div')
47261             .attr('class', 'disclosure-wrap disclosure-wrap-' + key)
47262             .merge(wrap);
47263
47264         wrap
47265             .classed('hide', !_expanded)
47266             .call(_content);
47267
47268
47269         function toggle() {
47270             event.preventDefault();
47271
47272             _expanded = !_expanded;
47273
47274             if (_updatePreference) {
47275                 context.storage('disclosure.' + key + '.expanded', _expanded);
47276             }
47277
47278             hideToggle
47279                 .classed('expanded', _expanded);
47280
47281             hideToggle.selectAll('.hide-toggle-icon')
47282                 .attr('xlink:href', _expanded ? '#icon-down'
47283                     : (textDirection === 'rtl') ? '#icon-backward' : '#icon-forward'
47284                 );
47285
47286             wrap
47287                 .call(uiToggle(_expanded));
47288
47289             dispatch$$1.call('toggled', this, _expanded);
47290         }
47291     };
47292
47293
47294     disclosure.title = function(_) {
47295         if (!arguments.length) return _title;
47296         _title = _;
47297         return disclosure;
47298     };
47299
47300
47301     disclosure.expanded = function(_) {
47302         if (!arguments.length) return _expanded;
47303         _expanded = _;
47304         return disclosure;
47305     };
47306
47307
47308     disclosure.updatePreference = function(_) {
47309         if (!arguments.length) return _updatePreference;
47310         _updatePreference = _;
47311         return disclosure;
47312     };
47313
47314
47315     disclosure.content = function(_) {
47316         if (!arguments.length) return _content;
47317         _content = _;
47318         return disclosure;
47319     };
47320
47321
47322     return utilRebind(disclosure, dispatch$$1, 'on');
47323 }
47324
47325 function uiBackgroundDisplayOptions(context) {
47326     var detected = utilDetect();
47327     var storedOpacity = context.storage('background-opacity');
47328     var minVal = 0.25;
47329     var maxVal = detected.cssfilters ? 2 : 1;
47330
47331     var sliders = detected.cssfilters
47332         ? ['brightness', 'contrast', 'saturation', 'sharpness']
47333         : ['brightness'];
47334
47335     var _options = {
47336         brightness: (storedOpacity !== null ? (+storedOpacity) : 1),
47337         contrast: 1,
47338         saturation: 1,
47339         sharpness: 1
47340     };
47341
47342     var _selection = d3_select(null);
47343
47344
47345     function clamp(x, min, max) {
47346         return Math.max(min, Math.min(x, max));
47347     }
47348
47349
47350     function updateValue(d, val) {
47351         if (!val && event && event.target) {
47352             val = event.target.value;
47353         }
47354
47355         val = clamp(val, minVal, maxVal);
47356
47357         _options[d] = val;
47358         context.background()[d](val);
47359
47360         if (d === 'brightness') {
47361             context.storage('background-opacity', val);
47362         }
47363
47364         _selection
47365             .call(render);
47366     }
47367
47368
47369     function render(selection) {
47370         var container = selection.selectAll('.display-options-container')
47371             .data([0]);
47372
47373         var containerEnter = container.enter()
47374             .append('div')
47375             .attr('class', 'display-options-container controls-list');
47376
47377         // add slider controls
47378         var slidersEnter = containerEnter.selectAll('.display-control')
47379             .data(sliders)
47380             .enter()
47381             .append('div')
47382             .attr('class', function(d) { return 'display-control display-control-' + d; });
47383
47384         slidersEnter
47385             .append('h5')
47386             .text(function(d) { return t('background.' + d); })
47387             .append('span')
47388             .attr('class', function(d) { return 'display-option-value display-option-value-' + d; });
47389
47390         slidersEnter
47391             .append('input')
47392             .attr('class', function(d) { return 'display-option-input display-option-input-' + d; })
47393             .attr('type', 'range')
47394             .attr('min', minVal)
47395             .attr('max', maxVal)
47396             .attr('step', '0.05')
47397             .on('input', function(d) {
47398                 var val = d3_select(this).property('value');
47399                 updateValue(d, val);
47400             });
47401
47402         slidersEnter
47403             .append('button')
47404             .attr('title', t('background.reset'))
47405             .attr('class', function(d) { return 'display-option-reset display-option-reset-' + d; })
47406             .on('click', function(d) {
47407                 if (event.button !== 0) return;
47408                 updateValue(d, 1);
47409             })
47410             .call(svgIcon('#icon-' + (textDirection === 'rtl' ? 'redo' : 'undo')));
47411
47412
47413         // update
47414         container = containerEnter
47415             .merge(container);
47416
47417         container.selectAll('.display-option-input')
47418             .property('value', function(d) { return _options[d]; });
47419
47420         container.selectAll('.display-option-value')
47421             .text(function(d) { return Math.floor(_options[d] * 100) + '%'; });
47422
47423         container.selectAll('.display-option-reset')
47424             .classed('disabled', function(d) { return _options[d] === 1; });
47425
47426         // first time only, set brightness if needed
47427         if (containerEnter.size() && _options.brightness !== 1) {
47428             context.background().brightness(_options.brightness);
47429         }
47430     }
47431
47432
47433     function backgroundDisplayOptions(selection) {
47434         _selection = selection;
47435
47436         selection
47437             .call(uiDisclosure(context, 'background_display_options', true)
47438                 .title(t('background.display_options'))
47439                 .content(render)
47440             );
47441     }
47442
47443
47444     return backgroundDisplayOptions;
47445 }
47446
47447 function uiBackgroundOffset(context) {
47448     var directions = [
47449         ['right', [0.5, 0]],
47450         ['top', [0, -0.5]],
47451         ['left', [-0.5, 0]],
47452         ['bottom', [0, 0.5]]
47453     ];
47454
47455
47456     function d3_eventCancel() {
47457         event.stopPropagation();
47458         event.preventDefault();
47459     }
47460
47461
47462     function updateValue() {
47463         var meters = geoOffsetToMeters(context.background().offset());
47464         var x = +meters[0].toFixed(2);
47465         var y = +meters[1].toFixed(2);
47466
47467         d3_selectAll('.nudge-inner-rect')
47468             .select('input')
47469             .classed('error', false)
47470             .property('value', x + ', ' + y);
47471
47472         d3_selectAll('.nudge-reset')
47473             .classed('disabled', function() {
47474                 return (x === 0 && y === 0);
47475             });
47476     }
47477
47478
47479     function resetOffset() {
47480         context.background().offset([0, 0]);
47481         updateValue();
47482     }
47483
47484
47485     function nudge(d) {
47486         context.background().nudge(d, context.map().zoom());
47487         updateValue();
47488     }
47489
47490
47491     function clickNudgeButton(d) {
47492         var interval;
47493         var timeout = window.setTimeout(function() {
47494                 interval = window.setInterval(nudge.bind(null, d), 100);
47495             }, 500);
47496
47497         function doneNudge() {
47498             window.clearTimeout(timeout);
47499             window.clearInterval(interval);
47500             d3_select(window)
47501                 .on('mouseup.buttonoffset', null, true)
47502                 .on('mousedown.buttonoffset', null, true);
47503         }
47504
47505         d3_select(window)
47506             .on('mouseup.buttonoffset', doneNudge, true)
47507             .on('mousedown.buttonoffset', doneNudge, true);
47508
47509         nudge(d);
47510     }
47511
47512
47513     function inputOffset() {
47514         var input = d3_select(this);
47515         var d = input.node().value;
47516
47517         if (d === '') return resetOffset();
47518
47519         d = d.replace(/;/g, ',').split(',').map(function(n) {
47520             // if n is NaN, it will always get mapped to false.
47521             return !isNaN(n) && n;
47522         });
47523
47524         if (d.length !== 2 || !d[0] || !d[1]) {
47525             input.classed('error', true);
47526             return;
47527         }
47528
47529         context.background().offset(geoMetersToOffset(d));
47530         updateValue();
47531     }
47532
47533
47534     function dragOffset() {
47535         event.preventDefault();
47536         if (event.button !== 0) return;
47537
47538         var origin = [event.clientX, event.clientY];
47539
47540         context.container()
47541             .append('div')
47542             .attr('class', 'nudge-surface');
47543
47544         d3_select(window)
47545             .on('mousemove.offset', function() {
47546                 var latest = [event.clientX, event.clientY];
47547                 var d = [
47548                     -(origin[0] - latest[0]) / 4,
47549                     -(origin[1] - latest[1]) / 4
47550                 ];
47551
47552                 origin = latest;
47553                 nudge(d);
47554             })
47555             .on('mouseup.offset', function() {
47556                 if (event.button !== 0) return;
47557                 d3_selectAll('.nudge-surface')
47558                     .remove();
47559
47560                 d3_select(window)
47561                     .on('mousemove.offset', null)
47562                     .on('mouseup.offset', null);
47563             });
47564     }
47565
47566
47567     function render(selection) {
47568         var container = selection.selectAll('.nudge-container')
47569             .data([0]);
47570
47571         var containerEnter = container.enter()
47572             .append('div')
47573             .attr('class', 'nudge-container cf');
47574
47575         containerEnter
47576             .append('div')
47577             .attr('class', 'nudge-instructions')
47578             .text(t('background.offset'));
47579
47580         var nudgeEnter = containerEnter
47581             .append('div')
47582             .attr('class', 'nudge-outer-rect')
47583             .on('mousedown', dragOffset);
47584
47585         nudgeEnter
47586             .append('div')
47587             .attr('class', 'nudge-inner-rect')
47588             .append('input')
47589             .on('change', inputOffset);
47590
47591         containerEnter
47592             .append('div')
47593             .selectAll('button')
47594             .data(directions).enter()
47595             .append('button')
47596             .attr('class', function(d) { return d[0] + ' nudge'; })
47597             .on('contextmenu', d3_eventCancel)
47598             .on('mousedown', function(d) {
47599                 if (event.button !== 0) return;
47600                 clickNudgeButton(d[1]);
47601             });
47602
47603         containerEnter
47604             .append('button')
47605             .attr('title', t('background.reset'))
47606             .attr('class', 'nudge-reset disabled')
47607             .on('contextmenu', d3_eventCancel)
47608             .on('click', function() {
47609                 if (event.button !== 0) return;
47610                 resetOffset();
47611             })
47612             .call(svgIcon('#icon-' + (textDirection === 'rtl' ? 'redo' : 'undo')));
47613
47614         updateValue();
47615     }
47616
47617
47618     function backgroundOffset(selection) {
47619         selection
47620             .call(uiDisclosure(context, 'background_offset', false)
47621                 .title(t('background.fix_misalignment'))
47622                 .content(render)
47623             );
47624     }
47625
47626
47627     context.background()
47628         .on('change.backgroundOffset-update', updateValue);
47629
47630     return backgroundOffset;
47631 }
47632
47633 var marked = createCommonjsModule(function (module, exports) {
47634 /**
47635  * marked - a markdown parser
47636  * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
47637  * https://github.com/chjj/marked
47638  */
47639
47640 (function() {
47641 var block = {
47642   newline: /^\n+/,
47643   code: /^( {4}[^\n]+\n*)+/,
47644   fences: noop,
47645   hr: /^( *[-*_]){3,} *(?:\n+|$)/,
47646   heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
47647   nptable: noop,
47648   lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
47649   blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
47650   list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
47651   html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
47652   def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
47653   table: noop,
47654   paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
47655   text: /^[^\n]+/
47656 };
47657
47658 block.bullet = /(?:[*+-]|\d+\.)/;
47659 block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
47660 block.item = replace(block.item, 'gm')
47661   (/bull/g, block.bullet)
47662   ();
47663
47664 block.list = replace(block.list)
47665   (/bull/g, block.bullet)
47666   ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
47667   ('def', '\\n+(?=' + block.def.source + ')')
47668   ();
47669
47670 block.blockquote = replace(block.blockquote)
47671   ('def', block.def)
47672   ();
47673
47674 block._tag = '(?!(?:'
47675   + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
47676   + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
47677   + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b';
47678
47679 block.html = replace(block.html)
47680   ('comment', /<!--[\s\S]*?-->/)
47681   ('closed', /<(tag)[\s\S]+?<\/\1>/)
47682   ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
47683   (/tag/g, block._tag)
47684   ();
47685
47686 block.paragraph = replace(block.paragraph)
47687   ('hr', block.hr)
47688   ('heading', block.heading)
47689   ('lheading', block.lheading)
47690   ('blockquote', block.blockquote)
47691   ('tag', '<' + block._tag)
47692   ('def', block.def)
47693   ();
47694
47695 /**
47696  * Normal Block Grammar
47697  */
47698
47699 block.normal = merge({}, block);
47700
47701 /**
47702  * GFM Block Grammar
47703  */
47704
47705 block.gfm = merge({}, block.normal, {
47706   fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,
47707   paragraph: /^/,
47708   heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/
47709 });
47710
47711 block.gfm.paragraph = replace(block.paragraph)
47712   ('(?!', '(?!'
47713     + block.gfm.fences.source.replace('\\1', '\\2') + '|'
47714     + block.list.source.replace('\\1', '\\3') + '|')
47715   ();
47716
47717 /**
47718  * GFM + Tables Block Grammar
47719  */
47720
47721 block.tables = merge({}, block.gfm, {
47722   nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
47723   table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
47724 });
47725
47726 /**
47727  * Block Lexer
47728  */
47729
47730 function Lexer(options) {
47731   this.tokens = [];
47732   this.tokens.links = {};
47733   this.options = options || marked.defaults;
47734   this.rules = block.normal;
47735
47736   if (this.options.gfm) {
47737     if (this.options.tables) {
47738       this.rules = block.tables;
47739     } else {
47740       this.rules = block.gfm;
47741     }
47742   }
47743 }
47744
47745 /**
47746  * Expose Block Rules
47747  */
47748
47749 Lexer.rules = block;
47750
47751 /**
47752  * Static Lex Method
47753  */
47754
47755 Lexer.lex = function(src, options) {
47756   var lexer = new Lexer(options);
47757   return lexer.lex(src);
47758 };
47759
47760 /**
47761  * Preprocessing
47762  */
47763
47764 Lexer.prototype.lex = function(src) {
47765   src = src
47766     .replace(/\r\n|\r/g, '\n')
47767     .replace(/\t/g, '    ')
47768     .replace(/\u00a0/g, ' ')
47769     .replace(/\u2424/g, '\n');
47770
47771   return this.token(src, true);
47772 };
47773
47774 /**
47775  * Lexing
47776  */
47777
47778 Lexer.prototype.token = function(src, top, bq) {
47779   var src = src.replace(/^ +$/gm, '')
47780     , next
47781     , loose
47782     , cap
47783     , bull
47784     , b
47785     , item
47786     , space
47787     , i
47788     , l;
47789
47790   while (src) {
47791     // newline
47792     if (cap = this.rules.newline.exec(src)) {
47793       src = src.substring(cap[0].length);
47794       if (cap[0].length > 1) {
47795         this.tokens.push({
47796           type: 'space'
47797         });
47798       }
47799     }
47800
47801     // code
47802     if (cap = this.rules.code.exec(src)) {
47803       src = src.substring(cap[0].length);
47804       cap = cap[0].replace(/^ {4}/gm, '');
47805       this.tokens.push({
47806         type: 'code',
47807         text: !this.options.pedantic
47808           ? cap.replace(/\n+$/, '')
47809           : cap
47810       });
47811       continue;
47812     }
47813
47814     // fences (gfm)
47815     if (cap = this.rules.fences.exec(src)) {
47816       src = src.substring(cap[0].length);
47817       this.tokens.push({
47818         type: 'code',
47819         lang: cap[2],
47820         text: cap[3] || ''
47821       });
47822       continue;
47823     }
47824
47825     // heading
47826     if (cap = this.rules.heading.exec(src)) {
47827       src = src.substring(cap[0].length);
47828       this.tokens.push({
47829         type: 'heading',
47830         depth: cap[1].length,
47831         text: cap[2]
47832       });
47833       continue;
47834     }
47835
47836     // table no leading pipe (gfm)
47837     if (top && (cap = this.rules.nptable.exec(src))) {
47838       src = src.substring(cap[0].length);
47839
47840       item = {
47841         type: 'table',
47842         header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
47843         align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
47844         cells: cap[3].replace(/\n$/, '').split('\n')
47845       };
47846
47847       for (i = 0; i < item.align.length; i++) {
47848         if (/^ *-+: *$/.test(item.align[i])) {
47849           item.align[i] = 'right';
47850         } else if (/^ *:-+: *$/.test(item.align[i])) {
47851           item.align[i] = 'center';
47852         } else if (/^ *:-+ *$/.test(item.align[i])) {
47853           item.align[i] = 'left';
47854         } else {
47855           item.align[i] = null;
47856         }
47857       }
47858
47859       for (i = 0; i < item.cells.length; i++) {
47860         item.cells[i] = item.cells[i].split(/ *\| */);
47861       }
47862
47863       this.tokens.push(item);
47864
47865       continue;
47866     }
47867
47868     // lheading
47869     if (cap = this.rules.lheading.exec(src)) {
47870       src = src.substring(cap[0].length);
47871       this.tokens.push({
47872         type: 'heading',
47873         depth: cap[2] === '=' ? 1 : 2,
47874         text: cap[1]
47875       });
47876       continue;
47877     }
47878
47879     // hr
47880     if (cap = this.rules.hr.exec(src)) {
47881       src = src.substring(cap[0].length);
47882       this.tokens.push({
47883         type: 'hr'
47884       });
47885       continue;
47886     }
47887
47888     // blockquote
47889     if (cap = this.rules.blockquote.exec(src)) {
47890       src = src.substring(cap[0].length);
47891
47892       this.tokens.push({
47893         type: 'blockquote_start'
47894       });
47895
47896       cap = cap[0].replace(/^ *> ?/gm, '');
47897
47898       // Pass `top` to keep the current
47899       // "toplevel" state. This is exactly
47900       // how markdown.pl works.
47901       this.token(cap, top, true);
47902
47903       this.tokens.push({
47904         type: 'blockquote_end'
47905       });
47906
47907       continue;
47908     }
47909
47910     // list
47911     if (cap = this.rules.list.exec(src)) {
47912       src = src.substring(cap[0].length);
47913       bull = cap[2];
47914
47915       this.tokens.push({
47916         type: 'list_start',
47917         ordered: bull.length > 1
47918       });
47919
47920       // Get each top-level item.
47921       cap = cap[0].match(this.rules.item);
47922
47923       next = false;
47924       l = cap.length;
47925       i = 0;
47926
47927       for (; i < l; i++) {
47928         item = cap[i];
47929
47930         // Remove the list item's bullet
47931         // so it is seen as the next token.
47932         space = item.length;
47933         item = item.replace(/^ *([*+-]|\d+\.) +/, '');
47934
47935         // Outdent whatever the
47936         // list item contains. Hacky.
47937         if (~item.indexOf('\n ')) {
47938           space -= item.length;
47939           item = !this.options.pedantic
47940             ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
47941             : item.replace(/^ {1,4}/gm, '');
47942         }
47943
47944         // Determine whether the next list item belongs here.
47945         // Backpedal if it does not belong in this list.
47946         if (this.options.smartLists && i !== l - 1) {
47947           b = block.bullet.exec(cap[i + 1])[0];
47948           if (bull !== b && !(bull.length > 1 && b.length > 1)) {
47949             src = cap.slice(i + 1).join('\n') + src;
47950             i = l - 1;
47951           }
47952         }
47953
47954         // Determine whether item is loose or not.
47955         // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
47956         // for discount behavior.
47957         loose = next || /\n\n(?!\s*$)/.test(item);
47958         if (i !== l - 1) {
47959           next = item.charAt(item.length - 1) === '\n';
47960           if (!loose) loose = next;
47961         }
47962
47963         this.tokens.push({
47964           type: loose
47965             ? 'loose_item_start'
47966             : 'list_item_start'
47967         });
47968
47969         // Recurse.
47970         this.token(item, false, bq);
47971
47972         this.tokens.push({
47973           type: 'list_item_end'
47974         });
47975       }
47976
47977       this.tokens.push({
47978         type: 'list_end'
47979       });
47980
47981       continue;
47982     }
47983
47984     // html
47985     if (cap = this.rules.html.exec(src)) {
47986       src = src.substring(cap[0].length);
47987       this.tokens.push({
47988         type: this.options.sanitize
47989           ? 'paragraph'
47990           : 'html',
47991         pre: !this.options.sanitizer
47992           && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
47993         text: cap[0]
47994       });
47995       continue;
47996     }
47997
47998     // def
47999     if ((!bq && top) && (cap = this.rules.def.exec(src))) {
48000       src = src.substring(cap[0].length);
48001       this.tokens.links[cap[1].toLowerCase()] = {
48002         href: cap[2],
48003         title: cap[3]
48004       };
48005       continue;
48006     }
48007
48008     // table (gfm)
48009     if (top && (cap = this.rules.table.exec(src))) {
48010       src = src.substring(cap[0].length);
48011
48012       item = {
48013         type: 'table',
48014         header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
48015         align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
48016         cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
48017       };
48018
48019       for (i = 0; i < item.align.length; i++) {
48020         if (/^ *-+: *$/.test(item.align[i])) {
48021           item.align[i] = 'right';
48022         } else if (/^ *:-+: *$/.test(item.align[i])) {
48023           item.align[i] = 'center';
48024         } else if (/^ *:-+ *$/.test(item.align[i])) {
48025           item.align[i] = 'left';
48026         } else {
48027           item.align[i] = null;
48028         }
48029       }
48030
48031       for (i = 0; i < item.cells.length; i++) {
48032         item.cells[i] = item.cells[i]
48033           .replace(/^ *\| *| *\| *$/g, '')
48034           .split(/ *\| */);
48035       }
48036
48037       this.tokens.push(item);
48038
48039       continue;
48040     }
48041
48042     // top-level paragraph
48043     if (top && (cap = this.rules.paragraph.exec(src))) {
48044       src = src.substring(cap[0].length);
48045       this.tokens.push({
48046         type: 'paragraph',
48047         text: cap[1].charAt(cap[1].length - 1) === '\n'
48048           ? cap[1].slice(0, -1)
48049           : cap[1]
48050       });
48051       continue;
48052     }
48053
48054     // text
48055     if (cap = this.rules.text.exec(src)) {
48056       // Top-level should never reach here.
48057       src = src.substring(cap[0].length);
48058       this.tokens.push({
48059         type: 'text',
48060         text: cap[0]
48061       });
48062       continue;
48063     }
48064
48065     if (src) {
48066       throw new
48067         Error('Infinite loop on byte: ' + src.charCodeAt(0));
48068     }
48069   }
48070
48071   return this.tokens;
48072 };
48073
48074 /**
48075  * Inline-Level Grammar
48076  */
48077
48078 var inline = {
48079   escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
48080   autolink: /^<([^ <>]+(@|:\/)[^ <>]+)>/,
48081   url: noop,
48082   tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^<'">])*?>/,
48083   link: /^!?\[(inside)\]\(href\)/,
48084   reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
48085   nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
48086   strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
48087   em: /^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
48088   code: /^(`+)([\s\S]*?[^`])\1(?!`)/,
48089   br: /^ {2,}\n(?!\s*$)/,
48090   del: noop,
48091   text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
48092 };
48093
48094 inline._inside = /(?:\[[^\]]*\]|\\[\[\]]|[^\[\]]|\](?=[^\[]*\]))*/;
48095 inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
48096
48097 inline.link = replace(inline.link)
48098   ('inside', inline._inside)
48099   ('href', inline._href)
48100   ();
48101
48102 inline.reflink = replace(inline.reflink)
48103   ('inside', inline._inside)
48104   ();
48105
48106 /**
48107  * Normal Inline Grammar
48108  */
48109
48110 inline.normal = merge({}, inline);
48111
48112 /**
48113  * Pedantic Inline Grammar
48114  */
48115
48116 inline.pedantic = merge({}, inline.normal, {
48117   strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
48118   em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
48119 });
48120
48121 /**
48122  * GFM Inline Grammar
48123  */
48124
48125 inline.gfm = merge({}, inline.normal, {
48126   escape: replace(inline.escape)('])', '~|])')(),
48127   url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
48128   del: /^~~(?=\S)([\s\S]*?\S)~~/,
48129   text: replace(inline.text)
48130     (']|', '~]|')
48131     ('|', '|https?://|')
48132     ()
48133 });
48134
48135 /**
48136  * GFM + Line Breaks Inline Grammar
48137  */
48138
48139 inline.breaks = merge({}, inline.gfm, {
48140   br: replace(inline.br)('{2,}', '*')(),
48141   text: replace(inline.gfm.text)('{2,}', '*')()
48142 });
48143
48144 /**
48145  * Inline Lexer & Compiler
48146  */
48147
48148 function InlineLexer(links, options) {
48149   this.options = options || marked.defaults;
48150   this.links = links;
48151   this.rules = inline.normal;
48152   this.renderer = this.options.renderer || new Renderer;
48153   this.renderer.options = this.options;
48154
48155   if (!this.links) {
48156     throw new
48157       Error('Tokens array requires a `links` property.');
48158   }
48159
48160   if (this.options.gfm) {
48161     if (this.options.breaks) {
48162       this.rules = inline.breaks;
48163     } else {
48164       this.rules = inline.gfm;
48165     }
48166   } else if (this.options.pedantic) {
48167     this.rules = inline.pedantic;
48168   }
48169 }
48170
48171 /**
48172  * Expose Inline Rules
48173  */
48174
48175 InlineLexer.rules = inline;
48176
48177 /**
48178  * Static Lexing/Compiling Method
48179  */
48180
48181 InlineLexer.output = function(src, links, options) {
48182   var inline = new InlineLexer(links, options);
48183   return inline.output(src);
48184 };
48185
48186 /**
48187  * Lexing/Compiling
48188  */
48189
48190 InlineLexer.prototype.output = function(src) {
48191   var out = ''
48192     , link
48193     , text
48194     , href
48195     , cap;
48196
48197   while (src) {
48198     // escape
48199     if (cap = this.rules.escape.exec(src)) {
48200       src = src.substring(cap[0].length);
48201       out += cap[1];
48202       continue;
48203     }
48204
48205     // autolink
48206     if (cap = this.rules.autolink.exec(src)) {
48207       src = src.substring(cap[0].length);
48208       if (cap[2] === '@') {
48209         text = escape(
48210           cap[1].charAt(6) === ':'
48211           ? this.mangle(cap[1].substring(7))
48212           : this.mangle(cap[1])
48213         );
48214         href = this.mangle('mailto:') + text;
48215       } else {
48216         text = escape(cap[1]);
48217         href = text;
48218       }
48219       out += this.renderer.link(href, null, text);
48220       continue;
48221     }
48222
48223     // url (gfm)
48224     if (!this.inLink && (cap = this.rules.url.exec(src))) {
48225       src = src.substring(cap[0].length);
48226       text = escape(cap[1]);
48227       href = text;
48228       out += this.renderer.link(href, null, text);
48229       continue;
48230     }
48231
48232     // tag
48233     if (cap = this.rules.tag.exec(src)) {
48234       if (!this.inLink && /^<a /i.test(cap[0])) {
48235         this.inLink = true;
48236       } else if (this.inLink && /^<\/a>/i.test(cap[0])) {
48237         this.inLink = false;
48238       }
48239       src = src.substring(cap[0].length);
48240       out += this.options.sanitize
48241         ? this.options.sanitizer
48242           ? this.options.sanitizer(cap[0])
48243           : escape(cap[0])
48244         : cap[0];
48245       continue;
48246     }
48247
48248     // link
48249     if (cap = this.rules.link.exec(src)) {
48250       src = src.substring(cap[0].length);
48251       this.inLink = true;
48252       out += this.outputLink(cap, {
48253         href: cap[2],
48254         title: cap[3]
48255       });
48256       this.inLink = false;
48257       continue;
48258     }
48259
48260     // reflink, nolink
48261     if ((cap = this.rules.reflink.exec(src))
48262         || (cap = this.rules.nolink.exec(src))) {
48263       src = src.substring(cap[0].length);
48264       link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
48265       link = this.links[link.toLowerCase()];
48266       if (!link || !link.href) {
48267         out += cap[0].charAt(0);
48268         src = cap[0].substring(1) + src;
48269         continue;
48270       }
48271       this.inLink = true;
48272       out += this.outputLink(cap, link);
48273       this.inLink = false;
48274       continue;
48275     }
48276
48277     // strong
48278     if (cap = this.rules.strong.exec(src)) {
48279       src = src.substring(cap[0].length);
48280       out += this.renderer.strong(this.output(cap[2] || cap[1]));
48281       continue;
48282     }
48283
48284     // em
48285     if (cap = this.rules.em.exec(src)) {
48286       src = src.substring(cap[0].length);
48287       out += this.renderer.em(this.output(cap[2] || cap[1]));
48288       continue;
48289     }
48290
48291     // code
48292     if (cap = this.rules.code.exec(src)) {
48293       src = src.substring(cap[0].length);
48294       out += this.renderer.codespan(escape(cap[2].trim(), true));
48295       continue;
48296     }
48297
48298     // br
48299     if (cap = this.rules.br.exec(src)) {
48300       src = src.substring(cap[0].length);
48301       out += this.renderer.br();
48302       continue;
48303     }
48304
48305     // del (gfm)
48306     if (cap = this.rules.del.exec(src)) {
48307       src = src.substring(cap[0].length);
48308       out += this.renderer.del(this.output(cap[1]));
48309       continue;
48310     }
48311
48312     // text
48313     if (cap = this.rules.text.exec(src)) {
48314       src = src.substring(cap[0].length);
48315       out += this.renderer.text(escape(this.smartypants(cap[0])));
48316       continue;
48317     }
48318
48319     if (src) {
48320       throw new
48321         Error('Infinite loop on byte: ' + src.charCodeAt(0));
48322     }
48323   }
48324
48325   return out;
48326 };
48327
48328 /**
48329  * Compile Link
48330  */
48331
48332 InlineLexer.prototype.outputLink = function(cap, link) {
48333   var href = escape(link.href)
48334     , title = link.title ? escape(link.title) : null;
48335
48336   return cap[0].charAt(0) !== '!'
48337     ? this.renderer.link(href, title, this.output(cap[1]))
48338     : this.renderer.image(href, title, escape(cap[1]));
48339 };
48340
48341 /**
48342  * Smartypants Transformations
48343  */
48344
48345 InlineLexer.prototype.smartypants = function(text) {
48346   if (!this.options.smartypants) return text;
48347   return text
48348     // em-dashes
48349     .replace(/---/g, '\u2014')
48350     // en-dashes
48351     .replace(/--/g, '\u2013')
48352     // opening singles
48353     .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
48354     // closing singles & apostrophes
48355     .replace(/'/g, '\u2019')
48356     // opening doubles
48357     .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
48358     // closing doubles
48359     .replace(/"/g, '\u201d')
48360     // ellipses
48361     .replace(/\.{3}/g, '\u2026');
48362 };
48363
48364 /**
48365  * Mangle Links
48366  */
48367
48368 InlineLexer.prototype.mangle = function(text) {
48369   if (!this.options.mangle) return text;
48370   var out = ''
48371     , l = text.length
48372     , i = 0
48373     , ch;
48374
48375   for (; i < l; i++) {
48376     ch = text.charCodeAt(i);
48377     if (Math.random() > 0.5) {
48378       ch = 'x' + ch.toString(16);
48379     }
48380     out += '&#' + ch + ';';
48381   }
48382
48383   return out;
48384 };
48385
48386 /**
48387  * Renderer
48388  */
48389
48390 function Renderer(options) {
48391   this.options = options || {};
48392 }
48393
48394 Renderer.prototype.code = function(code, lang, escaped) {
48395   if (this.options.highlight) {
48396     var out = this.options.highlight(code, lang);
48397     if (out != null && out !== code) {
48398       escaped = true;
48399       code = out;
48400     }
48401   }
48402
48403   if (!lang) {
48404     return '<pre><code>'
48405       + (escaped ? code : escape(code, true))
48406       + '\n</code></pre>';
48407   }
48408
48409   return '<pre><code class="'
48410     + this.options.langPrefix
48411     + escape(lang, true)
48412     + '">'
48413     + (escaped ? code : escape(code, true))
48414     + '\n</code></pre>\n';
48415 };
48416
48417 Renderer.prototype.blockquote = function(quote) {
48418   return '<blockquote>\n' + quote + '</blockquote>\n';
48419 };
48420
48421 Renderer.prototype.html = function(html) {
48422   return html;
48423 };
48424
48425 Renderer.prototype.heading = function(text, level, raw) {
48426   return '<h'
48427     + level
48428     + ' id="'
48429     + this.options.headerPrefix
48430     + raw.toLowerCase().replace(/[^\w]+/g, '-')
48431     + '">'
48432     + text
48433     + '</h'
48434     + level
48435     + '>\n';
48436 };
48437
48438 Renderer.prototype.hr = function() {
48439   return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
48440 };
48441
48442 Renderer.prototype.list = function(body, ordered) {
48443   var type = ordered ? 'ol' : 'ul';
48444   return '<' + type + '>\n' + body + '</' + type + '>\n';
48445 };
48446
48447 Renderer.prototype.listitem = function(text) {
48448   return '<li>' + text + '</li>\n';
48449 };
48450
48451 Renderer.prototype.paragraph = function(text) {
48452   return '<p>' + text + '</p>\n';
48453 };
48454
48455 Renderer.prototype.table = function(header, body) {
48456   return '<table>\n'
48457     + '<thead>\n'
48458     + header
48459     + '</thead>\n'
48460     + '<tbody>\n'
48461     + body
48462     + '</tbody>\n'
48463     + '</table>\n';
48464 };
48465
48466 Renderer.prototype.tablerow = function(content) {
48467   return '<tr>\n' + content + '</tr>\n';
48468 };
48469
48470 Renderer.prototype.tablecell = function(content, flags) {
48471   var type = flags.header ? 'th' : 'td';
48472   var tag = flags.align
48473     ? '<' + type + ' style="text-align:' + flags.align + '">'
48474     : '<' + type + '>';
48475   return tag + content + '</' + type + '>\n';
48476 };
48477
48478 // span level renderer
48479 Renderer.prototype.strong = function(text) {
48480   return '<strong>' + text + '</strong>';
48481 };
48482
48483 Renderer.prototype.em = function(text) {
48484   return '<em>' + text + '</em>';
48485 };
48486
48487 Renderer.prototype.codespan = function(text) {
48488   return '<code>' + text + '</code>';
48489 };
48490
48491 Renderer.prototype.br = function() {
48492   return this.options.xhtml ? '<br/>' : '<br>';
48493 };
48494
48495 Renderer.prototype.del = function(text) {
48496   return '<del>' + text + '</del>';
48497 };
48498
48499 Renderer.prototype.link = function(href, title, text) {
48500   if (this.options.sanitize) {
48501     try {
48502       var prot = decodeURIComponent(unescape(href))
48503         .replace(/[^\w:]/g, '')
48504         .toLowerCase();
48505     } catch (e) {
48506       return text;
48507     }
48508     if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
48509       return text;
48510     }
48511   }
48512   if (this.options.baseUrl && !originIndependentUrl.test(href)) {
48513     href = resolveUrl(this.options.baseUrl, href);
48514   }
48515   var out = '<a href="' + href + '"';
48516   if (title) {
48517     out += ' title="' + title + '"';
48518   }
48519   out += '>' + text + '</a>';
48520   return out;
48521 };
48522
48523 Renderer.prototype.image = function(href, title, text) {
48524   if (this.options.baseUrl && !originIndependentUrl.test(href)) {
48525     href = resolveUrl(this.options.baseUrl, href);
48526   }
48527   var out = '<img src="' + href + '" alt="' + text + '"';
48528   if (title) {
48529     out += ' title="' + title + '"';
48530   }
48531   out += this.options.xhtml ? '/>' : '>';
48532   return out;
48533 };
48534
48535 Renderer.prototype.text = function(text) {
48536   return text;
48537 };
48538
48539 /**
48540  * Parsing & Compiling
48541  */
48542
48543 function Parser(options) {
48544   this.tokens = [];
48545   this.token = null;
48546   this.options = options || marked.defaults;
48547   this.options.renderer = this.options.renderer || new Renderer;
48548   this.renderer = this.options.renderer;
48549   this.renderer.options = this.options;
48550 }
48551
48552 /**
48553  * Static Parse Method
48554  */
48555
48556 Parser.parse = function(src, options, renderer) {
48557   var parser = new Parser(options, renderer);
48558   return parser.parse(src);
48559 };
48560
48561 /**
48562  * Parse Loop
48563  */
48564
48565 Parser.prototype.parse = function(src) {
48566   this.inline = new InlineLexer(src.links, this.options, this.renderer);
48567   this.tokens = src.reverse();
48568
48569   var out = '';
48570   while (this.next()) {
48571     out += this.tok();
48572   }
48573
48574   return out;
48575 };
48576
48577 /**
48578  * Next Token
48579  */
48580
48581 Parser.prototype.next = function() {
48582   return this.token = this.tokens.pop();
48583 };
48584
48585 /**
48586  * Preview Next Token
48587  */
48588
48589 Parser.prototype.peek = function() {
48590   return this.tokens[this.tokens.length - 1] || 0;
48591 };
48592
48593 /**
48594  * Parse Text Tokens
48595  */
48596
48597 Parser.prototype.parseText = function() {
48598   var body = this.token.text;
48599
48600   while (this.peek().type === 'text') {
48601     body += '\n' + this.next().text;
48602   }
48603
48604   return this.inline.output(body);
48605 };
48606
48607 /**
48608  * Parse Current Token
48609  */
48610
48611 Parser.prototype.tok = function() {
48612   switch (this.token.type) {
48613     case 'space': {
48614       return '';
48615     }
48616     case 'hr': {
48617       return this.renderer.hr();
48618     }
48619     case 'heading': {
48620       return this.renderer.heading(
48621         this.inline.output(this.token.text),
48622         this.token.depth,
48623         this.token.text);
48624     }
48625     case 'code': {
48626       return this.renderer.code(this.token.text,
48627         this.token.lang,
48628         this.token.escaped);
48629     }
48630     case 'table': {
48631       var header = ''
48632         , body = ''
48633         , i
48634         , row
48635         , cell
48636         , flags
48637         , j;
48638
48639       // header
48640       cell = '';
48641       for (i = 0; i < this.token.header.length; i++) {
48642         flags = { header: true, align: this.token.align[i] };
48643         cell += this.renderer.tablecell(
48644           this.inline.output(this.token.header[i]),
48645           { header: true, align: this.token.align[i] }
48646         );
48647       }
48648       header += this.renderer.tablerow(cell);
48649
48650       for (i = 0; i < this.token.cells.length; i++) {
48651         row = this.token.cells[i];
48652
48653         cell = '';
48654         for (j = 0; j < row.length; j++) {
48655           cell += this.renderer.tablecell(
48656             this.inline.output(row[j]),
48657             { header: false, align: this.token.align[j] }
48658           );
48659         }
48660
48661         body += this.renderer.tablerow(cell);
48662       }
48663       return this.renderer.table(header, body);
48664     }
48665     case 'blockquote_start': {
48666       var body = '';
48667
48668       while (this.next().type !== 'blockquote_end') {
48669         body += this.tok();
48670       }
48671
48672       return this.renderer.blockquote(body);
48673     }
48674     case 'list_start': {
48675       var body = ''
48676         , ordered = this.token.ordered;
48677
48678       while (this.next().type !== 'list_end') {
48679         body += this.tok();
48680       }
48681
48682       return this.renderer.list(body, ordered);
48683     }
48684     case 'list_item_start': {
48685       var body = '';
48686
48687       while (this.next().type !== 'list_item_end') {
48688         body += this.token.type === 'text'
48689           ? this.parseText()
48690           : this.tok();
48691       }
48692
48693       return this.renderer.listitem(body);
48694     }
48695     case 'loose_item_start': {
48696       var body = '';
48697
48698       while (this.next().type !== 'list_item_end') {
48699         body += this.tok();
48700       }
48701
48702       return this.renderer.listitem(body);
48703     }
48704     case 'html': {
48705       var html = !this.token.pre && !this.options.pedantic
48706         ? this.inline.output(this.token.text)
48707         : this.token.text;
48708       return this.renderer.html(html);
48709     }
48710     case 'paragraph': {
48711       return this.renderer.paragraph(this.inline.output(this.token.text));
48712     }
48713     case 'text': {
48714       return this.renderer.paragraph(this.parseText());
48715     }
48716   }
48717 };
48718
48719 /**
48720  * Helpers
48721  */
48722
48723 function escape(html, encode) {
48724   return html
48725     .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&amp;')
48726     .replace(/</g, '&lt;')
48727     .replace(/>/g, '&gt;')
48728     .replace(/"/g, '&quot;')
48729     .replace(/'/g, '&#39;');
48730 }
48731
48732 function unescape(html) {
48733         // explicitly match decimal, hex, and named HTML entities
48734   return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig, function(_, n) {
48735     n = n.toLowerCase();
48736     if (n === 'colon') return ':';
48737     if (n.charAt(0) === '#') {
48738       return n.charAt(1) === 'x'
48739         ? String.fromCharCode(parseInt(n.substring(2), 16))
48740         : String.fromCharCode(+n.substring(1));
48741     }
48742     return '';
48743   });
48744 }
48745
48746 function replace(regex, opt) {
48747   regex = regex.source;
48748   opt = opt || '';
48749   return function self(name, val) {
48750     if (!name) return new RegExp(regex, opt);
48751     val = val.source || val;
48752     val = val.replace(/(^|[^\[])\^/g, '$1');
48753     regex = regex.replace(name, val);
48754     return self;
48755   };
48756 }
48757
48758 function resolveUrl(base, href) {
48759   if (!baseUrls[' ' + base]) {
48760     // we can ignore everything in base after the last slash of its path component,
48761     // but we might need to add _that_
48762     // https://tools.ietf.org/html/rfc3986#section-3
48763     if (/^[^:]+:\/*[^/]*$/.test(base)) {
48764       baseUrls[' ' + base] = base + '/';
48765     } else {
48766       baseUrls[' ' + base] = base.replace(/[^/]*$/, '');
48767     }
48768   }
48769   base = baseUrls[' ' + base];
48770
48771   if (href.slice(0, 2) === '//') {
48772     return base.replace(/:[\s\S]*/, ':') + href;
48773   } else if (href.charAt(0) === '/') {
48774     return base.replace(/(:\/*[^/]*)[\s\S]*/, '$1') + href;
48775   } else {
48776     return base + href;
48777   }
48778 }
48779 var baseUrls = {};
48780 var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
48781
48782 function noop() {}
48783 noop.exec = noop;
48784
48785 function merge(obj) {
48786   var i = 1
48787     , target
48788     , key;
48789
48790   for (; i < arguments.length; i++) {
48791     target = arguments[i];
48792     for (key in target) {
48793       if (Object.prototype.hasOwnProperty.call(target, key)) {
48794         obj[key] = target[key];
48795       }
48796     }
48797   }
48798
48799   return obj;
48800 }
48801
48802
48803 /**
48804  * Marked
48805  */
48806
48807 function marked(src, opt, callback) {
48808   if (callback || typeof opt === 'function') {
48809     if (!callback) {
48810       callback = opt;
48811       opt = null;
48812     }
48813
48814     opt = merge({}, marked.defaults, opt || {});
48815
48816     var highlight = opt.highlight
48817       , tokens
48818       , pending
48819       , i = 0;
48820
48821     try {
48822       tokens = Lexer.lex(src, opt);
48823     } catch (e) {
48824       return callback(e);
48825     }
48826
48827     pending = tokens.length;
48828
48829     var done = function(err) {
48830       if (err) {
48831         opt.highlight = highlight;
48832         return callback(err);
48833       }
48834
48835       var out;
48836
48837       try {
48838         out = Parser.parse(tokens, opt);
48839       } catch (e) {
48840         err = e;
48841       }
48842
48843       opt.highlight = highlight;
48844
48845       return err
48846         ? callback(err)
48847         : callback(null, out);
48848     };
48849
48850     if (!highlight || highlight.length < 3) {
48851       return done();
48852     }
48853
48854     delete opt.highlight;
48855
48856     if (!pending) return done();
48857
48858     for (; i < tokens.length; i++) {
48859       (function(token) {
48860         if (token.type !== 'code') {
48861           return --pending || done();
48862         }
48863         return highlight(token.text, token.lang, function(err, code) {
48864           if (err) return done(err);
48865           if (code == null || code === token.text) {
48866             return --pending || done();
48867           }
48868           token.text = code;
48869           token.escaped = true;
48870           --pending || done();
48871         });
48872       })(tokens[i]);
48873     }
48874
48875     return;
48876   }
48877   try {
48878     if (opt) opt = merge({}, marked.defaults, opt);
48879     return Parser.parse(Lexer.lex(src, opt), opt);
48880   } catch (e) {
48881     e.message += '\nPlease report this to https://github.com/chjj/marked.';
48882     if ((opt || marked.defaults).silent) {
48883       return '<p>An error occurred:</p><pre>'
48884         + escape(e.message + '', true)
48885         + '</pre>';
48886     }
48887     throw e;
48888   }
48889 }
48890
48891 /**
48892  * Options
48893  */
48894
48895 marked.options =
48896 marked.setOptions = function(opt) {
48897   merge(marked.defaults, opt);
48898   return marked;
48899 };
48900
48901 marked.defaults = {
48902   gfm: true,
48903   tables: true,
48904   breaks: false,
48905   pedantic: false,
48906   sanitize: false,
48907   sanitizer: null,
48908   mangle: true,
48909   smartLists: false,
48910   silent: false,
48911   highlight: null,
48912   langPrefix: 'lang-',
48913   smartypants: false,
48914   headerPrefix: '',
48915   renderer: new Renderer,
48916   xhtml: false,
48917   baseUrl: null
48918 };
48919
48920 /**
48921  * Expose
48922  */
48923
48924 marked.Parser = Parser;
48925 marked.parser = Parser.parse;
48926
48927 marked.Renderer = Renderer;
48928
48929 marked.Lexer = Lexer;
48930 marked.lexer = Lexer.lex;
48931
48932 marked.InlineLexer = InlineLexer;
48933 marked.inlineLexer = InlineLexer.output;
48934
48935 marked.parse = marked;
48936
48937 {
48938   module.exports = marked;
48939 }
48940
48941 }).call(function() {
48942   return this || (typeof window !== 'undefined' ? window : commonjsGlobal);
48943 }());
48944 });
48945
48946 function pointBox(loc, context) {
48947     var rect = context.surfaceRect();
48948     var point = context.curtainProjection(loc);
48949     return {
48950         left: point[0] + rect.left - 40,
48951         top: point[1] + rect.top - 60,
48952         width: 80,
48953         height: 90
48954     };
48955 }
48956
48957
48958 function pad$1(locOrBox, padding, context) {
48959     var box;
48960     if (locOrBox instanceof Array) {
48961         var rect = context.surfaceRect();
48962         var point = context.curtainProjection(locOrBox);
48963         box = {
48964             left: point[0] + rect.left,
48965             top: point[1] + rect.top
48966         };
48967     } else {
48968         box = locOrBox;
48969     }
48970
48971     return {
48972         left: box.left - padding,
48973         top: box.top - padding,
48974         width: (box.width || 0) + 2 * padding,
48975         height: (box.width || 0) + 2 * padding
48976     };
48977 }
48978
48979
48980 function icon(name, svgklass, useklass) {
48981     return '<svg class="icon ' + (svgklass || '') + '">' +
48982          '<use xlink:href="' + name + '"' +
48983          (useklass ? ' class="' + useklass + '"' : '') + '></use></svg>';
48984 }
48985
48986
48987 function slugify(text) {
48988     return text.toString().toLowerCase()
48989         .replace(/\s+/g, '-')           // Replace spaces with -
48990         .replace(/[^\w\-]+/g, '')       // Remove all non-word chars
48991         .replace(/\-\-+/g, '-')         // Replace multiple - with single -
48992         .replace(/^-+/, '')             // Trim - from start of text
48993         .replace(/-+$/, '');            // Trim - from end of text
48994 }
48995
48996
48997 // console warning for missing walkthrough names
48998 var missingStrings = {};
48999 function checkKey(key, text) {
49000     if (t(key, { default: undefined}) === undefined) {
49001         if (missingStrings.hasOwnProperty(key)) return;  // warn once
49002         missingStrings[key] = text;
49003         var missing = key + ': ' + text;
49004         if (typeof console !== 'undefined') console.log(missing); // eslint-disable-line
49005     }
49006 }
49007
49008
49009 function localize(obj) {
49010     var key;
49011
49012     // Assign name if entity has one..
49013     var name = obj.tags && obj.tags.name;
49014     if (name) {
49015         key = 'intro.graph.name.' + slugify(name);
49016         obj.tags.name = t(key, { default: name });
49017         checkKey(key, name);
49018     }
49019
49020     // Assign street name if entity has one..
49021     var street = obj.tags && obj.tags['addr:street'];
49022     if (street) {
49023         key = 'intro.graph.name.' + slugify(street);
49024         obj.tags['addr:street'] = t(key, { default: street });
49025         checkKey(key, street);
49026
49027         // Add address details common across walkthrough..
49028         var addrTags = [
49029             'block_number', 'city', 'county', 'district', 'hamlet', 'neighbourhood',
49030             'postcode', 'province', 'quarter', 'state', 'subdistrict', 'suburb'
49031         ];
49032         addrTags.forEach(function(k) {
49033             var key = 'intro.graph.' + k,
49034                 tag = 'addr:' + k,
49035                 val = obj.tags && obj.tags[tag],
49036                 str = t(key, { default: val });
49037
49038             if (str) {
49039                 if (str.match(/^<.*>$/) !== null) {
49040                     delete obj.tags[tag];
49041                 } else {
49042                     obj.tags[tag] = str;
49043                 }
49044             }
49045         });
49046     }
49047
49048     return obj;
49049 }
49050
49051
49052 // Used to detect squareness.. some duplicataion of code from actionOrthogonalize.
49053 function isMostlySquare(points) {
49054     // note: uses 15 here instead of the 12 from actionOrthogonalize because
49055     // actionOrthogonalize can actually straighten some larger angles as it iterates
49056     var threshold = 15, // degrees within right or straight
49057         lowerBound = Math.cos((90 - threshold) * Math.PI / 180),  // near right
49058         upperBound = Math.cos(threshold * Math.PI / 180),         // near straight
49059         mag;
49060
49061     for (var i = 0; i < points.length; i++) {
49062         mag = Math.abs(normalizedDotProduct(i, points));
49063         if (mag > lowerBound && mag < upperBound) {
49064             return false;
49065         }
49066     }
49067
49068     return true;
49069
49070
49071     function normalizedDotProduct(i, points) {
49072         var a = points[(i - 1 + points.length) % points.length],
49073             b = points[i],
49074             c = points[(i + 1) % points.length],
49075             p = subtractPoints(a, b),
49076             q = subtractPoints(c, b);
49077
49078         p = normalizePoint(p);
49079         q = normalizePoint(q);
49080
49081         return p[0] * q[0] + p[1] * q[1];
49082
49083
49084         function subtractPoints(a, b) {
49085             return [a[0] - b[0], a[1] - b[1]];
49086         }
49087
49088         function normalizePoint(point) {
49089             var vector = [0, 0];
49090             var length = Math.sqrt(point[0] * point[0] + point[1] * point[1]);
49091             if (length !== 0) {
49092                 vector[0] = point[0] / length;
49093                 vector[1] = point[1] / length;
49094             }
49095             return vector;
49096         }
49097     }
49098 }
49099
49100
49101 function selectMenuItem(operation) {
49102     var selector = '.edit-menu .edit-menu-item-' + operation +
49103         ', .radial-menu .radial-menu-item-' + operation;
49104     return d3_select(selector);
49105 }
49106
49107
49108 function transitionTime(point1, point2) {
49109     var distance = geoSphericalDistance(point1, point2);
49110     if (distance === 0)
49111         return 0;
49112     else if (distance < 80)
49113         return 500;
49114     else
49115         return 1000;
49116 }
49117
49118 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]}};
49119
49120 // Tooltips and svg mask used to highlight certain features
49121 function uiCurtain() {
49122
49123     var surface = d3_select(null),
49124         tooltip = d3_select(null),
49125         darkness = d3_select(null);
49126
49127     function curtain(selection) {
49128         surface = selection
49129             .append('svg')
49130             .attr('id', 'curtain')
49131             .style('z-index', 1000)
49132             .style('pointer-events', 'none')
49133             .style('position', 'absolute')
49134             .style('top', 0)
49135             .style('left', 0);
49136
49137         darkness = surface.append('path')
49138             .attr('x', 0)
49139             .attr('y', 0)
49140             .attr('class', 'curtain-darkness');
49141
49142         d3_select(window).on('resize.curtain', resize);
49143
49144         tooltip = selection.append('div')
49145             .attr('class', 'tooltip')
49146             .style('z-index', 1002);
49147
49148         tooltip
49149             .append('div')
49150             .attr('class', 'tooltip-arrow');
49151
49152         tooltip
49153             .append('div')
49154             .attr('class', 'tooltip-inner');
49155
49156         resize();
49157
49158
49159         function resize() {
49160             surface
49161                 .attr('width', window.innerWidth)
49162                 .attr('height', window.innerHeight);
49163             curtain.cut(darkness.datum());
49164         }
49165     }
49166
49167
49168     /**
49169      * Reveal cuts the curtain to highlight the given box,
49170      * and shows a tooltip with instructions next to the box.
49171      *
49172      * @param  {String|ClientRect} [box]   box used to cut the curtain
49173      * @param  {String}    [text]          text for a tooltip
49174      * @param  {Object}    [options]
49175      * @param  {string}    [options.tooltipClass]    optional class to add to the tooltip
49176      * @param  {integer}   [options.duration]        transition time in milliseconds
49177      * @param  {string}    [options.buttonText]      if set, create a button with this text label
49178      * @param  {function}  [options.buttonCallback]  if set, the callback for the button
49179      * @param  {String|ClientRect} [options.tooltipBox]  box for tooltip position, if different from box for the curtain
49180      */
49181     curtain.reveal = function(box, text, options) {
49182         if (typeof box === 'string') {
49183             box = d3_select(box).node();
49184         }
49185         if (box && box.getBoundingClientRect) {
49186             box = copyBox(box.getBoundingClientRect());
49187         }
49188
49189         options = options || {};
49190
49191         var tooltipBox;
49192         if (options.tooltipBox) {
49193             tooltipBox = options.tooltipBox;
49194             if (typeof tooltipBox === 'string') {
49195                 tooltipBox = d3_select(tooltipBox).node();
49196             }
49197             if (tooltipBox && tooltipBox.getBoundingClientRect) {
49198                 tooltipBox = copyBox(tooltipBox.getBoundingClientRect());
49199             }
49200         } else {
49201             tooltipBox = box;
49202         }
49203
49204         if (tooltipBox && text) {
49205             // pseudo markdown bold text for the instruction section..
49206             var parts = text.split('**');
49207             var html = parts[0] ? '<span>' + parts[0] + '</span>' : '';
49208             if (parts[1]) {
49209                 html += '<span class="instruction">' + parts[1] + '</span>';
49210             }
49211
49212             html = html.replace(/\*(.*?)\*/g, '<em>$1</em>');   // emphasis
49213             html = html.replace(/\{br\}/g, '<br/><br/>');       // linebreak
49214
49215             if (options.buttonText && options.buttonCallback) {
49216                 html += '<div class="button-section">' +
49217                     '<button href="#" class="button action col8">' + options.buttonText + '</button></div>';
49218             }
49219
49220             var classes = 'curtain-tooltip tooltip in ' + (options.tooltipClass || '');
49221             tooltip
49222                 .classed(classes, true)
49223                 .selectAll('.tooltip-inner')
49224                 .html(html);
49225
49226             if (options.buttonText && options.buttonCallback) {
49227                 var button = tooltip.selectAll('.button-section .button.action');
49228                 button
49229                     .on('click', function() {
49230                         event.preventDefault();
49231                         options.buttonCallback();
49232                     });
49233             }
49234
49235             var tip = copyBox(tooltip.node().getBoundingClientRect()),
49236                 w = window.innerWidth,
49237                 h = window.innerHeight,
49238                 tooltipWidth = 200,
49239                 tooltipArrow = 5,
49240                 side, pos;
49241
49242
49243             // hack: this will have bottom placement,
49244             // so need to reserve extra space for the tooltip illustration.
49245             if (options.tooltipClass === 'intro-mouse') {
49246                 tip.height += 80;
49247             }
49248
49249             // trim box dimensions to just the portion that fits in the window..
49250             if (tooltipBox.top + tooltipBox.height > h) {
49251                 tooltipBox.height -= (tooltipBox.top + tooltipBox.height - h);
49252             }
49253             if (tooltipBox.left + tooltipBox.width > w) {
49254                 tooltipBox.width -= (tooltipBox.left + tooltipBox.width - w);
49255             }
49256
49257             // determine tooltip placement..
49258
49259             if (tooltipBox.top + tooltipBox.height < 100) {
49260                 // tooltip below box..
49261                 side = 'bottom';
49262                 pos = [
49263                     tooltipBox.left + tooltipBox.width / 2 - tip.width / 2,
49264                     tooltipBox.top + tooltipBox.height
49265                 ];
49266
49267             } else if (tooltipBox.top > h - 140) {
49268                 // tooltip above box..
49269                 side = 'top';
49270                 pos = [
49271                     tooltipBox.left + tooltipBox.width / 2 - tip.width / 2,
49272                     tooltipBox.top - tip.height
49273                 ];
49274
49275             } else {
49276                 // tooltip to the side of the tooltipBox..
49277                 var tipY = tooltipBox.top + tooltipBox.height / 2 - tip.height / 2;
49278
49279                 if (textDirection === 'rtl') {
49280                     if (tooltipBox.left - tooltipWidth - tooltipArrow < 70) {
49281                         side = 'right';
49282                         pos = [tooltipBox.left + tooltipBox.width + tooltipArrow, tipY];
49283
49284                     } else {
49285                         side = 'left';
49286                         pos = [tooltipBox.left - tooltipWidth - tooltipArrow, tipY];
49287                     }
49288
49289                 } else {
49290                     if (tooltipBox.left + tooltipBox.width + tooltipArrow + tooltipWidth > w - 70) {
49291                         side = 'left';
49292                         pos = [tooltipBox.left - tooltipWidth - tooltipArrow, tipY];
49293                     }
49294                     else {
49295                         side = 'right';
49296                         pos = [tooltipBox.left + tooltipBox.width + tooltipArrow, tipY];
49297                     }
49298                 }
49299             }
49300
49301             if (options.duration !== 0 || !tooltip.classed(side)) {
49302                 tooltip.call(uiToggle(true));
49303             }
49304
49305             tooltip
49306                 .style('top', pos[1] + 'px')
49307                 .style('left', pos[0] + 'px')
49308                 .attr('class', classes + ' ' + side);
49309
49310
49311             // shift tooltip-inner if it is very close to the top or bottom edge
49312             // (doesn't affect the placement of the tooltip-arrow)
49313             var shiftY = 0;
49314             if (side === 'left' || side === 'right') {
49315                 if (pos[1] < 60) {
49316                     shiftY = 60 - pos[1];
49317                 }
49318                 else if (pos[1] + tip.height > h - 100) {
49319                     shiftY = h - pos[1] - tip.height - 100;
49320                 }
49321             }
49322             tooltip.selectAll('.tooltip-inner')
49323                 .style('top', shiftY + 'px');
49324
49325         } else {
49326             tooltip
49327                 .classed('in', false)
49328                 .call(uiToggle(false));
49329         }
49330
49331         curtain.cut(box, options.duration);
49332
49333         return tooltip;
49334     };
49335
49336
49337     curtain.cut = function(datum, duration) {
49338         darkness.datum(datum)
49339             .interrupt();
49340
49341         var selection;
49342         if (duration === 0) {
49343             selection = darkness;
49344         } else {
49345             selection = darkness
49346                 .transition()
49347                 .duration(duration || 600)
49348                 .ease(linear$1);
49349         }
49350
49351         selection
49352             .attr('d', function(d) {
49353                 var string = 'M 0,0 L 0,' + window.innerHeight + ' L ' +
49354                     window.innerWidth + ',' + window.innerHeight + 'L' +
49355                     window.innerWidth + ',0 Z';
49356
49357                 if (!d) return string;
49358                 return string + 'M' +
49359                     d.left + ',' + d.top + 'L' +
49360                     d.left + ',' + (d.top + d.height) + 'L' +
49361                     (d.left + d.width) + ',' + (d.top + d.height) + 'L' +
49362                     (d.left + d.width) + ',' + (d.top) + 'Z';
49363
49364             });
49365     };
49366
49367
49368     curtain.remove = function() {
49369         surface.remove();
49370         tooltip.remove();
49371         d3_select(window).on('resize.curtain', null);
49372     };
49373
49374
49375     // ClientRects are immutable, so copy them to an object,
49376     // in case we need to trim the height/width.
49377     function copyBox(src) {
49378         return {
49379             top: src.top,
49380             right: src.right,
49381             bottom: src.bottom,
49382             left: src.left,
49383             width: src.width,
49384             height: src.height
49385         };
49386     }
49387
49388
49389     return curtain;
49390 }
49391
49392 function uiIntroWelcome(context, reveal) {
49393     var dispatch$$1 = dispatch('done'),
49394         listener = clickListener();
49395
49396     var chapter = {
49397         title: 'intro.welcome.title'
49398     };
49399
49400
49401     function welcome() {
49402         context.map().centerZoom([-85.63591, 41.94285], 19);
49403         reveal('.intro-nav-wrap .chapter-welcome',
49404             t('intro.welcome.welcome'),
49405             { buttonText: t('intro.ok'), buttonCallback: practice }
49406         );
49407     }
49408
49409     function practice() {
49410         reveal('.intro-nav-wrap .chapter-welcome',
49411             t('intro.welcome.practice'),
49412             { buttonText: t('intro.ok'), buttonCallback: words }
49413         );
49414     }
49415
49416     function words() {
49417         reveal('.intro-nav-wrap .chapter-welcome',
49418             t('intro.welcome.words'),
49419             { buttonText: t('intro.ok'), buttonCallback: mouse }
49420         );
49421     }
49422
49423
49424     function mouse() {
49425         reveal('.intro-nav-wrap .chapter-welcome',
49426             t('intro.welcome.mouse'),
49427             { buttonText: t('intro.ok'), buttonCallback: leftClick }
49428         );
49429     }
49430
49431
49432     function leftClick() {
49433         var counter = 0,
49434             times = 5;
49435
49436         var tooltip = reveal('.intro-nav-wrap .chapter-welcome',
49437             t('intro.welcome.leftclick', { num: times }),
49438             { tooltipClass: 'intro-mouse' }
49439         );
49440
49441         tooltip.selectAll('.tooltip-inner')
49442             .insert('svg', 'span')
49443             .attr('class', 'tooltip-illustration')
49444             .append('use')
49445             .attr('xlink:href', '#walkthrough-mouse');
49446
49447         tooltip
49448             .append('div')
49449             .attr('class', 'counter');
49450
49451         tooltip.call(listener);
49452
49453         listener.on('click', function(which) {
49454             if (which === 'left') {
49455                 d3_select('.curtain-tooltip.intro-mouse .counter')
49456                     .text(String(++counter));
49457
49458                 if (counter === times) {
49459                     window.setTimeout(function() { continueTo(rightClick); }, 1000);
49460                 }
49461             }
49462         });
49463
49464         function continueTo(nextStep) {
49465             listener.on('click', null);
49466             tooltip.call(listener.off);
49467             tooltip.select('.counter').remove();
49468             nextStep();
49469         }
49470     }
49471
49472
49473     function rightClick() {
49474         var counter = 0,
49475             times = 5;
49476
49477         var tooltip = reveal('.intro-nav-wrap .chapter-welcome',
49478             t('intro.welcome.rightclick', { num: times }),
49479             { tooltipClass: 'intro-mouse' }
49480         );
49481
49482         tooltip.selectAll('.tooltip-inner')
49483             .insert('svg', 'span')
49484             .attr('class', 'tooltip-illustration')
49485             .append('use')
49486             .attr('xlink:href', '#walkthrough-mouse');
49487
49488         tooltip
49489             .append('div')
49490             .attr('class', 'counter');
49491
49492         tooltip.call(listener);
49493
49494         listener.on('click', function(which) {
49495             if (which === 'right') {
49496                 d3_select('.curtain-tooltip.intro-mouse .counter')
49497                     .text(String(++counter));
49498
49499                 if (counter === times) {
49500                     window.setTimeout(function() { continueTo(chapters); }, 1000);
49501                 }
49502             }
49503         });
49504
49505         function continueTo(nextStep) {
49506             listener.on('click', null);
49507             tooltip.call(listener.off);
49508             tooltip.select('.counter').remove();
49509             nextStep();
49510         }
49511     }
49512
49513
49514     function chapters() {
49515         dispatch$$1.call('done');
49516         reveal('.intro-nav-wrap .chapter-navigation',
49517             t('intro.welcome.chapters', { next: t('intro.navigation.title') })
49518         );
49519     }
49520
49521
49522     chapter.enter = function() {
49523         welcome();
49524     };
49525
49526
49527     chapter.exit = function() {
49528         listener.off();
49529         d3_select('.curtain-tooltip.intro-mouse')
49530             .selectAll('.counter')
49531             .remove();
49532     };
49533
49534
49535     chapter.restart = function() {
49536         chapter.exit();
49537         chapter.enter();
49538     };
49539
49540
49541     return utilRebind(chapter, dispatch$$1, 'on');
49542 }
49543
49544
49545
49546 function clickListener() {
49547     var dispatch$$1 = dispatch('click'),
49548         minTime = 120,
49549         tooltip = d3_select(null),
49550         down = {};
49551
49552     // `down` keeps track of which buttons/keys are down.
49553     // Setting a property in `down` happens immediately.
49554     // Unsetting a property in `down` is delayed because
49555     //   on Windows a contextmenu event happens after keyup/mouseup
49556
49557     function keydown() {
49558         if (event.keyCode === 93)  {   // context menu
49559             event.preventDefault();
49560             event.stopPropagation();
49561             down.menu = event.timeStamp;
49562             tooltip.classed('rightclick', true);
49563         }
49564     }
49565
49566
49567     function keyup() {
49568         if (event.keyCode === 93)  {   // context menu
49569             event.preventDefault();
49570             event.stopPropagation();
49571             var endTime = event.timeStamp,
49572                 startTime = down.menu || endTime,
49573                 delay = (endTime - startTime < minTime) ? minTime : 0;
49574
49575             window.setTimeout(function() {
49576                 tooltip.classed('rightclick', false);
49577                 down.menu = undefined;  // delayed, for Windows
49578             }, delay);
49579
49580             dispatch$$1.call('click', this, 'right');
49581         }
49582     }
49583
49584
49585     function mousedown() {
49586         var button = event.button;
49587         if (button === 0 && !event.ctrlKey) {
49588             tooltip.classed('leftclick', true);
49589         } else if (button === 2) {
49590             tooltip.classed('rightclick', true);
49591         }
49592         down[button] = event.timeStamp;
49593     }
49594
49595
49596     function mouseup() {
49597         var button = event.button,
49598             endTime = event.timeStamp,
49599             startTime = down[button] || endTime,
49600             delay = (endTime - startTime < minTime) ? minTime : 0;
49601
49602         if (button === 0 && !event.ctrlKey) {
49603             window.setTimeout(function() {
49604                 tooltip.classed('leftclick', false);
49605                 down[button] = undefined;  // delayed, for Windows
49606             }, delay);
49607
49608             dispatch$$1.call('click', this, 'left');
49609
49610         } else if (button === 2) {
49611             window.setTimeout(function() {
49612                 tooltip.classed('rightclick', false);
49613                 down[button] = undefined;  // delayed, for Windows
49614             }, delay);
49615
49616             dispatch$$1.call('click', this, 'right');
49617
49618         } else {
49619             window.setTimeout(function() {
49620                 down[button] = undefined;  // delayed, for Windows
49621             }, delay);
49622         }
49623     }
49624
49625
49626     function contextmenu() {
49627         event.preventDefault();
49628         event.stopPropagation();
49629         if (!down[2] && !down.menu) {
49630             tooltip.classed('rightclick', true);
49631             window.setTimeout(function() {
49632                 tooltip.classed('rightclick', false);
49633             }, minTime);
49634             dispatch$$1.call('click', this, 'right');
49635         }
49636     }
49637
49638
49639     var behavior = function(selection) {
49640         tooltip = selection;
49641         down = {};
49642
49643         d3_select(window)
49644             .on('keydown.intro', keydown)
49645             .on('keyup.intro', keyup)
49646             .on('mousedown.intro', mousedown)
49647             .on('mouseup.intro', mouseup)
49648             .on('contextmenu.intro', contextmenu);
49649     };
49650
49651
49652     behavior.off = function() {
49653         d3_select(window)
49654             .on('keydown.intro', null)
49655             .on('keyup.intro', null)
49656             .on('mousedown.intro', null)
49657             .on('mouseup.intro', null)
49658             .on('contextmenu.intro', null);
49659
49660         tooltip
49661             .classed('leftclick', false)
49662             .classed('rightclick', false);
49663     };
49664
49665     return utilRebind(behavior, dispatch$$1, 'on');
49666 }
49667
49668 function uiIntroNavigation(context, reveal) {
49669     var dispatch$$1 = dispatch('done'),
49670         timeouts = [],
49671         hallId = 'n2061',
49672         townHall = [-85.63591, 41.94285],
49673         springStreetId = 'w397',
49674         springStreetEndId = 'n1834',
49675         springStreet = [-85.63582, 41.94255],
49676         onewayField = context.presets().field('oneway'),
49677         maxspeedField = context.presets().field('maxspeed');
49678
49679
49680     var chapter = {
49681         title: 'intro.navigation.title'
49682     };
49683
49684
49685     function timeout(f, t$$1) {
49686         timeouts.push(window.setTimeout(f, t$$1));
49687     }
49688
49689
49690     function eventCancel() {
49691         event.stopPropagation();
49692         event.preventDefault();
49693     }
49694
49695
49696     function isTownHallSelected() {
49697         var ids = context.selectedIDs();
49698         return ids.length === 1 && ids[0] === hallId;
49699     }
49700
49701
49702     function dragMap() {
49703         context.enter(modeBrowse(context));
49704         context.history().reset('initial');
49705
49706         var msec = transitionTime(townHall, context.map().center());
49707         if (msec) { reveal(null, null, { duration: 0 }); }
49708         context.map().zoom(19).centerEase(townHall, msec);
49709
49710         timeout(function() {
49711             var centerStart = context.map().center();
49712
49713             reveal('#surface', t('intro.navigation.drag'));
49714             context.map().on('drawn.intro', function() {
49715                 reveal('#surface', t('intro.navigation.drag'), { duration: 0 });
49716             });
49717
49718             context.map().on('move.intro', function() {
49719                 var centerNow = context.map().center();
49720                 if (centerStart[0] !== centerNow[0] || centerStart[1] !== centerNow[1]) {
49721                     context.map().on('move.intro', null);
49722                     timeout(function() { continueTo(zoomMap); }, 3000);
49723                 }
49724             });
49725
49726         }, msec + 100);
49727
49728         function continueTo(nextStep) {
49729             context.map().on('move.intro drawn.intro', null);
49730             nextStep();
49731         }
49732     }
49733
49734
49735     function zoomMap() {
49736         var zoomStart = context.map().zoom();
49737
49738         reveal('#surface',
49739             t('intro.navigation.zoom', {
49740                 plus: icon('#icon-plus', 'pre-text'),
49741                 minus: icon('#icon-minus', 'pre-text')
49742             })
49743         );
49744
49745         context.map().on('drawn.intro', function() {
49746             reveal('#surface',
49747                 t('intro.navigation.zoom', {
49748                     plus: icon('#icon-plus', 'pre-text'),
49749                     minus: icon('#icon-minus', 'pre-text')
49750                 }), { duration: 0 }
49751             );
49752         });
49753
49754         context.map().on('move.intro', function() {
49755             if (context.map().zoom() !== zoomStart) {
49756                 context.map().on('move.intro', null);
49757                 timeout(function() { continueTo(features); }, 3000);
49758             }
49759         });
49760
49761         function continueTo(nextStep) {
49762             context.map().on('move.intro drawn.intro', null);
49763             nextStep();
49764         }
49765     }
49766
49767
49768     function features() {
49769         var onClick = function() { continueTo(pointsLinesAreas); };
49770
49771         reveal('#surface', t('intro.navigation.features'),
49772             { buttonText: t('intro.ok'), buttonCallback: onClick }
49773         );
49774
49775         context.map().on('drawn.intro', function() {
49776             reveal('#surface', t('intro.navigation.features'),
49777                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
49778             );
49779         });
49780
49781         function continueTo(nextStep) {
49782             context.map().on('drawn.intro', null);
49783             nextStep();
49784         }
49785     }
49786
49787     function pointsLinesAreas() {
49788         var onClick = function() { continueTo(nodesWays); };
49789
49790         reveal('#surface', t('intro.navigation.points_lines_areas'),
49791             { buttonText: t('intro.ok'), buttonCallback: onClick }
49792         );
49793
49794         context.map().on('drawn.intro', function() {
49795             reveal('#surface', t('intro.navigation.points_lines_areas'),
49796                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
49797             );
49798         });
49799
49800         function continueTo(nextStep) {
49801             context.map().on('drawn.intro', null);
49802             nextStep();
49803         }
49804     }
49805
49806     function nodesWays() {
49807         var onClick = function() { continueTo(clickTownHall); };
49808
49809         reveal('#surface', t('intro.navigation.nodes_ways'),
49810             { buttonText: t('intro.ok'), buttonCallback: onClick }
49811         );
49812
49813         context.map().on('drawn.intro', function() {
49814             reveal('#surface', t('intro.navigation.nodes_ways'),
49815                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
49816             );
49817         });
49818
49819         function continueTo(nextStep) {
49820             context.map().on('drawn.intro', null);
49821             nextStep();
49822         }
49823     }
49824
49825     function clickTownHall() {
49826         context.enter(modeBrowse(context));
49827         context.history().reset('initial');
49828
49829         reveal(null, null, { duration: 0 });
49830         context.map().zoomEase(19, 500);
49831
49832         timeout(function() {
49833             var entity = context.hasEntity(hallId);
49834             if (!entity) return;
49835             context.map().centerEase(entity.loc, 500);
49836
49837             timeout(function() {
49838                 var entity = context.hasEntity(hallId);
49839                 if (!entity) return;
49840                 var box = pointBox(entity.loc, context);
49841                 reveal(box, t('intro.navigation.click_townhall'));
49842
49843                 context.map().on('move.intro drawn.intro', function() {
49844                     var entity = context.hasEntity(hallId);
49845                     if (!entity) return;
49846                     var box = pointBox(entity.loc, context);
49847                     reveal(box, t('intro.navigation.click_townhall'), { duration: 0 });
49848                 });
49849
49850                 context.on('enter.intro', function() {
49851                     if (isTownHallSelected()) continueTo(selectedTownHall);
49852                 });
49853
49854             }, 550);  // after centerEase
49855
49856         }, 550); // after zoomEase
49857
49858         context.history().on('change.intro', function() {
49859             if (!context.hasEntity(hallId)) {
49860                 continueTo(clickTownHall);
49861             }
49862         });
49863
49864         function continueTo(nextStep) {
49865             context.on('enter.intro', null);
49866             context.map().on('move.intro drawn.intro', null);
49867             context.history().on('change.intro', null);
49868             nextStep();
49869         }
49870     }
49871
49872
49873     function selectedTownHall() {
49874         if (!isTownHallSelected()) return clickTownHall();
49875
49876         var entity = context.hasEntity(hallId);
49877         if (!entity) return clickTownHall();
49878
49879         var box = pointBox(entity.loc, context);
49880         var onClick = function() { continueTo(editorTownHall); };
49881
49882         reveal(box, t('intro.navigation.selected_townhall'),
49883             { buttonText: t('intro.ok'), buttonCallback: onClick }
49884         );
49885
49886         context.map().on('move.intro drawn.intro', function() {
49887             var entity = context.hasEntity(hallId);
49888             if (!entity) return;
49889             var box = pointBox(entity.loc, context);
49890             reveal(box, t('intro.navigation.selected_townhall'),
49891                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
49892             );
49893         });
49894
49895         context.history().on('change.intro', function() {
49896             if (!context.hasEntity(hallId)) {
49897                 continueTo(clickTownHall);
49898             }
49899         });
49900
49901         function continueTo(nextStep) {
49902             context.map().on('move.intro drawn.intro', null);
49903             context.history().on('change.intro', null);
49904             nextStep();
49905         }
49906     }
49907
49908
49909     function editorTownHall() {
49910         if (!isTownHallSelected()) return clickTownHall();
49911
49912         // disallow scrolling
49913         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
49914
49915         var onClick = function() { continueTo(presetTownHall); };
49916
49917         reveal('.entity-editor-pane',
49918             t('intro.navigation.editor_townhall'),
49919             { buttonText: t('intro.ok'), buttonCallback: onClick }
49920         );
49921
49922         context.on('exit.intro', function() {
49923             continueTo(clickTownHall);
49924         });
49925
49926         context.history().on('change.intro', function() {
49927             if (!context.hasEntity(hallId)) {
49928                 continueTo(clickTownHall);
49929             }
49930         });
49931
49932         function continueTo(nextStep) {
49933             context.on('exit.intro', null);
49934             context.history().on('change.intro', null);
49935             d3_select('.inspector-wrap').on('wheel.intro', null);
49936             nextStep();
49937         }
49938     }
49939
49940
49941     function presetTownHall() {
49942         if (!isTownHallSelected()) return clickTownHall();
49943
49944         // reset pane, in case user happened to change it..
49945         d3_select('.inspector-wrap .panewrap').style('right', '0%');
49946         // disallow scrolling
49947         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
49948
49949         // preset match, in case the user happened to change it.
49950         var entity = context.entity(context.selectedIDs()[0]);
49951         var preset = context.presets().match(entity, context.graph());
49952
49953         var onClick = function() { continueTo(fieldsTownHall); };
49954
49955         context.on('exit.intro', function() {
49956             continueTo(clickTownHall);
49957         });
49958
49959         context.history().on('change.intro', function() {
49960             if (!context.hasEntity(hallId)) {
49961                 continueTo(clickTownHall);
49962             }
49963         });
49964
49965         reveal('.inspector-body .preset-list-item.inspector-inner',
49966             t('intro.navigation.preset_townhall', { preset: preset.name() }),
49967             { buttonText: t('intro.ok'), buttonCallback: onClick }
49968         );
49969
49970         function continueTo(nextStep) {
49971             context.on('exit.intro', null);
49972             context.history().on('change.intro', null);
49973             d3_select('.inspector-wrap').on('wheel.intro', null);
49974             nextStep();
49975         }
49976     }
49977
49978
49979     function fieldsTownHall() {
49980         if (!isTownHallSelected()) return clickTownHall();
49981
49982         // reset pane, in case user happened to change it..
49983         d3_select('.inspector-wrap .panewrap').style('right', '0%');
49984         // disallow scrolling
49985         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
49986
49987         var onClick = function() { continueTo(closeTownHall); };
49988
49989         reveal('.inspector-body .preset-editor',
49990             t('intro.navigation.fields_townhall'),
49991             { buttonText: t('intro.ok'), buttonCallback: onClick }
49992         );
49993
49994         context.on('exit.intro', function() {
49995             continueTo(clickTownHall);
49996         });
49997
49998         context.history().on('change.intro', function() {
49999             if (!context.hasEntity(hallId)) {
50000                 continueTo(clickTownHall);
50001             }
50002         });
50003
50004         function continueTo(nextStep) {
50005             context.on('exit.intro', null);
50006             context.history().on('change.intro', null);
50007             d3_select('.inspector-wrap').on('wheel.intro', null);
50008             nextStep();
50009         }
50010     }
50011
50012
50013     function closeTownHall() {
50014         if (!isTownHallSelected()) return clickTownHall();
50015
50016         var selector = '.entity-editor-pane button.preset-close svg use';
50017         var href = d3_select(selector).attr('href') || '#icon-close';
50018
50019         reveal('.entity-editor-pane',
50020             t('intro.navigation.close_townhall', { button: icon(href, 'pre-text') })
50021         );
50022
50023         context.on('exit.intro', function() {
50024             continueTo(searchStreet);
50025         });
50026
50027         context.history().on('change.intro', function() {
50028             // update the close icon in the tooltip if the user edits something.
50029             var selector = '.entity-editor-pane button.preset-close svg use';
50030             var href = d3_select(selector).attr('href') || '#icon-close';
50031
50032             reveal('.entity-editor-pane',
50033                 t('intro.navigation.close_townhall', { button: icon(href, 'pre-text') }),
50034                 { duration: 0 }
50035             );
50036         });
50037
50038         function continueTo(nextStep) {
50039             context.on('exit.intro', null);
50040             context.history().on('change.intro', null);
50041             nextStep();
50042         }
50043     }
50044
50045
50046     function searchStreet() {
50047         context.enter(modeBrowse(context));
50048         context.history().reset('initial');  // ensure spring street exists
50049
50050         var msec = transitionTime(springStreet, context.map().center());
50051         if (msec) { reveal(null, null, { duration: 0 }); }
50052         context.map().zoom(19).centerEase(springStreet, msec);  // ..and user can see it
50053
50054         timeout(function() {
50055             reveal('.search-header input',
50056                 t('intro.navigation.search_street', { name: t('intro.graph.name.spring-street') })
50057             );
50058
50059             d3_select('.search-header input')
50060                 .on('keyup.intro', checkSearchResult);
50061         }, msec + 100);
50062     }
50063
50064
50065     function checkSearchResult() {
50066         var first = d3_select('.feature-list-item:nth-child(0n+2)'),  // skip "No Results" item
50067             firstName = first.select('.entity-name'),
50068             name = t('intro.graph.name.spring-street');
50069
50070         if (!firstName.empty() && firstName.text() === name) {
50071             reveal(first.node(),
50072                 t('intro.navigation.choose_street', { name: name }),
50073                 { duration: 300 }
50074             );
50075
50076             context.on('exit.intro', function() {
50077                 continueTo(selectedStreet);
50078             });
50079
50080             d3_select('.search-header input')
50081                 .on('keydown.intro', eventCancel, true)
50082                 .on('keyup.intro', null);
50083         }
50084
50085         function continueTo(nextStep) {
50086             context.on('exit.intro', null);
50087             d3_select('.search-header input')
50088                 .on('keydown.intro', null)
50089                 .on('keyup.intro', null);
50090             nextStep();
50091         }
50092     }
50093
50094
50095     function selectedStreet() {
50096         if (!context.hasEntity(springStreetEndId) || !context.hasEntity(springStreetId)) {
50097             return searchStreet();
50098         }
50099
50100         var onClick = function() { continueTo(editorStreet); };
50101         var entity = context.entity(springStreetEndId);
50102         var box = pointBox(entity.loc, context);
50103         box.height = 500;
50104
50105         reveal(box,
50106             t('intro.navigation.selected_street', { name: t('intro.graph.name.spring-street') }),
50107             { duration: 600, buttonText: t('intro.ok'), buttonCallback: onClick }
50108         );
50109
50110         timeout(function() {
50111             context.map().on('move.intro drawn.intro', function() {
50112                 var entity = context.hasEntity(springStreetEndId);
50113                 if (!entity) return;
50114                 var box = pointBox(entity.loc, context);
50115                 box.height = 500;
50116                 reveal(box,
50117                     t('intro.navigation.selected_street', { name: t('intro.graph.name.spring-street') }),
50118                     { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
50119                 );
50120             });
50121         }, 600);  // after reveal.
50122
50123         context.on('enter.intro', function(mode) {
50124             if (!context.hasEntity(springStreetId)) {
50125                 return continueTo(searchStreet);
50126             }
50127             var ids = context.selectedIDs();
50128             if (mode.id !== 'select' || !ids.length || ids[0] !== springStreetId) {
50129                 // keep Spring Street selected..
50130                 context.enter(modeSelect(context, [springStreetId]));
50131             }
50132         });
50133
50134         context.history().on('change.intro', function() {
50135             if (!context.hasEntity(springStreetEndId) || !context.hasEntity(springStreetId)) {
50136                 timeout(function() {
50137                     continueTo(searchStreet);
50138                 }, 300);  // after any transition (e.g. if user deleted intersection)
50139             }
50140         });
50141
50142         function continueTo(nextStep) {
50143             context.map().on('move.intro drawn.intro', null);
50144             context.on('enter.intro', null);
50145             context.history().on('change.intro', null);
50146             nextStep();
50147         }
50148     }
50149
50150
50151     function editorStreet() {
50152         var selector = '.entity-editor-pane button.preset-close svg use';
50153         var href = d3_select(selector).attr('href') || '#icon-close';
50154
50155         reveal('.entity-editor-pane',
50156             t('intro.navigation.editor_street', {
50157                 button: icon(href, 'pre-text'),
50158                 field1: onewayField.label(),
50159                 field2: maxspeedField.label()
50160             })
50161         );
50162
50163         context.on('exit.intro', function() {
50164             continueTo(play);
50165         });
50166
50167         context.history().on('change.intro', function() {
50168             // update the close icon in the tooltip if the user edits something.
50169             var selector = '.entity-editor-pane button.preset-close svg use';
50170             var href = d3_select(selector).attr('href') || '#icon-close';
50171
50172             reveal('.entity-editor-pane',
50173                 t('intro.navigation.editor_street', {
50174                     button: icon(href, 'pre-text'),
50175                     field1: onewayField.label().toLowerCase(),
50176                     field2: maxspeedField.label().toLowerCase()
50177                 }), { duration: 0 }
50178             );
50179         });
50180
50181         function continueTo(nextStep) {
50182             context.on('exit.intro', null);
50183             context.history().on('change.intro', null);
50184             nextStep();
50185         }
50186     }
50187
50188
50189     function play() {
50190         dispatch$$1.call('done');
50191         reveal('#id-container',
50192             t('intro.navigation.play', { next: t('intro.points.title') }), {
50193                 tooltipBox: '.intro-nav-wrap .chapter-point',
50194                 buttonText: t('intro.ok'),
50195                 buttonCallback: function() { reveal('#id-container'); }
50196             }
50197         );
50198     }
50199
50200
50201     chapter.enter = function() {
50202         dragMap();
50203     };
50204
50205
50206     chapter.exit = function() {
50207         timeouts.forEach(window.clearTimeout);
50208         context.on('enter.intro exit.intro', null);
50209         context.map().on('move.intro drawn.intro', null);
50210         context.history().on('change.intro', null);
50211         d3_select('.inspector-wrap').on('wheel.intro', null);
50212         d3_select('.search-header input').on('keydown.intro keyup.intro', null);
50213     };
50214
50215
50216     chapter.restart = function() {
50217         chapter.exit();
50218         chapter.enter();
50219     };
50220
50221
50222     return utilRebind(chapter, dispatch$$1, 'on');
50223 }
50224
50225 function uiIntroPoint(context, reveal) {
50226     var dispatch$$1 = dispatch('done'),
50227         timeouts = [],
50228         intersection = [-85.63279, 41.94394],
50229         building = [-85.632422, 41.944045],
50230         cafePreset = context.presets().item('amenity/cafe'),
50231         pointId = null;
50232
50233
50234     var chapter = {
50235         title: 'intro.points.title'
50236     };
50237
50238
50239     function timeout(f, t$$1) {
50240         timeouts.push(window.setTimeout(f, t$$1));
50241     }
50242
50243
50244     function revealEditMenu(loc, text, options) {
50245         var rect = context.surfaceRect();
50246         var point = context.curtainProjection(loc);
50247         var pad = 40;
50248         var width = 250 + (2 * pad);
50249         var height = 250;
50250         var startX = rect.left + point[0];
50251         var left = (textDirection === 'rtl') ? (startX - width + pad) : (startX - pad);
50252         var box = {
50253             left: left,
50254             top: point[1] + rect.top - 60,
50255             width: width,
50256             height: height
50257         };
50258         reveal(box, text, options);
50259     }
50260
50261
50262     function eventCancel() {
50263         event.stopPropagation();
50264         event.preventDefault();
50265     }
50266
50267
50268     function addPoint() {
50269         context.enter(modeBrowse(context));
50270         context.history().reset('initial');
50271
50272         var msec = transitionTime(intersection, context.map().center());
50273         if (msec) { reveal(null, null, { duration: 0 }); }
50274         context.map().zoom(19).centerEase(intersection, msec);
50275
50276         timeout(function() {
50277             var tooltip = reveal('button.add-point',
50278                 t('intro.points.add_point', { button: icon('#icon-point', 'pre-text') }));
50279
50280             pointId = null;
50281
50282             tooltip.selectAll('.tooltip-inner')
50283                 .insert('svg', 'span')
50284                 .attr('class', 'tooltip-illustration')
50285                 .append('use')
50286                 .attr('xlink:href', '#poi-images');
50287
50288             context.on('enter.intro', function(mode) {
50289                 if (mode.id !== 'add-point') return;
50290                 continueTo(placePoint);
50291             });
50292         }, msec + 100);
50293
50294         function continueTo(nextStep) {
50295             context.on('enter.intro', null);
50296             nextStep();
50297         }
50298     }
50299
50300
50301     function placePoint() {
50302         if (context.mode().id !== 'add-point') {
50303             return chapter.restart();
50304         }
50305
50306         var pointBox$$1 = pad$1(building, 150, context);
50307         reveal(pointBox$$1, t('intro.points.place_point'));
50308
50309         context.map().on('move.intro drawn.intro', function() {
50310             pointBox$$1 = pad$1(building, 150, context);
50311             reveal(pointBox$$1, t('intro.points.place_point'), { duration: 0 });
50312         });
50313
50314         context.on('enter.intro', function(mode) {
50315             if (mode.id !== 'select') return chapter.restart();
50316             pointId = context.mode().selectedIDs()[0];
50317             continueTo(searchPreset);
50318         });
50319
50320         function continueTo(nextStep) {
50321             context.map().on('move.intro drawn.intro', null);
50322             context.on('enter.intro', null);
50323             nextStep();
50324         }
50325     }
50326
50327
50328     function searchPreset() {
50329         if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
50330             return addPoint();
50331         }
50332
50333         // disallow scrolling
50334         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
50335
50336         d3_select('.preset-search-input')
50337             .on('keydown.intro', null)
50338             .on('keyup.intro', checkPresetSearch);
50339
50340         reveal('.preset-search-input',
50341             t('intro.points.search_cafe', { preset: cafePreset.name() })
50342         );
50343
50344         context.on('enter.intro', function(mode) {
50345             if (!pointId || !context.hasEntity(pointId)) {
50346                 return continueTo(addPoint);
50347             }
50348
50349             var ids = context.selectedIDs();
50350             if (mode.id !== 'select' || !ids.length || ids[0] !== pointId) {
50351                 // keep the user's point selected..
50352                 context.enter(modeSelect(context, [pointId]));
50353
50354                 // disallow scrolling
50355                 d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
50356
50357                 d3_select('.preset-search-input')
50358                     .on('keydown.intro', null)
50359                     .on('keyup.intro', checkPresetSearch);
50360
50361                 reveal('.preset-search-input',
50362                     t('intro.points.search_cafe', { preset: cafePreset.name() })
50363                 );
50364
50365                 context.history().on('change.intro', null);
50366             }
50367         });
50368
50369
50370         function checkPresetSearch() {
50371             var first = d3_select('.preset-list-item:first-child');
50372
50373             if (first.classed('preset-amenity-cafe')) {
50374                 d3_select('.preset-search-input')
50375                     .on('keydown.intro', eventCancel, true)
50376                     .on('keyup.intro', null);
50377
50378                 reveal(first.select('.preset-list-button').node(),
50379                     t('intro.points.choose_cafe', { preset: cafePreset.name() }),
50380                     { duration: 300 }
50381                 );
50382
50383                 context.history().on('change.intro', function() {
50384                     continueTo(aboutFeatureEditor);
50385                 });
50386             }
50387         }
50388
50389         function continueTo(nextStep) {
50390             context.on('enter.intro', null);
50391             context.history().on('change.intro', null);
50392             d3_select('.inspector-wrap').on('wheel.intro', null);
50393             d3_select('.preset-search-input').on('keydown.intro keyup.intro', null);
50394             nextStep();
50395         }
50396     }
50397
50398
50399     function aboutFeatureEditor() {
50400         if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
50401             return addPoint();
50402         }
50403
50404         timeout(function() {
50405             reveal('.entity-editor-pane', t('intro.points.feature_editor'), {
50406                 tooltipClass: 'intro-points-describe',
50407                 buttonText: t('intro.ok'),
50408                 buttonCallback: function() { continueTo(addName); }
50409             });
50410         }, 400);
50411
50412         context.on('exit.intro', function() {
50413             // if user leaves select mode here, just continue with the tutorial.
50414             continueTo(reselectPoint);
50415         });
50416
50417         function continueTo(nextStep) {
50418             context.on('exit.intro', null);
50419             nextStep();
50420         }
50421     }
50422
50423
50424     function addName() {
50425         if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
50426             return addPoint();
50427         }
50428
50429         // reset pane, in case user happened to change it..
50430         d3_select('.inspector-wrap .panewrap').style('right', '0%');
50431
50432         timeout(function() {
50433             // It's possible for the user to add a name in a previous step..
50434             // If so, don't tell them to add the name in this step.
50435             // Give them an OK button instead.
50436             var entity = context.entity(pointId);
50437             if (entity.tags.name) {
50438                 var tooltip = reveal('.entity-editor-pane', t('intro.points.add_name'), {
50439                     tooltipClass: 'intro-points-describe',
50440                     buttonText: t('intro.ok'),
50441                     buttonCallback: function() { continueTo(addCloseEditor); }
50442                 });
50443                 tooltip.select('.instruction').style('display', 'none');
50444
50445             } else {
50446                 reveal('.entity-editor-pane', t('intro.points.add_name'),
50447                     { tooltipClass: 'intro-points-describe' }
50448                 );
50449             }
50450         }, 400);
50451
50452         context.history().on('change.intro', function() {
50453             continueTo(addCloseEditor);
50454         });
50455
50456         context.on('exit.intro', function() {
50457             // if user leaves select mode here, just continue with the tutorial.
50458             continueTo(reselectPoint);
50459         });
50460
50461         function continueTo(nextStep) {
50462             context.on('exit.intro', null);
50463             context.history().on('change.intro', null);
50464             nextStep();
50465         }
50466     }
50467
50468
50469     function addCloseEditor() {
50470         // reset pane, in case user happened to change it..
50471         d3_select('.inspector-wrap .panewrap').style('right', '0%');
50472
50473         var selector = '.entity-editor-pane button.preset-close svg use';
50474         var href = d3_select(selector).attr('href') || '#icon-close';
50475
50476         context.on('exit.intro', function() {
50477             continueTo(reselectPoint);
50478         });
50479
50480         reveal('.entity-editor-pane',
50481             t('intro.points.add_close', { button: icon(href, 'pre-text') })
50482         );
50483
50484         function continueTo(nextStep) {
50485             context.on('exit.intro', null);
50486             nextStep();
50487         }
50488     }
50489
50490
50491     function reselectPoint() {
50492         if (!pointId) return chapter.restart();
50493         var entity = context.hasEntity(pointId);
50494         if (!entity) return chapter.restart();
50495
50496         // make sure it's still a cafe, in case user somehow changed it..
50497         var oldPreset = context.presets().match(entity, context.graph());
50498         context.replace(actionChangePreset(pointId, oldPreset, cafePreset));
50499
50500         context.enter(modeBrowse(context));
50501
50502         var msec = transitionTime(entity.loc, context.map().center());
50503         if (msec) { reveal(null, null, { duration: 0 }); }
50504         context.map().centerEase(entity.loc, msec);
50505
50506         timeout(function() {
50507             var box = pointBox(entity.loc, context);
50508             reveal(box, t('intro.points.reselect'), { duration: 600 });
50509
50510             timeout(function() {
50511                 context.map().on('move.intro drawn.intro', function() {
50512                     var entity = context.hasEntity(pointId);
50513                     if (!entity) return chapter.restart();
50514                     var box = pointBox(entity.loc, context);
50515                     reveal(box, t('intro.points.reselect'), { duration: 0 });
50516                 });
50517             }, 600); // after reveal..
50518
50519             context.on('enter.intro', function(mode) {
50520                 if (mode.id !== 'select') return;
50521                 continueTo(updatePoint);
50522             });
50523
50524         }, msec + 100);
50525
50526         function continueTo(nextStep) {
50527             context.map().on('move.intro drawn.intro', null);
50528             context.on('enter.intro', null);
50529             nextStep();
50530         }
50531     }
50532
50533
50534     function updatePoint() {
50535         if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
50536             return continueTo(reselectPoint);
50537         }
50538
50539         // reset pane, in case user happened to untag the point..
50540         d3_select('.inspector-wrap .panewrap').style('right', '0%');
50541
50542         context.on('exit.intro', function() {
50543             continueTo(reselectPoint);
50544         });
50545
50546         context.history().on('change.intro', function() {
50547             continueTo(updateCloseEditor);
50548         });
50549
50550         timeout(function() {
50551             reveal('.entity-editor-pane', t('intro.points.update'),
50552                 { tooltipClass: 'intro-points-describe' }
50553             );
50554         }, 400);
50555
50556         function continueTo(nextStep) {
50557             context.on('exit.intro', null);
50558             context.history().on('change.intro', null);
50559             nextStep();
50560         }
50561     }
50562
50563
50564     function updateCloseEditor() {
50565         if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
50566             return continueTo(reselectPoint);
50567         }
50568
50569         // reset pane, in case user happened to change it..
50570         d3_select('.inspector-wrap .panewrap').style('right', '0%');
50571
50572         context.on('exit.intro', function() {
50573             continueTo(rightClickPoint);
50574         });
50575
50576         timeout(function() {
50577             reveal('.entity-editor-pane',
50578                 t('intro.points.update_close', { button: icon('#icon-apply', 'pre-text') })
50579             );
50580         }, 500);
50581
50582         function continueTo(nextStep) {
50583             context.on('exit.intro', null);
50584             nextStep();
50585         }
50586     }
50587
50588
50589     function rightClickPoint() {
50590         if (!pointId) return chapter.restart();
50591         var entity = context.hasEntity(pointId);
50592         if (!entity) return chapter.restart();
50593
50594         context.enter(modeBrowse(context));
50595
50596         var box = pointBox(entity.loc, context);
50597         reveal(box, t('intro.points.rightclick'), { duration: 600 });
50598
50599         timeout(function() {
50600             context.map().on('move.intro drawn.intro', function() {
50601                 var entity = context.hasEntity(pointId);
50602                 if (!entity) return chapter.restart();
50603                 var box = pointBox(entity.loc, context);
50604                 reveal(box, t('intro.points.rightclick'), { duration: 0 });
50605             });
50606         }, 600); // after reveal
50607
50608         context.on('enter.intro', function(mode) {
50609             if (mode.id !== 'select') return;
50610             var ids = context.selectedIDs();
50611             if (ids.length !== 1 || ids[0] !== pointId) return;
50612
50613             timeout(function() {
50614                 var node = selectMenuItem('delete').node();
50615                 if (!node) return;
50616                 continueTo(enterDelete);
50617             }, 300);  // after menu visible
50618         });
50619
50620         function continueTo(nextStep) {
50621             context.on('enter.intro', null);
50622             context.map().on('move.intro drawn.intro', null);
50623             nextStep();
50624         }
50625     }
50626
50627
50628     function enterDelete() {
50629         if (!pointId) return chapter.restart();
50630         var entity = context.hasEntity(pointId);
50631         if (!entity) return chapter.restart();
50632
50633         var node = selectMenuItem('delete').node();
50634         if (!node) { return continueTo(rightClickPoint); }
50635
50636         revealEditMenu(entity.loc,
50637             t('intro.points.delete', { button: icon('#operation-delete', 'pre-text') })
50638         );
50639
50640         timeout(function() {
50641             context.map().on('move.intro drawn.intro', function() {
50642                 revealEditMenu(entity.loc,
50643                     t('intro.points.delete', { button: icon('#operation-delete', 'pre-text') }),
50644                     { duration: 0}
50645                 );
50646             });
50647         }, 300); // after menu visible
50648
50649         context.on('exit.intro', function() {
50650             if (!pointId) return chapter.restart();
50651             var entity = context.hasEntity(pointId);
50652             if (entity) return continueTo(rightClickPoint);  // point still exists
50653         });
50654
50655         context.history().on('change.intro', function(changed) {
50656             if (changed.deleted().length) {
50657                 continueTo(undo);
50658             }
50659         });
50660
50661         function continueTo(nextStep) {
50662             context.map().on('move.intro drawn.intro', null);
50663             context.history().on('change.intro', null);
50664             context.on('exit.intro', null);
50665             nextStep();
50666         }
50667     }
50668
50669
50670     function undo() {
50671         context.history().on('change.intro', function() {
50672             continueTo(play);
50673         });
50674
50675         var iconName = '#icon-' + (textDirection === 'rtl' ? 'redo' : 'undo');
50676         reveal('#bar button.undo-button',
50677             t('intro.points.undo', { button: icon(iconName, 'pre-text') })
50678         );
50679
50680         function continueTo(nextStep) {
50681             context.history().on('change.intro', null);
50682             nextStep();
50683         }
50684     }
50685
50686
50687     function play() {
50688         dispatch$$1.call('done');
50689         reveal('#id-container',
50690             t('intro.points.play', { next: t('intro.areas.title') }), {
50691                 tooltipBox: '.intro-nav-wrap .chapter-area',
50692                 buttonText: t('intro.ok'),
50693                 buttonCallback: function() { reveal('#id-container'); }
50694             }
50695         );
50696     }
50697
50698
50699     chapter.enter = function() {
50700         addPoint();
50701     };
50702
50703
50704     chapter.exit = function() {
50705         timeouts.forEach(window.clearTimeout);
50706         context.on('enter.intro exit.intro', null);
50707         context.map().on('move.intro drawn.intro', null);
50708         context.history().on('change.intro', null);
50709         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
50710         d3_select('.preset-search-input').on('keydown.intro keyup.intro', null);
50711     };
50712
50713
50714     chapter.restart = function() {
50715         chapter.exit();
50716         chapter.enter();
50717     };
50718
50719
50720     return utilRebind(chapter, dispatch$$1, 'on');
50721 }
50722
50723 function uiIntroArea(context, reveal) {
50724     var dispatch$$1 = dispatch('done'),
50725         playground = [-85.63552, 41.94159],
50726         playgroundPreset = context.presets().item('leisure/playground'),
50727         descriptionField = context.presets().field('description'),
50728         timeouts = [],
50729         areaId;
50730
50731
50732     var chapter = {
50733         title: 'intro.areas.title'
50734     };
50735
50736
50737     function timeout(f, t$$1) {
50738         timeouts.push(window.setTimeout(f, t$$1));
50739     }
50740
50741
50742     function eventCancel() {
50743         event.stopPropagation();
50744         event.preventDefault();
50745     }
50746
50747
50748     function revealPlayground(center, text, options) {
50749         var padding = 180 * Math.pow(2, context.map().zoom() - 19.5);
50750         var box = pad$1(center, padding, context);
50751         reveal(box, text, options);
50752     }
50753
50754
50755     function addArea() {
50756         context.enter(modeBrowse(context));
50757         context.history().reset('initial');
50758         areaId = null;
50759
50760         var msec = transitionTime(playground, context.map().center());
50761         if (msec) { reveal(null, null, { duration: 0 }); }
50762         context.map().zoom(19).centerEase(playground, msec);
50763
50764         timeout(function() {
50765             var tooltip = reveal('button.add-area',
50766                 t('intro.areas.add_playground', { button: icon('#icon-area', 'pre-text') }));
50767
50768             tooltip.selectAll('.tooltip-inner')
50769                 .insert('svg', 'span')
50770                 .attr('class', 'tooltip-illustration')
50771                 .append('use')
50772                 .attr('xlink:href', '#landuse-images');
50773
50774             context.on('enter.intro', function(mode) {
50775                 if (mode.id !== 'add-area') return;
50776                 continueTo(startPlayground);
50777             });
50778         }, msec + 100);
50779
50780         function continueTo(nextStep) {
50781             context.on('enter.intro', null);
50782             nextStep();
50783         }
50784     }
50785
50786
50787     function startPlayground() {
50788         if (context.mode().id !== 'add-area') {
50789             return chapter.restart();
50790         }
50791
50792         areaId = null;
50793         context.map().zoomEase(19.5, 500);
50794
50795         timeout(function() {
50796             revealPlayground(playground,
50797                 t('intro.areas.start_playground'), { duration: 250 }
50798             );
50799
50800             timeout(function() {
50801                 context.map().on('move.intro drawn.intro', function() {
50802                     revealPlayground(playground,
50803                         t('intro.areas.start_playground'), { duration: 0 }
50804                     );
50805                 });
50806                 context.on('enter.intro', function(mode) {
50807                     if (mode.id !== 'draw-area') return chapter.restart();
50808                     continueTo(continuePlayground);
50809                 });
50810             }, 250);  // after reveal
50811
50812         }, 550);  // after easing
50813
50814         function continueTo(nextStep) {
50815             context.map().on('move.intro drawn.intro', null);
50816             context.on('enter.intro', null);
50817             nextStep();
50818         }
50819     }
50820
50821
50822     function continuePlayground() {
50823         if (context.mode().id !== 'draw-area') {
50824             return chapter.restart();
50825         }
50826
50827         areaId = null;
50828         revealPlayground(playground,
50829             t('intro.areas.continue_playground', { alt: uiCmd.display('⌥') }),
50830             { duration: 250 }
50831         );
50832
50833         timeout(function() {
50834             context.map().on('move.intro drawn.intro', function() {
50835                 revealPlayground(playground,
50836                     t('intro.areas.continue_playground', { alt: uiCmd.display('⌥') }),
50837                     { duration: 0 }
50838                 );
50839             });
50840         }, 250);  // after reveal
50841
50842         context.on('enter.intro', function(mode) {
50843             if (mode.id === 'draw-area') {
50844                 var entity = context.hasEntity(context.selectedIDs()[0]);
50845                 if (entity && entity.nodes.length >= 6) {
50846                     return continueTo(finishPlayground);
50847                 } else {
50848                     return;
50849                 }
50850             } else if (mode.id === 'select') {
50851                 areaId = context.selectedIDs()[0];
50852                 return continueTo(searchPresets);
50853             } else {
50854                 return chapter.restart();
50855             }
50856         });
50857
50858         function continueTo(nextStep) {
50859             context.map().on('move.intro drawn.intro', null);
50860             context.on('enter.intro', null);
50861             nextStep();
50862         }
50863     }
50864
50865
50866     function finishPlayground() {
50867         if (context.mode().id !== 'draw-area') {
50868             return chapter.restart();
50869         }
50870
50871         areaId = null;
50872         revealPlayground(playground,
50873             t('intro.areas.finish_playground'), { duration: 250 }
50874         );
50875
50876         timeout(function() {
50877             context.map().on('move.intro drawn.intro', function() {
50878                 revealPlayground(playground,
50879                     t('intro.areas.finish_playground'), { duration: 0 }
50880                 );
50881             });
50882         }, 250);  // after reveal
50883
50884         context.on('enter.intro', function(mode) {
50885             if (mode.id === 'draw-area') {
50886                 return;
50887             } else if (mode.id === 'select') {
50888                 areaId = context.selectedIDs()[0];
50889                 return continueTo(searchPresets);
50890             } else {
50891                 return chapter.restart();
50892             }
50893         });
50894
50895         function continueTo(nextStep) {
50896             context.map().on('move.intro drawn.intro', null);
50897             context.on('enter.intro', null);
50898             nextStep();
50899         }
50900     }
50901
50902
50903     function searchPresets() {
50904         if (!areaId || !context.hasEntity(areaId)) {
50905             return addArea();
50906         }
50907         var ids = context.selectedIDs();
50908         if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
50909             context.enter(modeSelect(context, [areaId]));
50910         }
50911
50912         // disallow scrolling
50913         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
50914
50915         timeout(function() {
50916             // reset pane, in case user somehow happened to change it..
50917             d3_select('.inspector-wrap .panewrap').style('right', '-100%');
50918
50919             d3_select('.preset-search-input')
50920                 .on('keydown.intro', null)
50921                 .on('keyup.intro', checkPresetSearch);
50922
50923             reveal('.preset-search-input',
50924                 t('intro.areas.search_playground', { preset: playgroundPreset.name() })
50925             );
50926         }, 400);  // after preset list pane visible..
50927
50928         context.on('enter.intro', function(mode) {
50929             if (!areaId || !context.hasEntity(areaId)) {
50930                 return continueTo(addArea);
50931             }
50932
50933             var ids = context.selectedIDs();
50934             if (mode.id !== 'select' || !ids.length || ids[0] !== areaId) {
50935                 // keep the user's area selected..
50936                 context.enter(modeSelect(context, [areaId]));
50937
50938                 // reset pane, in case user somehow happened to change it..
50939                 d3_select('.inspector-wrap .panewrap').style('right', '-100%');
50940                 // disallow scrolling
50941                 d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
50942
50943                 d3_select('.preset-search-input')
50944                     .on('keydown.intro', null)
50945                     .on('keyup.intro', checkPresetSearch);
50946
50947                 reveal('.preset-search-input',
50948                     t('intro.areas.search_playground', { preset: playgroundPreset.name() })
50949                 );
50950
50951                 context.history().on('change.intro', null);
50952             }
50953         });
50954
50955         function checkPresetSearch() {
50956             var first = d3_select('.preset-list-item:first-child');
50957
50958             if (first.classed('preset-leisure-playground')) {
50959                 reveal(first.select('.preset-list-button').node(),
50960                     t('intro.areas.choose_playground', { preset: playgroundPreset.name() }),
50961                     { duration: 300 }
50962                 );
50963
50964                 d3_select('.preset-search-input')
50965                     .on('keydown.intro', eventCancel, true)
50966                     .on('keyup.intro', null);
50967
50968                 context.history().on('change.intro', function() {
50969                     continueTo(clickAddField);
50970                 });
50971             }
50972         }
50973
50974         function continueTo(nextStep) {
50975             d3_select('.inspector-wrap').on('wheel.intro', null);
50976             context.on('enter.intro', null);
50977             context.history().on('change.intro', null);
50978             d3_select('.preset-search-input').on('keydown.intro keyup.intro', null);
50979             nextStep();
50980         }
50981     }
50982
50983
50984     function clickAddField() {
50985         if (!areaId || !context.hasEntity(areaId)) {
50986             return addArea();
50987         }
50988         var ids = context.selectedIDs();
50989         if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
50990             return searchPresets();
50991         }
50992
50993         if (!d3_select('.form-field-description').empty()) {
50994             return continueTo(describePlayground);
50995         }
50996
50997         // disallow scrolling
50998         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
50999
51000         timeout(function() {
51001             // reset pane, in case user somehow happened to change it..
51002             d3_select('.inspector-wrap .panewrap').style('right', '0%');
51003
51004             // It's possible for the user to add a description in a previous step..
51005             // If they did this already, just continue to next step.
51006             var entity = context.entity(areaId);
51007             if (entity.tags.description) {
51008                 return continueTo(play);
51009             }
51010
51011             // scroll "Add field" into view
51012             var box = d3_select('.more-fields').node().getBoundingClientRect();
51013             if (box.top > 300) {
51014                 var pane = d3_select('.entity-editor-pane .inspector-body');
51015                 var start = pane.node().scrollTop;
51016                 var end = start + (box.top - 300);
51017
51018                 pane
51019                     .transition()
51020                     .duration(250)
51021                     .tween('scroll.inspector', function() {
51022                         var node = this;
51023                         var i = d3_interpolateNumber(start, end);
51024                         return function(t$$1) {
51025                             node.scrollTop = i(t$$1);
51026                         };
51027                     });
51028             }
51029
51030             timeout(function() {
51031                 reveal('.more-fields .combobox-input',
51032                     t('intro.areas.add_field'),
51033                     { duration: 300 }
51034                 );
51035
51036                 d3_select('.more-fields .combobox-input')
51037                     .on('click.intro', function() {
51038                         continueTo(chooseDescriptionField);
51039                     });
51040             }, 300);  // after "Add Field" visible
51041
51042         }, 400);  // after editor pane visible
51043
51044         context.on('exit.intro', function() {
51045             return continueTo(searchPresets);
51046         });
51047
51048         function continueTo(nextStep) {
51049             d3_select('.inspector-wrap').on('wheel.intro', null);
51050             d3_select('.more-fields .combobox-input').on('click.intro', null);
51051             context.on('exit.intro', null);
51052             nextStep();
51053         }
51054     }
51055
51056
51057     function chooseDescriptionField() {
51058         if (!areaId || !context.hasEntity(areaId)) {
51059             return addArea();
51060         }
51061         var ids = context.selectedIDs();
51062         if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
51063             return searchPresets();
51064         }
51065
51066         if (!d3_select('.form-field-description').empty()) {
51067             return continueTo(describePlayground);
51068         }
51069
51070         // Make sure combobox is ready..
51071         if (d3_select('div.combobox').empty()) {
51072             return continueTo(clickAddField);
51073         }
51074         // Watch for the combobox to go away..
51075         var watcher;
51076         watcher = window.setInterval(function() {
51077             if (d3_select('div.combobox').empty()) {
51078                 window.clearInterval(watcher);
51079                 timeout(function() {
51080                     if (d3_select('.form-field-description').empty()) {
51081                         continueTo(retryChooseDescription);
51082                     } else {
51083                         continueTo(describePlayground);
51084                     }
51085                 }, 300);  // after description field added.
51086             }
51087         }, 300);
51088
51089         reveal('div.combobox',
51090             t('intro.areas.choose_field', { field: descriptionField.label() }),
51091             { duration: 300 }
51092         );
51093
51094         context.on('exit.intro', function() {
51095             return continueTo(searchPresets);
51096         });
51097
51098         function continueTo(nextStep) {
51099             if (watcher) window.clearInterval(watcher);
51100             context.on('exit.intro', null);
51101             nextStep();
51102         }
51103     }
51104
51105
51106     function describePlayground() {
51107         if (!areaId || !context.hasEntity(areaId)) {
51108             return addArea();
51109         }
51110         var ids = context.selectedIDs();
51111         if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
51112             return searchPresets();
51113         }
51114
51115         // reset pane, in case user happened to change it..
51116         d3_select('.inspector-wrap .panewrap').style('right', '0%');
51117
51118         if (d3_select('.form-field-description').empty()) {
51119             return continueTo(retryChooseDescription);
51120         }
51121
51122         context.on('exit.intro', function() {
51123             continueTo(play);
51124         });
51125
51126         reveal('.entity-editor-pane',
51127             t('intro.areas.describe_playground', { button: icon('#icon-apply', 'pre-text') }),
51128             { duration: 300 }
51129         );
51130
51131         function continueTo(nextStep) {
51132             context.on('exit.intro', null);
51133             nextStep();
51134         }
51135     }
51136
51137
51138     function retryChooseDescription() {
51139         if (!areaId || !context.hasEntity(areaId)) {
51140             return addArea();
51141         }
51142         var ids = context.selectedIDs();
51143         if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
51144             return searchPresets();
51145         }
51146
51147         // reset pane, in case user happened to change it..
51148         d3_select('.inspector-wrap .panewrap').style('right', '0%');
51149
51150         reveal('.entity-editor-pane',
51151             t('intro.areas.retry_add_field', { field: descriptionField.label() }), {
51152             buttonText: t('intro.ok'),
51153             buttonCallback: function() { continueTo(clickAddField); }
51154         });
51155
51156         context.on('exit.intro', function() {
51157             return continueTo(searchPresets);
51158         });
51159
51160         function continueTo(nextStep) {
51161             context.on('exit.intro', null);
51162             nextStep();
51163         }
51164     }
51165
51166
51167     function play() {
51168         dispatch$$1.call('done');
51169         reveal('#id-container',
51170             t('intro.areas.play', { next: t('intro.lines.title') }), {
51171                 tooltipBox: '.intro-nav-wrap .chapter-line',
51172                 buttonText: t('intro.ok'),
51173                 buttonCallback: function() { reveal('#id-container'); }
51174             }
51175         );
51176     }
51177
51178
51179     chapter.enter = function() {
51180         addArea();
51181     };
51182
51183
51184     chapter.exit = function() {
51185         timeouts.forEach(window.clearTimeout);
51186         context.on('enter.intro exit.intro', null);
51187         context.map().on('move.intro drawn.intro', null);
51188         context.history().on('change.intro', null);
51189         d3_select('.inspector-wrap').on('wheel.intro', null);
51190         d3_select('.preset-search-input').on('keydown.intro keyup.intro', null);
51191         d3_select('.more-fields .combobox-input').on('click.intro', null);
51192     };
51193
51194
51195     chapter.restart = function() {
51196         chapter.exit();
51197         chapter.enter();
51198     };
51199
51200
51201     return utilRebind(chapter, dispatch$$1, 'on');
51202 }
51203
51204 function uiIntroLine(context, reveal) {
51205     var dispatch$$1 = dispatch('done'),
51206         timeouts = [],
51207         tulipRoadId = null,
51208         flowerRoadId = 'w646',
51209         tulipRoadStart = [-85.6297754121684, 41.95805253325314],
51210         tulipRoadMidpoint = [-85.62975395449628, 41.95787501510204],
51211         tulipRoadIntersection = [-85.62974496187628, 41.95742515554585],
51212         roadCategory = context.presets().item('category-road'),
51213         residentialPreset = context.presets().item('highway/residential'),
51214         woodRoadId = 'w525',
51215         woodRoadEndId = 'n2862',
51216         woodRoadAddNode = [-85.62390110349587, 41.95397111462291],
51217         woodRoadDragEndpoint = [-85.623867390213, 41.95466987786487],
51218         woodRoadDragMidpoint = [-85.62386254803509, 41.95430395953872],
51219         washingtonStreetId = 'w522',
51220         twelfthAvenueId = 'w1',
51221         eleventhAvenueEndId = 'n3550',
51222         twelfthAvenueEndId = 'n5',
51223         washingtonSegmentId = null,
51224         eleventhAvenueEnd = context.entity(eleventhAvenueEndId).loc,
51225         twelfthAvenueEnd = context.entity(twelfthAvenueEndId).loc,
51226         deleteLinesLoc = [-85.6219395542764, 41.95228033922477],
51227         twelfthAvenue = [-85.62219310052491, 41.952505413152956];
51228
51229
51230     var chapter = {
51231         title: 'intro.lines.title'
51232     };
51233
51234
51235     function timeout(f, t$$1) {
51236         timeouts.push(window.setTimeout(f, t$$1));
51237     }
51238
51239
51240     function eventCancel() {
51241         event.stopPropagation();
51242         event.preventDefault();
51243     }
51244
51245
51246     function revealEditMenu(loc, text, options) {
51247         var rect = context.surfaceRect();
51248         var point = context.curtainProjection(loc);
51249         var pad = 40;
51250         var width = 250 + (2 * pad);
51251         var height = 350;
51252         var startX = rect.left + point[0];
51253         var left = (textDirection === 'rtl') ? (startX - width + pad) : (startX - pad);
51254         var box = {
51255             left: left,
51256             top: point[1] + rect.top - 60,
51257             width: width,
51258             height: height
51259         };
51260         reveal(box, text, options);
51261     }
51262
51263
51264     function addLine() {
51265         context.enter(modeBrowse(context));
51266         context.history().reset('initial');
51267
51268         var msec = transitionTime(tulipRoadStart, context.map().center());
51269         if (msec) { reveal(null, null, { duration: 0 }); }
51270         context.map().zoom(18.5).centerEase(tulipRoadStart, msec);
51271
51272         timeout(function() {
51273             var tooltip = reveal('button.add-line',
51274                 t('intro.lines.add_line', { button: icon('#icon-line', 'pre-text') }));
51275
51276             tooltip.selectAll('.tooltip-inner')
51277                 .insert('svg', 'span')
51278                 .attr('class', 'tooltip-illustration')
51279                 .append('use')
51280                 .attr('xlink:href', '#feature-images');
51281
51282             context.on('enter.intro', function(mode) {
51283                 if (mode.id !== 'add-line') return;
51284                 continueTo(startLine);
51285             });
51286         }, msec + 100);
51287
51288         function continueTo(nextStep) {
51289             context.on('enter.intro', null);
51290             nextStep();
51291         }
51292     }
51293
51294
51295     function startLine() {
51296         if (context.mode().id !== 'add-line') {
51297             return chapter.restart();
51298         }
51299
51300         tulipRoadId = null;
51301
51302         var padding = 70 * Math.pow(2, context.map().zoom() - 18);
51303         var box = pad$1(tulipRoadStart, padding, context);
51304         box.height = box.height + 100;
51305         reveal(box, t('intro.lines.start_line'));
51306
51307         context.map().on('move.intro drawn.intro', function() {
51308             padding = 70 * Math.pow(2, context.map().zoom() - 18);
51309             box = pad$1(tulipRoadStart, padding, context);
51310             box.height = box.height + 100;
51311             reveal(box, t('intro.lines.start_line'), { duration: 0 });
51312         });
51313
51314         context.on('enter.intro', function(mode) {
51315             if (mode.id !== 'draw-line') return chapter.restart();
51316             continueTo(drawLine);
51317         });
51318
51319         function continueTo(nextStep) {
51320             context.map().on('move.intro drawn.intro', null);
51321             context.on('enter.intro', null);
51322             nextStep();
51323         }
51324     }
51325
51326
51327     function drawLine() {
51328         if (context.mode().id !== 'draw-line') {
51329             return chapter.restart();
51330         }
51331
51332         tulipRoadId = context.mode().selectedIDs()[0];
51333         context.map().centerEase(tulipRoadMidpoint, 500);
51334
51335         timeout(function() {
51336             var padding = 200 * Math.pow(2, context.map().zoom() - 18.5);
51337             var box = pad$1(tulipRoadMidpoint, padding, context);
51338             box.height = box.height * 2;
51339             reveal(box,
51340                 t('intro.lines.intersect', { name: t('intro.graph.name.flower-street') })
51341             );
51342
51343             context.map().on('move.intro drawn.intro', function() {
51344                 padding = 200 * Math.pow(2, context.map().zoom() - 18.5);
51345                 box = pad$1(tulipRoadMidpoint, padding, context);
51346                 box.height = box.height * 2;
51347                 reveal(box,
51348                     t('intro.lines.intersect', { name: t('intro.graph.name.flower-street') }),
51349                     { duration: 0 }
51350                 );
51351             });
51352         }, 550);  // after easing..
51353
51354         context.history().on('change.intro', function() {
51355             var entity = tulipRoadId && context.hasEntity(tulipRoadId);
51356             if (!entity) return chapter.restart();
51357
51358             if (isLineConnected()) {
51359                 continueTo(continueLine);
51360             }
51361         });
51362
51363         context.on('enter.intro', function(mode) {
51364             if (mode.id === 'draw-line')
51365                 return;
51366             else if (mode.id === 'select') {
51367                 continueTo(retryIntersect);
51368                 return;
51369             }
51370             else
51371                 return chapter.restart();
51372         });
51373
51374         function continueTo(nextStep) {
51375             context.map().on('move.intro drawn.intro', null);
51376             context.history().on('change.intro', null);
51377             context.on('enter.intro', null);
51378             nextStep();
51379         }
51380     }
51381
51382
51383     function isLineConnected() {
51384         var entity = tulipRoadId && context.hasEntity(tulipRoadId);
51385         if (!entity) return false;
51386
51387         var drawNodes = context.graph().childNodes(entity);
51388         return some(drawNodes, function(node) {
51389             return some(context.graph().parentWays(node), function(parent) {
51390                 return parent.id === flowerRoadId;
51391             });
51392         });
51393     }
51394
51395
51396     function retryIntersect() {
51397         d3_select(window).on('mousedown.intro', eventCancel, true);
51398
51399         var box = pad$1(tulipRoadIntersection, 80, context);
51400         reveal(box,
51401             t('intro.lines.retry_intersect', { name: t('intro.graph.name.flower-street') })
51402         );
51403
51404         timeout(chapter.restart, 3000);
51405     }
51406
51407
51408     function continueLine() {
51409         if (context.mode().id !== 'draw-line') return chapter.restart();
51410         var entity = tulipRoadId && context.hasEntity(tulipRoadId);
51411         if (!entity) return chapter.restart();
51412
51413         context.map().centerEase(tulipRoadIntersection, 500);
51414
51415         reveal('#surface', t('intro.lines.continue_line'));
51416
51417         context.on('enter.intro', function(mode) {
51418             if (mode.id === 'draw-line')
51419                 return;
51420             else if (mode.id === 'select')
51421                 return continueTo(chooseCategoryRoad);
51422             else
51423                 return chapter.restart();
51424         });
51425
51426         function continueTo(nextStep) {
51427             context.on('enter.intro', null);
51428             nextStep();
51429         }
51430     }
51431
51432
51433     function chooseCategoryRoad() {
51434         if (context.mode().id !== 'select') {
51435             return chapter.restart();
51436         }
51437
51438         context.on('exit.intro', function() {
51439             return chapter.restart();
51440         });
51441
51442         var button = d3_select('.preset-category-road .preset-list-button');
51443         if (button.empty()) return chapter.restart();
51444
51445         // disallow scrolling
51446         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
51447
51448         timeout(function() {
51449             // reset pane, in case user somehow happened to change it..
51450             d3_select('.inspector-wrap .panewrap').style('right', '-100%');
51451
51452             reveal(button.node(),
51453                 t('intro.lines.choose_category_road', { category: roadCategory.name() })
51454             );
51455
51456             button.on('click.intro', function() {
51457                 continueTo(choosePresetResidential);
51458             });
51459
51460         }, 400);  // after editor pane visible
51461
51462         function continueTo(nextStep) {
51463             d3_select('.inspector-wrap').on('wheel.intro', null);
51464             d3_select('.preset-list-button').on('click.intro', null);
51465             context.on('exit.intro', null);
51466             nextStep();
51467         }
51468     }
51469
51470
51471     function choosePresetResidential() {
51472         if (context.mode().id !== 'select') {
51473             return chapter.restart();
51474         }
51475
51476         context.on('exit.intro', function() {
51477             return chapter.restart();
51478         });
51479
51480         var subgrid = d3_select('.preset-category-road .subgrid');
51481         if (subgrid.empty()) return chapter.restart();
51482
51483         subgrid.selectAll(':not(.preset-highway-residential) .preset-list-button')
51484             .on('click.intro', function() {
51485                 continueTo(retryPresetResidential);
51486             });
51487
51488         subgrid.selectAll('.preset-highway-residential .preset-list-button')
51489             .on('click.intro', function() {
51490                 continueTo(nameRoad);
51491             });
51492
51493         timeout(function() {
51494             reveal(subgrid.node(),
51495                 t('intro.lines.choose_preset_residential', { preset: residentialPreset.name() }),
51496                 { tooltipBox: '.preset-highway-residential .preset-list-button', duration: 300 }
51497             );
51498         }, 300);
51499
51500         function continueTo(nextStep) {
51501             d3_select('.preset-list-button').on('click.intro', null);
51502             context.on('exit.intro', null);
51503             nextStep();
51504         }
51505     }
51506
51507
51508     // selected wrong road type
51509     function retryPresetResidential() {
51510         if (context.mode().id !== 'select') {
51511             return chapter.restart();
51512         }
51513
51514         context.on('exit.intro', function() {
51515             return chapter.restart();
51516         });
51517
51518         // disallow scrolling
51519         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
51520
51521         timeout(function() {
51522             var button = d3_select('.entity-editor-pane .preset-list-button');
51523
51524             reveal(button.node(),
51525                 t('intro.lines.retry_preset_residential', { preset: residentialPreset.name() })
51526             );
51527
51528             button.on('click.intro', function() {
51529                 continueTo(chooseCategoryRoad);
51530             });
51531
51532         }, 500);
51533
51534         function continueTo(nextStep) {
51535             d3_select('.inspector-wrap').on('wheel.intro', null);
51536             d3_select('.preset-list-button').on('click.intro', null);
51537             context.on('exit.intro', null);
51538             nextStep();
51539         }
51540     }
51541
51542
51543     function nameRoad() {
51544         context.on('exit.intro', function() {
51545             continueTo(didNameRoad);
51546         });
51547
51548         timeout(function() {
51549             reveal('.entity-editor-pane',
51550                 t('intro.lines.name_road', { button: icon('#icon-apply', 'pre-text') }),
51551                 { tooltipClass: 'intro-lines-name_road' }
51552             );
51553         }, 500);
51554
51555         function continueTo(nextStep) {
51556             context.on('exit.intro', null);
51557             nextStep();
51558         }
51559     }
51560
51561
51562     function didNameRoad() {
51563         context.history().checkpoint('doneAddLine');
51564
51565         timeout(function() {
51566             reveal('#surface', t('intro.lines.did_name_road'), {
51567                 buttonText: t('intro.ok'),
51568                 buttonCallback: function() { continueTo(updateLine); }
51569             });
51570         }, 500);
51571
51572         function continueTo(nextStep) {
51573             nextStep();
51574         }
51575     }
51576
51577
51578     function updateLine() {
51579         context.history().reset('doneAddLine');
51580         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
51581             return chapter.restart();
51582         }
51583
51584         var msec = transitionTime(woodRoadDragMidpoint, context.map().center());
51585         if (msec) { reveal(null, null, { duration: 0 }); }
51586         context.map().zoom(19).centerEase(woodRoadDragMidpoint, msec);
51587
51588         timeout(function() {
51589             var padding = 250 * Math.pow(2, context.map().zoom() - 19);
51590             var box = pad$1(woodRoadDragMidpoint, padding, context);
51591             var advance = function() { continueTo(addNode); };
51592
51593             reveal(box, t('intro.lines.update_line'),
51594                 { buttonText: t('intro.ok'), buttonCallback: advance }
51595             );
51596
51597             context.map().on('move.intro drawn.intro', function() {
51598                 var padding = 250 * Math.pow(2, context.map().zoom() - 19);
51599                 var box = pad$1(woodRoadDragMidpoint, padding, context);
51600                 reveal(box, t('intro.lines.update_line'),
51601                     { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance }
51602                 );
51603             });
51604         }, msec + 100);
51605
51606         function continueTo(nextStep) {
51607             context.map().on('move.intro drawn.intro', null);
51608             nextStep();
51609         }
51610     }
51611
51612
51613     function addNode() {
51614         context.history().reset('doneAddLine');
51615         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
51616             return chapter.restart();
51617         }
51618
51619         var padding = 40 * Math.pow(2, context.map().zoom() - 19);
51620         var box = pad$1(woodRoadAddNode, padding, context);
51621         reveal(box, t('intro.lines.add_node'));
51622
51623         context.map().on('move.intro drawn.intro', function() {
51624             var padding = 40 * Math.pow(2, context.map().zoom() - 19);
51625             var box = pad$1(woodRoadAddNode, padding, context);
51626             reveal(box, t('intro.lines.add_node'), { duration: 0 });
51627         });
51628
51629         context.history().on('change.intro', function(changed) {
51630             if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
51631                 return continueTo(updateLine);
51632             }
51633             if (changed.created().length === 1) {
51634                 timeout(function() { continueTo(startDragEndpoint); }, 500);
51635             }
51636         });
51637
51638         context.on('enter.intro', function(mode) {
51639             if (mode.id !== 'select') {
51640                 continueTo(updateLine);
51641             }
51642         });
51643
51644         function continueTo(nextStep) {
51645             context.map().on('move.intro drawn.intro', null);
51646             context.history().on('change.intro', null);
51647             context.on('enter.intro', null);
51648             nextStep();
51649         }
51650     }
51651
51652
51653     function startDragEndpoint() {
51654         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
51655             return continueTo(updateLine);
51656         }
51657         var padding = 100 * Math.pow(2, context.map().zoom() - 19);
51658         var box = pad$1(woodRoadDragEndpoint, padding, context);
51659         reveal(box, t('intro.lines.start_drag_endpoint'));
51660
51661         context.map().on('move.intro drawn.intro', function() {
51662             if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
51663                 return continueTo(updateLine);
51664             }
51665             var padding = 100 * Math.pow(2, context.map().zoom() - 19);
51666             var box = pad$1(woodRoadDragEndpoint, padding, context);
51667             reveal(box, t('intro.lines.start_drag_endpoint'), { duration: 0 });
51668
51669             var entity = context.entity(woodRoadEndId);
51670             if (geoSphericalDistance(entity.loc, woodRoadDragEndpoint) <= 4) {
51671                 continueTo(finishDragEndpoint);
51672             }
51673         });
51674
51675         function continueTo(nextStep) {
51676             context.map().on('move.intro drawn.intro', null);
51677             nextStep();
51678         }
51679     }
51680
51681
51682     function finishDragEndpoint() {
51683         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
51684             return continueTo(updateLine);
51685         }
51686
51687         var padding = 100 * Math.pow(2, context.map().zoom() - 19);
51688         var box = pad$1(woodRoadDragEndpoint, padding, context);
51689         reveal(box, t('intro.lines.finish_drag_endpoint'));
51690
51691         context.map().on('move.intro drawn.intro', function() {
51692             if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
51693                 return continueTo(updateLine);
51694             }
51695             var padding = 100 * Math.pow(2, context.map().zoom() - 19);
51696             var box = pad$1(woodRoadDragEndpoint, padding, context);
51697             reveal(box, t('intro.lines.finish_drag_endpoint'), { duration: 0 });
51698
51699             var entity = context.entity(woodRoadEndId);
51700             if (geoSphericalDistance(entity.loc, woodRoadDragEndpoint) > 4) {
51701                 continueTo(startDragEndpoint);
51702             }
51703         });
51704
51705         context.on('enter.intro', function() {
51706             continueTo(startDragMidpoint);
51707         });
51708
51709         function continueTo(nextStep) {
51710             context.map().on('move.intro drawn.intro', null);
51711             context.on('enter.intro', null);
51712             nextStep();
51713         }
51714     }
51715
51716
51717     function startDragMidpoint() {
51718         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
51719             return continueTo(updateLine);
51720         }
51721         if (context.selectedIDs().indexOf(woodRoadId) === -1) {
51722             context.enter(modeSelect(context, [woodRoadId]));
51723         }
51724
51725         var padding = 80 * Math.pow(2, context.map().zoom() - 19);
51726         var box = pad$1(woodRoadDragMidpoint, padding, context);
51727         reveal(box, t('intro.lines.start_drag_midpoint'));
51728
51729         context.map().on('move.intro drawn.intro', function() {
51730             if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
51731                 return continueTo(updateLine);
51732             }
51733             var padding = 80 * Math.pow(2, context.map().zoom() - 19);
51734             var box = pad$1(woodRoadDragMidpoint, padding, context);
51735             reveal(box, t('intro.lines.start_drag_midpoint'), { duration: 0 });
51736         });
51737
51738         context.history().on('change.intro', function(changed) {
51739             if (changed.created().length === 1) {
51740                 continueTo(continueDragMidpoint);
51741             }
51742         });
51743
51744         context.on('enter.intro', function(mode) {
51745             if (mode.id !== 'select') {
51746                 // keep Wood Road selected so midpoint triangles are drawn..
51747                 context.enter(modeSelect(context, [woodRoadId]));
51748             }
51749         });
51750
51751         function continueTo(nextStep) {
51752             context.map().on('move.intro drawn.intro', null);
51753             context.history().on('change.intro', null);
51754             context.on('enter.intro', null);
51755             nextStep();
51756         }
51757     }
51758
51759
51760     function continueDragMidpoint() {
51761         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
51762             return continueTo(updateLine);
51763         }
51764
51765         var padding = 100 * Math.pow(2, context.map().zoom() - 19);
51766         var box = pad$1(woodRoadDragEndpoint, padding, context);
51767         box.height += 400;
51768
51769         var advance = function() {
51770             context.history().checkpoint('doneUpdateLine');
51771             continueTo(deleteLines);
51772         };
51773
51774         reveal(box, t('intro.lines.continue_drag_midpoint'),
51775             { buttonText: t('intro.ok'), buttonCallback: advance }
51776         );
51777
51778         context.map().on('move.intro drawn.intro', function() {
51779             if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
51780                 return continueTo(updateLine);
51781             }
51782             var padding = 100 * Math.pow(2, context.map().zoom() - 19);
51783             var box = pad$1(woodRoadDragEndpoint, padding, context);
51784             box.height += 400;
51785             reveal(box, t('intro.lines.continue_drag_midpoint'),
51786                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance }
51787             );
51788         });
51789
51790         function continueTo(nextStep) {
51791             context.map().on('move.intro drawn.intro', null);
51792             nextStep();
51793         }
51794     }
51795
51796
51797     function deleteLines() {
51798         context.history().reset('doneUpdateLine');
51799         context.enter(modeBrowse(context));
51800
51801         if (!context.hasEntity(washingtonStreetId) ||
51802             !context.hasEntity(twelfthAvenueId) ||
51803             !context.hasEntity(eleventhAvenueEndId)) {
51804             return chapter.restart();
51805         }
51806
51807         var msec = transitionTime(deleteLinesLoc, context.map().center());
51808         if (msec) { reveal(null, null, { duration: 0 }); }
51809         context.map().zoom(18).centerEase(deleteLinesLoc, msec);
51810
51811         timeout(function() {
51812             var padding = 200 * Math.pow(2, context.map().zoom() - 18);
51813             var box = pad$1(deleteLinesLoc, padding, context);
51814             box.top -= 200;
51815             box.height += 400;
51816             var advance = function() { continueTo(rightClickIntersection); };
51817
51818             reveal(box, t('intro.lines.delete_lines', { street: t('intro.graph.name.12th-avenue') }),
51819                 { buttonText: t('intro.ok'), buttonCallback: advance }
51820             );
51821
51822             context.map().on('move.intro drawn.intro', function() {
51823                 var padding = 200 * Math.pow(2, context.map().zoom() - 18);
51824                 var box = pad$1(deleteLinesLoc, padding, context);
51825                 box.top -= 200;
51826                 box.height += 400;
51827                 reveal(box, t('intro.lines.delete_lines', { street: t('intro.graph.name.12th-avenue') }),
51828                     { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance }
51829                 );
51830             });
51831
51832             context.history().on('change.intro', function() {
51833                 timeout(function() {
51834                     continueTo(deleteLines);
51835                 }, 500);  // after any transition (e.g. if user deleted intersection)
51836             });
51837
51838         }, msec + 100);
51839
51840         function continueTo(nextStep) {
51841             context.map().on('move.intro drawn.intro', null);
51842             context.history().on('change.intro', null);
51843             nextStep();
51844         }
51845     }
51846
51847
51848     function rightClickIntersection() {
51849         context.history().reset('doneUpdateLine');
51850         context.enter(modeBrowse(context));
51851
51852         context.map().zoom(18).centerEase(eleventhAvenueEnd, 500);
51853
51854         timeout(function() {
51855             var padding = 60 * Math.pow(2, context.map().zoom() - 18);
51856             var box = pad$1(eleventhAvenueEnd, padding, context);
51857             reveal(box, t('intro.lines.rightclick_intersection',
51858                 { street1: t('intro.graph.name.11th-avenue'), street2: t('intro.graph.name.washington-street') })
51859             );
51860
51861             context.map().on('move.intro drawn.intro', function() {
51862                 var padding = 60 * Math.pow(2, context.map().zoom() - 18);
51863                 var box = pad$1(eleventhAvenueEnd, padding, context);
51864                 reveal(box, t('intro.lines.rightclick_intersection',
51865                     { street1: t('intro.graph.name.11th-avenue'), street2: t('intro.graph.name.washington-street') }),
51866                     { duration: 0 }
51867                 );
51868             });
51869
51870             context.on('enter.intro', function(mode) {
51871                 if (mode.id !== 'select') return;
51872                 var ids = context.selectedIDs();
51873                 if (ids.length !== 1 || ids[0] !== eleventhAvenueEndId) return;
51874
51875                 timeout(function() {
51876                     var node = selectMenuItem('split').node();
51877                     if (!node) return;
51878                     continueTo(splitIntersection);
51879                 }, 300);  // after menu visible
51880             });
51881
51882             context.history().on('change.intro', function() {
51883                 timeout(function() {
51884                     continueTo(deleteLines);
51885                 }, 300);  // after any transition (e.g. if user deleted intersection)
51886             });
51887
51888         }, 600);
51889
51890         function continueTo(nextStep) {
51891             context.map().on('move.intro drawn.intro', null);
51892             context.on('enter.intro', null);
51893             context.history().on('change.intro', null);
51894             nextStep();
51895         }
51896     }
51897
51898
51899     function splitIntersection() {
51900         if (!context.hasEntity(washingtonStreetId) ||
51901             !context.hasEntity(twelfthAvenueId) ||
51902             !context.hasEntity(eleventhAvenueEndId)) {
51903             return continueTo(deleteLines);
51904         }
51905
51906         var node = selectMenuItem('split').node();
51907         if (!node) { return continueTo(rightClickIntersection); }
51908
51909         var wasChanged = false;
51910         var menuCoords = context.map().mouseCoordinates();
51911         washingtonSegmentId = null;
51912
51913         revealEditMenu(menuCoords, t('intro.lines.split_intersection',
51914             { button: icon('#operation-split', 'pre-text'), street: t('intro.graph.name.washington-street') })
51915         );
51916
51917         context.map().on('move.intro drawn.intro', function() {
51918             var node = selectMenuItem('split').node();
51919             if (!wasChanged && !node) { return continueTo(rightClickIntersection); }
51920
51921             revealEditMenu(menuCoords, t('intro.lines.split_intersection',
51922                 { button: icon('#operation-split', 'pre-text'), street: t('intro.graph.name.washington-street') }),
51923                 { duration: 0 }
51924             );
51925         });
51926
51927         context.history().on('change.intro', function(changed) {
51928             wasChanged = true;
51929             timeout(function() {
51930                 if (context.history().undoAnnotation() === t('operations.split.annotation.line')) {
51931                     washingtonSegmentId = changed.created()[0].id;
51932                     continueTo(didSplit);
51933                 } else {
51934                     washingtonSegmentId = null;
51935                     continueTo(retrySplit);
51936                 }
51937             }, 300);  // after any transition (e.g. if user deleted intersection)
51938         });
51939
51940         function continueTo(nextStep) {
51941             context.map().on('move.intro drawn.intro', null);
51942             context.history().on('change.intro', null);
51943             nextStep();
51944         }
51945     }
51946
51947
51948     function retrySplit() {
51949         context.enter(modeBrowse(context));
51950         context.map().zoom(18).centerEase(eleventhAvenueEnd, 500);
51951         var advance = function() { continueTo(rightClickIntersection); };
51952
51953         var padding = 60 * Math.pow(2, context.map().zoom() - 18);
51954         var box = pad$1(eleventhAvenueEnd, padding, context);
51955         reveal(box, t('intro.lines.retry_split'),
51956             { buttonText: t('intro.ok'), buttonCallback: advance }
51957         );
51958
51959         context.map().on('move.intro drawn.intro', function() {
51960             var padding = 60 * Math.pow(2, context.map().zoom() - 18);
51961             var box = pad$1(eleventhAvenueEnd, padding, context);
51962             reveal(box, t('intro.lines.retry_split'),
51963                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance }
51964             );
51965         });
51966
51967         function continueTo(nextStep) {
51968             context.map().on('move.intro drawn.intro', null);
51969             nextStep();
51970         }
51971     }
51972
51973
51974     function didSplit() {
51975         if (!washingtonSegmentId ||
51976             !context.hasEntity(washingtonSegmentId) ||
51977             !context.hasEntity(washingtonStreetId) ||
51978             !context.hasEntity(twelfthAvenueId) ||
51979             !context.hasEntity(eleventhAvenueEndId)) {
51980             return continueTo(rightClickIntersection);
51981         }
51982
51983         var ids = context.selectedIDs();
51984         var string = 'intro.lines.did_split_' + (ids.length > 1 ? 'multi' : 'single');
51985         var street = t('intro.graph.name.washington-street');
51986
51987         var padding = 200 * Math.pow(2, context.map().zoom() - 18);
51988         var box = pad$1(twelfthAvenue, padding, context);
51989         box.width = box.width / 2;
51990         reveal(box, t(string, { street1: street, street2: street }),
51991             { duration: 500 }
51992         );
51993
51994         timeout(function() {
51995             context.map().zoom(18).centerEase(twelfthAvenue, 500);
51996
51997             context.map().on('move.intro drawn.intro', function() {
51998                 var padding = 200 * Math.pow(2, context.map().zoom() - 18);
51999                 var box = pad$1(twelfthAvenue, padding, context);
52000                 box.width = box.width / 2;
52001                 reveal(box, t(string, { street1: street, street2: street }),
52002                     { duration: 0 }
52003                 );
52004             });
52005         }, 600);  // after initial reveal and curtain cut
52006
52007         context.on('enter.intro', function() {
52008             var ids = context.selectedIDs();
52009             if (ids.length === 1 && ids[0] === washingtonSegmentId) {
52010                 continueTo(multiSelect);
52011             }
52012         });
52013
52014         context.history().on('change.intro', function() {
52015             if (!washingtonSegmentId ||
52016                 !context.hasEntity(washingtonSegmentId) ||
52017                 !context.hasEntity(washingtonStreetId) ||
52018                 !context.hasEntity(twelfthAvenueId) ||
52019                 !context.hasEntity(eleventhAvenueEndId)) {
52020                 return continueTo(rightClickIntersection);
52021             }
52022         });
52023
52024         function continueTo(nextStep) {
52025             context.map().on('move.intro drawn.intro', null);
52026             context.on('enter.intro', null);
52027             context.history().on('change.intro', null);
52028             nextStep();
52029         }
52030     }
52031
52032
52033     function multiSelect() {
52034         if (!washingtonSegmentId ||
52035             !context.hasEntity(washingtonSegmentId) ||
52036             !context.hasEntity(washingtonStreetId) ||
52037             !context.hasEntity(twelfthAvenueId) ||
52038             !context.hasEntity(eleventhAvenueEndId)) {
52039             return continueTo(rightClickIntersection);
52040         }
52041
52042         var ids = context.selectedIDs();
52043         var hasWashington = ids.indexOf(washingtonSegmentId) !== -1;
52044         var hasTwelfth = ids.indexOf(twelfthAvenueId) !== -1;
52045
52046         if (hasWashington && hasTwelfth) {
52047             return continueTo(multiRightClick);
52048         } else if (!hasWashington && !hasTwelfth) {
52049             return continueTo(didSplit);
52050         }
52051
52052         context.map().zoom(18).centerEase(twelfthAvenue, 500);
52053
52054         timeout(function() {
52055             var selected, other, padding, box;
52056             if (hasWashington) {
52057                 selected = t('intro.graph.name.washington-street');
52058                 other = t('intro.graph.name.12th-avenue');
52059                 padding = 60 * Math.pow(2, context.map().zoom() - 18);
52060                 box = pad$1(twelfthAvenueEnd, padding, context);
52061                 box.width *= 3;
52062             } else {
52063                 selected = t('intro.graph.name.12th-avenue');
52064                 other = t('intro.graph.name.washington-street');
52065                 padding = 200 * Math.pow(2, context.map().zoom() - 18);
52066                 box = pad$1(twelfthAvenue, padding, context);
52067                 box.width /= 2;
52068             }
52069
52070             reveal(box,
52071                 t('intro.lines.multi_select', { selected: selected, other1: other, other2: other })
52072             );
52073
52074             context.map().on('move.intro drawn.intro', function() {
52075                 if (hasWashington) {
52076                     selected = t('intro.graph.name.washington-street');
52077                     other = t('intro.graph.name.12th-avenue');
52078                     padding = 60 * Math.pow(2, context.map().zoom() - 18);
52079                     box = pad$1(twelfthAvenueEnd, padding, context);
52080                     box.width *= 3;
52081                 } else {
52082                     selected = t('intro.graph.name.12th-avenue');
52083                     other = t('intro.graph.name.washington-street');
52084                     padding = 200 * Math.pow(2, context.map().zoom() - 18);
52085                     box = pad$1(twelfthAvenue, padding, context);
52086                     box.width /= 2;
52087                 }
52088
52089                 reveal(box,
52090                     t('intro.lines.multi_select', { selected: selected, other1: other, other2: other }),
52091                     { duration: 0 }
52092                 );
52093             });
52094
52095             context.on('enter.intro', function() {
52096                 continueTo(multiSelect);
52097             });
52098
52099             context.history().on('change.intro', function() {
52100                 if (!washingtonSegmentId ||
52101                     !context.hasEntity(washingtonSegmentId) ||
52102                     !context.hasEntity(washingtonStreetId) ||
52103                     !context.hasEntity(twelfthAvenueId) ||
52104                     !context.hasEntity(eleventhAvenueEndId)) {
52105                     return continueTo(rightClickIntersection);
52106                 }
52107             });
52108         }, 600);
52109
52110         function continueTo(nextStep) {
52111             context.map().on('move.intro drawn.intro', null);
52112             context.on('enter.intro', null);
52113             context.history().on('change.intro', null);
52114             nextStep();
52115         }
52116     }
52117
52118
52119     function multiRightClick() {
52120         if (!washingtonSegmentId ||
52121             !context.hasEntity(washingtonSegmentId) ||
52122             !context.hasEntity(washingtonStreetId) ||
52123             !context.hasEntity(twelfthAvenueId) ||
52124             !context.hasEntity(eleventhAvenueEndId)) {
52125             return continueTo(rightClickIntersection);
52126         }
52127
52128         var padding = 200 * Math.pow(2, context.map().zoom() - 18);
52129         var box = pad$1(twelfthAvenue, padding, context);
52130         reveal(box, t('intro.lines.multi_rightclick'));
52131
52132         context.map().on('move.intro drawn.intro', function() {
52133             var padding = 200 * Math.pow(2, context.map().zoom() - 18);
52134             var box = pad$1(twelfthAvenue, padding, context);
52135             reveal(box, t('intro.lines.multi_rightclick'), { duration: 0 });
52136         });
52137
52138         d3_select(window).on('click.intro contextmenu.intro', function() {
52139             timeout(function() {
52140                 var ids = context.selectedIDs();
52141                 if (ids.length === 2 &&
52142                     ids.indexOf(twelfthAvenueId) !== -1 &&
52143                     ids.indexOf(washingtonSegmentId) !== -1) {
52144                         var node = selectMenuItem('delete').node();
52145                         if (!node) return;
52146                         continueTo(multiDelete);
52147                 } else if (ids.length === 1 &&
52148                     ids.indexOf(washingtonSegmentId) !== -1) {
52149                     return continueTo(multiSelect);
52150                 } else {
52151                     return continueTo(didSplit);
52152                 }
52153             }, 300);  // after edit menu visible
52154         }, true);
52155
52156         context.history().on('change.intro', function() {
52157             if (!washingtonSegmentId ||
52158                 !context.hasEntity(washingtonSegmentId) ||
52159                 !context.hasEntity(washingtonStreetId) ||
52160                 !context.hasEntity(twelfthAvenueId) ||
52161                 !context.hasEntity(eleventhAvenueEndId)) {
52162                 return continueTo(rightClickIntersection);
52163             }
52164         });
52165
52166         function continueTo(nextStep) {
52167             context.map().on('move.intro drawn.intro', null);
52168             d3_select(window).on('click.intro contextmenu.intro', null, true);
52169             context.history().on('change.intro', null);
52170             nextStep();
52171         }
52172     }
52173
52174
52175     function multiDelete() {
52176         if (!washingtonSegmentId ||
52177             !context.hasEntity(washingtonSegmentId) ||
52178             !context.hasEntity(washingtonStreetId) ||
52179             !context.hasEntity(twelfthAvenueId) ||
52180             !context.hasEntity(eleventhAvenueEndId)) {
52181             return continueTo(rightClickIntersection);
52182         }
52183
52184         var node = selectMenuItem('delete').node();
52185         if (!node) return continueTo(multiRightClick);
52186
52187         var menuCoords = context.map().mouseCoordinates();
52188         revealEditMenu(menuCoords,
52189             t('intro.lines.multi_delete', { button: icon('#operation-delete', 'pre-text') })
52190         );
52191
52192         context.map().on('move.intro drawn.intro', function() {
52193             revealEditMenu(menuCoords,
52194                 t('intro.lines.multi_delete', { button: icon('#operation-delete', 'pre-text') }),
52195                 { duration: 0 }
52196             );
52197         });
52198
52199         context.on('exit.intro', function() {
52200             if (context.hasEntity(washingtonSegmentId) || context.hasEntity(twelfthAvenueId)) {
52201                 return continueTo(multiSelect);  // left select mode but roads still exist
52202             }
52203         });
52204
52205         context.history().on('change.intro', function() {
52206             if (context.hasEntity(washingtonSegmentId) || context.hasEntity(twelfthAvenueId)) {
52207                 continueTo(retryDelete);         // changed something but roads still exist
52208             } else {
52209                 continueTo(play);
52210             }
52211         });
52212
52213         function continueTo(nextStep) {
52214             context.map().on('move.intro drawn.intro', null);
52215             context.on('exit.intro', null);
52216             context.history().on('change.intro', null);
52217             nextStep();
52218         }
52219     }
52220
52221
52222     function retryDelete() {
52223         context.enter(modeBrowse(context));
52224
52225         var padding = 200 * Math.pow(2, context.map().zoom() - 18);
52226         var box = pad$1(twelfthAvenue, padding, context);
52227         reveal(box, t('intro.lines.retry_delete'), {
52228             buttonText: t('intro.ok'),
52229             buttonCallback: function() { continueTo(multiSelect); }
52230         });
52231
52232         function continueTo(nextStep) {
52233             nextStep();
52234         }
52235     }
52236
52237
52238     function play() {
52239         dispatch$$1.call('done');
52240         reveal('#id-container',
52241             t('intro.lines.play', { next: t('intro.buildings.title') }), {
52242                 tooltipBox: '.intro-nav-wrap .chapter-building',
52243                 buttonText: t('intro.ok'),
52244                 buttonCallback: function() { reveal('#id-container'); }
52245             }
52246         );
52247    }
52248
52249
52250     chapter.enter = function() {
52251         addLine();
52252     };
52253
52254
52255     chapter.exit = function() {
52256         timeouts.forEach(window.clearTimeout);
52257         d3_select(window).on('mousedown.intro', null, true);
52258         context.on('enter.intro exit.intro', null);
52259         context.map().on('move.intro drawn.intro', null);
52260         context.history().on('change.intro', null);
52261         d3_select('.inspector-wrap').on('wheel.intro', null);
52262         d3_select('.preset-list-button').on('click.intro', null);
52263     };
52264
52265
52266     chapter.restart = function() {
52267         chapter.exit();
52268         chapter.enter();
52269     };
52270
52271
52272     return utilRebind(chapter, dispatch$$1, 'on');
52273 }
52274
52275 function uiIntroBuilding(context, reveal) {
52276     var dispatch$$1 = dispatch('done'),
52277         house = [-85.62815, 41.95638],
52278         tank = [-85.62732, 41.95347],
52279         buildingCatetory = context.presets().item('category-building'),
52280         housePreset = context.presets().item('building/house'),
52281         tankPreset = context.presets().item('man_made/storage_tank'),
52282         timeouts = [],
52283         houseId = null,
52284         tankId = null;
52285
52286
52287     var chapter = {
52288         title: 'intro.buildings.title'
52289     };
52290
52291
52292     function timeout(f, t$$1) {
52293         timeouts.push(window.setTimeout(f, t$$1));
52294     }
52295
52296
52297     function eventCancel() {
52298         event.stopPropagation();
52299         event.preventDefault();
52300     }
52301
52302
52303     function revealHouse(center, text, options) {
52304         var padding = 160 * Math.pow(2, context.map().zoom() - 20);
52305         var box = pad$1(center, padding, context);
52306         reveal(box, text, options);
52307     }
52308
52309
52310     function revealTank(center, text, options) {
52311         var padding = 190 * Math.pow(2, context.map().zoom() - 19.5);
52312         var box = pad$1(center, padding, context);
52313         reveal(box, text, options);
52314     }
52315
52316
52317     function revealEditMenu(loc, text, options) {
52318         var rect = context.surfaceRect();
52319         var point = context.curtainProjection(loc);
52320         var pad = 40;
52321         var width = 250 + (2 * pad);
52322         var height = 350;
52323         var startX = rect.left + point[0];
52324         var left = (textDirection === 'rtl') ? (startX - width + pad) : (startX - pad);
52325         var box = {
52326             left: left,
52327             top: point[1] + rect.top - 60,
52328             width: width,
52329             height: height
52330         };
52331         reveal(box, text, options);
52332     }
52333
52334
52335     function addHouse() {
52336         context.enter(modeBrowse(context));
52337         context.history().reset('initial');
52338         houseId = null;
52339
52340         var msec = transitionTime(house, context.map().center());
52341         if (msec) { reveal(null, null, { duration: 0 }); }
52342         context.map().zoom(19).centerEase(house, msec);
52343
52344         timeout(function() {
52345             var tooltip = reveal('button.add-area',
52346                 t('intro.buildings.add_building', { button: icon('#icon-area', 'pre-text') }));
52347
52348             tooltip.selectAll('.tooltip-inner')
52349                 .insert('svg', 'span')
52350                 .attr('class', 'tooltip-illustration')
52351                 .append('use')
52352                 .attr('xlink:href', '#building-images');
52353
52354             context.on('enter.intro', function(mode) {
52355                 if (mode.id !== 'add-area') return;
52356                 continueTo(startHouse);
52357             });
52358         }, msec + 100);
52359
52360         function continueTo(nextStep) {
52361             context.on('enter.intro', null);
52362             nextStep();
52363         }
52364     }
52365
52366
52367     function startHouse() {
52368         if (context.mode().id !== 'add-area') {
52369             return continueTo(addHouse);
52370         }
52371
52372         houseId = null;
52373         context.map().zoomEase(20, 500);
52374
52375         timeout(function() {
52376             revealHouse(house, t('intro.buildings.start_building'));
52377
52378             context.map().on('move.intro drawn.intro', function() {
52379                 revealHouse(house, t('intro.buildings.start_building'), { duration: 0 });
52380             });
52381
52382             context.on('enter.intro', function(mode) {
52383                 if (mode.id !== 'draw-area') return chapter.restart();
52384                 continueTo(continueHouse);
52385             });
52386
52387         }, 550);  // after easing
52388
52389         function continueTo(nextStep) {
52390             context.map().on('move.intro drawn.intro', null);
52391             context.on('enter.intro', null);
52392             nextStep();
52393         }
52394     }
52395
52396
52397     function continueHouse() {
52398         if (context.mode().id !== 'draw-area') {
52399             return continueTo(addHouse);
52400         }
52401
52402         houseId = null;
52403
52404         revealHouse(house, t('intro.buildings.continue_building'));
52405
52406         context.map().on('move.intro drawn.intro', function() {
52407             revealHouse(house, t('intro.buildings.continue_building'), { duration: 0 });
52408         });
52409
52410         context.on('enter.intro', function(mode) {
52411             if (mode.id === 'draw-area') {
52412                 return;
52413             } else if (mode.id === 'select') {
52414                 var graph = context.graph(),
52415                     way = context.entity(context.selectedIDs()[0]),
52416                     nodes = graph.childNodes(way),
52417                     points = uniq(nodes).map(function(n) { return context.projection(n.loc); });
52418
52419                 if (isMostlySquare(points)) {
52420                     houseId = way.id;
52421                     return continueTo(chooseCategoryBuilding);
52422                 } else {
52423                     return continueTo(retryHouse);
52424                 }
52425
52426             } else {
52427                 return chapter.restart();
52428             }
52429         });
52430
52431         function continueTo(nextStep) {
52432             context.map().on('move.intro drawn.intro', null);
52433             context.on('enter.intro', null);
52434             nextStep();
52435         }
52436     }
52437
52438
52439     function retryHouse() {
52440         var onClick = function() { continueTo(addHouse); };
52441
52442         revealHouse(house, t('intro.buildings.retry_building'),
52443             { buttonText: t('intro.ok'), buttonCallback: onClick }
52444         );
52445
52446         context.map().on('move.intro drawn.intro', function() {
52447             revealHouse(house, t('intro.buildings.retry_building'),
52448                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
52449             );
52450         });
52451
52452         function continueTo(nextStep) {
52453             context.map().on('move.intro drawn.intro', null);
52454             nextStep();
52455         }
52456     }
52457
52458
52459     function chooseCategoryBuilding() {
52460         if (!houseId || !context.hasEntity(houseId)) {
52461             return addHouse();
52462         }
52463         var ids = context.selectedIDs();
52464         if (context.mode().id !== 'select' || !ids.length || ids[0] !== houseId) {
52465             context.enter(modeSelect(context, [houseId]));
52466         }
52467
52468         // disallow scrolling
52469         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
52470
52471         timeout(function() {
52472             // reset pane, in case user somehow happened to change it..
52473             d3_select('.inspector-wrap .panewrap').style('right', '-100%');
52474
52475             var button = d3_select('.preset-category-building .preset-list-button');
52476
52477             reveal(button.node(),
52478                 t('intro.buildings.choose_category_building', { category: buildingCatetory.name() })
52479             );
52480
52481             button.on('click.intro', function() {
52482                 button.on('click.intro', null);
52483                 continueTo(choosePresetHouse);
52484             });
52485
52486         }, 400);  // after preset list pane visible..
52487
52488
52489         context.on('enter.intro', function(mode) {
52490             if (!houseId || !context.hasEntity(houseId)) {
52491                 return continueTo(addHouse);
52492             }
52493             var ids = context.selectedIDs();
52494             if (mode.id !== 'select' || !ids.length || ids[0] !== houseId) {
52495                 return continueTo(chooseCategoryBuilding);
52496             }
52497         });
52498
52499         function continueTo(nextStep) {
52500             d3_select('.inspector-wrap').on('wheel.intro', null);
52501             d3_select('.preset-list-button').on('click.intro', null);
52502             context.on('enter.intro', null);
52503             nextStep();
52504         }
52505     }
52506
52507
52508     function choosePresetHouse() {
52509         if (!houseId || !context.hasEntity(houseId)) {
52510             return addHouse();
52511         }
52512         var ids = context.selectedIDs();
52513         if (context.mode().id !== 'select' || !ids.length || ids[0] !== houseId) {
52514             context.enter(modeSelect(context, [houseId]));
52515         }
52516
52517         // disallow scrolling
52518         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
52519
52520         timeout(function() {
52521             // reset pane, in case user somehow happened to change it..
52522             d3_select('.inspector-wrap .panewrap').style('right', '-100%');
52523
52524             var button = d3_select('.preset-building-house .preset-list-button');
52525
52526             reveal(button.node(),
52527                 t('intro.buildings.choose_preset_house', { preset: housePreset.name() }),
52528                 { duration: 300 }
52529             );
52530
52531             button.on('click.intro', function() {
52532                 button.on('click.intro', null);
52533                 continueTo(closeEditorHouse);
52534             });
52535
52536
52537         }, 400);  // after preset list pane visible..
52538
52539         context.on('enter.intro', function(mode) {
52540             if (!houseId || !context.hasEntity(houseId)) {
52541                 return continueTo(addHouse);
52542             }
52543             var ids = context.selectedIDs();
52544             if (mode.id !== 'select' || !ids.length || ids[0] !== houseId) {
52545                 return continueTo(chooseCategoryBuilding);
52546             }
52547         });
52548
52549         function continueTo(nextStep) {
52550             d3_select('.inspector-wrap').on('wheel.intro', null);
52551             d3_select('.preset-list-button').on('click.intro', null);
52552             context.on('enter.intro', null);
52553             nextStep();
52554         }
52555     }
52556
52557
52558     function closeEditorHouse() {
52559         if (!houseId || !context.hasEntity(houseId)) {
52560             return addHouse();
52561         }
52562         var ids = context.selectedIDs();
52563         if (context.mode().id !== 'select' || !ids.length || ids[0] !== houseId) {
52564             context.enter(modeSelect(context, [houseId]));
52565         }
52566
52567         context.history().checkpoint('hasHouse');
52568
52569         context.on('exit.intro', function() {
52570             continueTo(rightClickHouse);
52571         });
52572
52573         timeout(function() {
52574             reveal('.entity-editor-pane',
52575                 t('intro.buildings.close', { button: icon('#icon-apply', 'pre-text') })
52576             );
52577         }, 500);
52578
52579         function continueTo(nextStep) {
52580             context.on('exit.intro', null);
52581             nextStep();
52582         }
52583     }
52584
52585
52586     function rightClickHouse() {
52587         if (!houseId) return chapter.restart();
52588
52589         context.enter(modeBrowse(context));
52590         context.history().reset('hasHouse');
52591         context.map().centerEase(house, 500);
52592
52593         timeout(function() {
52594             if (context.map().zoom() < 20) {
52595                 context.map().zoomEase(20, 500);
52596             }
52597         }, 520);
52598
52599         context.on('enter.intro', function(mode) {
52600             if (mode.id !== 'select') return;
52601             var ids = context.selectedIDs();
52602             if (ids.length !== 1 || ids[0] !== houseId) return;
52603
52604             timeout(function() {
52605                 var node = selectMenuItem('orthogonalize').node();
52606                 if (!node) return;
52607                 continueTo(clickSquare);
52608             }, 300);  // after menu visible
52609         });
52610
52611         context.map().on('move.intro drawn.intro', function() {
52612             revealHouse(house, t('intro.buildings.rightclick_building'), { duration: 0 });
52613         });
52614
52615         context.history().on('change.intro', function() {
52616             continueTo(rightClickHouse);
52617         });
52618
52619         function continueTo(nextStep) {
52620             context.on('enter.intro', null);
52621             context.map().on('move.intro drawn.intro', null);
52622             context.history().on('change.intro', null);
52623             nextStep();
52624         }
52625     }
52626
52627
52628     function clickSquare() {
52629         if (!houseId) return chapter.restart();
52630         var entity = context.hasEntity(houseId);
52631         if (!entity) return continueTo(rightClickHouse);
52632
52633         var node = selectMenuItem('orthogonalize').node();
52634         if (!node) { return continueTo(rightClickHouse); }
52635
52636         var wasChanged = false;
52637         var menuCoords = context.map().mouseCoordinates();
52638
52639         revealEditMenu(menuCoords,
52640             t('intro.buildings.square_building', { button: icon('#operation-orthogonalize', 'pre-text') })
52641         );
52642
52643         context.on('enter.intro', function(mode) {
52644             if (mode.id === 'browse') {
52645                 continueTo(rightClickHouse);
52646             } else if (mode.id === 'move' || mode.id === 'rotate') {
52647                 continueTo(retryClickSquare);
52648             }
52649         });
52650
52651         context.map().on('move.intro drawn.intro', function() {
52652             var node = selectMenuItem('orthogonalize').node();
52653             if (!wasChanged && !node) { return continueTo(rightClickHouse); }
52654
52655             revealEditMenu(menuCoords,
52656                 t('intro.buildings.square_building', { button: icon('#operation-orthogonalize', 'pre-text') }),
52657                 { duration: 0 }
52658             );
52659         });
52660
52661         context.history().on('change.intro', function() {
52662             wasChanged = true;
52663             context.history().on('change.intro', null);
52664
52665             // Something changed.  Wait for transition to complete and check undo annotation.
52666             timeout(function() {
52667                 if (context.history().undoAnnotation() === t('operations.orthogonalize.annotation.area')) {
52668                     continueTo(doneSquare);
52669                 } else {
52670                     continueTo(retryClickSquare);
52671                 }
52672             }, 500);  // after transitioned actions
52673         });
52674
52675         function continueTo(nextStep) {
52676             context.on('enter.intro', null);
52677             context.map().on('move.intro drawn.intro', null);
52678             context.history().on('change.intro', null);
52679             nextStep();
52680         }
52681     }
52682
52683
52684     function retryClickSquare() {
52685         context.enter(modeBrowse(context));
52686
52687         revealHouse(house, t('intro.buildings.retry_square'), {
52688             buttonText: t('intro.ok'),
52689             buttonCallback: function() { continueTo(rightClickHouse); }
52690         });
52691
52692         function continueTo(nextStep) {
52693             nextStep();
52694         }
52695     }
52696
52697
52698     function doneSquare() {
52699         context.history().checkpoint('doneSquare');
52700
52701         revealHouse(house, t('intro.buildings.done_square'), {
52702             buttonText: t('intro.ok'),
52703             buttonCallback: function() { continueTo(addTank); }
52704         });
52705
52706         function continueTo(nextStep) {
52707             nextStep();
52708         }
52709     }
52710
52711
52712     function addTank() {
52713         context.enter(modeBrowse(context));
52714         context.history().reset('doneSquare');
52715         tankId = null;
52716
52717         var msec = transitionTime(tank, context.map().center());
52718         if (msec) { reveal(null, null, { duration: 0 }); }
52719         context.map().zoom(19.5).centerEase(tank, msec);
52720
52721         timeout(function() {
52722             reveal('button.add-area',
52723                 t('intro.buildings.add_tank', { button: icon('#icon-area', 'pre-text') })
52724             );
52725
52726             context.on('enter.intro', function(mode) {
52727                 if (mode.id !== 'add-area') return;
52728                 continueTo(startTank);
52729             });
52730         }, msec + 100);
52731
52732         function continueTo(nextStep) {
52733             context.on('enter.intro', null);
52734             nextStep();
52735         }
52736     }
52737
52738
52739     function startTank() {
52740         if (context.mode().id !== 'add-area') {
52741             return continueTo(addTank);
52742         }
52743
52744         tankId = null;
52745
52746         timeout(function() {
52747             revealTank(tank, t('intro.buildings.start_tank'));
52748
52749             context.map().on('move.intro drawn.intro', function() {
52750                 revealTank(tank, t('intro.buildings.start_tank'), { duration: 0 });
52751             });
52752
52753             context.on('enter.intro', function(mode) {
52754                 if (mode.id !== 'draw-area') return chapter.restart();
52755                 continueTo(continueTank);
52756             });
52757
52758         }, 550);  // after easing
52759
52760         function continueTo(nextStep) {
52761             context.map().on('move.intro drawn.intro', null);
52762             context.on('enter.intro', null);
52763             nextStep();
52764         }
52765     }
52766
52767
52768     function continueTank() {
52769         if (context.mode().id !== 'draw-area') {
52770             return continueTo(addTank);
52771         }
52772
52773         tankId = null;
52774
52775         revealTank(tank, t('intro.buildings.continue_tank'));
52776
52777         context.map().on('move.intro drawn.intro', function() {
52778             revealTank(tank, t('intro.buildings.continue_tank'), { duration: 0 });
52779         });
52780
52781         context.on('enter.intro', function(mode) {
52782             if (mode.id === 'draw-area') {
52783                 return;
52784             } else if (mode.id === 'select') {
52785                 tankId = context.selectedIDs()[0];
52786                 return continueTo(searchPresetTank);
52787             } else {
52788                 return continueTo(addTank);
52789             }
52790         });
52791
52792         function continueTo(nextStep) {
52793             context.map().on('move.intro drawn.intro', null);
52794             context.on('enter.intro', null);
52795             nextStep();
52796         }
52797     }
52798
52799
52800     function searchPresetTank() {
52801         if (!tankId || !context.hasEntity(tankId)) {
52802             return addTank();
52803         }
52804         var ids = context.selectedIDs();
52805         if (context.mode().id !== 'select' || !ids.length || ids[0] !== tankId) {
52806             context.enter(modeSelect(context, [tankId]));
52807         }
52808
52809         // disallow scrolling
52810         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
52811
52812         timeout(function() {
52813             // reset pane, in case user somehow happened to change it..
52814             d3_select('.inspector-wrap .panewrap').style('right', '-100%');
52815
52816             d3_select('.preset-search-input')
52817                 .on('keydown.intro', null)
52818                 .on('keyup.intro', checkPresetSearch);
52819
52820             reveal('.preset-search-input',
52821                 t('intro.buildings.search_tank', { preset: tankPreset.name() })
52822             );
52823         }, 400);  // after preset list pane visible..
52824
52825         context.on('enter.intro', function(mode) {
52826             if (!tankId || !context.hasEntity(tankId)) {
52827                 return continueTo(addTank);
52828             }
52829
52830             var ids = context.selectedIDs();
52831             if (mode.id !== 'select' || !ids.length || ids[0] !== tankId) {
52832                 // keep the user's area selected..
52833                 context.enter(modeSelect(context, [tankId]));
52834
52835                 // reset pane, in case user somehow happened to change it..
52836                 d3_select('.inspector-wrap .panewrap').style('right', '-100%');
52837                 // disallow scrolling
52838                 d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
52839
52840                 d3_select('.preset-search-input')
52841                     .on('keydown.intro', null)
52842                     .on('keyup.intro', checkPresetSearch);
52843
52844                 reveal('.preset-search-input',
52845                     t('intro.buildings.search_tank', { preset: tankPreset.name() })
52846                 );
52847
52848                 context.history().on('change.intro', null);
52849             }
52850         });
52851
52852         function checkPresetSearch() {
52853             var first = d3_select('.preset-list-item:first-child');
52854
52855             if (first.classed('preset-man_made-storage_tank')) {
52856                 reveal(first.select('.preset-list-button').node(),
52857                     t('intro.buildings.choose_tank', { preset: tankPreset.name() }),
52858                     { duration: 300 }
52859                 );
52860
52861                 d3_select('.preset-search-input')
52862                     .on('keydown.intro', eventCancel, true)
52863                     .on('keyup.intro', null);
52864
52865                 context.history().on('change.intro', function() {
52866                     continueTo(closeEditorTank);
52867                 });
52868             }
52869         }
52870
52871         function continueTo(nextStep) {
52872             d3_select('.inspector-wrap').on('wheel.intro', null);
52873             context.on('enter.intro', null);
52874             context.history().on('change.intro', null);
52875             d3_select('.preset-search-input').on('keydown.intro keyup.intro', null);
52876             nextStep();
52877         }
52878     }
52879
52880
52881     function closeEditorTank() {
52882         if (!tankId || !context.hasEntity(tankId)) {
52883             return addTank();
52884         }
52885         var ids = context.selectedIDs();
52886         if (context.mode().id !== 'select' || !ids.length || ids[0] !== tankId) {
52887             context.enter(modeSelect(context, [tankId]));
52888         }
52889
52890         context.history().checkpoint('hasTank');
52891
52892         context.on('exit.intro', function() {
52893             continueTo(rightClickTank);
52894         });
52895
52896         timeout(function() {
52897             reveal('.entity-editor-pane',
52898                 t('intro.buildings.close', { button: icon('#icon-apply', 'pre-text') })
52899             );
52900         }, 500);
52901
52902         function continueTo(nextStep) {
52903             context.on('exit.intro', null);
52904             nextStep();
52905         }
52906     }
52907
52908
52909     function rightClickTank() {
52910         if (!tankId) return continueTo(addTank);
52911
52912         context.enter(modeBrowse(context));
52913         context.history().reset('hasTank');
52914         context.map().centerEase(tank, 500);
52915
52916         timeout(function() {
52917             context.on('enter.intro', function(mode) {
52918                 if (mode.id !== 'select') return;
52919                 var ids = context.selectedIDs();
52920                 if (ids.length !== 1 || ids[0] !== tankId) return;
52921
52922                 timeout(function() {
52923                     var node = selectMenuItem('circularize').node();
52924                     if (!node) return;
52925                     continueTo(clickCircle);
52926                 }, 300);  // after menu visible
52927             });
52928
52929             revealTank(tank, t('intro.buildings.rightclick_tank'));
52930
52931             context.map().on('move.intro drawn.intro', function() {
52932                 revealTank(tank, t('intro.buildings.rightclick_tank'), { duration: 0 });
52933             });
52934
52935             context.history().on('change.intro', function() {
52936                 continueTo(rightClickTank);
52937             });
52938
52939         }, 600);
52940
52941         function continueTo(nextStep) {
52942             context.on('enter.intro', null);
52943             context.map().on('move.intro drawn.intro', null);
52944             context.history().on('change.intro', null);
52945             nextStep();
52946         }
52947     }
52948
52949
52950     function clickCircle() {
52951         if (!tankId) return chapter.restart();
52952         var entity = context.hasEntity(tankId);
52953         if (!entity) return continueTo(rightClickTank);
52954
52955         var node = selectMenuItem('circularize').node();
52956         if (!node) { return continueTo(rightClickTank); }
52957
52958         var wasChanged = false;
52959         var menuCoords = context.map().mouseCoordinates();
52960
52961         revealEditMenu(menuCoords,
52962             t('intro.buildings.circle_tank', { button: icon('#operation-circularize', 'pre-text') })
52963         );
52964
52965         context.on('enter.intro', function(mode) {
52966             if (mode.id === 'browse') {
52967                 continueTo(rightClickTank);
52968             } else if (mode.id === 'move' || mode.id === 'rotate') {
52969                 continueTo(retryClickCircle);
52970             }
52971         });
52972
52973         context.map().on('move.intro drawn.intro', function() {
52974             var node = selectMenuItem('circularize').node();
52975             if (!wasChanged && !node) { return continueTo(rightClickTank); }
52976
52977             revealEditMenu(menuCoords,
52978                 t('intro.buildings.circle_tank', { button: icon('#operation-circularize', 'pre-text') }),
52979                 { duration: 0 }
52980             );
52981         });
52982
52983         context.history().on('change.intro', function() {
52984             wasChanged = true;
52985             context.history().on('change.intro', null);
52986
52987             // Something changed.  Wait for transition to complete and check undo annotation.
52988             timeout(function() {
52989                 if (context.history().undoAnnotation() === t('operations.circularize.annotation.area')) {
52990                     continueTo(play);
52991                 } else {
52992                     continueTo(retryClickCircle);
52993                 }
52994             }, 500);  // after transitioned actions
52995         });
52996
52997         function continueTo(nextStep) {
52998             context.on('enter.intro', null);
52999             context.map().on('move.intro drawn.intro', null);
53000             context.history().on('change.intro', null);
53001             nextStep();
53002         }
53003     }
53004
53005
53006     function retryClickCircle() {
53007         context.enter(modeBrowse(context));
53008
53009         revealTank(tank, t('intro.buildings.retry_circle'), {
53010             buttonText: t('intro.ok'),
53011             buttonCallback: function() { continueTo(rightClickTank); }
53012         });
53013
53014         function continueTo(nextStep) {
53015             nextStep();
53016         }
53017     }
53018
53019
53020     function play() {
53021         dispatch$$1.call('done');
53022         reveal('#id-container',
53023             t('intro.buildings.play', { next: t('intro.startediting.title') }), {
53024                 tooltipBox: '.intro-nav-wrap .chapter-startEditing',
53025                 buttonText: t('intro.ok'),
53026                 buttonCallback: function() { reveal('#id-container'); }
53027             }
53028         );
53029     }
53030
53031
53032     chapter.enter = function() {
53033         addHouse();
53034     };
53035
53036
53037     chapter.exit = function() {
53038         timeouts.forEach(window.clearTimeout);
53039         context.on('enter.intro exit.intro', null);
53040         context.map().on('move.intro drawn.intro', null);
53041         context.history().on('change.intro', null);
53042         d3_select('.inspector-wrap').on('wheel.intro', null);
53043         d3_select('.preset-search-input').on('keydown.intro keyup.intro', null);
53044         d3_select('.more-fields .combobox-input').on('click.intro', null);
53045     };
53046
53047
53048     chapter.restart = function() {
53049         chapter.exit();
53050         chapter.enter();
53051     };
53052
53053
53054     return utilRebind(chapter, dispatch$$1, 'on');
53055 }
53056
53057 function uiModal(selection, blocking) {
53058     var keybinding = d3keybinding('modal');
53059     var previous = selection.select('div.modal');
53060     var animate = previous.empty();
53061
53062     previous.transition()
53063         .duration(200)
53064         .style('opacity', 0)
53065         .remove();
53066
53067     var shaded = selection
53068         .append('div')
53069         .attr('class', 'shaded')
53070         .style('opacity', 0);
53071
53072     shaded.close = function() {
53073         shaded
53074             .transition()
53075             .duration(200)
53076             .style('opacity',0)
53077             .remove();
53078
53079         modal
53080             .transition()
53081             .duration(200)
53082             .style('top','0px');
53083
53084         keybinding.off();
53085     };
53086
53087
53088     var modal = shaded
53089         .append('div')
53090         .attr('class', 'modal fillL col6');
53091
53092     if (!blocking) {
53093         shaded.on('click.remove-modal', function() {
53094             if (event.target === this) {
53095                 shaded.close();
53096             }
53097         });
53098
53099         modal.append('button')
53100             .attr('class', 'close')
53101             .on('click', shaded.close)
53102             .call(svgIcon('#icon-close'));
53103
53104         keybinding
53105             .on('⌫', shaded.close)
53106             .on('⎋', shaded.close);
53107
53108         d3_select(document)
53109             .call(keybinding);
53110     }
53111
53112     modal
53113         .append('div')
53114         .attr('class', 'content');
53115
53116     if (animate) {
53117         shaded.transition().style('opacity', 1);
53118     } else {
53119         shaded.style('opacity', 1);
53120     }
53121
53122
53123     return shaded;
53124 }
53125
53126 function uiIntroStartEditing(context, reveal) {
53127     var dispatch$$1 = dispatch('done', 'startEditing'),
53128         modalSelection = d3_select(null);
53129
53130
53131     var chapter = {
53132         title: 'intro.startediting.title'
53133     };
53134
53135     function showHelp() {
53136         reveal('.map-control.help-control',
53137             t('intro.startediting.help', { button: icon('#icon-help', 'pre-text'), key: t('help.key') }), {
53138                 buttonText: t('intro.ok'),
53139                 buttonCallback: function() { shortcuts(); }
53140             }
53141         );
53142     }
53143
53144     function shortcuts() {
53145         reveal('.map-control.help-control',
53146             t('intro.startediting.shortcuts', { key: t('shortcuts.toggle.key') }), {
53147                 buttonText: t('intro.ok'),
53148                 buttonCallback: function() { showSave(); }
53149             }
53150         );
53151     }
53152
53153     function showSave() {
53154         d3_selectAll('.shaded').remove();  // in case user opened keyboard shortcuts
53155         reveal('#bar button.save',
53156             t('intro.startediting.save'), {
53157                 buttonText: t('intro.ok'),
53158                 buttonCallback: function() { showStart(); }
53159             }
53160         );
53161     }
53162
53163     function showStart() {
53164         d3_selectAll('.shaded').remove();  // in case user opened keyboard shortcuts
53165
53166         modalSelection = uiModal(context.container());
53167
53168         modalSelection.select('.modal')
53169             .attr('class', 'modal-splash modal col6');
53170
53171         modalSelection.selectAll('.close').remove();
53172
53173         var startbutton = modalSelection.select('.content')
53174             .attr('class', 'fillL')
53175             .append('button')
53176                 .attr('class', 'modal-section huge-modal-button')
53177                 .on('click', function() {
53178                     modalSelection.remove();
53179                 });
53180
53181             startbutton
53182                 .append('svg')
53183                 .attr('class', 'illustration')
53184                 .append('use')
53185                 .attr('xlink:href', '#logo-walkthrough');
53186
53187             startbutton
53188                 .append('h2')
53189                 .text(t('intro.startediting.start'));
53190
53191         dispatch$$1.call('startEditing');
53192     }
53193
53194
53195     chapter.enter = function() {
53196         showHelp();
53197     };
53198
53199
53200     chapter.exit = function() {
53201         modalSelection.remove();
53202         d3_selectAll('.shaded').remove();  // in case user opened keyboard shortcuts
53203     };
53204
53205
53206     return utilRebind(chapter, dispatch$$1, 'on');
53207 }
53208
53209 var chapterUi = {
53210     welcome: uiIntroWelcome,
53211     navigation: uiIntroNavigation,
53212     point: uiIntroPoint,
53213     area: uiIntroArea,
53214     line: uiIntroLine,
53215     building: uiIntroBuilding,
53216     startEditing: uiIntroStartEditing
53217 };
53218
53219 var chapterFlow = [
53220     'welcome',
53221     'navigation',
53222     'point',
53223     'area',
53224     'line',
53225     'building',
53226     'startEditing'
53227 ];
53228
53229
53230 function uiIntro(context) {
53231     var introGraph = {},
53232         currChapter;
53233
53234
53235     // create entities for intro graph and localize names
53236     for (var id in dataIntroGraph) {
53237         introGraph[id] = osmEntity(localize(dataIntroGraph[id]));
53238     }
53239
53240
53241     function intro(selection) {
53242         context.enter(modeBrowse(context));
53243
53244         // Save current map state
53245         var osm = context.connection(),
53246             history = context.history().toJSON(),
53247             hash = window.location.hash,
53248             center = context.map().center(),
53249             zoom = context.map().zoom(),
53250             background = context.background().baseLayerSource(),
53251             overlays = context.background().overlayLayerSources(),
53252             opacity = d3_selectAll('#map .layer-background').style('opacity'),
53253             loadedTiles = osm && osm.loadedTiles(),
53254             baseEntities = context.history().graph().base().entities,
53255             countryCode = services.geocoder.countryCode;
53256
53257         // Block saving
53258         context.inIntro(true);
53259
53260         // Load semi-real data used in intro
53261         if (osm) { osm.toggle(false).reset(); }
53262         context.history().reset();
53263         context.history().merge(values$1(coreGraph().load(introGraph).entities));
53264         context.history().checkpoint('initial');
53265
53266         var esri = context.background().findSource('EsriWorldImagery');
53267         if (esri) {
53268             context.background().baseLayerSource(esri);
53269         } else {
53270             context.background().bing();
53271         }
53272         overlays.forEach(function (d) {
53273             context.background().toggleOverlayLayer(d);
53274         });
53275
53276         // Mock geocoder
53277         services.geocoder.countryCode = function(location, callback) {
53278             callback(null, t('intro.graph.countrycode'));
53279         };
53280
53281         d3_selectAll('#map .layer-background').style('opacity', 1);
53282
53283         var curtain = uiCurtain();
53284         selection.call(curtain);
53285
53286         // store that the user started the walkthrough..
53287         context.storage('walkthrough_started', 'yes');
53288
53289         // restore previous walkthrough progress..
53290         var storedProgress = context.storage('walkthrough_progress') || '';
53291         var progress = storedProgress.split(';').filter(Boolean);
53292
53293         var chapters = chapterFlow.map(function(chapter, i) {
53294             var s = chapterUi[chapter](context, curtain.reveal)
53295                 .on('done', function() {
53296                     context.presets().init();  // clear away "recent" presets
53297
53298                     buttons.filter(function(d) {
53299                         return d.title === s.title;
53300                     }).classed('finished', true);
53301
53302                     if (i < chapterFlow.length - 1) {
53303                         var next = chapterFlow[i + 1];
53304                         d3_select('button.chapter-' + next)
53305                             .classed('next', true);
53306                     }
53307
53308                     // store walkthrough progress..
53309                     progress.push(chapter);
53310                     context.storage('walkthrough_progress', uniq(progress).join(';'));
53311                 });
53312             return s;
53313         });
53314
53315         chapters[chapters.length - 1].on('startEditing', function() {
53316             // store walkthrough progress..
53317             progress.push('startEditing');
53318             context.storage('walkthrough_progress', uniq(progress).join(';'));
53319
53320             // store if walkthrough is completed..
53321             var incomplete = difference(chapterFlow, progress);
53322             if (!incomplete.length) {
53323                 context.storage('walkthrough_completed', 'yes');
53324             }
53325
53326             curtain.remove();
53327             navwrap.remove();
53328             d3_selectAll('#map .layer-background').style('opacity', opacity);
53329             if (osm) { osm.toggle(true).reset().loadedTiles(loadedTiles); }
53330             context.history().reset().merge(values$1(baseEntities));
53331             context.background().baseLayerSource(background);
53332             overlays.forEach(function (d) { context.background().toggleOverlayLayer(d); });
53333             if (history) { context.history().fromJSON(history, false); }
53334             context.map().centerZoom(center, zoom);
53335             window.location.replace(hash);
53336             services.geocoder.countryCode = countryCode;
53337             context.inIntro(false);
53338         });
53339
53340         var navwrap = selection
53341             .append('div')
53342             .attr('class', 'intro-nav-wrap fillD');
53343
53344         navwrap
53345             .append('svg')
53346             .attr('class', 'intro-nav-wrap-logo')
53347             .append('use')
53348             .attr('xlink:href', '#logo-walkthrough');
53349
53350         var buttonwrap = navwrap
53351             .append('div')
53352             .attr('class', 'joined')
53353             .selectAll('button.chapter');
53354
53355         var buttons = buttonwrap
53356             .data(chapters)
53357             .enter()
53358             .append('button')
53359             .attr('class', function(d, i) { return 'chapter chapter-' + chapterFlow[i]; })
53360             .on('click', enterChapter);
53361
53362         buttons
53363             .append('span')
53364             .text(function(d) { return t(d.title); });
53365
53366         buttons
53367             .append('span')
53368             .attr('class', 'status')
53369             .call(svgIcon((textDirection === 'rtl' ? '#icon-backward' : '#icon-forward'), 'inline'));
53370
53371         enterChapter(chapters[0]);
53372
53373
53374         function enterChapter(newChapter) {
53375             if (currChapter) { currChapter.exit(); }
53376             context.enter(modeBrowse(context));
53377
53378             currChapter = newChapter;
53379             currChapter.enter();
53380
53381             buttons
53382                 .classed('next', false)
53383                 .classed('active', function(d) {
53384                     return d.title === currChapter.title;
53385                 });
53386         }
53387     }
53388
53389
53390     return intro;
53391 }
53392
53393 function uiTooltipHtml(text, key, heading) {
53394     var s = '';
53395
53396     if (heading) {
53397         s += '<div class="tooltip-heading"><span>' + heading + '</span></div>';
53398     }
53399     if (text) {
53400         s += '<div class="tooltip-text"><span>' + text + '</span></div>';
53401     }
53402     if (key) {
53403         s += '<div class="keyhint-wrap"><span>' + t('tooltip_keyhint') + '</span>' +
53404             '<span class="keyhint">' + key + '</span></div>';
53405     }
53406
53407     return s;
53408 }
53409
53410 function uiMapData(context) {
53411     var key = t('map_data.key');
53412     var features = context.features().keys();
53413     var layers = context.layers();
53414     var fills = ['wireframe', 'partial', 'full'];
53415
53416     var _fillDefault = context.storage('area-fill') || 'partial';
53417     var _fillSelected = _fillDefault;
53418     var _shown = false;
53419     var _dataLayerContainer = d3_select(null);
53420     var _fillList = d3_select(null);
53421     var _featureList = d3_select(null);
53422
53423
53424     function showsFeature(d) {
53425         return context.features().enabled(d);
53426     }
53427
53428
53429     function autoHiddenFeature(d) {
53430         return context.features().autoHidden(d);
53431     }
53432
53433
53434     function clickFeature(d) {
53435         context.features().toggle(d);
53436         update();
53437     }
53438
53439
53440     function showsFill(d) {
53441         return _fillSelected === d;
53442     }
53443
53444
53445     function setFill(d) {
53446         fills.forEach(function(opt) {
53447             context.surface().classed('fill-' + opt, Boolean(opt === d));
53448         });
53449
53450         _fillSelected = d;
53451         if (d !== 'wireframe') {
53452             _fillDefault = d;
53453             context.storage('area-fill', d);
53454         }
53455         update();
53456     }
53457
53458
53459     function showsLayer(which) {
53460         var layer = layers.layer(which);
53461         if (layer) {
53462             return layer.enabled();
53463         }
53464         return false;
53465     }
53466
53467
53468     function setLayer(which, enabled) {
53469         var layer = layers.layer(which);
53470         if (layer) {
53471             layer.enabled(enabled);
53472             update();
53473         }
53474     }
53475
53476
53477     function toggleLayer(which) {
53478         setLayer(which, !showsLayer(which));
53479     }
53480
53481
53482     function drawPhotoItems(selection) {
53483         var photoKeys = ['mapillary-images', 'mapillary-signs', 'openstreetcam-images'];
53484         var photoLayers = layers.all().filter(function(obj) { return photoKeys.indexOf(obj.id) !== -1; });
53485         var data = photoLayers.filter(function(obj) { return obj.layer.supported(); });
53486
53487         function layerSupported(d) {
53488             return d.layer && d.layer.supported();
53489         }
53490         function layerEnabled(d) {
53491             return layerSupported(d) && d.layer.enabled();
53492         }
53493
53494         var ul = selection
53495             .selectAll('.layer-list-photos')
53496             .data([0]);
53497
53498         ul = ul.enter()
53499             .append('ul')
53500             .attr('class', 'layer-list layer-list-photos')
53501             .merge(ul);
53502
53503         var li = ul.selectAll('.list-item-photos')
53504             .data(data);
53505
53506         li.exit()
53507             .remove();
53508
53509         var liEnter = li.enter()
53510             .append('li')
53511             .attr('class', function(d) { return 'list-item-photos list-item-' + d.id; });
53512
53513         var labelEnter = liEnter
53514             .append('label')
53515             .each(function(d) {
53516                 d3_select(this)
53517                     .call(tooltip()
53518                         .title(t(d.id.replace('-', '_') + '.tooltip'))
53519                         .placement('top')
53520                     );
53521             });
53522
53523         labelEnter
53524             .append('input')
53525             .attr('type', 'checkbox')
53526             .on('change', function(d) { toggleLayer(d.id); });
53527
53528         labelEnter
53529             .append('span')
53530             .text(function(d) { return t(d.id.replace('-', '_') + '.title'); });
53531
53532
53533         // Update
53534         li = li
53535             .merge(liEnter);
53536
53537         li
53538             .classed('active', layerEnabled)
53539             .selectAll('input')
53540             .property('checked', layerEnabled);
53541     }
53542
53543
53544     function drawOsmItem(selection) {
53545         var osm = layers.layer('osm'),
53546             showsOsm = osm.enabled();
53547
53548         var ul = selection
53549             .selectAll('.layer-list-osm')
53550             .data(osm ? [0] : []);
53551
53552         // Exit
53553         ul.exit()
53554             .remove();
53555
53556         // Enter
53557         var ulEnter = ul.enter()
53558             .append('ul')
53559             .attr('class', 'layer-list layer-list-osm');
53560
53561         var liEnter = ulEnter
53562             .append('li')
53563             .attr('class', 'list-item-osm');
53564
53565         var labelEnter = liEnter
53566             .append('label')
53567             .call(tooltip()
53568                 .title(t('map_data.layers.osm.tooltip'))
53569                 .placement('top')
53570             );
53571
53572         labelEnter
53573             .append('input')
53574             .attr('type', 'checkbox')
53575             .on('change', function() { toggleLayer('osm'); });
53576
53577         labelEnter
53578             .append('span')
53579             .text(t('map_data.layers.osm.title'));
53580
53581         // Update
53582         ul = ul
53583             .merge(ulEnter);
53584
53585         ul.selectAll('.list-item-osm')
53586             .classed('active', showsOsm)
53587             .selectAll('input')
53588             .property('checked', showsOsm);
53589     }
53590
53591
53592     function drawGpxItem(selection) {
53593         var gpx = layers.layer('gpx'),
53594             hasGpx = gpx && gpx.hasGpx(),
53595             showsGpx = hasGpx && gpx.enabled();
53596
53597         var ul = selection
53598             .selectAll('.layer-list-gpx')
53599             .data(gpx ? [0] : []);
53600
53601         // Exit
53602         ul.exit()
53603             .remove();
53604
53605         // Enter
53606         var ulEnter = ul.enter()
53607             .append('ul')
53608             .attr('class', 'layer-list layer-list-gpx');
53609
53610         var liEnter = ulEnter
53611             .append('li')
53612             .attr('class', 'list-item-gpx');
53613
53614         liEnter
53615             .append('button')
53616             .attr('class', 'list-item-gpx-extent')
53617             .call(tooltip()
53618                 .title(t('gpx.zoom'))
53619                 .placement((textDirection === 'rtl') ? 'right' : 'left')
53620             )
53621             .on('click', function() {
53622                 event.preventDefault();
53623                 event.stopPropagation();
53624                 gpx.fitZoom();
53625             })
53626             .call(svgIcon('#icon-search'));
53627
53628         liEnter
53629             .append('button')
53630             .attr('class', 'list-item-gpx-browse')
53631             .call(tooltip()
53632                 .title(t('gpx.browse'))
53633                 .placement((textDirection === 'rtl') ? 'right' : 'left')
53634             )
53635             .on('click', function() {
53636                 d3_select(document.createElement('input'))
53637                     .attr('type', 'file')
53638                     .on('change', function() {
53639                         gpx.files(event.target.files);
53640                     })
53641                     .node().click();
53642             })
53643             .call(svgIcon('#icon-geolocate'));
53644
53645         var labelEnter = liEnter
53646             .append('label')
53647             .call(tooltip()
53648                 .title(t('gpx.drag_drop'))
53649                 .placement('top')
53650             );
53651
53652         labelEnter
53653             .append('input')
53654             .attr('type', 'checkbox')
53655             .on('change', function() { toggleLayer('gpx'); });
53656
53657         labelEnter
53658             .append('span')
53659             .text(t('gpx.local_layer'));
53660
53661         // Update
53662         ul = ul
53663             .merge(ulEnter);
53664
53665         ul.selectAll('.list-item-gpx')
53666             .classed('active', showsGpx)
53667             .selectAll('label')
53668             .classed('deemphasize', !hasGpx)
53669             .selectAll('input')
53670             .property('disabled', !hasGpx)
53671             .property('checked', showsGpx);
53672     }
53673
53674
53675     function drawListItems(selection, data, type, name, change, active) {
53676         var items = selection.selectAll('li')
53677             .data(data);
53678
53679         // Exit
53680         items.exit()
53681             .remove();
53682
53683         // Enter
53684         var enter = items.enter()
53685             .append('li')
53686             .attr('class', 'layer')
53687             .call(tooltip()
53688                 .html(true)
53689                 .title(function(d) {
53690                     var tip = t(name + '.' + d + '.tooltip'),
53691                         key = (d === 'wireframe' ? t('area_fill.wireframe.key') : null);
53692
53693                     if (name === 'feature' && autoHiddenFeature(d)) {
53694                         var msg = showsLayer('osm') ? t('map_data.autohidden') : t('map_data.osmhidden');
53695                         tip += '<div>' + msg + '</div>';
53696                     }
53697                     return uiTooltipHtml(tip, key);
53698                 })
53699                 .placement('top')
53700             );
53701
53702         var label = enter
53703             .append('label');
53704
53705         label
53706             .append('input')
53707             .attr('type', type)
53708             .attr('name', name)
53709             .on('change', change);
53710
53711         label
53712             .append('span')
53713             .text(function(d) { return t(name + '.' + d + '.description'); });
53714
53715         // Update
53716         items = items
53717             .merge(enter);
53718
53719         items
53720             .classed('active', active)
53721             .selectAll('input')
53722             .property('checked', active)
53723             .property('indeterminate', function(d) {
53724                 return (name === 'feature' && autoHiddenFeature(d));
53725             });
53726     }
53727
53728
53729     function renderDataLayers(selection) {
53730         var container = selection.selectAll('data-layer-container')
53731             .data([0]);
53732
53733         _dataLayerContainer = container.enter()
53734             .append('div')
53735             .attr('class', 'data-layer-container')
53736             .merge(container);
53737     }
53738
53739
53740     function renderFillList(selection) {
53741         var container = selection.selectAll('layer-fill-list')
53742             .data([0]);
53743
53744         _fillList = container.enter()
53745             .append('ul')
53746             .attr('class', 'layer-list layer-fill-list')
53747             .merge(container);
53748     }
53749
53750
53751     function renderFeatureList(selection) {
53752         var container = selection.selectAll('layer-feature-list')
53753             .data([0]);
53754
53755         _featureList = container.enter()
53756             .append('ul')
53757             .attr('class', 'layer-list layer-feature-list')
53758             .merge(container);
53759     }
53760
53761
53762     function update() {
53763         _dataLayerContainer
53764             .call(drawOsmItem)
53765             .call(drawPhotoItems)
53766             .call(drawGpxItem);
53767
53768         _fillList
53769             .call(drawListItems, fills, 'radio', 'area_fill', setFill, showsFill);
53770
53771         _featureList
53772             .call(drawListItems, features, 'checkbox', 'feature', clickFeature, showsFeature);
53773     }
53774
53775
53776     function toggleWireframe() {
53777         if (event) {
53778             event.preventDefault();
53779             event.stopPropagation();
53780         }
53781         setFill((_fillSelected === 'wireframe' ? _fillDefault : 'wireframe'));
53782         context.map().pan([0,0]);  // trigger a redraw
53783     }
53784
53785
53786     function mapData(selection) {
53787
53788         function hidePane() {
53789             setVisible(false);
53790         }
53791
53792         function togglePane() {
53793             if (event) event.preventDefault();
53794             paneTooltip.hide(button);
53795             setVisible(!button.classed('active'));
53796         }
53797
53798         function setVisible(show) {
53799             if (show !== _shown) {
53800                 button.classed('active', show);
53801                 _shown = show;
53802
53803                 if (show) {
53804                     uiBackground.hidePane();
53805                     uiHelp.hidePane();
53806                     update();
53807
53808                     pane
53809                         .style('display', 'block')
53810                         .style('right', '-300px')
53811                         .transition()
53812                         .duration(200)
53813                         .style('right', '0px');
53814
53815                 } else {
53816                     pane
53817                         .style('display', 'block')
53818                         .style('right', '0px')
53819                         .transition()
53820                         .duration(200)
53821                         .style('right', '-300px')
53822                         .on('end', function() {
53823                             d3_select(this).style('display', 'none');
53824                         });
53825                 }
53826             }
53827         }
53828
53829
53830         var pane = selection
53831             .append('div')
53832             .attr('class', 'fillL map-overlay col3 content hide');
53833
53834         var paneTooltip = tooltip()
53835             .placement((textDirection === 'rtl') ? 'right' : 'left')
53836             .html(true)
53837             .title(uiTooltipHtml(t('map_data.description'), key));
53838
53839         var button = selection
53840             .append('button')
53841             .attr('tabindex', -1)
53842             .on('click', togglePane)
53843             .call(svgIcon('#icon-data', 'light'))
53844             .call(paneTooltip);
53845
53846
53847         pane
53848             .append('h2')
53849             .text(t('map_data.title'));
53850
53851
53852         // data layers
53853         pane
53854             .append('div')
53855             .attr('class', 'map-data-data-layers')
53856             .call(uiDisclosure(context, 'data_layers', true)
53857                 .title(t('map_data.data_layers'))
53858                 .content(renderDataLayers)
53859             );
53860
53861         // area fills
53862         pane
53863             .append('div')
53864             .attr('class', 'map-data-area-fills')
53865             .call(uiDisclosure(context, 'fill_area', false)
53866                 .title(t('map_data.fill_area'))
53867                 .content(renderFillList)
53868             );
53869
53870         // feature filters
53871         pane
53872             .append('div')
53873             .attr('class', 'map-data-feature-filters')
53874             .call(uiDisclosure(context, 'map_features', false)
53875                 .title(t('map_data.map_features'))
53876                 .content(renderFeatureList)
53877             );
53878
53879
53880         // add listeners
53881         context.features()
53882             .on('change.map_data-update', update);
53883
53884         update();
53885         setFill(_fillDefault);
53886
53887         var keybinding = d3keybinding('features')
53888             .on(key, togglePane)
53889             .on(t('area_fill.wireframe.key'), toggleWireframe)
53890             .on([t('background.key'), t('help.key')], hidePane);
53891
53892         d3_select(document)
53893             .call(keybinding);
53894
53895         uiMapData.hidePane = hidePane;
53896         uiMapData.togglePane = togglePane;
53897         uiMapData.setVisible = setVisible;
53898     }
53899
53900     return mapData;
53901 }
53902
53903 function uiShortcuts() {
53904     var detected = utilDetect();
53905     var activeTab = 0;
53906     var modalSelection;
53907     var savedSelection;
53908
53909
53910     var keybinding = d3keybinding('shortcuts')
53911         .on(t('shortcuts.toggle.key'), function () {
53912             if (d3_selectAll('.modal-shortcuts').size()) {  // already showing
53913                 if (modalSelection) {
53914                     modalSelection.close();
53915                     modalSelection = null;
53916                 }
53917             } else {
53918                 modalSelection = uiModal(savedSelection);
53919                 shortcutsModal(modalSelection);
53920             }
53921         });
53922
53923     d3_select(document)
53924         .call(keybinding);
53925
53926
53927
53928     function shortcutsModal(modalSelection) {
53929         modalSelection.select('.modal')
53930             .classed('modal-shortcuts', true);
53931
53932         var shortcutsModal = modalSelection.select('.content');
53933
53934         shortcutsModal
53935             .append('div')
53936             .attr('class', 'modal-section')
53937             .append('h3')
53938             .text(t('shortcuts.title'));
53939
53940         shortcutsModal
53941             .call(render);
53942     }
53943
53944
53945     function render(selection) {
53946         var wrapper = selection
53947             .selectAll('.wrapper')
53948             .data([0]);
53949
53950         var wrapperEnter = wrapper
53951             .enter()
53952             .append('div')
53953             .attr('class', 'wrapper modal-section');
53954
53955         var tabsBar = wrapperEnter
53956             .append('div')
53957             .attr('class', 'tabs-bar');
53958
53959         var shortcutsList = wrapperEnter
53960             .append('div')
53961             .attr('class', 'shortcuts-list');
53962
53963         wrapper = wrapper.merge(wrapperEnter);
53964
53965         var tabs = tabsBar
53966             .selectAll('.tab')
53967             .data(dataShortcuts);
53968
53969         var tabsEnter = tabs
53970             .enter()
53971             .append('div')
53972             .attr('class', 'tab')
53973             .on('click', function (d, i) {
53974                 activeTab = i;
53975                 render(selection);
53976             });
53977
53978         tabsEnter
53979             .append('span')
53980             .text(function (d) { return t(d.text); });
53981
53982         tabs = tabs
53983             .merge(tabsEnter);
53984
53985         // Update
53986         wrapper.selectAll('.tab')
53987             .classed('active', function (d, i) {
53988                 return i === activeTab;
53989             });
53990
53991
53992         var shortcuts = shortcutsList
53993             .selectAll('.shortcut-tab')
53994             .data(dataShortcuts);
53995
53996         var shortcutsEnter = shortcuts
53997             .enter()
53998             .append('div')
53999             .attr('class', function(d) { return 'shortcut-tab shortcut-tab-' + d.tab; });
54000
54001         var columnsEnter = shortcutsEnter
54002             .selectAll('.shortcut-column')
54003             .data(function (d) { return d.columns; })
54004             .enter()
54005             .append('table')
54006             .attr('class', 'shortcut-column');
54007
54008         var rowsEnter = columnsEnter
54009             .selectAll('.shortcut-row')
54010             .data(function (d) { return d.rows; })
54011             .enter()
54012             .append('tr')
54013             .attr('class', 'shortcut-row');
54014
54015
54016         var sectionRows = rowsEnter
54017             .filter(function (d) { return !d.shortcuts; });
54018
54019         sectionRows
54020             .append('td');
54021
54022         sectionRows
54023             .append('td')
54024             .attr('class', 'shortcut-section')
54025             .append('h3')
54026             .text(function (d) { return t(d.text); });
54027
54028
54029         var shortcutRows = rowsEnter
54030             .filter(function (d) { return d.shortcuts; });
54031
54032         var shortcutKeys = shortcutRows
54033             .append('td')
54034             .attr('class', 'shortcut-keys');
54035
54036         var modifierKeys = shortcutKeys
54037             .filter(function (d) { return d.modifiers; });
54038
54039         modifierKeys
54040             .selectAll('kbd.modifier')
54041             .data(function (d) {
54042                 if (detected.os === 'win' && d.text === 'shortcuts.editing.commands.redo') {
54043                     return ['⌘'];
54044                 } else if (detected.os !== 'mac' && d.text === 'shortcuts.browsing.display_options.fullscreen') {
54045                     return [];
54046                 } else {
54047                     return d.modifiers;
54048                 }
54049             })
54050             .enter()
54051             .each(function () {
54052                 var selection = d3_select(this);
54053
54054                 selection
54055                     .append('kbd')
54056                     .attr('class', 'modifier')
54057                     .text(function (d) { return uiCmd.display(d); });
54058
54059                 selection
54060                     .append('span')
54061                     .text('+');
54062             });
54063
54064
54065         shortcutKeys
54066             .selectAll('kbd.shortcut')
54067             .data(function (d) {
54068                 var arr = d.shortcuts;
54069                 if (detected.os === 'win' && d.text === 'shortcuts.editing.commands.redo') {
54070                     arr = ['Y'];
54071                 } else if (detected.os !== 'mac' && d.text === 'shortcuts.browsing.display_options.fullscreen') {
54072                     arr = ['F11'];
54073                 }
54074
54075                 return arr.map(function(s) {
54076                     return {
54077                         shortcut: s,
54078                         separator: d.separator
54079                     };
54080                 });
54081             })
54082             .enter()
54083             .each(function (d, i, nodes) {
54084                 var selection = d3_select(this);
54085                 var click = d.shortcut.toLowerCase().match(/(.*).click/);
54086
54087                 if (click && click[1]) {
54088                     selection
54089                         .call(svgIcon('#walkthrough-mouse', 'mouseclick', click[1]));
54090                 } else {
54091                     selection
54092                         .append('kbd')
54093                         .attr('class', 'shortcut')
54094                         .text(function (d) {
54095                             var key = d.shortcut;
54096                             return key.indexOf('.') !== -1 ? uiCmd.display(t(key)) : uiCmd.display(key);
54097                         });
54098                 }
54099
54100                 if (i < nodes.length - 1) {
54101                     selection
54102                         .append('span')
54103                         .text(d.separator || '\u00a0' + t('shortcuts.or') + '\u00a0');
54104                 }
54105             });
54106
54107
54108         shortcutKeys
54109             .filter(function(d) { return d.gesture; })
54110             .each(function () {
54111                 var selection = d3_select(this);
54112
54113                 selection
54114                     .append('span')
54115                     .text('+');
54116
54117                 selection
54118                     .append('span')
54119                     .attr('class', 'gesture')
54120                     .text(function (d) { return t(d.gesture); });
54121             });
54122
54123
54124         shortcutRows
54125             .append('td')
54126             .attr('class', 'shortcut-desc')
54127             .text(function (d) { return d.text ? t(d.text) : '\u00a0'; });
54128
54129
54130         shortcuts = shortcuts
54131             .merge(shortcutsEnter);
54132
54133         // Update
54134         wrapper.selectAll('.shortcut-tab')
54135             .style('display', function (d, i) {
54136                 return i === activeTab ? 'flex' : 'none';
54137             });
54138     }
54139
54140
54141     return function(selection, show) {
54142         savedSelection = selection;
54143         if (show) {
54144             modalSelection = uiModal(selection);
54145             shortcutsModal(modalSelection);
54146         }
54147     };
54148 }
54149
54150 function uiHelp(context) {
54151     var key = t('help.key');
54152
54153     var docKeys = [
54154         ['help', [
54155             'welcome',
54156             'open_data_h',
54157             'open_data',
54158             'before_start_h',
54159             'before_start',
54160             'open_source_h',
54161             'open_source',
54162             'open_source_help'
54163         ]],
54164         ['overview', [
54165             'navigation_h',
54166             'navigation_drag',
54167             'navigation_zoom',
54168             'features_h',
54169             'features',
54170             'nodes_ways'
54171         ]],
54172         ['editing', [
54173             'select_h',
54174             'select_left_click',
54175             'select_right_click',
54176             'multiselect_h',
54177             'multiselect_shift_click',
54178             'multiselect_lasso',
54179             'undo_redo_h',
54180             'undo_redo',
54181             'save_h',
54182             'save',
54183             'save_validation',
54184             'upload_h',
54185             'upload',
54186             'backups_h',
54187             'backups',
54188             'keyboard_h',
54189             'keyboard'
54190         ]],
54191         ['feature_editor', [
54192             'intro',
54193             'definitions',
54194             'type_h',
54195             'type',
54196             'type_picker',
54197             'fields_h',
54198             'fields_all_fields',
54199             'fields_example',
54200             'fields_add_field',
54201             'tags_h',
54202             'tags_all_tags',
54203             'tags_resources'
54204         ]],
54205         ['points', [
54206             'intro',
54207             'add_point_h',
54208             'add_point',
54209             'add_point_finish',
54210             'move_point_h',
54211             'move_point',
54212             'delete_point_h',
54213             'delete_point',
54214             'delete_point_command'
54215         ]],
54216         ['lines', [
54217             'intro',
54218             'add_line_h',
54219             'add_line',
54220             'add_line_draw',
54221             'add_line_finish',
54222             'modify_line_h',
54223             'modify_line_dragnode',
54224             'modify_line_addnode',
54225             'connect_line_h',
54226             'connect_line',
54227             'connect_line_display',
54228             'connect_line_drag',
54229             'connect_line_tag',
54230             'disconnect_line_h',
54231             'disconnect_line_command',
54232             'move_line_h',
54233             'move_line_command',
54234             'move_line_connected',
54235             'delete_line_h',
54236             'delete_line',
54237             'delete_line_command'
54238         ]],
54239         ['areas', [
54240             'intro',
54241             'point_or_area_h',
54242             'point_or_area',
54243             'add_area_h',
54244             'add_area_command',
54245             'add_area_draw',
54246             'add_area_finish',
54247             'square_area_h',
54248             'square_area_command',
54249             'modify_area_h',
54250             'modify_area_dragnode',
54251             'modify_area_addnode',
54252             'delete_area_h',
54253             'delete_area',
54254             'delete_area_command'
54255         ]],
54256         ['relations', [
54257             'intro',
54258             'edit_relation_h',
54259             'edit_relation',
54260             'edit_relation_add',
54261             'edit_relation_delete',
54262             'maintain_relation_h',
54263             'maintain_relation',
54264             'relation_types_h',
54265             'multipolygon_h',
54266             'multipolygon',
54267             'multipolygon_create',
54268             'multipolygon_merge',
54269             'turn_restriction_h',
54270             'turn_restriction',
54271             'turn_restriction_field',
54272             'turn_restriction_editing',
54273             'route_h',
54274             'route',
54275             'route_add',
54276             'boundary_h',
54277             'boundary',
54278             'boundary_add'
54279         ]],
54280         ['imagery', [
54281             'intro',
54282             'sources_h',
54283             'choosing',
54284             'sources',
54285             'offsets_h',
54286             'offset',
54287             'offset_change'
54288         ]],
54289         ['streetlevel', [
54290             'intro',
54291             'using_h',
54292             'using',
54293             'photos',
54294             'viewer'
54295         ]],
54296         ['gps', [
54297             'intro',
54298             'survey',
54299             'using_h',
54300             'using',
54301             'tracing',
54302             'upload'
54303         ]]
54304     ];
54305
54306     var headings = {
54307         'help.help.open_data_h': 3,
54308         'help.help.before_start_h': 3,
54309         'help.help.open_source_h': 3,
54310         'help.overview.navigation_h': 3,
54311         'help.overview.features_h': 3,
54312         'help.editing.select_h': 3,
54313         'help.editing.multiselect_h': 3,
54314         'help.editing.undo_redo_h': 3,
54315         'help.editing.save_h': 3,
54316         'help.editing.upload_h': 3,
54317         'help.editing.backups_h': 3,
54318         'help.editing.keyboard_h': 3,
54319         'help.feature_editor.type_h': 3,
54320         'help.feature_editor.fields_h': 3,
54321         'help.feature_editor.tags_h': 3,
54322         'help.points.add_point_h': 3,
54323         'help.points.move_point_h': 3,
54324         'help.points.delete_point_h': 3,
54325         'help.lines.add_line_h': 3,
54326         'help.lines.modify_line_h': 3,
54327         'help.lines.connect_line_h': 3,
54328         'help.lines.disconnect_line_h': 3,
54329         'help.lines.move_line_h': 3,
54330         'help.lines.delete_line_h': 3,
54331         'help.areas.point_or_area_h': 3,
54332         'help.areas.add_area_h': 3,
54333         'help.areas.square_area_h': 3,
54334         'help.areas.modify_area_h': 3,
54335         'help.areas.delete_area_h': 3,
54336         'help.relations.edit_relation_h': 3,
54337         'help.relations.maintain_relation_h': 3,
54338         'help.relations.relation_types_h': 2,
54339         'help.relations.multipolygon_h': 3,
54340         'help.relations.turn_restriction_h': 3,
54341         'help.relations.route_h': 3,
54342         'help.relations.boundary_h': 3,
54343         'help.imagery.sources_h': 3,
54344         'help.imagery.offsets_h': 3,
54345         'help.streetlevel.using_h': 3,
54346         'help.gps.using_h': 3,
54347     };
54348
54349     var replacements = {
54350         point: icon('#icon-point', 'pre-text'),
54351         line: icon('#icon-line', 'pre-text'),
54352         area: icon('#icon-area', 'pre-text'),
54353         plus: icon('#icon-plus', 'pre-text'),
54354         minus: icon('#icon-minus', 'pre-text'),
54355         orthogonalize: icon('#operation-orthogonalize', 'pre-text'),
54356         disconnect: icon('#operation-disconnect', 'pre-text'),
54357         layers: icon('#icon-layers', 'pre-text'),
54358         data: icon('#icon-data', 'pre-text'),
54359         inspect: icon('#icon-inspect', 'pre-text'),
54360         move: icon('#operation-move', 'pre-text'),
54361         merge: icon('#operation-merge', 'pre-text'),
54362         delete: icon('#operation-delete', 'pre-text'),
54363         close: icon('#icon-close', 'pre-text'),
54364         undo: icon(textDirection === 'rtl' ? '#icon-redo' : '#icon-undo', 'pre-text'),
54365         redo: icon(textDirection === 'rtl' ? '#icon-undo' : '#icon-redo', 'pre-text'),
54366         save: icon('#icon-save', 'pre-text'),
54367         leftclick: icon('#walkthrough-mouse', 'pre-text mouseclick', 'left'),
54368         rightclick: icon('#walkthrough-mouse', 'pre-text mouseclick', 'right'),
54369         shift: uiCmd.display('⇧'),
54370         alt: uiCmd.display('⌥'),
54371         return: uiCmd.display('↵'),
54372         version: context.version
54373     };
54374
54375     // For each section, squash all the texts into a single markdown document
54376     var docs = docKeys.map(function(key) {
54377         var helpkey = 'help.' + key[0];
54378         var text = key[1].reduce(function(all, part) {
54379             var subkey = helpkey + '.' + part;
54380             var depth = headings[subkey];                              // is this subkey a heading?
54381             var hhh = depth ? Array(depth + 1).join('#') + ' ' : '';   // if so, prepend with some ##'s
54382             return all + hhh + t(subkey, replacements) + '\n\n';
54383         }, '');
54384
54385         return {
54386             title: t(helpkey + '.title'),
54387             html: marked(text.trim())
54388         };
54389     });
54390
54391
54392     function help(selection) {
54393
54394         function hidePane() {
54395             setVisible(false);
54396         }
54397
54398
54399         function togglePane() {
54400             if (event) event.preventDefault();
54401             tooltipBehavior.hide(button);
54402             setVisible(!button.classed('active'));
54403         }
54404
54405
54406         function setVisible(show) {
54407             if (show !== shown) {
54408                 button.classed('active', show);
54409                 shown = show;
54410
54411                 if (show) {
54412                     uiBackground.hidePane();
54413                     uiMapData.hidePane();
54414
54415                     pane.style('display', 'block')
54416                         .style('right', '-500px')
54417                         .transition()
54418                         .duration(200)
54419                         .style('right', '0px');
54420
54421                 } else {
54422                     pane.style('right', '0px')
54423                         .transition()
54424                         .duration(200)
54425                         .style('right', '-500px')
54426                         .on('end', function() {
54427                             d3_select(this).style('display', 'none');
54428                         });
54429                 }
54430             }
54431         }
54432
54433
54434         function clickHelp(d, i) {
54435             var rtl = (textDirection === 'rtl');
54436             pane.property('scrollTop', 0);
54437             doctitle.html(d.title);
54438
54439             body.html(d.html);
54440             body.selectAll('a')
54441                 .attr('target', '_blank');
54442             menuItems.classed('selected', function(m) {
54443                 return m.title === d.title;
54444             });
54445
54446             nav.html('');
54447             if (rtl) {
54448                 nav.call(drawNext).call(drawPrevious);
54449             } else {
54450                 nav.call(drawPrevious).call(drawNext);
54451             }
54452
54453
54454             function drawNext(selection) {
54455                 if (i < docs.length - 1) {
54456                     var nextLink = selection
54457                         .append('a')
54458                         .attr('class', 'next')
54459                         .on('click', function() {
54460                             clickHelp(docs[i + 1], i + 1);
54461                         });
54462
54463                     nextLink
54464                         .append('span')
54465                         .text(docs[i + 1].title)
54466                         .call(svgIcon((rtl ? '#icon-backward' : '#icon-forward'), 'inline'));
54467                 }
54468             }
54469
54470
54471             function drawPrevious(selection) {
54472                 if (i > 0) {
54473                     var prevLink = selection
54474                         .append('a')
54475                         .attr('class', 'previous')
54476                         .on('click', function() {
54477                             clickHelp(docs[i - 1], i - 1);
54478                         });
54479
54480                     prevLink
54481                         .call(svgIcon((rtl ? '#icon-forward' : '#icon-backward'), 'inline'))
54482                         .append('span')
54483                         .text(docs[i - 1].title);
54484                 }
54485             }
54486         }
54487
54488
54489         function clickWalkthrough() {
54490             if (context.inIntro()) return;
54491             context.container().call(uiIntro(context));
54492             setVisible(false);
54493         }
54494
54495
54496         function clickShortcuts() {
54497             context.container().call(uiShortcuts(context), true);
54498         }
54499
54500
54501         var pane = selection.append('div')
54502             .attr('class', 'help-wrap map-overlay fillL col6 content hide');
54503         var tooltipBehavior = tooltip()
54504             .placement((textDirection === 'rtl') ? 'right' : 'left')
54505             .html(true)
54506             .title(uiTooltipHtml(t('help.title'), key));
54507         var button = selection.append('button')
54508             .attr('tabindex', -1)
54509             .on('click', togglePane)
54510             .call(svgIcon('#icon-help', 'light'))
54511             .call(tooltipBehavior);
54512         var shown = false;
54513
54514
54515         var toc = pane
54516             .append('ul')
54517             .attr('class', 'toc');
54518
54519         var menuItems = toc.selectAll('li')
54520             .data(docs)
54521             .enter()
54522             .append('li')
54523             .append('a')
54524             .html(function(d) { return d.title; })
54525             .on('click', clickHelp);
54526
54527         var shortcuts = toc
54528             .append('li')
54529             .attr('class', 'shortcuts')
54530             .call(tooltip()
54531                 .html(true)
54532                 .title(uiTooltipHtml(t('shortcuts.tooltip'), '?'))
54533                 .placement('top')
54534             )
54535             .append('a')
54536             .on('click', clickShortcuts);
54537
54538         shortcuts
54539             .append('div')
54540             .text(t('shortcuts.title'));
54541
54542         var walkthrough = toc
54543             .append('li')
54544             .attr('class', 'walkthrough')
54545             .append('a')
54546             .on('click', clickWalkthrough);
54547
54548         walkthrough
54549             .append('svg')
54550             .attr('class', 'logo logo-walkthrough')
54551             .append('use')
54552             .attr('xlink:href', '#logo-walkthrough');
54553
54554         walkthrough
54555             .append('div')
54556             .text(t('splash.walkthrough'));
54557
54558
54559         var content = pane
54560             .append('div')
54561             .attr('class', 'left-content');
54562
54563         var doctitle = content
54564             .append('h2')
54565             .text(t('help.title'));
54566
54567         var body = content
54568             .append('div')
54569             .attr('class', 'body');
54570
54571         var nav = content
54572             .append('div')
54573             .attr('class', 'nav');
54574
54575         clickHelp(docs[0], 0);
54576
54577         var keybinding = d3keybinding('help')
54578             .on(key, togglePane)
54579             .on([t('background.key'), t('map_data.key')], hidePane);
54580
54581         d3_select(document)
54582             .call(keybinding);
54583
54584         uiHelp.hidePane = hidePane;
54585         uiHelp.togglePane = togglePane;
54586         uiHelp.setVisible = setVisible;
54587     }
54588
54589     return help;
54590 }
54591
54592 function localeDateString(s) {
54593     if (!s) return null;
54594     var detected = utilDetect();
54595     var options = { day: 'numeric', month: 'short', year: 'numeric' };
54596     var d = new Date(s);
54597     if (isNaN(d.getTime())) return null;
54598     return d.toLocaleDateString(detected.locale, options);
54599 }
54600
54601 function vintageRange(vintage) {
54602     var s;
54603     if (vintage.start || vintage.end) {
54604         s = (vintage.start || '?');
54605         if (vintage.start !== vintage.end) {
54606             s += ' - ' + (vintage.end || '?');
54607         }
54608     }
54609     return s;
54610 }
54611
54612
54613 function rendererBackgroundSource(data) {
54614     var source = clone(data);
54615     var offset = [0, 0];
54616     var name = source.name;
54617     var description = source.description;
54618     var best = !!source.best;
54619     var template = source.template;
54620
54621     source.scaleExtent = data.scaleExtent || [0, 22];
54622     source.overzoom = data.overzoom !== false;
54623
54624
54625     source.offset = function(_) {
54626         if (!arguments.length) return offset;
54627         offset = _;
54628         return source;
54629     };
54630
54631
54632     source.nudge = function(_, zoomlevel) {
54633         offset[0] += _[0] / Math.pow(2, zoomlevel);
54634         offset[1] += _[1] / Math.pow(2, zoomlevel);
54635         return source;
54636     };
54637
54638
54639     source.name = function() {
54640         var id_safe = source.id.replace('.', '<TX_DOT>');
54641         return t('imagery.' + id_safe + '.name', { default: name });
54642     };
54643
54644
54645     source.description = function() {
54646         var id_safe = source.id.replace('.', '<TX_DOT>');
54647         return t('imagery.' + id_safe + '.description', { default: description });
54648     };
54649
54650
54651     source.best = function() {
54652         return best;
54653     };
54654
54655
54656     source.area = function() {
54657         if (!data.polygon) return Number.MAX_VALUE;  // worldwide
54658         var area = d3_geoArea({ type: 'MultiPolygon', coordinates: [ data.polygon ] });
54659         return isNaN(area) ? 0 : area;
54660     };
54661
54662
54663     source.imageryUsed = function() {
54664         return name || source.id;
54665     };
54666
54667
54668     source.template = function(_) {
54669         if (!arguments.length) return template;
54670         if (source.id === 'custom') template = _;
54671         return source;
54672     };
54673
54674
54675     source.url = function(coord) {
54676         return template
54677             .replace('{x}', coord[0])
54678             .replace('{y}', coord[1])
54679             // TMS-flipped y coordinate
54680             .replace(/\{[t-]y\}/, Math.pow(2, coord[2]) - coord[1] - 1)
54681             .replace(/\{z(oom)?\}/, coord[2])
54682             .replace(/\{switch:([^}]+)\}/, function(s, r) {
54683                 var subdomains = r.split(',');
54684                 return subdomains[(coord[0] + coord[1]) % subdomains.length];
54685             })
54686             .replace('{u}', function() {
54687                 var u = '';
54688                 for (var zoom = coord[2]; zoom > 0; zoom--) {
54689                     var b = 0;
54690                     var mask = 1 << (zoom - 1);
54691                     if ((coord[0] & mask) !== 0) b++;
54692                     if ((coord[1] & mask) !== 0) b += 2;
54693                     u += b.toString();
54694                 }
54695                 return u;
54696             });
54697     };
54698
54699
54700     source.intersects = function(extent) {
54701         extent = extent.polygon();
54702         return !data.polygon || data.polygon.some(function(polygon) {
54703             return geoPolygonIntersectsPolygon(polygon, extent, true);
54704         });
54705     };
54706
54707
54708     source.validZoom = function(z) {
54709         return source.scaleExtent[0] <= z &&
54710             (source.overzoom || source.scaleExtent[1] > z);
54711     };
54712
54713
54714     source.isLocatorOverlay = function() {
54715         return source.id === 'mapbox_locator_overlay';
54716     };
54717
54718
54719     /* hides a source from the list, but leaves it available for use */
54720     source.isHidden = function() {
54721         return source.id === 'DigitalGlobe-Premium-vintage' ||
54722             source.id === 'DigitalGlobe-Standard-vintage';
54723     };
54724
54725
54726     source.copyrightNotices = function() {};
54727
54728
54729     source.getMetadata = function(center, tileCoord, callback) {
54730         var vintage = {
54731             start: localeDateString(source.startDate),
54732             end: localeDateString(source.endDate)
54733         };
54734         vintage.range = vintageRange(vintage);
54735
54736         var metadata = { vintage: vintage };
54737         callback(null, metadata);
54738     };
54739
54740
54741     return source;
54742 }
54743
54744
54745 rendererBackgroundSource.Bing = function(data, dispatch) {
54746     // http://msdn.microsoft.com/en-us/library/ff701716.aspx
54747     // http://msdn.microsoft.com/en-us/library/ff701701.aspx
54748
54749     data.template = 'https://ecn.t{switch:0,1,2,3}.tiles.virtualearth.net/tiles/a{u}.jpeg?g=587&mkt=en-gb&n=z';
54750
54751     var bing = rendererBackgroundSource(data),
54752         key = 'Arzdiw4nlOJzRwOz__qailc8NiR31Tt51dN2D7cm57NrnceZnCpgOkmJhNpGoppU', // Same as P2 and JOSM
54753         url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial?include=ImageryProviders&key=' +
54754             key + '&jsonp={callback}',
54755         cache = {},
54756         inflight = {},
54757         providers = [];
54758
54759     jsonpRequest(url, function(json) {
54760         providers = json.resourceSets[0].resources[0].imageryProviders.map(function(provider) {
54761             return {
54762                 attribution: provider.attribution,
54763                 areas: provider.coverageAreas.map(function(area) {
54764                     return {
54765                         zoom: [area.zoomMin, area.zoomMax],
54766                         extent: geoExtent([area.bbox[1], area.bbox[0]], [area.bbox[3], area.bbox[2]])
54767                     };
54768                 })
54769             };
54770         });
54771         dispatch.call('change');
54772     });
54773
54774
54775     bing.copyrightNotices = function(zoom, extent) {
54776         zoom = Math.min(zoom, 21);
54777         return providers.filter(function(provider) {
54778             return some(provider.areas, function(area) {
54779                 return extent.intersects(area.extent) &&
54780                     area.zoom[0] <= zoom &&
54781                     area.zoom[1] >= zoom;
54782             });
54783         }).map(function(provider) {
54784             return provider.attribution;
54785         }).join(', ');
54786     };
54787
54788
54789     bing.getMetadata = function(center, tileCoord, callback) {
54790         var tileId = tileCoord.slice(0, 3).join('/'),
54791             zoom = Math.min(tileCoord[2], 21),
54792             centerPoint = center[1] + ',' + center[0],  // lat,lng
54793             url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial/' + centerPoint +
54794                 '?zl=' + zoom + '&key=' + key + '&jsonp={callback}';
54795
54796         if (inflight[tileId]) return;
54797
54798         if (!cache[tileId]) {
54799             cache[tileId] = {};
54800         }
54801         if (cache[tileId] && cache[tileId].metadata) {
54802             return callback(null, cache[tileId].metadata);
54803         }
54804
54805         inflight[tileId] = true;
54806         jsonpRequest(url, function(result) {
54807             delete inflight[tileId];
54808
54809             var err = (!result && 'Unknown Error') || result.errorDetails;
54810             if (err) {
54811                 return callback(err);
54812             } else {
54813                 var vintage = {
54814                     start: localeDateString(result.resourceSets[0].resources[0].vintageStart),
54815                     end: localeDateString(result.resourceSets[0].resources[0].vintageEnd)
54816                 };
54817                 vintage.range = vintageRange(vintage);
54818
54819                 var metadata = { vintage: vintage };
54820                 cache[tileId].metadata = metadata;
54821                 return callback(null, metadata);
54822             }
54823         });
54824     };
54825
54826
54827     bing.terms_url = 'https://blog.openstreetmap.org/2010/11/30/microsoft-imagery-details';
54828
54829
54830     return bing;
54831 };
54832
54833
54834
54835 rendererBackgroundSource.Esri = function(data) {
54836
54837     // don't request blank tiles, instead overzoom real tiles - #4327
54838     // deprecated technique, but it works (for now)
54839     if (data.template.match(/blankTile/) === null) {
54840         data.template = data.template + '?blankTile=false';
54841     }
54842
54843     var esri = rendererBackgroundSource(data),
54844         cache = {},
54845         inflight = {};
54846
54847     esri.getMetadata = function(center, tileCoord, callback) {
54848         var tileId = tileCoord.slice(0, 3).join('/'),
54849             zoom = Math.min(tileCoord[2], esri.scaleExtent[1]),
54850             centerPoint = center[0] + ',' + center[1],  // long, lat (as it should be)
54851             unknown = t('info_panels.background.unknown'),
54852             metadataLayer,
54853             vintage = {},
54854             metadata = {};
54855
54856         if (inflight[tileId]) return;
54857
54858         switch (true) {
54859             case zoom >= 19:
54860                 metadataLayer = 3;
54861                 break;
54862             case zoom >= 17:
54863                 metadataLayer = 2;
54864                 break;
54865             case zoom >= 13:
54866                 metadataLayer = 0;
54867                 break;
54868             default:
54869                 metadataLayer = 99;
54870         }
54871
54872         // build up query using the layer appropriate to the current zoom
54873         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}';
54874
54875         if (!cache[tileId]) {
54876             cache[tileId] = {};
54877         }
54878         if (cache[tileId] && cache[tileId].metadata) {
54879             return callback(null, cache[tileId].metadata);
54880         }
54881
54882         // accurate metadata is only available >= 13
54883         if (metadataLayer === 99) {
54884             vintage = {
54885                 start: null,
54886                 end: null,
54887                 range: null
54888             };
54889             metadata = {
54890                 vintage: null,
54891                 source: unknown,
54892                 description: unknown,
54893                 resolution: unknown,
54894                 accuracy: unknown
54895             };
54896
54897             callback(null, metadata);
54898
54899         } else {
54900             inflight[tileId] = true;
54901             jsonpRequest(url, function(result) {
54902                 delete inflight[tileId];
54903
54904                 var err;
54905                 if (!result) {
54906                     err = 'Unknown Error';
54907                 } else if (result.features && result.features.length < 1) {
54908                     err = 'No Results';
54909                 } else if (result.error && result.error.message) {
54910                     err = result.error.message;
54911                 }
54912
54913                 if (err) {
54914                     return callback(err);
54915                 } else {
54916                     // pass through the discrete capture date from metadata
54917                     var captureDate = localeDateString(result.features[0].attributes.SRC_DATE2);
54918                     vintage = {
54919                         start: captureDate,
54920                         end: captureDate,
54921                         range: captureDate
54922                     };
54923                     metadata = {
54924                         vintage: vintage,
54925                         source: clean(result.features[0].attributes.NICE_NAME),
54926                         description: clean(result.features[0].attributes.NICE_DESC),
54927                         resolution: clean(result.features[0].attributes.SRC_RES),
54928                         accuracy: clean(result.features[0].attributes.SRC_ACC)
54929                     };
54930
54931                     // append units - meters
54932                     if (isFinite(metadata.resolution)) {
54933                         metadata.resolution += ' m';
54934                     }
54935                     if (isFinite(metadata.accuracy)) {
54936                         metadata.accuracy += ' m';
54937                     }
54938
54939                     cache[tileId].metadata = metadata;
54940                     return callback(null, metadata);
54941                 }
54942             });
54943         }
54944
54945
54946         function clean(val) {
54947             return String(val).trim() || unknown;
54948         }
54949     };
54950
54951     return esri;
54952 };
54953
54954
54955 rendererBackgroundSource.None = function() {
54956     var source = rendererBackgroundSource({ id: 'none', template: '' });
54957
54958
54959     source.name = function() {
54960         return t('background.none');
54961     };
54962
54963
54964     source.imageryUsed = function() {
54965         return 'None';
54966     };
54967
54968
54969     source.area = function() {
54970         return -1;  // sources in background pane are sorted by area
54971     };
54972
54973
54974     return source;
54975 };
54976
54977
54978 rendererBackgroundSource.Custom = function(template) {
54979     var source = rendererBackgroundSource({ id: 'custom', template: template });
54980
54981
54982     source.name = function() {
54983         return t('background.custom');
54984     };
54985
54986
54987     source.imageryUsed = function() {
54988         return 'Custom (' + source.template() + ')';
54989     };
54990
54991
54992     source.area = function() {
54993         return -2;  // sources in background pane are sorted by area
54994     };
54995
54996
54997     return source;
54998 };
54999
55000 function rendererTileLayer(context) {
55001     var tileSize = 256;
55002     var transformProp = utilPrefixCSSProperty('Transform');
55003     var geotile = d3geoTile();
55004
55005     var _projection;
55006     var _cache = {};
55007     var _tileOrigin;
55008     var _zoom;
55009     var _source;
55010
55011
55012     // blacklist overlay tiles around Null Island..
55013     function nearNullIsland(x, y, z) {
55014         if (z >= 7) {
55015             var center = Math.pow(2, z - 1);
55016             var width = Math.pow(2, z - 6);
55017             var min = center - (width / 2);
55018             var max = center + (width / 2) - 1;
55019             return x >= min && x <= max && y >= min && y <= max;
55020         }
55021         return false;
55022     }
55023
55024
55025     function tileSizeAtZoom(d, z) {
55026         var EPSILON = 0.002;
55027         return ((tileSize * Math.pow(2, z - d[2])) / tileSize) + EPSILON;
55028     }
55029
55030
55031     function atZoom(t$$1, distance) {
55032         var power = Math.pow(2, distance);
55033         return [
55034             Math.floor(t$$1[0] * power),
55035             Math.floor(t$$1[1] * power),
55036             t$$1[2] + distance
55037         ];
55038     }
55039
55040
55041     function lookUp(d) {
55042         for (var up = -1; up > -d[2]; up--) {
55043             var tile = atZoom(d, up);
55044             if (_cache[_source.url(tile)] !== false) {
55045                 return tile;
55046             }
55047         }
55048     }
55049
55050
55051     function uniqueBy(a, n) {
55052         var o = [];
55053         var seen = {};
55054         for (var i = 0; i < a.length; i++) {
55055             if (seen[a[i][n]] === undefined) {
55056                 o.push(a[i]);
55057                 seen[a[i][n]] = true;
55058             }
55059         }
55060         return o;
55061     }
55062
55063
55064     function addSource(d) {
55065         d.push(_source.url(d));
55066         return d;
55067     }
55068
55069
55070     // Update tiles based on current state of `projection`.
55071     function background(selection) {
55072         _zoom = geoScaleToZoom(_projection.scale(), tileSize);
55073
55074         var pixelOffset;
55075         if (_source) {
55076             pixelOffset = [
55077                 _source.offset()[0] * Math.pow(2, _zoom),
55078                 _source.offset()[1] * Math.pow(2, _zoom)
55079             ];
55080         } else {
55081             pixelOffset = [0, 0];
55082         }
55083
55084         var translate = [
55085             _projection.translate()[0] + pixelOffset[0],
55086             _projection.translate()[1] + pixelOffset[1]
55087         ];
55088
55089         geotile
55090             .scale(_projection.scale() * 2 * Math.PI)
55091             .translate(translate);
55092
55093         _tileOrigin = [
55094             _projection.scale() * Math.PI - translate[0],
55095             _projection.scale() * Math.PI - translate[1]
55096         ];
55097
55098         render(selection);
55099     }
55100
55101
55102     // Derive the tiles onscreen, remove those offscreen and position them.
55103     // Important that this part not depend on `_projection` because it's
55104     // rentered when tiles load/error (see #644).
55105     function render(selection) {
55106         if (!_source) return;
55107         var requests = [];
55108         var showDebug = context.getDebug('tile') && !_source.overlay;
55109
55110         if (_source.validZoom(_zoom)) {
55111             geotile().forEach(function(d) {
55112                 addSource(d);
55113                 if (d[3] === '') return;
55114                 if (typeof d[3] !== 'string') return; // Workaround for #2295
55115                 requests.push(d);
55116                 if (_cache[d[3]] === false && lookUp(d)) {
55117                     requests.push(addSource(lookUp(d)));
55118                 }
55119             });
55120
55121             requests = uniqueBy(requests, 3).filter(function(r) {
55122                 if (!!_source.overlay && nearNullIsland(r[0], r[1], r[2])) {
55123                     return false;
55124                 }
55125                 // don't re-request tiles which have failed in the past
55126                 return _cache[r[3]] !== false;
55127             });
55128         }
55129
55130
55131         function load(d) {
55132             _cache[d[3]] = true;
55133             d3_select(this)
55134                 .on('error', null)
55135                 .on('load', null)
55136                 .classed('tile-loaded', true);
55137             render(selection);
55138         }
55139
55140         function error(d) {
55141             _cache[d[3]] = false;
55142             d3_select(this)
55143                 .on('error', null)
55144                 .on('load', null)
55145                 .remove();
55146             render(selection);
55147         }
55148
55149         function imageTransform(d) {
55150             var ts = tileSize * Math.pow(2, _zoom - d[2]);
55151             var scale = tileSizeAtZoom(d, _zoom);
55152             return 'translate(' +
55153                 ((d[0] * ts) - _tileOrigin[0]) + 'px,' +
55154                 ((d[1] * ts) - _tileOrigin[1]) + 'px) ' +
55155                 'scale(' + scale + ',' + scale + ')';
55156         }
55157
55158         function tileCenter(d) {
55159             var ts = tileSize * Math.pow(2, _zoom - d[2]);
55160             return [
55161                 ((d[0] * ts) - _tileOrigin[0] + (ts / 2)),
55162                 ((d[1] * ts) - _tileOrigin[1] + (ts / 2))
55163             ];
55164         }
55165
55166         function debugTransform(d) {
55167             var coord = tileCenter(d);
55168             return 'translate(' + coord[0] + 'px,' + coord[1] + 'px)';
55169         }
55170
55171
55172         // Pick a representative tile near the center of the viewport
55173         // (This is useful for sampling the imagery vintage)
55174         var dims = geotile.size();
55175         var mapCenter = [dims[0] / 2, dims[1] / 2];
55176         var minDist = Math.max(dims[0], dims[1]);
55177         var nearCenter;
55178
55179         requests.forEach(function(d) {
55180             var c = tileCenter(d);
55181             var dist = geoVecLength(c, mapCenter);
55182             if (dist < minDist) {
55183                 minDist = dist;
55184                 nearCenter = d;
55185             }
55186         });
55187
55188
55189         var image = selection.selectAll('img')
55190             .data(requests, function(d) { return d[3]; });
55191
55192         image.exit()
55193             .style(transformProp, imageTransform)
55194             .classed('tile-removing', true)
55195             .classed('tile-center', false)
55196             .each(function() {
55197                 var tile = d3_select(this);
55198                 window.setTimeout(function() {
55199                     if (tile.classed('tile-removing')) {
55200                         tile.remove();
55201                     }
55202                 }, 300);
55203             });
55204
55205         image.enter()
55206           .append('img')
55207             .attr('class', 'tile')
55208             .attr('src', function(d) { return d[3]; })
55209             .on('error', error)
55210             .on('load', load)
55211           .merge(image)
55212             .style(transformProp, imageTransform)
55213             .classed('tile-debug', showDebug)
55214             .classed('tile-removing', false)
55215             .classed('tile-center', function(d) { return d === nearCenter; });
55216
55217
55218
55219         var debug = selection.selectAll('.tile-label-debug')
55220             .data(showDebug ? requests : [], function(d) { return d[3]; });
55221
55222         debug.exit()
55223             .remove();
55224
55225         if (showDebug) {
55226             var debugEnter = debug.enter()
55227                 .append('div')
55228                 .attr('class', 'tile-label-debug');
55229
55230             debugEnter
55231                 .append('div')
55232                 .attr('class', 'tile-label-debug-coord');
55233
55234             debugEnter
55235                 .append('div')
55236                 .attr('class', 'tile-label-debug-vintage');
55237
55238             debug = debug.merge(debugEnter);
55239
55240             debug
55241                 .style(transformProp, debugTransform);
55242
55243             debug
55244                 .selectAll('.tile-label-debug-coord')
55245                 .text(function(d) { return d[2] + ' / ' + d[0] + ' / ' + d[1]; });
55246
55247             debug
55248                 .selectAll('.tile-label-debug-vintage')
55249                 .each(function(d) {
55250                     var span = d3_select(this);
55251                     var center = context._projection.invert(tileCenter(d));
55252                     _source.getMetadata(center, d, function(err, result) {
55253                         span.text((result && result.vintage && result.vintage.range) ||
55254                             t('info_panels.background.vintage') + ': ' + t('info_panels.background.unknown')
55255                         );
55256                     });
55257                 });
55258         }
55259
55260     }
55261
55262
55263     background.projection = function(_) {
55264         if (!arguments.length) return _projection;
55265         _projection = _;
55266         return background;
55267     };
55268
55269
55270     background.dimensions = function(_) {
55271         if (!arguments.length) return geotile.size();
55272         geotile.size(_);
55273         return background;
55274     };
55275
55276
55277     background.source = function(_) {
55278         if (!arguments.length) return _source;
55279         _source = _;
55280         _cache = {};
55281         geotile.scaleExtent(_source.scaleExtent);
55282         return background;
55283     };
55284
55285
55286     return background;
55287 }
55288
55289 function rendererBackground(context) {
55290     var dispatch$$1 = dispatch('change');
55291     var detected = utilDetect();
55292     var baseLayer = rendererTileLayer(context).projection(context.projection);
55293     var _overlayLayers = [];
55294     var _backgroundSources = [];
55295     var _brightness = 1;
55296     var _contrast = 1;
55297     var _saturation = 1;
55298     var _sharpness = 1;
55299
55300
55301     function background(selection) {
55302
55303         var baseFilter = '';
55304         if (detected.cssfilters) {
55305             if (_brightness !== 1) {
55306                 baseFilter += 'brightness(' + _brightness + ')';
55307             }
55308             if (_contrast !== 1) {
55309                 baseFilter += 'contrast(' + _contrast + ')';
55310             }
55311             if (_saturation !== 1) {
55312                 baseFilter += 'saturate(' + _saturation + ')';
55313             }
55314             if (_sharpness < 1) {  // gaussian blur
55315                 var blur = d3_interpolateNumber(0.5, 5)(1 - _sharpness);
55316                 baseFilter += 'blur(' + blur + 'px)';
55317             }
55318         }
55319
55320         var base = selection.selectAll('.layer-background')
55321             .data([0]);
55322
55323         base = base.enter()
55324             .insert('div', '.layer-data')
55325             .attr('class', 'layer layer-background')
55326             .merge(base);
55327
55328         if (detected.cssfilters) {
55329             base.style('filter', baseFilter || null);
55330         } else {
55331             base.style('opacity', _brightness);
55332         }
55333
55334
55335         var imagery = base.selectAll('.layer-imagery')
55336             .data([0]);
55337
55338         imagery.enter()
55339             .append('div')
55340             .attr('class', 'layer layer-imagery')
55341             .merge(imagery)
55342             .call(baseLayer);
55343
55344
55345         var maskFilter = '';
55346         var mixBlendMode = '';
55347         if (detected.cssfilters && _sharpness > 1) {  // apply unsharp mask
55348             mixBlendMode = 'overlay';
55349             maskFilter = 'saturate(0) blur(3px) invert(1)';
55350
55351             var contrast = _sharpness - 1;
55352             maskFilter += ' contrast(' + contrast + ')';
55353
55354             var brightness = d3_interpolateNumber(1, 0.85)(_sharpness - 1);
55355             maskFilter += ' brightness(' + brightness + ')';
55356         }
55357
55358         var mask = base.selectAll('.layer-unsharp-mask')
55359             .data(detected.cssfilters && _sharpness > 1 ? [0] : []);
55360
55361         mask.exit()
55362             .remove();
55363
55364         mask.enter()
55365             .append('div')
55366             .attr('class', 'layer layer-mask layer-unsharp-mask')
55367             .merge(mask)
55368             .call(baseLayer)
55369             .style('filter', maskFilter || null)
55370             .style('mix-blend-mode', mixBlendMode || null);
55371
55372
55373         var overlays = selection.selectAll('.layer-overlay')
55374             .data(_overlayLayers, function(d) { return d.source().name(); });
55375
55376         overlays.exit()
55377             .remove();
55378
55379         overlays.enter()
55380             .insert('div', '.layer-data')
55381             .attr('class', 'layer layer-overlay')
55382             .merge(overlays)
55383             .each(function(layer) { d3_select(this).call(layer); });
55384     }
55385
55386
55387     background.updateImagery = function() {
55388         if (context.inIntro()) return;
55389
55390         var b = background.baseLayerSource(),
55391             o = _overlayLayers
55392                 .filter(function (d) { return !d.source().isLocatorOverlay() && !d.source().isHidden(); })
55393                 .map(function (d) { return d.source().id; })
55394                 .join(','),
55395             meters = geoOffsetToMeters(b.offset()),
55396             epsilon = 0.01,
55397             x = +meters[0].toFixed(2),
55398             y = +meters[1].toFixed(2),
55399             q = utilStringQs(window.location.hash.substring(1));
55400
55401         var id = b.id;
55402         if (id === 'custom') {
55403             id = 'custom:' + b.template();
55404         }
55405
55406         if (id) {
55407             q.background = id;
55408         } else {
55409             delete q.background;
55410         }
55411
55412         if (o) {
55413             q.overlays = o;
55414         } else {
55415             delete q.overlays;
55416         }
55417
55418         if (Math.abs(x) > epsilon || Math.abs(y) > epsilon) {
55419             q.offset = x + ',' + y;
55420         } else {
55421             delete q.offset;
55422         }
55423
55424         if (!window.mocha) {
55425             window.location.replace('#' + utilQsString(q, true));
55426         }
55427
55428         var imageryUsed = [b.imageryUsed()];
55429
55430         _overlayLayers
55431             .filter(function (d) { return !d.source().isLocatorOverlay() && !d.source().isHidden(); })
55432             .forEach(function (d) { imageryUsed.push(d.source().imageryUsed()); });
55433
55434         var gpx = context.layers().layer('gpx');
55435         if (gpx && gpx.enabled() && gpx.hasGpx()) {
55436             // Include a string like '.gpx data file' or '.geojson data file'
55437             var match = gpx.getSrc().match(/(kml|gpx|(?:geo)?json)$/i);
55438             var extension = match ? ('.' + match[0].toLowerCase() + ' ') : '';
55439             imageryUsed.push(extension + 'data file');
55440         }
55441
55442         var mapillary_images = context.layers().layer('mapillary-images');
55443         if (mapillary_images && mapillary_images.enabled()) {
55444             imageryUsed.push('Mapillary Images');
55445         }
55446
55447         var mapillary_signs = context.layers().layer('mapillary-signs');
55448         if (mapillary_signs && mapillary_signs.enabled()) {
55449             imageryUsed.push('Mapillary Signs');
55450         }
55451
55452         var openstreetcam_images = context.layers().layer('openstreetcam-images');
55453         if (openstreetcam_images && openstreetcam_images.enabled()) {
55454             imageryUsed.push('OpenStreetCam Images');
55455         }
55456
55457         context.history().imageryUsed(imageryUsed);
55458     };
55459
55460
55461     background.sources = function(extent) {
55462         return _backgroundSources.filter(function(source) {
55463             return source.intersects(extent);
55464         });
55465     };
55466
55467
55468     background.dimensions = function(_) {
55469         if (!_) return;
55470         baseLayer.dimensions(_);
55471
55472         _overlayLayers.forEach(function(layer) {
55473             layer.dimensions(_);
55474         });
55475     };
55476
55477
55478     background.baseLayerSource = function(d) {
55479         if (!arguments.length) return baseLayer.source();
55480
55481         // test source against OSM imagery blacklists..
55482         var osm = context.connection();
55483         if (!osm) return background;
55484
55485         var blacklists = context.connection().imageryBlacklists();
55486
55487         var template = d.template(),
55488             fail = false,
55489             tested = 0,
55490             regex, i;
55491
55492         for (i = 0; i < blacklists.length; i++) {
55493             try {
55494                 regex = new RegExp(blacklists[i]);
55495                 fail = regex.test(template);
55496                 tested++;
55497                 if (fail) break;
55498             } catch (e) {
55499                 /* noop */
55500             }
55501         }
55502
55503         // ensure at least one test was run.
55504         if (!tested) {
55505             regex = new RegExp('.*\.google(apis)?\..*/(vt|kh)[\?/].*([xyz]=.*){3}.*');
55506             fail = regex.test(template);
55507         }
55508
55509         baseLayer.source(!fail ? d : background.findSource('none'));
55510         dispatch$$1.call('change');
55511         background.updateImagery();
55512         return background;
55513     };
55514
55515
55516     background.findSource = function(id) {
55517         return find$1(_backgroundSources, function(d) {
55518             return d.id && d.id === id;
55519         });
55520     };
55521
55522
55523     background.bing = function() {
55524         background.baseLayerSource(background.findSource('Bing'));
55525     };
55526
55527
55528     background.showsLayer = function(d) {
55529         return d.id === baseLayer.source().id ||
55530             _overlayLayers.some(function(layer) { return d.id === layer.source().id; });
55531     };
55532
55533
55534     background.overlayLayerSources = function() {
55535         return _overlayLayers.map(function (l) { return l.source(); });
55536     };
55537
55538
55539     background.toggleOverlayLayer = function(d) {
55540         var layer;
55541
55542         for (var i = 0; i < _overlayLayers.length; i++) {
55543             layer = _overlayLayers[i];
55544             if (layer.source() === d) {
55545                 _overlayLayers.splice(i, 1);
55546                 dispatch$$1.call('change');
55547                 background.updateImagery();
55548                 return;
55549             }
55550         }
55551
55552         layer = rendererTileLayer(context)
55553             .source(d)
55554             .projection(context.projection)
55555             .dimensions(baseLayer.dimensions()
55556         );
55557
55558         _overlayLayers.push(layer);
55559         dispatch$$1.call('change');
55560         background.updateImagery();
55561     };
55562
55563
55564     background.nudge = function(d, zoom) {
55565         baseLayer.source().nudge(d, zoom);
55566         dispatch$$1.call('change');
55567         background.updateImagery();
55568         return background;
55569     };
55570
55571
55572     background.offset = function(d) {
55573         if (!arguments.length) return baseLayer.source().offset();
55574         baseLayer.source().offset(d);
55575         dispatch$$1.call('change');
55576         background.updateImagery();
55577         return background;
55578     };
55579
55580
55581     background.brightness = function(d) {
55582         if (!arguments.length) return _brightness;
55583         _brightness = d;
55584         if (context.mode()) dispatch$$1.call('change');
55585         return background;
55586     };
55587
55588
55589     background.contrast = function(d) {
55590         if (!arguments.length) return _contrast;
55591         _contrast = d;
55592         if (context.mode()) dispatch$$1.call('change');
55593         return background;
55594     };
55595
55596
55597     background.saturation = function(d) {
55598         if (!arguments.length) return _saturation;
55599         _saturation = d;
55600         if (context.mode()) dispatch$$1.call('change');
55601         return background;
55602     };
55603
55604
55605     background.sharpness = function(d) {
55606         if (!arguments.length) return _sharpness;
55607         _sharpness = d;
55608         if (context.mode()) dispatch$$1.call('change');
55609         return background;
55610     };
55611
55612
55613     background.init = function() {
55614         function parseMap(qmap) {
55615             if (!qmap) return false;
55616             var args = qmap.split('/').map(Number);
55617             if (args.length < 3 || args.some(isNaN)) return false;
55618             return geoExtent([args[2], args[1]]);
55619         }
55620
55621         var dataImagery = data.imagery || [],
55622             q = utilStringQs(window.location.hash.substring(1)),
55623             requested = q.background || q.layer,
55624             extent = parseMap(q.map),
55625             first,
55626             best;
55627
55628         // Add all the available imagery sources
55629         _backgroundSources = dataImagery.map(function(source) {
55630             if (source.type === 'bing') {
55631                 return rendererBackgroundSource.Bing(source, dispatch$$1);
55632             } else if (source.id === 'EsriWorldImagery') {
55633                 return rendererBackgroundSource.Esri(source);
55634             } else {
55635                 return rendererBackgroundSource(source);
55636             }
55637         });
55638
55639         first = _backgroundSources.length && _backgroundSources[0];
55640
55641         // Add 'None'
55642         _backgroundSources.unshift(rendererBackgroundSource.None());
55643
55644         // Add 'Custom'
55645         var template = context.storage('background-custom-template') || '';
55646         var custom = rendererBackgroundSource.Custom(template);
55647         _backgroundSources.unshift(custom);
55648
55649
55650         // Decide which background layer to display
55651         if (!requested && extent) {
55652             best = find$1(this.sources(extent), function(s) { return s.best(); });
55653         }
55654         if (requested && requested.indexOf('custom:') === 0) {
55655             template = requested.replace(/^custom:/, '');
55656             background.baseLayerSource(custom.template(template));
55657             context.storage('background-custom-template', template);
55658         } else {
55659             background.baseLayerSource(
55660                 background.findSource(requested) ||
55661                 best ||
55662                 background.findSource('Bing') ||
55663                 first ||
55664                 background.findSource('none')
55665             );
55666         }
55667
55668         var locator = find$1(_backgroundSources, function(d) {
55669             return d.overlay && d.default;
55670         });
55671
55672         if (locator) {
55673             background.toggleOverlayLayer(locator);
55674         }
55675
55676         var overlays = (q.overlays || '').split(',');
55677         overlays.forEach(function(overlay) {
55678             overlay = background.findSource(overlay);
55679             if (overlay) {
55680                 background.toggleOverlayLayer(overlay);
55681             }
55682         });
55683
55684         if (q.gpx) {
55685             var gpx = context.layers().layer('gpx');
55686             if (gpx) {
55687                 gpx.url(q.gpx);
55688             }
55689         }
55690
55691         if (q.offset) {
55692             var offset = q.offset.replace(/;/g, ',').split(',').map(function(n) {
55693                 return !isNaN(n) && n;
55694             });
55695
55696             if (offset.length === 2) {
55697                 background.offset(geoMetersToOffset(offset));
55698             }
55699         }
55700     };
55701
55702
55703     return utilRebind(background, dispatch$$1, 'on');
55704 }
55705
55706 function rendererFeatures(context) {
55707     var traffic_roads = {
55708         'motorway': true,
55709         'motorway_link': true,
55710         'trunk': true,
55711         'trunk_link': true,
55712         'primary': true,
55713         'primary_link': true,
55714         'secondary': true,
55715         'secondary_link': true,
55716         'tertiary': true,
55717         'tertiary_link': true,
55718         'residential': true,
55719         'unclassified': true,
55720         'living_street': true
55721     };
55722
55723     var service_roads = {
55724         'service': true,
55725         'road': true,
55726         'track': true
55727     };
55728
55729     var paths = {
55730         'path': true,
55731         'footway': true,
55732         'cycleway': true,
55733         'bridleway': true,
55734         'steps': true,
55735         'pedestrian': true,
55736         'corridor': true
55737     };
55738
55739     var past_futures = {
55740         'proposed': true,
55741         'construction': true,
55742         'abandoned': true,
55743         'dismantled': true,
55744         'disused': true,
55745         'razed': true,
55746         'demolished': true,
55747         'obliterated': true
55748     };
55749
55750     var dispatch$$1 = dispatch('change', 'redraw'),
55751         _cullFactor = 1,
55752         _cache = {},
55753         _features = {},
55754         _stats = {},
55755         _keys = [],
55756         _hidden = [];
55757
55758
55759     function update() {
55760         if (!window.mocha) {
55761             var q = utilStringQs(window.location.hash.substring(1));
55762             var disabled = features.disabled();
55763             if (disabled.length) {
55764                 q.disable_features = features.disabled().join(',');
55765             } else {
55766                 delete q.disable_features;
55767             }
55768             window.location.replace('#' + utilQsString(q, true));
55769         }
55770
55771         _hidden = features.hidden();
55772         dispatch$$1.call('change');
55773         dispatch$$1.call('redraw');
55774     }
55775
55776
55777     function defineFeature(k, filter, max) {
55778         var isEnabled = true;
55779
55780         _keys.push(k);
55781         _features[k] = {
55782             filter: filter,
55783             enabled: isEnabled,   // whether the user wants it enabled..
55784             count: 0,
55785             currentMax: (max || Infinity),
55786             defaultMax: (max || Infinity),
55787             enable: function() { this.enabled = true; this.currentMax = this.defaultMax; },
55788             disable: function() { this.enabled = false; this.currentMax = 0; },
55789             hidden: function() { return !context.editable() || this.count > this.currentMax * _cullFactor; },
55790             autoHidden: function() { return this.hidden() && this.currentMax > 0; }
55791         };
55792     }
55793
55794
55795     defineFeature('points', function isPoint(entity, resolver, geometry) {
55796         return geometry === 'point';
55797     }, 200);
55798
55799     defineFeature('traffic_roads', function isTrafficRoad(entity) {
55800         return traffic_roads[entity.tags.highway];
55801     });
55802
55803     defineFeature('service_roads', function isServiceRoad(entity) {
55804         return service_roads[entity.tags.highway];
55805     });
55806
55807     defineFeature('paths', function isPath(entity) {
55808         return paths[entity.tags.highway];
55809     });
55810
55811     defineFeature('buildings', function isBuilding(entity) {
55812         return (
55813             !!entity.tags['building:part'] ||
55814             (!!entity.tags.building && entity.tags.building !== 'no') ||
55815             entity.tags.amenity === 'shelter' ||
55816             entity.tags.parking === 'multi-storey' ||
55817             entity.tags.parking === 'sheds' ||
55818             entity.tags.parking === 'carports' ||
55819             entity.tags.parking === 'garage_boxes'
55820         );
55821     }, 250);
55822
55823     defineFeature('landuse', function isLanduse(entity, resolver, geometry) {
55824         return geometry === 'area' &&
55825             !_features.buildings.filter(entity) &&
55826             !_features.water.filter(entity);
55827     });
55828
55829     defineFeature('boundaries', function isBoundary(entity) {
55830         return !!entity.tags.boundary;
55831     });
55832
55833     defineFeature('water', function isWater(entity) {
55834         return (
55835             !!entity.tags.waterway ||
55836             entity.tags.natural === 'water' ||
55837             entity.tags.natural === 'coastline' ||
55838             entity.tags.natural === 'bay' ||
55839             entity.tags.landuse === 'pond' ||
55840             entity.tags.landuse === 'basin' ||
55841             entity.tags.landuse === 'reservoir' ||
55842             entity.tags.landuse === 'salt_pond'
55843         );
55844     });
55845
55846     defineFeature('rail', function isRail(entity) {
55847         return (
55848             !!entity.tags.railway ||
55849             entity.tags.landuse === 'railway'
55850         ) && !(
55851             traffic_roads[entity.tags.highway] ||
55852             service_roads[entity.tags.highway] ||
55853             paths[entity.tags.highway]
55854         );
55855     });
55856
55857     defineFeature('power', function isPower(entity) {
55858         return !!entity.tags.power;
55859     });
55860
55861     // contains a past/future tag, but not in active use as a road/path/cycleway/etc..
55862     defineFeature('past_future', function isPastFuture(entity) {
55863         if (
55864             traffic_roads[entity.tags.highway] ||
55865             service_roads[entity.tags.highway] ||
55866             paths[entity.tags.highway]
55867         ) { return false; }
55868
55869         var strings = Object.keys(entity.tags);
55870
55871         for (var i = 0; i < strings.length; i++) {
55872             var s = strings[i];
55873             if (past_futures[s] || past_futures[entity.tags[s]]) { return true; }
55874         }
55875         return false;
55876     });
55877
55878     // Lines or areas that don't match another feature filter.
55879     // IMPORTANT: The 'others' feature must be the last one defined,
55880     //   so that code in getMatches can skip this test if `hasMatch = true`
55881     defineFeature('others', function isOther(entity, resolver, geometry) {
55882         return (geometry === 'line' || geometry === 'area');
55883     });
55884
55885
55886     function features() {}
55887
55888
55889     features.features = function() {
55890         return _features;
55891     };
55892
55893
55894     features.keys = function() {
55895         return _keys;
55896     };
55897
55898
55899     features.enabled = function(k) {
55900         if (!arguments.length) {
55901             return _keys.filter(function(k) { return _features[k].enabled; });
55902         }
55903         return _features[k] && _features[k].enabled;
55904     };
55905
55906
55907     features.disabled = function(k) {
55908         if (!arguments.length) {
55909             return _keys.filter(function(k) { return !_features[k].enabled; });
55910         }
55911         return _features[k] && !_features[k].enabled;
55912     };
55913
55914
55915     features.hidden = function(k) {
55916         if (!arguments.length) {
55917             return _keys.filter(function(k) { return _features[k].hidden(); });
55918         }
55919         return _features[k] && _features[k].hidden();
55920     };
55921
55922
55923     features.autoHidden = function(k) {
55924         if (!arguments.length) {
55925             return _keys.filter(function(k) { return _features[k].autoHidden(); });
55926         }
55927         return _features[k] && _features[k].autoHidden();
55928     };
55929
55930
55931     features.enable = function(k) {
55932         if (_features[k] && !_features[k].enabled) {
55933             _features[k].enable();
55934             update();
55935         }
55936     };
55937
55938
55939     features.disable = function(k) {
55940         if (_features[k] && _features[k].enabled) {
55941             _features[k].disable();
55942             update();
55943         }
55944     };
55945
55946
55947     features.toggle = function(k) {
55948         if (_features[k]) {
55949             (function(f) { return f.enabled ? f.disable() : f.enable(); }(_features[k]));
55950             update();
55951         }
55952     };
55953
55954
55955     features.resetStats = function() {
55956         for (var i = 0; i < _keys.length; i++) {
55957             _features[_keys[i]].count = 0;
55958         }
55959         dispatch$$1.call('change');
55960     };
55961
55962
55963     features.gatherStats = function(d, resolver, dimensions) {
55964         var needsRedraw = false,
55965             type = groupBy(d, function(ent) { return ent.type; }),
55966             entities = [].concat(type.relation || [], type.way || [], type.node || []),
55967             currHidden, geometry, matches, i, j;
55968
55969         for (i = 0; i < _keys.length; i++) {
55970             _features[_keys[i]].count = 0;
55971         }
55972
55973         // adjust the threshold for point/building culling based on viewport size..
55974         // a _cullFactor of 1 corresponds to a 1000x1000px viewport..
55975         _cullFactor = dimensions[0] * dimensions[1] / 1000000;
55976
55977         for (i = 0; i < entities.length; i++) {
55978             geometry = entities[i].geometry(resolver);
55979             if (!(geometry === 'vertex' || geometry === 'relation')) {
55980                 matches = Object.keys(features.getMatches(entities[i], resolver, geometry));
55981                 for (j = 0; j < matches.length; j++) {
55982                     _features[matches[j]].count++;
55983                 }
55984             }
55985         }
55986
55987         currHidden = features.hidden();
55988         if (currHidden !== _hidden) {
55989             _hidden = currHidden;
55990             needsRedraw = true;
55991             dispatch$$1.call('change');
55992         }
55993
55994         return needsRedraw;
55995     };
55996
55997
55998     features.stats = function() {
55999         for (var i = 0; i < _keys.length; i++) {
56000             _stats[_keys[i]] = _features[_keys[i]].count;
56001         }
56002
56003         return _stats;
56004     };
56005
56006
56007     features.clear = function(d) {
56008         for (var i = 0; i < d.length; i++) {
56009             features.clearEntity(d[i]);
56010         }
56011     };
56012
56013
56014     features.clearEntity = function(entity) {
56015         delete _cache[osmEntity.key(entity)];
56016     };
56017
56018
56019     features.reset = function() {
56020         _cache = {};
56021     };
56022
56023
56024     features.getMatches = function(entity, resolver, geometry) {
56025         if (geometry === 'vertex' || geometry === 'relation') return {};
56026
56027         var ent = osmEntity.key(entity);
56028         if (!_cache[ent]) {
56029             _cache[ent] = {};
56030         }
56031
56032         if (!_cache[ent].matches) {
56033             var matches = {},
56034                 hasMatch = false;
56035
56036             for (var i = 0; i < _keys.length; i++) {
56037                 if (_keys[i] === 'others') {
56038                     if (hasMatch) continue;
56039
56040                     // Multipolygon members:
56041                     // If an entity...
56042                     //   1. is a way that hasn't matched other 'interesting' feature rules,
56043                     //   2. and it belongs to a single parent multipolygon relation
56044                     // ...then match whatever feature rules the parent multipolygon has matched.
56045                     // see #2548, #2887
56046                     //
56047                     // IMPORTANT:
56048                     // For this to work, getMatches must be called on relations before ways.
56049                     //
56050                     if (entity.type === 'way') {
56051                         var parents = features.getParents(entity, resolver, geometry);
56052                         if (parents.length === 1 && parents[0].isMultipolygon()) {
56053                             var pkey = osmEntity.key(parents[0]);
56054                             if (_cache[pkey] && _cache[pkey].matches) {
56055                                 matches = clone(_cache[pkey].matches);
56056                                 continue;
56057                             }
56058                         }
56059                     }
56060                 }
56061
56062                 if (_features[_keys[i]].filter(entity, resolver, geometry)) {
56063                     matches[_keys[i]] = hasMatch = true;
56064                 }
56065             }
56066             _cache[ent].matches = matches;
56067         }
56068
56069         return _cache[ent].matches;
56070     };
56071
56072
56073     features.getParents = function(entity, resolver, geometry) {
56074         if (geometry === 'point') return [];
56075
56076         var ent = osmEntity.key(entity);
56077         if (!_cache[ent]) {
56078             _cache[ent] = {};
56079         }
56080
56081         if (!_cache[ent].parents) {
56082             var parents = [];
56083             if (geometry === 'vertex') {
56084                 parents = resolver.parentWays(entity);
56085             } else {   // 'line', 'area', 'relation'
56086                 parents = resolver.parentRelations(entity);
56087             }
56088             _cache[ent].parents = parents;
56089         }
56090         return _cache[ent].parents;
56091     };
56092
56093
56094     features.isHiddenFeature = function(entity, resolver, geometry) {
56095         if (!_hidden.length) return false;
56096         if (!entity.version) return false;
56097
56098         var matches = features.getMatches(entity, resolver, geometry);
56099
56100         for (var i = 0; i < _hidden.length; i++) {
56101             if (matches[_hidden[i]]) return true;
56102         }
56103         return false;
56104     };
56105
56106
56107     features.isHiddenChild = function(entity, resolver, geometry) {
56108         if (!_hidden.length) return false;
56109         if (!entity.version || geometry === 'point') return false;
56110
56111         var parents = features.getParents(entity, resolver, geometry);
56112         if (!parents.length) return false;
56113
56114         for (var i = 0; i < parents.length; i++) {
56115             if (!features.isHidden(parents[i], resolver, parents[i].geometry(resolver))) {
56116                 return false;
56117             }
56118         }
56119         return true;
56120     };
56121
56122
56123     features.hasHiddenConnections = function(entity, resolver) {
56124         if (!_hidden.length) return false;
56125         var childNodes, connections;
56126
56127         if (entity.type === 'midpoint') {
56128             childNodes = [resolver.entity(entity.edge[0]), resolver.entity(entity.edge[1])];
56129             connections = [];
56130         } else {
56131             childNodes = entity.nodes ? resolver.childNodes(entity) : [];
56132             connections = features.getParents(entity, resolver, entity.geometry(resolver));
56133         }
56134
56135         // gather ways connected to child nodes..
56136         connections = reduce(childNodes, function(result, e) {
56137             return resolver.isShared(e) ? union(result, resolver.parentWays(e)) : result;
56138         }, connections);
56139
56140         return connections.length ? some(connections, function(e) {
56141             return features.isHidden(e, resolver, e.geometry(resolver));
56142         }) : false;
56143     };
56144
56145
56146     features.isHidden = function(entity, resolver, geometry) {
56147         if (!_hidden.length) return false;
56148         if (!entity.version) return false;
56149
56150         var fn = (geometry === 'vertex' ? features.isHiddenChild : features.isHiddenFeature);
56151         return fn(entity, resolver, geometry);
56152     };
56153
56154
56155     features.filter = function(d, resolver) {
56156         if (!_hidden.length) return d;
56157
56158         var result = [];
56159         for (var i = 0; i < d.length; i++) {
56160             var entity = d[i];
56161             if (!features.isHidden(entity, resolver, entity.geometry(resolver))) {
56162                 result.push(entity);
56163             }
56164         }
56165         return result;
56166     };
56167
56168
56169     features.init = function() {
56170         var q = utilStringQs(window.location.hash.substring(1));
56171
56172         if (q.disable_features) {
56173             var disabled = q.disable_features.replace(/;/g, ',').split(',');
56174             disabled.forEach(features.disable);
56175         }
56176     };
56177
56178     return utilRebind(features, dispatch$$1, 'on');
56179 }
56180
56181 function utilBindOnce(target, type, listener, capture) {
56182     var typeOnce = type + '.once';
56183     function one() {
56184         target.on(typeOnce, null);
56185         listener.apply(this, arguments);
56186     }
56187     target.on(typeOnce, one, capture);
56188     return this;
56189 }
56190
56191 function rendererMap(context) {
56192
56193     var dimensions = [1, 1],
56194         dispatch$$1 = dispatch('move', 'drawn'),
56195         projection = context.projection,
56196         curtainProjection = context.curtainProjection,
56197         dblclickEnabled = true,
56198         redrawEnabled = true,
56199         transformStart = projection.transform(),
56200         transformLast,
56201         transformed = false,
56202         minzoom = 0,
56203         drawLayers = svgLayers(projection, context),
56204         drawPoints = svgPoints(projection, context),
56205         drawVertices = svgVertices(projection, context),
56206         drawLines = svgLines(projection, context),
56207         drawAreas = svgAreas(projection, context),
56208         drawMidpoints = svgMidpoints(projection, context),
56209         drawLabels = svgLabels(projection, context),
56210         supersurface = d3_select(null),
56211         wrapper = d3_select(null),
56212         surface = d3_select(null),
56213         mouse,
56214         mousemove;
56215
56216     var zoom$$1 = d3_zoom()
56217         .scaleExtent([ztok(2), ztok(24)])
56218         .interpolate(d3_interpolate)
56219         .filter(zoomEventFilter)
56220         .on('zoom', zoomPan);
56221
56222     var _selection = d3_select(null);
56223
56224     var scheduleRedraw = throttle(redraw, 750);
56225     // var isRedrawScheduled = false;
56226     // var pendingRedrawCall;
56227     // function scheduleRedraw() {
56228     //     // Only schedule the redraw if one has not already been set.
56229     //     if (isRedrawScheduled) return;
56230     //     isRedrawScheduled = true;
56231     //     var that = this;
56232     //     var args = arguments;
56233     //     pendingRedrawCall = window.requestIdleCallback(function () {
56234     //         // Reset the boolean so future redraws can be set.
56235     //         isRedrawScheduled = false;
56236     //         redraw.apply(that, args);
56237     //     }, { timeout: 1400 });
56238     // }
56239
56240     function cancelPendingRedraw() {
56241         scheduleRedraw.cancel();
56242         // isRedrawScheduled = false;
56243         // window.cancelIdleCallback(pendingRedrawCall);
56244     }
56245
56246     function map(selection) {
56247
56248         _selection = selection;
56249
56250         context
56251             .on('change.map', immediateRedraw);
56252
56253         var osm = context.connection();
56254         if (osm) {
56255             osm.on('change.map', immediateRedraw);
56256         }
56257
56258         context.history()
56259             .on('change.map', immediateRedraw)
56260             .on('undone.map redone.map', function(stack) {
56261                 var mode = context.mode().id;
56262                 if (mode !== 'browse' && mode !== 'select') return;
56263
56264                 var followSelected = false;
56265                 if (Array.isArray(stack.selectedIDs)) {
56266                     followSelected = (stack.selectedIDs.length === 1 && stack.selectedIDs[0][0] === 'n');
56267                     context.enter(
56268                         modeSelect(context, stack.selectedIDs).follow(followSelected)
56269                     );
56270                 }
56271                 if (!followSelected && stack.transform) {
56272                     map.transformEase(stack.transform);
56273                 }
56274             });
56275
56276         context.background()
56277             .on('change.map', immediateRedraw);
56278
56279         context.features()
56280             .on('redraw.map', immediateRedraw);
56281
56282         drawLayers
56283             .on('change.map', function() {
56284                 context.background().updateImagery();
56285                 immediateRedraw();
56286             });
56287
56288         selection
56289             .on('dblclick.map', dblClick)
56290             .call(zoom$$1)
56291             .call(zoom$$1.transform, projection.transform());
56292
56293         supersurface = selection.append('div')
56294             .attr('id', 'supersurface')
56295             .call(utilSetTransform, 0, 0);
56296
56297         // Need a wrapper div because Opera can't cope with an absolutely positioned
56298         // SVG element: http://bl.ocks.org/jfirebaugh/6fbfbd922552bf776c16
56299         wrapper = supersurface
56300             .append('div')
56301             .attr('class', 'layer layer-data');
56302
56303         map.surface = surface = wrapper
56304             .call(drawLayers)
56305             .selectAll('.surface')
56306             .attr('id', 'surface');
56307
56308         surface
56309             .call(drawLabels.observe)
56310             .on('mousedown.zoom', function() {
56311                 if (event.button === 2) {
56312                     event.stopPropagation();
56313                 }
56314             }, true)
56315             .on('mouseup.zoom', function() {
56316                 if (resetTransform()) immediateRedraw();
56317             })
56318             .on('mousemove.map', function() {
56319                 mousemove = event;
56320             })
56321             .on('mouseover.vertices', function() {
56322                 if (map.editable() && !transformed) {
56323                     var hover = event.target.__data__;
56324                     surface.selectAll('.data-layer-osm')
56325                         .call(drawVertices.drawHover, context.graph(), hover, map.extent());
56326                     dispatch$$1.call('drawn', this, { full: false });
56327                 }
56328             })
56329             .on('mouseout.vertices', function() {
56330                 if (map.editable() && !transformed) {
56331                     var hover = event.relatedTarget && event.relatedTarget.__data__;
56332                     surface.selectAll('.data-layer-osm')
56333                         .call(drawVertices.drawHover, context.graph(), hover, map.extent());
56334                     dispatch$$1.call('drawn', this, { full: false });
56335                 }
56336             });
56337
56338         supersurface
56339             .call(context.background());
56340
56341         context.on('enter.map',  function() {
56342             if (map.editable() && !transformed) {
56343
56344                 // redraw immediately any objects affected by a change in selectedIDs.
56345                 var graph = context.graph();
56346                 var selectedAndParents = {};
56347                 context.selectedIDs().forEach(function(id) {
56348                     var entity = graph.hasEntity(id);
56349                     if (entity) {
56350                         selectedAndParents[entity.id] = entity;
56351                         if (entity.type === 'node') {
56352                             graph.parentWays(entity).forEach(function(parent) {
56353                                 selectedAndParents[parent.id] = parent;
56354                             });
56355                         }
56356                     }
56357                 });
56358                 var data = values$1(selectedAndParents);
56359                 var filter = function(d) { return d.id in selectedAndParents; };
56360
56361                 data = context.features().filter(data, graph);
56362
56363                 surface.selectAll('.data-layer-osm')
56364                     .call(drawVertices.drawSelected, graph, map.extent())
56365                     .call(drawLines, graph, data, filter)
56366                     .call(drawAreas, graph, data, filter)
56367                     .call(drawMidpoints, graph, data, filter, map.trimmedExtent());
56368
56369                 dispatch$$1.call('drawn', this, { full: false });
56370
56371
56372                 // redraw everything else later
56373                 scheduleRedraw();
56374             }
56375         });
56376
56377         map.dimensions(utilGetDimensions(selection));
56378     }
56379
56380
56381     function zoomEventFilter() {
56382         // Fix for #2151, (see also d3/d3-zoom#60, d3/d3-brush#18)
56383         // Intercept `mousedown` and check if there is an orphaned zoom gesture.
56384         // This can happen if a previous `mousedown` occurred without a `mouseup`.
56385         // If we detect this, dispatch `mouseup` to complete the orphaned gesture,
56386         // so that d3-zoom won't stop propagation of new `mousedown` events.
56387         if (event.type === 'mousedown') {
56388             var hasOrphan = false;
56389             var listeners = window.__on;
56390             for (var i = 0; i < listeners.length; i++) {
56391                 var listener = listeners[i];
56392                 if (listener.name === 'zoom' && listener.type === 'mouseup') {
56393                     hasOrphan = true;
56394                     break;
56395                 }
56396             }
56397             if (hasOrphan) {
56398                 var event$$1 = window.CustomEvent;
56399                 if (event$$1) {
56400                     event$$1 = new event$$1('mouseup');
56401                 } else {
56402                     event$$1 = window.document.createEvent('Event');
56403                     event$$1.initEvent('mouseup', false, false);
56404                 }
56405                 // Event needs to be dispatched with an event.view property.
56406                 event$$1.view = window;
56407                 window.dispatchEvent(event$$1);
56408             }
56409         }
56410
56411         return event.button !== 2;   // ignore right clicks
56412     }
56413
56414
56415     function ztok(z) {
56416         return 256 * Math.pow(2, z);
56417     }
56418
56419     function ktoz(k) {
56420         return Math.max(Math.log(k) / Math.LN2 - 8, 0);
56421     }
56422
56423     function pxCenter() {
56424         return [dimensions[0] / 2, dimensions[1] / 2];
56425     }
56426
56427
56428     function drawVector(difference, extent) {
56429         var mode = context.mode();
56430         var graph = context.graph();
56431         var features = context.features();
56432         var all = context.intersects(map.extent());
56433         var fullRedraw = false;
56434         var data;
56435         var filter;
56436
56437         if (difference) {
56438             var complete = difference.complete(map.extent());
56439             data = compact(values$1(complete));
56440             filter = function(d) { return d.id in complete; };
56441             features.clear(data);
56442
56443         } else {
56444             // force a full redraw if gatherStats detects that a feature
56445             // should be auto-hidden (e.g. points or buildings)..
56446             if (features.gatherStats(all, graph, dimensions)) {
56447                 extent = undefined;
56448             }
56449
56450             if (extent) {
56451                 data = context.intersects(map.extent().intersection(extent));
56452                 var set$$1 = set$2(map$4(data, 'id'));
56453                 filter = function(d) { return set$$1.has(d.id); };
56454
56455             } else {
56456                 data = all;
56457                 fullRedraw = true;
56458                 filter = utilFunctor(true);
56459             }
56460         }
56461
56462         data = features.filter(data, graph);
56463
56464         if (mode && mode.id === 'select') {
56465             // update selected vertices - the user might have just double-clicked a way,
56466             // creating a new vertex, triggering a partial redraw without a mode change
56467             surface.selectAll('.data-layer-osm')
56468                 .call(drawVertices.drawSelected, graph, map.extent());
56469         }
56470
56471         surface.selectAll('.data-layer-osm')
56472             .call(drawVertices, graph, data, filter, map.extent(), fullRedraw)
56473             .call(drawLines, graph, data, filter)
56474             .call(drawAreas, graph, data, filter)
56475             .call(drawMidpoints, graph, data, filter, map.trimmedExtent())
56476             .call(drawLabels, graph, data, filter, dimensions, fullRedraw)
56477             .call(drawPoints, graph, data, filter);
56478
56479         dispatch$$1.call('drawn', this, {full: true});
56480     }
56481
56482
56483     function editOff() {
56484         context.features().resetStats();
56485         surface.selectAll('.layer-osm *').remove();
56486
56487         var mode = context.mode();
56488         if (mode && mode.id !== 'save') {
56489             context.enter(modeBrowse(context));
56490         }
56491
56492         dispatch$$1.call('drawn', this, {full: true});
56493     }
56494
56495
56496     function dblClick() {
56497         if (!dblclickEnabled) {
56498             event.preventDefault();
56499             event.stopImmediatePropagation();
56500         }
56501     }
56502
56503
56504     function zoomPan(manualEvent) {
56505         var event$$1 = (manualEvent || event);
56506         var source = event$$1.sourceEvent;
56507         var eventTransform = event$$1.transform;
56508
56509         if (transformStart.x === eventTransform.x &&
56510             transformStart.y === eventTransform.y &&
56511             transformStart.k === eventTransform.k) {
56512             return;  // no change
56513         }
56514
56515         // Normalize mousewheel - #3029
56516         // If wheel delta is provided in LINE units, recalculate it in PIXEL units
56517         // We are essentially redoing the calculations that occur here:
56518         //   https://github.com/d3/d3-zoom/blob/78563a8348aa4133b07cac92e2595c2227ca7cd7/src/zoom.js#L203
56519         // See this for more info:
56520         //   https://github.com/basilfx/normalize-wheel/blob/master/src/normalizeWheel.js
56521         if (source && source.type === 'wheel' && source.deltaMode === 1 /* LINE */) {
56522             // pick sensible scroll amount if user scrolling fast or slow..
56523             var lines = Math.abs(source.deltaY);
56524             var scroll = lines > 2 ? 40 : lines * 10;
56525
56526             var t0 = transformed ? transformLast : transformStart;
56527             var p0 = mouse(source);
56528             var p1 = t0.invert(p0);
56529             var k2 = t0.k * Math.pow(2, -source.deltaY * scroll / 500);
56530             var x2 = p0[0] - p1[0] * k2;
56531             var y2 = p0[1] - p1[1] * k2;
56532
56533             eventTransform = identity$7.translate(x2,y2).scale(k2);
56534             _selection.node().__zoom = eventTransform;
56535         }
56536
56537         if (ktoz(eventTransform.k * 2 * Math.PI) < minzoom) {
56538             surface.interrupt();
56539             uiFlash().text(t('cannot_zoom'))();
56540             setZoom(context.minEditableZoom(), true);
56541             scheduleRedraw();
56542             dispatch$$1.call('move', this, map);
56543             return;
56544         }
56545
56546         projection.transform(eventTransform);
56547
56548         var scale = eventTransform.k / transformStart.k;
56549         var tX = (eventTransform.x / scale - transformStart.x) * scale;
56550         var tY = (eventTransform.y / scale - transformStart.y) * scale;
56551
56552         if (context.inIntro()) {
56553             curtainProjection.transform({
56554                 x: eventTransform.x - tX,
56555                 y: eventTransform.y - tY,
56556                 k: eventTransform.k
56557             });
56558         }
56559
56560         if (source) mousemove = event$$1;
56561         transformed = true;
56562         transformLast = eventTransform;
56563         utilSetTransform(supersurface, tX, tY, scale);
56564         scheduleRedraw();
56565
56566         dispatch$$1.call('move', this, map);
56567     }
56568
56569
56570     function resetTransform() {
56571         if (!transformed) return false;
56572
56573         // deprecation warning - Radial Menu to be removed in iD v3
56574         surface.selectAll('.edit-menu, .radial-menu').interrupt().remove();
56575         utilSetTransform(supersurface, 0, 0);
56576         transformed = false;
56577         if (context.inIntro()) {
56578             curtainProjection.transform(projection.transform());
56579         }
56580         return true;
56581     }
56582
56583
56584     function redraw(difference, extent) {
56585         if (surface.empty() || !redrawEnabled) return;
56586
56587         // If we are in the middle of a zoom/pan, we can't do differenced redraws.
56588         // It would result in artifacts where differenced entities are redrawn with
56589         // one transform and unchanged entities with another.
56590         if (resetTransform()) {
56591             difference = extent = undefined;
56592         }
56593
56594         var z = String(~~map.zoom());
56595         if (surface.attr('data-zoom') !== z) {
56596             surface.attr('data-zoom', z)
56597                 .classed('low-zoom', z <= 16);
56598         }
56599
56600         if (!difference) {
56601             supersurface.call(context.background());
56602         }
56603
56604         wrapper
56605             .call(drawLayers);
56606
56607         // OSM
56608         if (map.editable()) {
56609             context.loadTiles(projection, dimensions);
56610             drawVector(difference, extent);
56611         } else {
56612             editOff();
56613         }
56614
56615         transformStart = projection.transform();
56616
56617         return map;
56618     }
56619
56620
56621
56622     var immediateRedraw = function(difference, extent) {
56623         if (!difference && !extent) cancelPendingRedraw();
56624         redraw(difference, extent);
56625     };
56626
56627
56628     function pointLocation(p) {
56629         var translate = projection.translate(),
56630             scale = projection.scale() * 2 * Math.PI;
56631         return [(p[0] - translate[0]) / scale, (p[1] - translate[1]) / scale];
56632     }
56633
56634
56635     function locationPoint(l) {
56636         var translate = projection.translate(),
56637             scale = projection.scale() * 2 * Math.PI;
56638         return [l[0] * scale + translate[0], l[1] * scale + translate[1]];
56639     }
56640
56641
56642     map.mouse = function() {
56643         var event$$1 = mousemove || event;
56644         if (event$$1) {
56645             var s;
56646             while ((s = event$$1.sourceEvent)) { event$$1 = s; }
56647             return mouse(event$$1);
56648         }
56649         return null;
56650     };
56651
56652
56653     // returns Lng/Lat
56654     map.mouseCoordinates = function() {
56655         var coord = map.mouse() || pxCenter();
56656         return projection.invert(coord);
56657     };
56658
56659
56660     map.dblclickEnable = function(_) {
56661         if (!arguments.length) return dblclickEnabled;
56662         dblclickEnabled = _;
56663         return map;
56664     };
56665
56666
56667     map.redrawEnable = function(_) {
56668         if (!arguments.length) return redrawEnabled;
56669         redrawEnabled = _;
56670         return map;
56671     };
56672
56673
56674     function setTransform(t2, duration, force) {
56675         var t$$1 = projection.transform();
56676         if (!force && t2.k === t$$1.k && t2.x === t$$1.x && t2.y === t$$1.y) {
56677             return false;
56678         }
56679
56680         if (duration) {
56681             _selection
56682                 .transition()
56683                 .duration(duration)
56684                 .on('start', function() { map.startEase(); })
56685                 .call(zoom$$1.transform, identity$7.translate(t2.x, t2.y).scale(t2.k));
56686         } else {
56687             projection.transform(t2);
56688             transformStart = t2;
56689             _selection.call(zoom$$1.transform, transformStart);
56690         }
56691     }
56692
56693
56694     function setZoom(z2, force, duration) {
56695         if (z2 === map.zoom() && !force) {
56696             return false;
56697         }
56698
56699         var k = projection.scale(),
56700             k2 = Math.max(ztok(2), Math.min(ztok(24), ztok(z2))) / (2 * Math.PI),
56701             center = pxCenter(),
56702             l = pointLocation(center);
56703
56704         projection.scale(k2);
56705
56706         var t$$1 = projection.translate();
56707         l = locationPoint(l);
56708
56709         t$$1[0] += center[0] - l[0];
56710         t$$1[1] += center[1] - l[1];
56711
56712         if (duration) {
56713             projection.scale(k);  // reset scale
56714             _selection
56715                 .transition()
56716                 .duration(duration)
56717                 .on('start', function() { map.startEase(); })
56718                 .call(zoom$$1.transform, identity$7.translate(t$$1[0], t$$1[1]).scale(k2));
56719         } else {
56720             projection.translate(t$$1);
56721             transformStart = projection.transform();
56722             _selection.call(zoom$$1.transform, transformStart);
56723         }
56724
56725         return true;
56726     }
56727
56728
56729     function setCenter(loc2, duration) {
56730         var c = map.center();
56731         if (loc2[0] === c[0] && loc2[1] === c[1]) {
56732             return false;
56733         }
56734
56735         var t$$1 = projection.translate(),
56736             k = projection.scale(),
56737             pxC = pxCenter(),
56738             ll = projection(loc2);
56739
56740         t$$1[0] = t$$1[0] - ll[0] + pxC[0];
56741         t$$1[1] = t$$1[1] - ll[1] + pxC[1];
56742
56743         if (duration) {
56744             _selection
56745                 .transition()
56746                 .duration(duration)
56747                 .on('start', function() { map.startEase(); })
56748                 .call(zoom$$1.transform, identity$7.translate(t$$1[0], t$$1[1]).scale(k));
56749         } else {
56750             projection.translate(t$$1);
56751             transformStart = projection.transform();
56752             _selection.call(zoom$$1.transform, transformStart);
56753         }
56754
56755         return true;
56756     }
56757
56758
56759     map.pan = function(delta, duration) {
56760         var t$$1 = projection.translate(),
56761             k = projection.scale();
56762
56763         t$$1[0] += delta[0];
56764         t$$1[1] += delta[1];
56765
56766         if (duration) {
56767             _selection
56768                 .transition()
56769                 .duration(duration)
56770                 .on('start', function() { map.startEase(); })
56771                 .call(zoom$$1.transform, identity$7.translate(t$$1[0], t$$1[1]).scale(k));
56772         } else {
56773             projection.translate(t$$1);
56774             transformStart = projection.transform();
56775             _selection.call(zoom$$1.transform, transformStart);
56776             dispatch$$1.call('move', this, map);
56777             immediateRedraw();
56778         }
56779
56780         return map;
56781     };
56782
56783
56784     map.dimensions = function(_) {
56785         if (!arguments.length) return dimensions;
56786         var center = map.center();
56787         dimensions = _;
56788         drawLayers.dimensions(dimensions);
56789         context.background().dimensions(dimensions);
56790         projection.clipExtent([[0, 0], dimensions]);
56791         mouse = utilFastMouse(supersurface.node());
56792         setCenter(center);
56793
56794         scheduleRedraw();
56795         return map;
56796     };
56797
56798
56799     function zoomIn(delta) {
56800         setZoom(~~map.zoom() + delta, true, 250);
56801     }
56802
56803     function zoomOut(delta) {
56804         setZoom(~~map.zoom() - delta, true, 250);
56805     }
56806
56807     map.zoomIn = function() { zoomIn(1); };
56808     map.zoomInFurther = function() { zoomIn(4); };
56809
56810     map.zoomOut = function() { zoomOut(1); };
56811     map.zoomOutFurther = function() { zoomOut(4); };
56812
56813
56814     map.center = function(loc2) {
56815         if (!arguments.length) {
56816             return projection.invert(pxCenter());
56817         }
56818
56819         if (setCenter(loc2)) {
56820             dispatch$$1.call('move', this, map);
56821         }
56822
56823         scheduleRedraw();
56824         return map;
56825     };
56826
56827
56828     map.zoom = function(z2) {
56829         if (!arguments.length) {
56830             return Math.max(ktoz(projection.scale() * 2 * Math.PI), 0);
56831         }
56832
56833         if (z2 < minzoom) {
56834             surface.interrupt();
56835             uiFlash().text(t('cannot_zoom'))();
56836             z2 = context.minEditableZoom();
56837         }
56838
56839         if (setZoom(z2)) {
56840             dispatch$$1.call('move', this, map);
56841         }
56842
56843         scheduleRedraw();
56844         return map;
56845     };
56846
56847
56848     map.zoomTo = function(entity, zoomLimits) {
56849         var extent = entity.extent(context.graph());
56850         if (!isFinite(extent.area())) return;
56851
56852         var z2 = map.trimmedExtentZoom(extent);
56853         zoomLimits = zoomLimits || [context.minEditableZoom(), 20];
56854         map.centerZoom(extent.center(), Math.min(Math.max(z2, zoomLimits[0]), zoomLimits[1]));
56855     };
56856
56857
56858     map.centerZoom = function(loc2, z2) {
56859         var centered = setCenter(loc2),
56860             zoomed   = setZoom(z2);
56861
56862         if (centered || zoomed) {
56863             dispatch$$1.call('move', this, map);
56864         }
56865
56866         scheduleRedraw();
56867         return map;
56868     };
56869
56870
56871     map.centerEase = function(loc2, duration) {
56872         duration = duration || 250;
56873         setCenter(loc2, duration);
56874         return map;
56875     };
56876
56877
56878     map.zoomEase = function(z2, duration) {
56879         duration = duration || 250;
56880         setZoom(z2, false, duration);
56881         return map;
56882     };
56883
56884
56885     map.transformEase = function(t2, duration) {
56886         duration = duration || 250;
56887         setTransform(t2, duration, false);
56888         return map;
56889     };
56890
56891
56892     map.startEase = function() {
56893         utilBindOnce(surface, 'mousedown.ease', function() {
56894             map.cancelEase();
56895         });
56896         return map;
56897     };
56898
56899
56900     map.cancelEase = function() {
56901         _selection.interrupt();
56902         return map;
56903     };
56904
56905
56906     map.extent = function(_) {
56907         if (!arguments.length) {
56908             return new geoExtent(projection.invert([0, dimensions[1]]),
56909                                  projection.invert([dimensions[0], 0]));
56910         } else {
56911             var extent = geoExtent(_);
56912             map.centerZoom(extent.center(), map.extentZoom(extent));
56913         }
56914     };
56915
56916
56917     map.trimmedExtent = function(_) {
56918         if (!arguments.length) {
56919             var headerY = 60, footerY = 30, pad = 10;
56920             return new geoExtent(projection.invert([pad, dimensions[1] - footerY - pad]),
56921                                  projection.invert([dimensions[0] - pad, headerY + pad]));
56922         } else {
56923             var extent = geoExtent(_);
56924             map.centerZoom(extent.center(), map.trimmedExtentZoom(extent));
56925         }
56926     };
56927
56928
56929     function calcZoom(extent, dim) {
56930         var tl = projection([extent[0][0], extent[1][1]]),
56931             br = projection([extent[1][0], extent[0][1]]);
56932
56933         // Calculate maximum zoom that fits extent
56934         var hFactor = (br[0] - tl[0]) / dim[0],
56935             vFactor = (br[1] - tl[1]) / dim[1],
56936             hZoomDiff = Math.log(Math.abs(hFactor)) / Math.LN2,
56937             vZoomDiff = Math.log(Math.abs(vFactor)) / Math.LN2,
56938             newZoom = map.zoom() - Math.max(hZoomDiff, vZoomDiff);
56939
56940         return newZoom;
56941     }
56942
56943
56944     map.extentZoom = function(_) {
56945         return calcZoom(geoExtent(_), dimensions);
56946     };
56947
56948
56949     map.trimmedExtentZoom = function(_) {
56950         var trimY = 120, trimX = 40,
56951             trimmed = [dimensions[0] - trimX, dimensions[1] - trimY];
56952         return calcZoom(geoExtent(_), trimmed);
56953     };
56954
56955
56956     map.editable = function() {
56957         var osmLayer = surface.selectAll('.data-layer-osm');
56958         if (!osmLayer.empty() && osmLayer.classed('disabled')) return false;
56959
56960         return map.zoom() >= context.minEditableZoom();
56961     };
56962
56963
56964     map.minzoom = function(_) {
56965         if (!arguments.length) return minzoom;
56966         minzoom = _;
56967         return map;
56968     };
56969
56970
56971     map.layers = drawLayers;
56972
56973
56974     return utilRebind(map, dispatch$$1, 'on');
56975 }
56976
56977 function uiMapInMap(context) {
56978
56979     function map_in_map(selection) {
56980         var backgroundLayer = rendererTileLayer(context);
56981         var overlayLayers = {};
56982         var projection = geoRawMercator();
56983         var gpxLayer = svgGpx(projection, context).showLabels(false);
56984         var debugLayer = svgDebug(projection, context);
56985         var zoom$$1 = d3_zoom()
56986             .scaleExtent([geoZoomToScale(0.5), geoZoomToScale(24)])
56987             .on('start', zoomStarted)
56988             .on('zoom', zoomed)
56989             .on('end', zoomEnded);
56990         var isTransformed = false;
56991         var isHidden = true;
56992         var skipEvents = false;
56993         var gesture = null;
56994         var zDiff = 6;    // by default, minimap renders at (main zoom - 6)
56995         var wrap = d3_select(null);
56996         var tiles = d3_select(null);
56997         var viewport = d3_select(null);
56998         var tStart;    // transform at start of gesture
56999         var tCurr;     // transform at most recent event
57000         var timeoutId;
57001
57002
57003         function zoomStarted() {
57004             if (skipEvents) return;
57005             tStart = tCurr = projection.transform();
57006             gesture = null;
57007         }
57008
57009
57010         function zoomed() {
57011             if (skipEvents) return;
57012
57013             var x = event.transform.x;
57014             var y = event.transform.y;
57015             var k = event.transform.k;
57016             var isZooming = (k !== tStart.k);
57017             var isPanning = (x !== tStart.x || y !== tStart.y);
57018
57019             if (!isZooming && !isPanning) {
57020                 return;  // no change
57021             }
57022
57023             // lock in either zooming or panning, don't allow both in minimap.
57024             if (!gesture) {
57025                 gesture = isZooming ? 'zoom' : 'pan';
57026             }
57027
57028             var tMini = projection.transform();
57029             var tX, tY, scale;
57030
57031             if (gesture === 'zoom') {
57032                 var dMini = utilGetDimensions(wrap);
57033                 var cMini = geoVecScale(dMini, 0.5);
57034                 scale = k / tMini.k;
57035                 tX = (cMini[0] / scale - cMini[0]) * scale;
57036                 tY = (cMini[1] / scale - cMini[1]) * scale;
57037             } else {
57038                 k = tMini.k;
57039                 scale = 1;
57040                 tX = x - tMini.x;
57041                 tY = y - tMini.y;
57042             }
57043
57044             utilSetTransform(tiles, tX, tY, scale);
57045             utilSetTransform(viewport, 0, 0, scale);
57046             isTransformed = true;
57047             tCurr = identity$7.translate(x, y).scale(k);
57048
57049             var zMain = geoScaleToZoom(context.projection.scale());
57050             var zMini = geoScaleToZoom(k);
57051
57052             zDiff = zMain - zMini;
57053
57054             queueRedraw();
57055         }
57056
57057
57058         function zoomEnded() {
57059             if (skipEvents) return;
57060             if (gesture !== 'pan') return;
57061
57062             updateProjection();
57063             gesture = null;
57064             var dMini = utilGetDimensions(wrap);
57065             var cMini = geoVecScale(dMini, 0.5);
57066             context.map().center(projection.invert(cMini));   // recenter main map..
57067         }
57068
57069
57070         function updateProjection() {
57071             var loc = context.map().center();
57072             var dMini = utilGetDimensions(wrap);
57073             var cMini = geoVecScale(dMini, 0.5);
57074             var tMain = context.projection.transform();
57075             var zMain = geoScaleToZoom(tMain.k);
57076             var zMini = Math.max(zMain - zDiff, 0.5);
57077             var kMini = geoZoomToScale(zMini);
57078
57079             projection
57080                 .translate([tMain.x, tMain.y])
57081                 .scale(kMini);
57082
57083             var point = projection(loc);
57084             var mouse = (gesture === 'pan') ? geoVecSubtract([tCurr.x, tCurr.y], [tStart.x, tStart.y]) : [0, 0];
57085             var xMini = cMini[0] - point[0] + tMain.x + mouse[0];
57086             var yMini = cMini[1] - point[1] + tMain.y + mouse[1];
57087
57088             projection
57089                 .translate([xMini, yMini])
57090                 .clipExtent([[0, 0], dMini]);
57091
57092             tCurr = projection.transform();
57093
57094             if (isTransformed) {
57095                 utilSetTransform(tiles, 0, 0);
57096                 utilSetTransform(viewport, 0, 0);
57097                 isTransformed = false;
57098             }
57099
57100             zoom$$1
57101                 .scaleExtent([geoZoomToScale(0.5), geoZoomToScale(zMain - 3)]);
57102
57103             skipEvents = true;
57104             wrap.call(zoom$$1.transform, tCurr);
57105             skipEvents = false;
57106         }
57107
57108
57109         function redraw() {
57110             clearTimeout(timeoutId);
57111             if (isHidden) return;
57112
57113             updateProjection();
57114
57115             var dMini = utilGetDimensions(wrap);
57116             var zMini = geoScaleToZoom(projection.scale());
57117
57118             // setup tile container
57119             tiles = wrap
57120                 .selectAll('.map-in-map-tiles')
57121                 .data([0]);
57122
57123             tiles = tiles.enter()
57124                 .append('div')
57125                 .attr('class', 'map-in-map-tiles')
57126                 .merge(tiles);
57127
57128             // redraw background
57129             backgroundLayer
57130                 .source(context.background().baseLayerSource())
57131                 .projection(projection)
57132                 .dimensions(dMini);
57133
57134             var background = tiles
57135                 .selectAll('.map-in-map-background')
57136                 .data([0]);
57137
57138             background.enter()
57139                 .append('div')
57140                 .attr('class', 'map-in-map-background')
57141                 .merge(background)
57142                 .call(backgroundLayer);
57143
57144
57145             // redraw overlay
57146             var overlaySources = context.background().overlayLayerSources();
57147             var activeOverlayLayers = [];
57148             for (var i = 0; i < overlaySources.length; i++) {
57149                 if (overlaySources[i].validZoom(zMini)) {
57150                     if (!overlayLayers[i]) overlayLayers[i] = rendererTileLayer(context);
57151                     activeOverlayLayers.push(overlayLayers[i]
57152                         .source(overlaySources[i])
57153                         .projection(projection)
57154                         .dimensions(dMini));
57155                 }
57156             }
57157
57158             var overlay = tiles
57159                 .selectAll('.map-in-map-overlay')
57160                 .data([0]);
57161
57162             overlay = overlay.enter()
57163                 .append('div')
57164                 .attr('class', 'map-in-map-overlay')
57165                 .merge(overlay);
57166
57167
57168             var overlays = overlay
57169                 .selectAll('div')
57170                 .data(activeOverlayLayers, function(d) { return d.source().name(); });
57171
57172             overlays.exit()
57173                 .remove();
57174
57175             overlays = overlays.enter()
57176                 .append('div')
57177                 .merge(overlays)
57178                 .each(function(layer) { d3_select(this).call(layer); });
57179
57180
57181             var dataLayers = tiles
57182                 .selectAll('.map-in-map-data')
57183                 .data([0]);
57184
57185             dataLayers.exit()
57186                 .remove();
57187
57188             dataLayers = dataLayers.enter()
57189                 .append('svg')
57190                 .attr('class', 'map-in-map-data')
57191                 .merge(dataLayers)
57192                 .call(gpxLayer)
57193                 .call(debugLayer);
57194
57195
57196             // redraw viewport bounding box
57197             if (gesture !== 'pan') {
57198                 var getPath = d3_geoPath(projection);
57199                 var bbox = { type: 'Polygon', coordinates: [context.map().extent().polygon()] };
57200
57201                 viewport = wrap.selectAll('.map-in-map-viewport')
57202                     .data([0]);
57203
57204                 viewport = viewport.enter()
57205                     .append('svg')
57206                     .attr('class', 'map-in-map-viewport')
57207                     .merge(viewport);
57208
57209
57210                 var path = viewport.selectAll('.map-in-map-bbox')
57211                     .data([bbox]);
57212
57213                 path.enter()
57214                     .append('path')
57215                     .attr('class', 'map-in-map-bbox')
57216                     .merge(path)
57217                     .attr('d', getPath)
57218                     .classed('thick', function(d) { return getPath.area(d) < 30; });
57219             }
57220         }
57221
57222
57223         function queueRedraw() {
57224             clearTimeout(timeoutId);
57225             timeoutId = setTimeout(function() { redraw(); }, 750);
57226         }
57227
57228
57229         function toggle() {
57230             if (event) event.preventDefault();
57231
57232             isHidden = !isHidden;
57233
57234             d3_select('.minimap-toggle-item')
57235                 .classed('active', !isHidden)
57236                 .select('input')
57237                 .property('checked', !isHidden);
57238
57239             if (isHidden) {
57240                 wrap
57241                     .style('display', 'block')
57242                     .style('opacity', '1')
57243                     .transition()
57244                     .duration(200)
57245                     .style('opacity', '0')
57246                     .on('end', function() {
57247                         selection.selectAll('.map-in-map')
57248                             .style('display', 'none');
57249                     });
57250             } else {
57251                 wrap
57252                     .style('display', 'block')
57253                     .style('opacity', '0')
57254                     .transition()
57255                     .duration(200)
57256                     .style('opacity', '1')
57257                     .on('end', function() {
57258                         redraw();
57259                     });
57260             }
57261         }
57262
57263
57264         uiMapInMap.toggle = toggle;
57265
57266         wrap = selection.selectAll('.map-in-map')
57267             .data([0]);
57268
57269         wrap = wrap.enter()
57270             .append('div')
57271             .attr('class', 'map-in-map')
57272             .style('display', (isHidden ? 'none' : 'block'))
57273             .call(zoom$$1)
57274             .on('dblclick.zoom', null)
57275             .merge(wrap);
57276
57277         context.map()
57278             .on('drawn.map-in-map', function(drawn) {
57279                 if (drawn.full === true) {
57280                     redraw();
57281                 }
57282             });
57283
57284         redraw();
57285
57286         var keybinding = d3keybinding('map-in-map')
57287             .on(t('background.minimap.key'), toggle);
57288
57289         d3_select(document)
57290             .call(keybinding);
57291     }
57292
57293     return map_in_map;
57294 }
57295
57296 function uiBackground(context) {
57297     var key = t('background.key');
57298
57299     var _customSource = context.background().findSource('custom');
57300     var _previousBackground;
57301     var _shown = false;
57302
57303     var _backgroundList = d3_select(null);
57304     var _overlayList = d3_select(null);
57305     var _displayOptionsContainer = d3_select(null);
57306     var _offsetContainer = d3_select(null);
57307
57308     var backgroundDisplayOptions = uiBackgroundDisplayOptions(context);
57309     var backgroundOffset = uiBackgroundOffset(context);
57310
57311
57312     function setTooltips(selection) {
57313         selection.each(function(d, i, nodes) {
57314             var item = d3_select(this).select('label');
57315             var span = item.select('span');
57316             var placement = (i < nodes.length / 2) ? 'bottom' : 'top';
57317             var description = d.description();
57318             var isOverflowing = (span.property('clientWidth') !== span.property('scrollWidth'));
57319
57320             if (d === _previousBackground) {
57321                 item.call(tooltip()
57322                     .placement(placement)
57323                     .html(true)
57324                     .title(function() {
57325                         var tip = '<div>' + t('background.switch') + '</div>';
57326                         return uiTooltipHtml(tip, uiCmd('⌘' + key));
57327                     })
57328                 );
57329             } else if (description || isOverflowing) {
57330                 item.call(tooltip()
57331                     .placement(placement)
57332                     .title(description || d.name())
57333                 );
57334             } else {
57335                 item.call(tooltip().destroy);
57336             }
57337         });
57338     }
57339
57340
57341     function updateLayerSelections(selection) {
57342         function active(d) {
57343             return context.background().showsLayer(d);
57344         }
57345
57346         selection.selectAll('.layer')
57347             .classed('active', active)
57348             .classed('switch', function(d) { return d === _previousBackground; })
57349             .call(setTooltips)
57350             .selectAll('input')
57351             .property('checked', active);
57352     }
57353
57354
57355     function chooseBackground(d) {
57356         if (d.id === 'custom' && !d.template()) {
57357             return editCustom();
57358         }
57359
57360         event.preventDefault();
57361         _previousBackground = context.background().baseLayerSource();
57362         context.background().baseLayerSource(d);
57363         _backgroundList.call(updateLayerSelections);
57364         document.activeElement.blur();
57365     }
57366
57367
57368     function editCustom() {
57369         event.preventDefault();
57370         var example = 'https://{switch:a,b,c}.tile.openstreetmap.org/{zoom}/{x}/{y}.png';
57371         var template = window.prompt(
57372             t('background.custom_prompt', { example: example }),
57373             _customSource.template() || example
57374         );
57375
57376         if (template) {
57377             context.storage('background-custom-template', template);
57378             _customSource.template(template);
57379             chooseBackground(_customSource);
57380         } else {
57381             _backgroundList.call(updateLayerSelections);
57382         }
57383     }
57384
57385
57386     function chooseOverlay(d) {
57387         event.preventDefault();
57388         context.background().toggleOverlayLayer(d);
57389         _overlayList.call(updateLayerSelections);
57390         document.activeElement.blur();
57391     }
57392
57393
57394     function drawListItems(layerList, type, change, filter) {
57395         var sources = context.background()
57396             .sources(context.map().extent())
57397             .filter(filter);
57398
57399         var layerLinks = layerList.selectAll('li.layer')
57400             .data(sources, function(d) { return d.name(); });
57401
57402         layerLinks.exit()
57403             .remove();
57404
57405         var enter = layerLinks.enter()
57406             .append('li')
57407             .attr('class', 'layer')
57408             .classed('layer-custom', function(d) { return d.id === 'custom'; })
57409             .classed('best', function(d) { return d.best(); });
57410
57411         enter.filter(function(d) { return d.id === 'custom'; })
57412             .append('button')
57413             .attr('class', 'layer-browse')
57414             .call(tooltip()
57415                 .title(t('background.custom_button'))
57416                 .placement((textDirection === 'rtl') ? 'right' : 'left')
57417             )
57418             .on('click', editCustom)
57419             .call(svgIcon('#icon-search'));
57420
57421         enter.filter(function(d) { return d.best(); })
57422             .append('div')
57423             .attr('class', 'best')
57424             .call(tooltip()
57425                 .title(t('background.best_imagery'))
57426                 .placement((textDirection === 'rtl') ? 'right' : 'left')
57427             )
57428             .append('span')
57429             .html('&#9733;');
57430
57431         var label = enter
57432             .append('label');
57433
57434         label
57435             .append('input')
57436             .attr('type', type)
57437             .attr('name', 'layers')
57438             .on('change', change);
57439
57440         label
57441             .append('span')
57442             .text(function(d) { return d.name(); });
57443
57444
57445         layerList.selectAll('li.layer')
57446             .sort(sortSources)
57447             .style('display', layerList.selectAll('li.layer').data().length > 0 ? 'block' : 'none');
57448
57449         layerList
57450             .call(updateLayerSelections);
57451
57452
57453         function sortSources(a, b) {
57454             return a.best() && !b.best() ? -1
57455                 : b.best() && !a.best() ? 1
57456                 : d3_descending(a.area(), b.area()) || d3_ascending(a.name(), b.name()) || 0;
57457         }
57458     }
57459
57460
57461     function renderBackgroundList(selection) {
57462
57463         // the background list
57464         var container = selection.selectAll('.layer-background-list')
57465             .data([0]);
57466
57467         _backgroundList = container.enter()
57468             .append('ul')
57469             .attr('class', 'layer-list layer-background-list')
57470             .attr('dir', 'auto')
57471             .merge(container);
57472
57473
57474         // add minimap toggle below list
57475         var minimapEnter = selection.selectAll('.minimap-toggle-list')
57476             .data([0])
57477             .enter()
57478             .append('ul')
57479             .attr('class', 'layer-list minimap-toggle-list')
57480             .append('li')
57481             .attr('class', 'layer minimap-toggle-item');
57482
57483         var minimapLabelEnter = minimapEnter
57484             .append('label')
57485             .call(tooltip()
57486                 .html(true)
57487                 .title(uiTooltipHtml(t('background.minimap.tooltip'), t('background.minimap.key')))
57488                 .placement('top')
57489             );
57490
57491         minimapLabelEnter
57492             .append('input')
57493             .attr('type', 'checkbox')
57494             .on('change', function() {
57495                 event.preventDefault();
57496                 uiMapInMap.toggle();
57497             });
57498
57499         minimapLabelEnter
57500             .append('span')
57501             .text(t('background.minimap.description'));
57502
57503
57504         // "Info / Report a Problem" link
57505         selection.selectAll('.imagery-faq')
57506             .data([0])
57507             .enter()
57508             .append('div')
57509             .attr('class', 'imagery-faq')
57510             .append('a')
57511             .attr('target', '_blank')
57512             .attr('tabindex', -1)
57513             .call(svgIcon('#icon-out-link', 'inline'))
57514             .attr('href', 'https://github.com/openstreetmap/iD/blob/master/FAQ.md#how-can-i-report-an-issue-with-background-imagery')
57515             .append('span')
57516             .text(t('background.imagery_source_faq'));
57517     }
57518
57519
57520     function renderOverlayList(selection) {
57521         var container = selection.selectAll('.layer-overlay-list')
57522             .data([0]);
57523
57524         _overlayList = container.enter()
57525             .append('ul')
57526             .attr('class', 'layer-list layer-overlay-list')
57527             .attr('dir', 'auto')
57528             .merge(container);
57529     }
57530
57531
57532     function update() {
57533         _backgroundList
57534             .call(drawListItems, 'radio', chooseBackground, function(d) { return !d.isHidden() && !d.overlay; });
57535
57536         _overlayList
57537             .call(drawListItems, 'checkbox', chooseOverlay, function(d) { return !d.isHidden() && d.overlay; });
57538
57539         _displayOptionsContainer
57540             .call(backgroundDisplayOptions);
57541
57542         _offsetContainer
57543             .call(backgroundOffset);
57544     }
57545
57546
57547     function quickSwitch() {
57548         if (event) {
57549             event.stopImmediatePropagation();
57550             event.preventDefault();
57551         }
57552         if (_previousBackground) {
57553             chooseBackground(_previousBackground);
57554         }
57555     }
57556
57557
57558     function background(selection) {
57559
57560         function hidePane() {
57561             setVisible(false);
57562         }
57563
57564         function togglePane() {
57565             if (event) event.preventDefault();
57566             paneTooltip.hide(button);
57567             setVisible(!button.classed('active'));
57568         }
57569
57570         function setVisible(show) {
57571             if (show !== _shown) {
57572                 button.classed('active', show);
57573                 _shown = show;
57574
57575                 if (show) {
57576                     uiMapData.hidePane();
57577                     uiHelp.hidePane();
57578                     update();
57579
57580                     pane
57581                         .style('display', 'block')
57582                         .style('right', '-300px')
57583                         .transition()
57584                         .duration(200)
57585                         .style('right', '0px');
57586
57587                 } else {
57588                     pane
57589                         .style('display', 'block')
57590                         .style('right', '0px')
57591                         .transition()
57592                         .duration(200)
57593                         .style('right', '-300px')
57594                         .on('end', function() {
57595                             d3_select(this).style('display', 'none');
57596                         });
57597                 }
57598             }
57599         }
57600
57601
57602         var pane = selection
57603             .append('div')
57604             .attr('class', 'fillL map-overlay col3 content hide');
57605
57606         var paneTooltip = tooltip()
57607             .placement((textDirection === 'rtl') ? 'right' : 'left')
57608             .html(true)
57609             .title(uiTooltipHtml(t('background.description'), key));
57610
57611         var button = selection
57612             .append('button')
57613             .attr('tabindex', -1)
57614             .on('click', togglePane)
57615             .call(svgIcon('#icon-layers', 'light'))
57616             .call(paneTooltip);
57617
57618         pane
57619             .append('h2')
57620             .text(t('background.title'));
57621
57622         // background list
57623         pane
57624             .append('div')
57625             .attr('class', 'background-background-list-container')
57626             .call(uiDisclosure(context, 'background_list', true)
57627                 .title(t('background.backgrounds'))
57628                 .content(renderBackgroundList)
57629             );
57630
57631         // overlay list
57632         pane
57633             .append('div')
57634             .attr('class', 'background-overlay-list-container')
57635             .call(uiDisclosure(context, 'overlay_list', true)
57636                 .title(t('background.overlays'))
57637                 .content(renderOverlayList)
57638             );
57639
57640         // display options
57641         _displayOptionsContainer = pane
57642             .append('div')
57643             .attr('class', 'background-display-options');
57644
57645         // offset controls
57646         _offsetContainer = pane
57647             .append('div')
57648             .attr('class', 'background-offset');
57649
57650
57651         // add listeners
57652         context.map()
57653             .on('move.background-update', debounce(utilCallWhenIdle(update), 1000));
57654
57655         context.background()
57656             .on('change.background-update', update);
57657
57658
57659         update();
57660
57661         var keybinding = d3keybinding('background')
57662             .on(key, togglePane)
57663             .on(uiCmd('⌘' + key), quickSwitch)
57664             .on([t('map_data.key'), t('help.key')], hidePane);
57665
57666         d3_select(document)
57667             .call(keybinding);
57668
57669         uiBackground.hidePane = hidePane;
57670         uiBackground.togglePane = togglePane;
57671         uiBackground.setVisible = setVisible;
57672     }
57673
57674     return background;
57675 }
57676
57677 function uiContributors(context) {
57678     var osm = context.connection(),
57679         debouncedUpdate = debounce(function() { update(); }, 1000),
57680         limit = 4,
57681         hidden = false,
57682         wrap = d3_select(null);
57683
57684
57685     function update() {
57686         if (!osm) return;
57687
57688         var users = {},
57689             entities = context.intersects(context.map().extent());
57690
57691         entities.forEach(function(entity) {
57692             if (entity && entity.user) users[entity.user] = true;
57693         });
57694
57695         var u = Object.keys(users),
57696             subset = u.slice(0, u.length > limit ? limit - 1 : limit);
57697
57698         wrap.html('')
57699             .call(svgIcon('#icon-nearby', 'pre-text light'));
57700
57701         var userList = d3_select(document.createElement('span'));
57702
57703         userList.selectAll()
57704             .data(subset)
57705             .enter()
57706             .append('a')
57707             .attr('class', 'user-link')
57708             .attr('href', function(d) { return osm.userURL(d); })
57709             .attr('target', '_blank')
57710             .attr('tabindex', -1)
57711             .text(String);
57712
57713         if (u.length > limit) {
57714             var count = d3_select(document.createElement('span'));
57715
57716             count.append('a')
57717                 .attr('target', '_blank')
57718                 .attr('tabindex', -1)
57719                 .attr('href', function() {
57720                     return osm.changesetsURL(context.map().center(), context.map().zoom());
57721                 })
57722                 .text(u.length - limit + 1);
57723
57724             wrap.append('span')
57725                 .html(t('contributors.truncated_list', { users: userList.html(), count: count.html() }));
57726
57727         } else {
57728             wrap.append('span')
57729                 .html(t('contributors.list', { users: userList.html() }));
57730         }
57731
57732         if (!u.length) {
57733             hidden = true;
57734             wrap
57735                 .transition()
57736                 .style('opacity', 0);
57737
57738         } else if (hidden) {
57739             wrap
57740                 .transition()
57741                 .style('opacity', 1);
57742         }
57743     }
57744
57745
57746     return function(selection) {
57747         if (!osm) return;
57748         wrap = selection;
57749         update();
57750
57751         osm.on('loaded.contributors', debouncedUpdate);
57752         context.map().on('move.contributors', debouncedUpdate);
57753     };
57754 }
57755
57756 function uiFeatureInfo(context) {
57757     function update(selection) {
57758         var features = context.features(),
57759             stats = features.stats(),
57760             count = 0,
57761             hiddenList = compact(map$4(features.hidden(), function(k) {
57762                 if (stats[k]) {
57763                     count += stats[k];
57764                     return String(stats[k]) + ' ' + t('feature.' + k + '.description');
57765                 }
57766             }));
57767
57768         selection.html('');
57769
57770         if (hiddenList.length) {
57771             var tooltipBehavior = tooltip()
57772                 .placement('top')
57773                 .html(true)
57774                 .title(function() {
57775                     return uiTooltipHtml(hiddenList.join('<br/>'));
57776                 });
57777
57778             var warning = selection.append('a')
57779                 .attr('href', '#')
57780                 .attr('tabindex', -1)
57781                 .html(t('feature_info.hidden_warning', { count: count }))
57782                 .call(tooltipBehavior)
57783                 .on('click', function() {
57784                     tooltipBehavior.hide(warning);
57785                     // open map data panel?
57786                     event.preventDefault();
57787                 });
57788         }
57789
57790         selection
57791             .classed('hide', !hiddenList.length);
57792     }
57793
57794
57795     return function(selection) {
57796         update(selection);
57797
57798         context.features().on('change.feature_info', function() {
57799             update(selection);
57800         });
57801     };
57802 }
57803
57804 function uiFullScreen(context) {
57805     var element = context.container().node(),
57806         keybinding = d3keybinding('full-screen');
57807         // button;
57808
57809
57810     function getFullScreenFn() {
57811         if (element.requestFullscreen) {
57812             return element.requestFullscreen;
57813         } else if (element.msRequestFullscreen) {
57814             return element.msRequestFullscreen;
57815         } else if (element.mozRequestFullScreen) {
57816             return element.mozRequestFullScreen;
57817         } else if (element.webkitRequestFullscreen) {
57818             return element.webkitRequestFullscreen;
57819         }
57820     }
57821
57822
57823     function getExitFullScreenFn() {
57824         if (document.exitFullscreen) {
57825             return document.exitFullscreen;
57826         } else if (document.msExitFullscreen) {
57827             return document.msExitFullscreen;
57828         } else if (document.mozCancelFullScreen) {
57829             return document.mozCancelFullScreen;
57830         } else if (document.webkitExitFullscreen) {
57831             return document.webkitExitFullscreen;
57832         }
57833     }
57834
57835
57836     function isFullScreen() {
57837         return document.fullscreenElement ||
57838             document.mozFullScreenElement ||
57839             document.webkitFullscreenElement ||
57840             document.msFullscreenElement;
57841     }
57842
57843
57844     function isSupported() {
57845         return !!getFullScreenFn();
57846     }
57847
57848
57849     function fullScreen() {
57850         event.preventDefault();
57851         if (!isFullScreen()) {
57852             // button.classed('active', true);
57853             getFullScreenFn().apply(element);
57854         } else {
57855             // button.classed('active', false);
57856             getExitFullScreenFn().apply(document);
57857         }
57858     }
57859
57860
57861     return function() { // selection) {
57862         if (!isSupported())
57863             return;
57864
57865         // button = selection.append('button')
57866         //     .attr('title', t('full_screen'))
57867         //     .attr('tabindex', -1)
57868         //     .on('click', fullScreen)
57869         //     .call(tooltip);
57870
57871         // button.append('span')
57872         //     .attr('class', 'icon full-screen');
57873
57874         var detected = utilDetect();
57875         var keys = detected.os === 'mac' ? [uiCmd('⌃⌘F'), 'f11'] : ['f11'];
57876         keybinding.on(keys, fullScreen);
57877
57878         d3_select(document)
57879             .call(keybinding);
57880     };
57881 }
57882
57883 function uiLoading(context) {
57884     var _modalSelection = d3_select(null);
57885     var _message = '';
57886     var _blocking = false;
57887
57888
57889     var loading = function(selection) {
57890         _modalSelection = uiModal(selection, _blocking);
57891
57892         var loadertext = _modalSelection.select('.content')
57893             .classed('loading-modal', true)
57894             .append('div')
57895             .attr('class', 'modal-section fillL');
57896
57897         loadertext
57898             .append('img')
57899             .attr('class', 'loader')
57900             .attr('src', context.imagePath('loader-white.gif'));
57901
57902         loadertext
57903             .append('h3')
57904             .text(_message);
57905
57906         _modalSelection.select('button.close')
57907             .attr('class', 'hide');
57908
57909         return loading;
57910     };
57911
57912
57913     loading.message = function(_) {
57914         if (!arguments.length) return _message;
57915         _message = _;
57916         return loading;
57917     };
57918
57919
57920     loading.blocking = function(_) {
57921         if (!arguments.length) return _blocking;
57922         _blocking = _;
57923         return loading;
57924     };
57925
57926
57927     loading.close = function() {
57928         _modalSelection.remove();
57929     };
57930
57931
57932     return loading;
57933 }
57934
57935 function uiGeolocate(context) {
57936     var geoOptions = { enableHighAccuracy: false, timeout: 6000 /* 6sec */ },
57937         locating = uiLoading(context).message(t('geolocate.locating')).blocking(true),
57938         timeoutId;
57939
57940
57941     function click() {
57942         if (context.inIntro()) return;
57943         context.enter(modeBrowse(context));
57944         context.container().call(locating);
57945         navigator.geolocation.getCurrentPosition(success, error, geoOptions);
57946
57947         // This timeout ensures that we still call finish() even if
57948         // the user declines to share their location in Firefox
57949         timeoutId = setTimeout(finish, 10000 /* 10sec */ );
57950     }
57951
57952
57953     function success(position) {
57954         var map = context.map(),
57955             extent = geoExtent([position.coords.longitude, position.coords.latitude])
57956                 .padByMeters(position.coords.accuracy);
57957
57958         map.centerZoom(extent.center(), Math.min(20, map.extentZoom(extent)));
57959         finish();
57960     }
57961
57962
57963     function error() {
57964         finish();
57965     }
57966
57967
57968     function finish() {
57969         locating.close();  // unblock ui
57970         if (timeoutId) { clearTimeout(timeoutId); }
57971         timeoutId = undefined;
57972     }
57973
57974
57975     return function(selection) {
57976         if (!navigator.geolocation) return;
57977
57978         selection
57979             .append('button')
57980             .attr('tabindex', -1)
57981             .attr('title', t('geolocate.title'))
57982             .on('click', click)
57983             .call(svgIcon('#icon-geolocate', 'light'))
57984             .call(tooltip()
57985                 .placement((textDirection === 'rtl') ? 'right' : 'left'));
57986     };
57987 }
57988
57989 function uiPanelBackground(context) {
57990     var background = context.background();
57991     var currSourceName = null;
57992     var metadata = {};
57993     var metadataKeys = [
57994         'zoom', 'vintage', 'source', 'description', 'resolution', 'accuracy'
57995     ];
57996
57997     var debouncedRedraw = debounce(redraw, 250);
57998
57999     function redraw(selection) {
58000         var source = background.baseLayerSource(),
58001             isDG = (source.id.match(/^DigitalGlobe/i) !== null);
58002
58003         if (currSourceName !== source.name()) {
58004             currSourceName = source.name();
58005             metadata = {};
58006         }
58007
58008         selection.html('');
58009
58010         var list = selection
58011             .append('ul')
58012             .attr('class', 'background-info');
58013
58014         list
58015             .append('li')
58016             .text(currSourceName);
58017
58018         metadataKeys.forEach(function(k) {
58019             // DigitalGlobe vintage is available in raster layers for now.
58020             if (isDG && k === 'vintage') return;
58021
58022             list
58023                 .append('li')
58024                 .attr('class', 'background-info-list-' + k)
58025                 .classed('hide', !metadata[k])
58026                 .text(t('info_panels.background.' + k) + ':')
58027                 .append('span')
58028                 .attr('class', 'background-info-span-' + k)
58029                 .text(metadata[k]);
58030         });
58031
58032         debouncedGetMetadata(selection);
58033
58034         var toggleTiles = context.getDebug('tile') ? 'hide_tiles' : 'show_tiles';
58035
58036         selection
58037             .append('a')
58038             .text(t('info_panels.background.' + toggleTiles))
58039             .attr('href', '#')
58040             .attr('class', 'button button-toggle-tiles')
58041             .on('click', function() {
58042                 event.preventDefault();
58043                 context.setDebug('tile', !context.getDebug('tile'));
58044                 selection.call(redraw);
58045             });
58046
58047         if (isDG) {
58048             var key = source.id + '-vintage';
58049             var sourceVintage = context.background().findSource(key);
58050             var showsVintage = context.background().showsLayer(sourceVintage);
58051             var toggleVintage = showsVintage ? 'hide_vintage' : 'show_vintage';
58052             selection
58053                 .append('a')
58054                 .text(t('info_panels.background.' + toggleVintage))
58055                 .attr('href', '#')
58056                 .attr('class', 'button button-toggle-vintage')
58057                 .on('click', function() {
58058                     event.preventDefault();
58059                     context.background().toggleOverlayLayer(sourceVintage);
58060                     selection.call(redraw);
58061                 });
58062         }
58063
58064         // disable if necessary
58065         ['DigitalGlobe-Premium', 'DigitalGlobe-Standard'].forEach(function(layerId) {
58066             if (source.id !== layerId) {
58067                 var key = layerId + '-vintage';
58068                 var sourceVintage = context.background().findSource(key);
58069                 if (context.background().showsLayer(sourceVintage)) {
58070                     context.background().toggleOverlayLayer(sourceVintage);
58071                 }
58072             }
58073         });
58074     }
58075
58076
58077     var debouncedGetMetadata = debounce(getMetadata, 250);
58078
58079     function getMetadata(selection) {
58080         var tile = d3_select('.layer-background img.tile-center');   // tile near viewport center
58081         if (tile.empty()) return;
58082
58083         var sourceName = currSourceName,
58084             d = tile.datum(),
58085             zoom = (d && d.length >= 3 && d[2]) || Math.floor(context.map().zoom()),
58086             center = context.map().center();
58087
58088         // update zoom
58089         metadata.zoom = String(zoom);
58090         selection.selectAll('.background-info-list-zoom')
58091             .classed('hide', false)
58092             .selectAll('.background-info-span-zoom')
58093             .text(metadata.zoom);
58094
58095         if (!d || !d.length >= 3) return;
58096
58097         background.baseLayerSource().getMetadata(center, d, function(err, result) {
58098             if (err || currSourceName !== sourceName) return;
58099
58100             // update vintage
58101             var vintage = result.vintage;
58102             metadata.vintage = (vintage && vintage.range) || t('info_panels.background.unknown');
58103             selection.selectAll('.background-info-list-vintage')
58104                 .classed('hide', false)
58105                 .selectAll('.background-info-span-vintage')
58106                 .text(metadata.vintage);
58107
58108             // update other metdata
58109             without(metadataKeys, 'zoom', 'vintage')
58110                 .forEach(function(k) {
58111                     var val = result[k];
58112                     metadata[k] = val;
58113                     selection.selectAll('.background-info-list-' + k)
58114                         .classed('hide', !val)
58115                         .selectAll('.background-info-span-' + k)
58116                         .text(val);
58117                 });
58118         });
58119     }
58120
58121
58122     var panel = function(selection) {
58123         selection.call(redraw);
58124
58125         context.map()
58126             .on('drawn.info-background', function() {
58127                 selection.call(debouncedRedraw);
58128             })
58129             .on('move.info-background', function() {
58130                 selection.call(debouncedGetMetadata);
58131             });
58132
58133     };
58134
58135     panel.off = function() {
58136         context.map()
58137             .on('drawn.info-background', null)
58138             .on('move.info-background', null);
58139     };
58140
58141     panel.id = 'background';
58142     panel.title = t('info_panels.background.title');
58143     panel.key = t('info_panels.background.key');
58144
58145
58146     return panel;
58147 }
58148
58149 function uiPanelHistory(context) {
58150     var osm;
58151
58152     function displayTimestamp(entity) {
58153         if (!entity.timestamp) return t('info_panels.history.unknown');
58154         var detected = utilDetect();
58155         var options = {
58156             day: 'numeric', month: 'short', year: 'numeric',
58157             hour: 'numeric', minute: 'numeric', second: 'numeric'
58158         };
58159         var d = new Date(entity.timestamp);
58160         if (isNaN(d.getTime())) return t('info_panels.history.unknown');
58161         return d.toLocaleString(detected.locale, options);
58162     }
58163
58164
58165     function displayUser(selection, entity) {
58166         if (!entity.user) {
58167             selection
58168                 .append('span')
58169                 .text(t('info_panels.history.unknown'));
58170             return;
58171         }
58172
58173         selection
58174             .append('span')
58175             .attr('class', 'user-name')
58176             .text(entity.user);
58177
58178         var links = selection
58179             .append('div')
58180             .attr('class', 'links');
58181
58182         if (osm) {
58183             links
58184                 .append('a')
58185                 .attr('class', 'user-osm-link')
58186                 .attr('href', osm.userURL(entity.user))
58187                 .attr('target', '_blank')
58188                 .attr('tabindex', -1)
58189                 .text('OSM');
58190         }
58191
58192         links
58193             .append('a')
58194             .attr('class', 'user-hdyc-link')
58195             .attr('href', 'https://hdyc.neis-one.org/?' + entity.user)
58196             .attr('target', '_blank')
58197             .attr('tabindex', -1)
58198             .text('HDYC');
58199     }
58200
58201
58202     function displayChangeset(selection, entity) {
58203         if (!entity.changeset) {
58204             selection
58205                 .append('span')
58206                 .text(t('info_panels.history.unknown'));
58207             return;
58208         }
58209
58210         selection
58211             .append('span')
58212             .attr('class', 'changeset-id')
58213             .text(entity.changeset);
58214
58215         var links = selection
58216             .append('div')
58217             .attr('class', 'links');
58218
58219         if (osm) {
58220             links
58221                 .append('a')
58222                 .attr('class', 'changeset-osm-link')
58223                 .attr('href', osm.changesetURL(entity.changeset))
58224                 .attr('target', '_blank')
58225                 .attr('tabindex', -1)
58226                 .text('OSM');
58227         }
58228
58229         links
58230             .append('a')
58231             .attr('class', 'changeset-osmcha-link')
58232             .attr('href', 'https://osmcha.mapbox.com/changesets/' + entity.changeset)
58233             .attr('target', '_blank')
58234             .attr('tabindex', -1)
58235             .text('OSMCha');
58236     }
58237
58238
58239     function redraw(selection) {
58240         var selected = filter(context.selectedIDs(), function(e) { return context.hasEntity(e); }),
58241             singular = selected.length === 1 ? selected[0] : null;
58242
58243         osm = context.connection();
58244
58245         selection.html('');
58246
58247         selection
58248             .append('h4')
58249             .attr('class', 'history-heading')
58250             .text(singular || t('info_panels.history.selected', { n: selected.length }));
58251
58252         if (!singular) return;
58253
58254         var entity = context.entity(singular);
58255
58256         var list = selection
58257             .append('ul');
58258
58259         list
58260             .append('li')
58261             .text(t('info_panels.history.version') + ':')
58262             .append('span')
58263             .text(entity.version);
58264
58265         list
58266             .append('li')
58267             .text(t('info_panels.history.last_edit') + ':')
58268             .append('span')
58269             .text(displayTimestamp(entity));
58270
58271         list
58272             .append('li')
58273             .text(t('info_panels.history.edited_by') + ':')
58274             .call(displayUser, entity);
58275
58276         list
58277             .append('li')
58278             .text(t('info_panels.history.changeset') + ':')
58279             .call(displayChangeset, entity);
58280
58281         if (osm) {
58282             selection
58283                 .append('a')
58284                 .attr('class', 'view-history-on-osm')
58285                 .attr('target', '_blank')
58286                 .attr('tabindex', -1)
58287                 .attr('href', osm.historyURL(entity))
58288                 .call(svgIcon('#icon-out-link', 'inline'))
58289                 .append('span')
58290                 .text(t('info_panels.history.link_text'));
58291         }
58292     }
58293
58294
58295     var panel = function(selection) {
58296         selection.call(redraw);
58297
58298         context.map()
58299             .on('drawn.info-history', function() {
58300                 selection.call(redraw);
58301             });
58302     };
58303
58304     panel.off = function() {
58305         context.map()
58306             .on('drawn.info-history', null);
58307     };
58308
58309     panel.id = 'history';
58310     panel.title = t('info_panels.history.title');
58311     panel.key = t('info_panels.history.key');
58312
58313
58314     return panel;
58315 }
58316
58317 function uiPanelLocation(context) {
58318     var currLocation = '';
58319     var OSM_PRECISION = 7;
58320
58321
58322     function wrap(x, min, max) {
58323         var d = max - min;
58324         return ((x - min) % d + d) % d + min;
58325     }
58326
58327
58328     function clamp(x, min, max) {
58329         return Math.max(min, Math.min(x, max));
58330     }
58331
58332
58333     function redraw(selection) {
58334         selection.html('');
58335
58336         var list = selection
58337             .append('ul');
58338
58339         // Mouse coordinates
58340         var coord = context.map().mouseCoordinates();
58341         if (coord.some(isNaN)) {
58342             coord = context.map().center();
58343         }
58344
58345         var coordStr =
58346             clamp(coord[1], -90, 90).toFixed(OSM_PRECISION) + ', ' +
58347             wrap(coord[0], -180, 180).toFixed(OSM_PRECISION);
58348
58349         list
58350             .append('li')
58351             .text(coordStr);
58352
58353         // Location Info
58354         selection
58355             .append('div')
58356             .attr('class', 'location-info')
58357             .text(currLocation || ' ');
58358
58359         debouncedGetLocation(selection, coord);
58360     }
58361
58362
58363     var debouncedGetLocation = debounce(getLocation, 250);
58364     function getLocation(selection, coord) {
58365         if (!services.geocoder) {
58366             currLocation = t('info_panels.location.unknown_location');
58367             selection.selectAll('.location-info')
58368                 .text(currLocation);
58369         } else {
58370             services.geocoder.reverse(coord, function(err, result) {
58371                 currLocation = result ? result.display_name : t('info_panels.location.unknown_location');
58372                 selection.selectAll('.location-info')
58373                     .text(currLocation);
58374             });
58375         }
58376     }
58377
58378
58379     var panel = function(selection) {
58380         selection.call(redraw);
58381
58382         context.surface()
58383             .on('mousemove.info-location', function() {
58384                 selection.call(redraw);
58385             });
58386     };
58387
58388     panel.off = function() {
58389         context.surface()
58390             .on('mousemove.info-location', null);
58391     };
58392
58393     panel.id = 'location';
58394     panel.title = t('info_panels.location.title');
58395     panel.key = t('info_panels.location.key');
58396
58397
58398     return panel;
58399 }
58400
58401 function uiPanelMeasurement(context) {
58402     var isImperial = (utilDetect().locale.toLowerCase() === 'en-us');
58403     var OSM_PRECISION = 7;
58404
58405
58406     function radiansToMeters(r) {
58407         // using WGS84 authalic radius (6371007.1809 m)
58408         return r * 6371007.1809;
58409     }
58410
58411     function steradiansToSqmeters(r) {
58412         // http://gis.stackexchange.com/a/124857/40446
58413         return r / (4 * Math.PI) * 510065621724000;
58414     }
58415
58416
58417     function toLineString(feature) {
58418         if (feature.type === 'LineString') return feature;
58419
58420         var result = { type: 'LineString', coordinates: [] };
58421         if (feature.type === 'Polygon') {
58422             result.coordinates = feature.coordinates[0];
58423         } else if (feature.type === 'MultiPolygon') {
58424             result.coordinates = feature.coordinates[0][0];
58425         }
58426
58427         return result;
58428     }
58429
58430     function nodeCount(feature) {
58431       if (feature.type === 'LineString') return feature.coordinates.length;
58432
58433       if (feature.type === 'Polygon') {
58434           return feature.coordinates[0].length - 1;
58435       }
58436     }
58437
58438
58439     function displayLength(m) {
58440         var d = m * (isImperial ? 3.28084 : 1),
58441             p, unit;
58442
58443         if (isImperial) {
58444             if (d >= 5280) {
58445                 d /= 5280;
58446                 unit = 'mi';
58447             } else {
58448                 unit = 'ft';
58449             }
58450         } else {
58451             if (d >= 1000) {
58452                 d /= 1000;
58453                 unit = 'km';
58454             } else {
58455                 unit = 'm';
58456             }
58457         }
58458
58459         // drop unnecessary precision
58460         p = d > 1000 ? 0 : d > 100 ? 1 : 2;
58461
58462         return String(d.toFixed(p)) + ' ' + unit;
58463     }
58464
58465
58466     function displayArea(m2) {
58467         var d = m2 * (isImperial ? 10.7639111056 : 1),
58468             d1, d2, p1, p2, unit1, unit2;
58469
58470         if (isImperial) {
58471             if (d >= 6969600) {     // > 0.25mi² show mi²
58472                 d1 = d / 27878400;
58473                 unit1 = 'mi²';
58474             } else {
58475                 d1 = d;
58476                 unit1 = 'ft²';
58477             }
58478
58479             if (d > 4356 && d < 43560000) {   // 0.1 - 1000 acres
58480                 d2 = d / 43560;
58481                 unit2 = 'ac';
58482             }
58483
58484         } else {
58485             if (d >= 250000) {    // > 0.25km² show km²
58486                 d1 = d / 1000000;
58487                 unit1 = 'km²';
58488             } else {
58489                 d1 = d;
58490                 unit1 = 'm²';
58491             }
58492
58493             if (d > 1000 && d < 10000000) {   // 0.1 - 1000 hectares
58494                 d2 = d / 10000;
58495                 unit2 = 'ha';
58496             }
58497         }
58498
58499         // drop unnecessary precision
58500         p1 = d1 > 1000 ? 0 : d1 > 100 ? 1 : 2;
58501         p2 = d2 > 1000 ? 0 : d2 > 100 ? 1 : 2;
58502
58503         return String(d1.toFixed(p1)) + ' ' + unit1 +
58504             (d2 ? ' (' + String(d2.toFixed(p2)) + ' ' + unit2 + ')' : '');
58505     }
58506
58507
58508     function redraw(selection) {
58509         var resolver = context.graph();
58510         var selected = filter(context.selectedIDs(), function(e) { return context.hasEntity(e); });
58511         var singular = selected.length === 1 ? selected[0] : null;
58512         var extent = geoExtent();
58513         var entity;
58514
58515         selection.html('');
58516
58517         selection
58518             .append('h4')
58519             .attr('class', 'measurement-heading')
58520             .text(singular || t('info_panels.measurement.selected', { n: selected.length }));
58521
58522         if (!selected.length) return;
58523
58524         var center;
58525         for (var i = 0; i < selected.length; i++) {
58526             entity = context.entity(selected[i]);
58527             extent._extend(entity.extent(resolver));
58528         }
58529         center = extent.center();
58530
58531
58532         var list = selection
58533             .append('ul');
58534
58535         // multiple features, just display extent center..
58536         if (!singular) {
58537             list
58538                 .append('li')
58539                 .text(t('info_panels.measurement.center') + ':')
58540                 .append('span')
58541                 .text(
58542                     center[1].toFixed(OSM_PRECISION) + ', ' + center[0].toFixed(OSM_PRECISION)
58543                 );
58544             return;
58545         }
58546
58547         // single feature, display details..
58548         if (!entity) return;
58549         var geometry = entity.geometry(resolver);
58550
58551         if (geometry === 'line' || geometry === 'area') {
58552             var closed = (entity.type === 'relation') || (entity.isClosed() && !entity.isDegenerate()),
58553                 feature = entity.asGeoJSON(resolver),
58554                 length = radiansToMeters(d3_geoLength(toLineString(feature))),
58555                 lengthLabel = t('info_panels.measurement.' + (closed ? 'perimeter' : 'length')),
58556                 centroid = d3_geoCentroid(feature);
58557
58558             list
58559                 .append('li')
58560                 .text(t('info_panels.measurement.geometry') + ':')
58561                 .append('span')
58562                 .text(
58563                     (closed ? t('info_panels.measurement.closed') + ' ' : '') + t('geometry.' + geometry)
58564                 );
58565
58566             if (entity.type !== 'relation') {
58567                 list
58568                     .append('li')
58569                     .text(t('info_panels.measurement.node_count') + ':')
58570                     .append('span')
58571                     .text(nodeCount(feature)
58572                     );
58573             }
58574
58575             if (closed) {
58576                 var area = steradiansToSqmeters(entity.area(resolver));
58577                 list
58578                     .append('li')
58579                     .text(t('info_panels.measurement.area') + ':')
58580                     .append('span')
58581                     .text(displayArea(area));
58582             }
58583
58584
58585             list
58586                 .append('li')
58587                 .text(lengthLabel + ':')
58588                 .append('span')
58589                 .text(displayLength(length));
58590
58591             list
58592                 .append('li')
58593                 .text(t('info_panels.measurement.centroid') + ':')
58594                 .append('span')
58595                 .text(
58596                     centroid[1].toFixed(OSM_PRECISION) + ', ' + centroid[0].toFixed(OSM_PRECISION)
58597                 );
58598
58599             var toggle  = isImperial ? 'imperial' : 'metric';
58600
58601             selection
58602                 .append('a')
58603                 .text(t('info_panels.measurement.' + toggle))
58604                 .attr('href', '#')
58605                 .attr('class', 'button button-toggle-units')
58606                 .on('click', function() {
58607                     event.preventDefault();
58608                     isImperial = !isImperial;
58609                     selection.call(redraw);
58610                 });
58611
58612         } else {
58613             var centerLabel = t('info_panels.measurement.' + (entity.type === 'node' ? 'location' : 'center'));
58614
58615             list
58616                 .append('li')
58617                 .text(t('info_panels.measurement.geometry') + ':')
58618                 .append('span')
58619                 .text(t('geometry.' + geometry));
58620
58621             list
58622                 .append('li')
58623                 .text(centerLabel + ':')
58624                 .append('span')
58625                 .text(
58626                     center[1].toFixed(OSM_PRECISION) + ', ' + center[0].toFixed(OSM_PRECISION)
58627                 );
58628         }
58629     }
58630
58631
58632     var panel = function(selection) {
58633         selection.call(redraw);
58634
58635         context.map()
58636             .on('drawn.info-measurement', function() {
58637                 selection.call(redraw);
58638             });
58639     };
58640
58641     panel.off = function() {
58642         context.map()
58643             .on('drawn.info-measurement', null);
58644     };
58645
58646     panel.id = 'measurement';
58647     panel.title = t('info_panels.measurement.title');
58648     panel.key = t('info_panels.measurement.key');
58649
58650
58651     return panel;
58652 }
58653
58654 var uiInfoPanels = {
58655     background: uiPanelBackground,
58656     history: uiPanelHistory,
58657     location: uiPanelLocation,
58658     measurement: uiPanelMeasurement,
58659 };
58660
58661 function uiInfo(context) {
58662     var ids = Object.keys(uiInfoPanels),
58663         wasActive = ['measurement'],
58664         panels = {},
58665         active = {};
58666
58667     // create panels
58668     ids.forEach(function(k) {
58669         if (!panels[k]) {
58670             panels[k] = uiInfoPanels[k](context);
58671             active[k] = false;
58672         }
58673     });
58674
58675
58676     function info(selection) {
58677
58678         function redraw() {
58679             var activeids = ids.filter(function(k) { return active[k]; }).sort();
58680
58681             var containers = infoPanels.selectAll('.panel-container')
58682                 .data(activeids, function(k) { return k; });
58683
58684             containers.exit()
58685                 .style('opacity', 1)
58686                 .transition()
58687                 .duration(200)
58688                 .style('opacity', 0)
58689                 .on('end', function(d) {
58690                     d3_select(this)
58691                         .call(panels[d].off)
58692                         .remove();
58693                 });
58694
58695             var enter = containers.enter()
58696                 .append('div')
58697                 .attr('class', function(d) { return 'fillD2 panel-container panel-container-' + d; });
58698
58699             enter
58700                 .style('opacity', 0)
58701                 .transition()
58702                 .duration(200)
58703                 .style('opacity', 1);
58704
58705             var title = enter
58706                 .append('div')
58707                 .attr('class', 'panel-title fillD2');
58708
58709             title
58710                 .append('h3')
58711                 .text(function(d) { return panels[d].title; });
58712
58713             title
58714                 .append('button')
58715                 .attr('class', 'close')
58716                 .on('click', function (d) { toggle(d); })
58717                 .call(svgIcon('#icon-close'));
58718
58719             enter
58720                 .append('div')
58721                 .attr('class', function(d) { return 'panel-content panel-content-' + d; });
58722
58723
58724             // redraw the panels
58725             infoPanels.selectAll('.panel-content')
58726                 .each(function(d) {
58727                     d3_select(this).call(panels[d]);
58728                 });
58729         }
58730
58731
58732         function toggle(which) {
58733             if (event) {
58734                 event.stopImmediatePropagation();
58735                 event.preventDefault();
58736             }
58737
58738             var activeids = ids.filter(function(k) { return active[k]; });
58739
58740             if (which) {  // toggle one
58741                 active[which] = !active[which];
58742                 if (activeids.length === 1 && activeids[0] === which) {  // none active anymore
58743                     wasActive = [which];
58744                 }
58745             } else {      // toggle all
58746                 if (activeids.length) {
58747                     wasActive = activeids;
58748                     activeids.forEach(function(k) { active[k] = false; });
58749                 } else {
58750                     wasActive.forEach(function(k) { active[k] = true; });
58751                 }
58752             }
58753
58754             redraw();
58755         }
58756
58757
58758         var infoPanels = selection.selectAll('.info-panels')
58759             .data([0]);
58760
58761         infoPanels = infoPanels.enter()
58762             .append('div')
58763             .attr('class', 'info-panels')
58764             .merge(infoPanels);
58765
58766         redraw();
58767
58768         var keybinding = d3keybinding('info')
58769             .on(uiCmd('⌘' + t('info_panels.key')), toggle);
58770
58771         ids.forEach(function(k) {
58772             var key = t('info_panels.' + k + '.key', { default: null });
58773             if (!key) return;
58774             keybinding
58775                 .on(uiCmd('⌘⇧' + key), function() { toggle(k); });
58776         });
58777
58778         d3_select(document)
58779             .call(keybinding);
58780     }
58781
58782     return info;
58783 }
58784
58785 function uiModes(context) {
58786     var modes = [
58787         modeAddPoint(context),
58788         modeAddLine(context),
58789         modeAddArea(context)
58790     ];
58791
58792
58793     function editable() {
58794         var mode = context.mode();
58795         return context.editable() && mode && mode.id !== 'save';
58796     }
58797
58798
58799     return function(selection) {
58800         var buttons = selection.selectAll('button.add-button')
58801             .data(modes);
58802
58803         buttons = buttons.enter()
58804             .append('button')
58805             .attr('tabindex', -1)
58806             .attr('class', function(mode) { return mode.id + ' add-button col4'; })
58807             .on('click.mode-buttons', function(mode) {
58808                 // When drawing, ignore accidental clicks on mode buttons - #4042
58809                 var currMode = context.mode().id;
58810                 if (currMode.match(/^draw/) !== null) return;
58811
58812                 if (mode.id === currMode) {
58813                     context.enter(modeBrowse(context));
58814                 } else {
58815                     context.enter(mode);
58816                 }
58817             })
58818             .call(tooltip()
58819                 .placement('bottom')
58820                 .html(true)
58821                 .title(function(mode) {
58822                     return uiTooltipHtml(mode.description, mode.key);
58823                 })
58824             );
58825
58826         buttons
58827             .each(function(d) {
58828                 d3_select(this)
58829                     .call(svgIcon('#icon-' + d.button, 'pre-text'));
58830             });
58831
58832         buttons
58833             .append('span')
58834             .attr('class', 'label')
58835             .text(function(mode) { return mode.title; });
58836
58837         context
58838             .on('enter.editor', function(entered) {
58839                 selection.selectAll('button.add-button')
58840                     .classed('active', function(mode) { return entered.button === mode.button; });
58841                 context.container()
58842                     .classed('mode-' + entered.id, true);
58843             });
58844
58845         context
58846             .on('exit.editor', function(exited) {
58847                 context.container()
58848                     .classed('mode-' + exited.id, false);
58849             });
58850
58851         var keybinding = d3keybinding('mode-buttons');
58852
58853         modes.forEach(function(mode) {
58854             keybinding.on(mode.key, function() {
58855                 if (editable()) {
58856                     if (mode.id === context.mode().id) {
58857                         context.enter(modeBrowse(context));
58858                     } else {
58859                         context.enter(mode);
58860                     }
58861                 }
58862             });
58863         });
58864
58865         d3_select(document)
58866             .call(keybinding);
58867
58868
58869         var debouncedUpdate = debounce(update, 500, { leading: true, trailing: true });
58870
58871         context.map()
58872             .on('move.modes', debouncedUpdate)
58873             .on('drawn.modes', debouncedUpdate);
58874
58875         context
58876             .on('enter.modes', update);
58877
58878
58879
58880         function update() {
58881             selection.selectAll('button.add-button')
58882                 .property('disabled', !editable());
58883         }
58884     };
58885 }
58886
58887 function uiNotice(context) {
58888
58889     return function(selection) {
58890         var div = selection
58891             .append('div')
58892             .attr('class', 'notice');
58893
58894         var button = div
58895             .append('button')
58896             .attr('class', 'zoom-to notice fillD')
58897             .on('click', function() {
58898                 context.map().zoomEase(context.minEditableZoom());
58899             })
58900             .on('wheel', function() {   // let wheel events pass through #4482
58901                 var e2 = new WheelEvent(event.type, event);
58902                 context.surface().node().dispatchEvent(e2);
58903             });
58904
58905         button
58906             .call(svgIcon('#icon-plus', 'pre-text'))
58907             .append('span')
58908             .attr('class', 'label')
58909             .text(t('zoom_in_edit'));
58910
58911
58912         function disableTooHigh() {
58913             var canEdit = context.map().zoom() >= context.minEditableZoom();
58914             div.style('display', canEdit ? 'none' : 'block');
58915         }
58916
58917         context.map()
58918             .on('move.notice', debounce(disableTooHigh, 500));
58919
58920         disableTooHigh();
58921     };
58922 }
58923
58924 function uiRestore(context) {
58925
58926     return function(selection) {
58927         if (!context.history().lock() || !context.history().restorableChanges())
58928             return;
58929
58930         var modalSelection = uiModal(selection, true);
58931
58932         modalSelection.select('.modal')
58933             .attr('class', 'modal fillL col6');
58934
58935         var introModal = modalSelection.select('.content');
58936
58937         introModal
58938             .attr('class','cf');
58939
58940         introModal
58941             .append('div')
58942             .attr('class', 'modal-section')
58943             .append('h3')
58944             .text(t('restore.heading'));
58945
58946         introModal
58947             .append('div')
58948             .attr('class','modal-section')
58949             .append('p')
58950             .text(t('restore.description'));
58951
58952         var buttonWrap = introModal
58953             .append('div')
58954             .attr('class', 'modal-actions cf');
58955
58956         var restore = buttonWrap
58957             .append('button')
58958             .attr('class', 'restore col6')
58959             .on('click', function() {
58960                 context.history().restore();
58961                 modalSelection.remove();
58962             });
58963
58964         restore
58965             .append('svg')
58966             .attr('class', 'logo logo-restore')
58967             .append('use')
58968             .attr('xlink:href', '#logo-restore');
58969
58970         restore
58971             .append('div')
58972             .text(t('restore.restore'));
58973
58974         var reset = buttonWrap
58975             .append('button')
58976             .attr('class', 'reset col6')
58977             .on('click', function() {
58978                 context.history().clearSaved();
58979                 modalSelection.remove();
58980             });
58981
58982         reset
58983             .append('svg')
58984             .attr('class', 'logo logo-reset')
58985             .append('use')
58986             .attr('xlink:href', '#logo-reset');
58987
58988         reset
58989             .append('div')
58990             .text(t('restore.reset'));
58991
58992         restore.node().focus();
58993     };
58994 }
58995
58996 function uiSave(context) {
58997     var history = context.history(),
58998         key = uiCmd('⌘S');
58999
59000
59001     function saving() {
59002         return context.mode().id === 'save';
59003     }
59004
59005
59006     function save() {
59007         event.preventDefault();
59008         if (!context.inIntro() && !saving() && history.hasChanges()) {
59009             context.enter(modeSave(context));
59010         }
59011     }
59012
59013
59014     function getBackground(numChanges) {
59015         var step;
59016         if (numChanges === 0) {
59017             return null;
59018         } else if (numChanges <= 50) {
59019             step = numChanges / 50;
59020             return d3_interpolateRgb('#fff', '#ff8')(step);  // white -> yellow
59021         } else {
59022             step = Math.min((numChanges - 50) / 50, 1.0);
59023             return d3_interpolateRgb('#ff8', '#f88')(step);  // yellow -> red
59024         }
59025     }
59026
59027
59028     return function(selection) {
59029         var numChanges = 0;
59030
59031         function updateCount() {
59032             var _ = history.difference().summary().length;
59033             if (_ === numChanges) return;
59034             numChanges = _;
59035
59036             tooltipBehavior
59037                 .title(uiTooltipHtml(
59038                     t(numChanges > 0 ? 'save.help' : 'save.no_changes'), key)
59039                 );
59040
59041             var background = getBackground(numChanges);
59042
59043             button
59044                 .classed('disabled', numChanges === 0)
59045                 .classed('has-count', numChanges > 0)
59046                 .style('background', background);
59047
59048             button.select('span.count')
59049                 .text(numChanges)
59050                 .style('background', background)
59051                 .style('border-color', background);
59052         }
59053
59054
59055         var tooltipBehavior = tooltip()
59056             .placement('bottom')
59057             .html(true)
59058             .title(uiTooltipHtml(t('save.no_changes'), key));
59059
59060         var button = selection
59061             .append('button')
59062             .attr('class', 'save col12 disabled')
59063             .attr('tabindex', -1)
59064             .on('click', save)
59065             .call(tooltipBehavior);
59066
59067         button
59068             .call(svgIcon('#icon-save', 'pre-text'))
59069             .append('span')
59070             .attr('class', 'label')
59071             .text(t('save.title'));
59072
59073         button
59074             .append('span')
59075             .attr('class', 'count')
59076             .text('0');
59077
59078         updateCount();
59079
59080
59081         var keybinding = d3keybinding('save')
59082             .on(key, save, true);
59083
59084         d3_select(document)
59085             .call(keybinding);
59086
59087         context.history()
59088             .on('change.save', updateCount);
59089
59090         context
59091             .on('enter.save', function() {
59092                 button.property('disabled', saving());
59093                 if (saving()) button.call(tooltipBehavior.hide);
59094             });
59095     };
59096 }
59097
59098 function uiScale(context) {
59099     var projection = context.projection,
59100         isImperial = (utilDetect().locale.toLowerCase() === 'en-us'),
59101         maxLength = 180,
59102         tickHeight = 8;
59103
59104
59105     function scaleDefs(loc1, loc2) {
59106         var lat = (loc2[1] + loc1[1]) / 2,
59107             conversion = (isImperial ? 3.28084 : 1),
59108             dist = geoLonToMeters(loc2[0] - loc1[0], lat) * conversion,
59109             scale = { dist: 0, px: 0, text: '' },
59110             buckets, i, val, dLon;
59111
59112         if (isImperial) {
59113             buckets = [5280000, 528000, 52800, 5280, 500, 50, 5, 1];
59114         } else {
59115             buckets = [5000000, 500000, 50000, 5000, 500, 50, 5, 1];
59116         }
59117
59118         // determine a user-friendly endpoint for the scale
59119         for (i = 0; i < buckets.length; i++) {
59120             val = buckets[i];
59121             if (dist >= val) {
59122                 scale.dist = Math.floor(dist / val) * val;
59123                 break;
59124             } else {
59125                 scale.dist = +dist.toFixed(2);
59126             }
59127         }
59128
59129         dLon = geoMetersToLon(scale.dist / conversion, lat);
59130         scale.px = Math.round(projection([loc1[0] + dLon, loc1[1]])[0]);
59131
59132         if (isImperial) {
59133             if (scale.dist >= 5280) {
59134                 scale.dist /= 5280;
59135                 scale.text = String(scale.dist) + ' mi';
59136             } else {
59137                 scale.text = String(scale.dist) + ' ft';
59138             }
59139         } else {
59140             if (scale.dist >= 1000) {
59141                 scale.dist /= 1000;
59142                 scale.text = String(scale.dist) + ' km';
59143             } else {
59144                 scale.text = String(scale.dist) + ' m';
59145             }
59146         }
59147
59148         return scale;
59149     }
59150
59151
59152     function update(selection) {
59153         // choose loc1, loc2 along bottom of viewport (near where the scale will be drawn)
59154         var dims = context.map().dimensions(),
59155             loc1 = projection.invert([0, dims[1]]),
59156             loc2 = projection.invert([maxLength, dims[1]]),
59157             scale = scaleDefs(loc1, loc2);
59158
59159         selection.select('#scale-path')
59160             .attr('d', 'M0.5,0.5v' + tickHeight + 'h' + scale.px + 'v-' + tickHeight);
59161
59162         selection.select('#scale-textgroup')
59163             .attr('transform', 'translate(' + (scale.px + 8) + ',' + tickHeight + ')');
59164
59165         selection.select('#scale-text')
59166             .text(scale.text);
59167     }
59168
59169
59170     return function(selection) {
59171         function switchUnits() {
59172             isImperial = !isImperial;
59173             selection.call(update);
59174         }
59175
59176         var scalegroup = selection.append('svg')
59177             .attr('id', 'scale')
59178             .on('click', switchUnits)
59179             .append('g')
59180             .attr('transform', 'translate(10,11)');
59181
59182         scalegroup
59183             .append('path')
59184             .attr('id', 'scale-path');
59185
59186         scalegroup
59187             .append('g')
59188             .attr('id', 'scale-textgroup')
59189             .append('text')
59190             .attr('id', 'scale-text');
59191
59192         selection.call(update);
59193
59194         context.map().on('move.scale', function() {
59195             update(selection);
59196         });
59197     };
59198 }
59199
59200 var pair_1 = pair$1;
59201 function search(x, dims, r) {
59202   if (!dims) dims = 'NSEW';
59203   if (typeof x !== 'string') return { val: null, regex: r };
59204
59205   r = r || /[\s\,]*([NSEW])?\s*([\-|\—|\―]?[0-9.]+)°?\s*(?:([0-9.]+)['’′‘]\s*)?(?:([0-9.]+)(?:''|"|”|″)\s*)?([NSEW])?/gi;
59206
59207   var m = r.exec(x);
59208   if (!m) return { val: null, regex: r };
59209
59210   var dim = m[1] || m[5];
59211   if (dim && dims.indexOf(dim) === -1) return { val: null, regex: r };
59212
59213   return {
59214     val: (((m[2]) ? parseFloat(m[2]) : 0) +
59215           ((m[3] ? parseFloat(m[3]) / 60 : 0)) +
59216           ((m[4] ? parseFloat(m[4]) / 3600 : 0))) *
59217           ((dim === 'S' || dim === 'W') ? -1 : 1),
59218     regex: r,
59219     raw: m[0],
59220     dim: dim
59221   };
59222 }
59223
59224 function pair$1(x, dims) {
59225   x = x.trim();
59226   var one = search(x, dims);
59227   if (one.val === null) return null;
59228   var two = search(x, dims, one.regex);
59229   if (two.val === null) return null;
59230   // null if one/two are not contiguous.
59231   if (one.raw + two.raw !== x) return null;
59232   if (one.dim) {
59233     return swapdim(one.val, two.val, one.dim);
59234   } else {
59235     return [one.val, two.val];
59236   }
59237 }
59238
59239 function swapdim(a, b, dim) {
59240   if (dim === 'N' || dim === 'S') return [a, b];
59241   if (dim === 'W' || dim === 'E') return [b, a];
59242 }
59243
59244 function uiFeatureList(context) {
59245     var keybinding = d3keybinding('feature-list');
59246     var _geocodeResults;
59247
59248
59249     function featureList(selection) {
59250         var header = selection
59251             .append('div')
59252             .attr('class', 'header fillL cf');
59253
59254         header
59255             .append('h3')
59256             .text(t('inspector.feature_list'));
59257
59258         var searchWrap = selection
59259             .append('div')
59260             .attr('class', 'search-header');
59261
59262         var search = searchWrap
59263             .append('input')
59264             .attr('placeholder', t('inspector.search'))
59265             .attr('type', 'search')
59266             .call(utilNoAuto)
59267             .on('keypress', keypress)
59268             .on('keydown', keydown)
59269             .on('input', inputevent);
59270
59271         searchWrap
59272             .call(svgIcon('#icon-search', 'pre-text'));
59273
59274         var listWrap = selection
59275             .append('div')
59276             .attr('class', 'inspector-body');
59277
59278         var list = listWrap
59279             .append('div')
59280             .attr('class', 'feature-list cf');
59281
59282         context
59283             .on('exit.feature-list', clearSearch);
59284         context.map()
59285             .on('drawn.feature-list', mapDrawn);
59286
59287         keybinding
59288             .on(uiCmd('⌘F'), focusSearch);
59289
59290         d3_select(document)
59291             .call(keybinding);
59292
59293
59294         function focusSearch() {
59295             var mode = context.mode() && context.mode().id;
59296             if (mode !== 'browse') return;
59297
59298             event.preventDefault();
59299             search.node().focus();
59300         }
59301
59302
59303         function keydown() {
59304             if (event.keyCode === 27) {  // escape
59305                 search.node().blur();
59306             }
59307         }
59308
59309
59310         function keypress() {
59311             var q = search.property('value'),
59312                 items = list.selectAll('.feature-list-item');
59313             if (event.keyCode === 13 && q.length && items.size()) {  // return
59314                 click(items.datum());
59315             }
59316         }
59317
59318
59319         function inputevent() {
59320             _geocodeResults = undefined;
59321             drawList();
59322         }
59323
59324
59325         function clearSearch() {
59326             search.property('value', '');
59327             drawList();
59328         }
59329
59330
59331         function mapDrawn(e) {
59332             if (e.full) {
59333                 drawList();
59334             }
59335         }
59336
59337
59338         function features() {
59339             var entities = {},
59340                 result = [],
59341                 graph = context.graph(),
59342                 q = search.property('value').toLowerCase();
59343
59344             if (!q) return result;
59345
59346             var idMatch = q.match(/^([nwr])([0-9]+)$/);
59347
59348             if (idMatch) {
59349                 result.push({
59350                     id: idMatch[0],
59351                     geometry: idMatch[1] === 'n' ? 'point' : idMatch[1] === 'w' ? 'line' : 'relation',
59352                     type: idMatch[1] === 'n' ? t('inspector.node') : idMatch[1] === 'w' ? t('inspector.way') : t('inspector.relation'),
59353                     name: idMatch[2]
59354                 });
59355             }
59356
59357             var locationMatch = pair_1(q.toUpperCase()) || q.match(/^(-?\d+\.?\d*)\s+(-?\d+\.?\d*)$/);
59358
59359             if (locationMatch) {
59360                 var loc = [parseFloat(locationMatch[0]), parseFloat(locationMatch[1])];
59361                 result.push({
59362                     id: -1,
59363                     geometry: 'point',
59364                     type: t('inspector.location'),
59365                     name: loc[0].toFixed(6) + ', ' + loc[1].toFixed(6),
59366                     location: loc
59367                 });
59368             }
59369
59370             function addEntity(entity) {
59371                 if (entity.id in entities || result.length > 200)
59372                     return;
59373
59374                 entities[entity.id] = true;
59375
59376                 var name = utilDisplayName(entity) || '';
59377                 if (name.toLowerCase().indexOf(q) >= 0) {
59378                     var matched = context.presets().match(entity, graph),
59379                         type = (matched && matched.name()) || utilDisplayType(entity.id);
59380                     result.push({
59381                         id: entity.id,
59382                         entity: entity,
59383                         geometry: context.geometry(entity.id),
59384                         type: type,
59385                         name: name
59386                     });
59387                 }
59388
59389                 graph.parentRelations(entity).forEach(function(parent) {
59390                     addEntity(parent);
59391                 });
59392             }
59393
59394             var visible = context.surface().selectAll('.point, .line, .area').nodes();
59395             for (var i = 0; i < visible.length && result.length <= 200; i++) {
59396                 var datum = visible[i].__data__;
59397                 var entity = datum && datum.properties && datum.properties.entity;
59398                 if (entity) { addEntity(entity); }
59399             }
59400
59401             (_geocodeResults || []).forEach(function(d) {
59402                 // https://github.com/openstreetmap/iD/issues/1890
59403                 if (d.osm_type && d.osm_id) {
59404                     result.push({
59405                         id: osmEntity.id.fromOSM(d.osm_type, d.osm_id),
59406                         geometry: d.osm_type === 'relation' ? 'relation' : d.osm_type === 'way' ? 'line' : 'point',
59407                         type: d.type !== 'yes' ? (d.type.charAt(0).toUpperCase() + d.type.slice(1)).replace('_', ' ')
59408                                                : (d.class.charAt(0).toUpperCase() + d.class.slice(1)).replace('_', ' '),
59409                         name: d.display_name,
59410                         extent: new geoExtent(
59411                             [parseFloat(d.boundingbox[3]), parseFloat(d.boundingbox[0])],
59412                             [parseFloat(d.boundingbox[2]), parseFloat(d.boundingbox[1])])
59413                     });
59414                 }
59415             });
59416
59417             return result;
59418         }
59419
59420
59421         function drawList() {
59422             var value = search.property('value'),
59423                 results = features();
59424
59425             list.classed('filtered', value.length);
59426
59427             var noResultsWorldwide = _geocodeResults && _geocodeResults.length === 0;
59428
59429             var resultsIndicator = list.selectAll('.no-results-item')
59430                 .data([0])
59431                 .enter()
59432                 .append('button')
59433                 .property('disabled', true)
59434                 .attr('class', 'no-results-item')
59435                 .call(svgIcon('#icon-alert', 'pre-text'));
59436
59437             resultsIndicator.append('span')
59438                 .attr('class', 'entity-name');
59439
59440             list.selectAll('.no-results-item .entity-name')
59441                 .text(noResultsWorldwide ? t('geocoder.no_results_worldwide') : t('geocoder.no_results_visible'));
59442
59443             if (services.geocoder) {
59444               list.selectAll('.geocode-item')
59445                   .data([0])
59446                   .enter()
59447                   .append('button')
59448                   .attr('class', 'geocode-item')
59449                   .on('click', geocoderSearch)
59450                   .append('div')
59451                   .attr('class', 'label')
59452                   .append('span')
59453                   .attr('class', 'entity-name')
59454                   .text(t('geocoder.search'));
59455             }
59456
59457             list.selectAll('.no-results-item')
59458                 .style('display', (value.length && !results.length) ? 'block' : 'none');
59459
59460             list.selectAll('.geocode-item')
59461                 .style('display', (value && _geocodeResults === undefined) ? 'block' : 'none');
59462
59463             list.selectAll('.feature-list-item')
59464                 .data([-1])
59465                 .remove();
59466
59467             var items = list.selectAll('.feature-list-item')
59468                 .data(results, function(d) { return d.id; });
59469
59470             var enter = items.enter()
59471                 .insert('button', '.geocode-item')
59472                 .attr('class', 'feature-list-item')
59473                 .on('mouseover', mouseover)
59474                 .on('mouseout', mouseout)
59475                 .on('click', click);
59476
59477             var label = enter
59478                 .append('div')
59479                 .attr('class', 'label');
59480
59481             label
59482                 .each(function(d) {
59483                     d3_select(this)
59484                         .call(svgIcon('#icon-' + d.geometry, 'pre-text'));
59485                 });
59486
59487             label
59488                 .append('span')
59489                 .attr('class', 'entity-type')
59490                 .text(function(d) { return d.type; });
59491
59492             label
59493                 .append('span')
59494                 .attr('class', 'entity-name')
59495                 .text(function(d) { return d.name; });
59496
59497             enter
59498                 .style('opacity', 0)
59499                 .transition()
59500                 .style('opacity', 1);
59501
59502             items.order();
59503
59504             items.exit()
59505                 .remove();
59506         }
59507
59508
59509         function mouseover(d) {
59510             if (d.id === -1) return;
59511
59512             context.surface().selectAll(utilEntityOrMemberSelector([d.id], context.graph()))
59513                 .classed('hover', true);
59514         }
59515
59516
59517         function mouseout() {
59518             context.surface().selectAll('.hover')
59519                 .classed('hover', false);
59520         }
59521
59522
59523         function click(d) {
59524             event.preventDefault();
59525             if (d.location) {
59526                 context.map().centerZoom([d.location[1], d.location[0]], 20);
59527             }
59528             else if (d.entity) {
59529                 if (d.entity.type === 'node') {
59530                     context.map().center(d.entity.loc);
59531                 } else if (d.entity.type === 'way') {
59532                     var center = context.projection(context.map().center()),
59533                         edge = geoChooseEdge(context.childNodes(d.entity), center, context.projection);
59534                     context.map().center(edge.loc);
59535                 }
59536                 context.enter(modeSelect(context, [d.entity.id]));
59537             } else {
59538                 context.zoomToEntity(d.id);
59539             }
59540         }
59541
59542
59543         function geocoderSearch() {
59544             services.geocoder.search(search.property('value'), function (err, resp) {
59545                 _geocodeResults = resp || [];
59546                 drawList();
59547             });
59548         }
59549     }
59550
59551
59552     return featureList;
59553 }
59554
59555 function uiPresetIcon() {
59556     var preset, geometry;
59557
59558
59559     function presetIcon(selection) {
59560         selection.each(render);
59561     }
59562
59563
59564     function getIcon(p, geom) {
59565         if (p.icon)
59566             return p.icon;
59567         else if (geom === 'line')
59568             return 'other-line';
59569         else if (geom === 'vertex')
59570             return p.isFallback() ? '' : 'poi-vertex';
59571         else
59572             return 'marker-stroked';
59573     }
59574
59575
59576     function render() {
59577         var selection = d3_select(this),
59578             p = preset.apply(this, arguments),
59579             geom = geometry.apply(this, arguments),
59580             picon = getIcon(p, geom),
59581             isPoi = picon.match(/^poi-/) !== null,
59582             isMaki = dataFeatureIcons.indexOf(picon) !== -1,
59583             isFramed = (geom === 'area' || geom === 'verex');
59584
59585
59586         function tag_classes(p) {
59587             var s = '';
59588             for (var i in p.tags) {
59589                 s += ' tag-' + i;
59590                 if (p.tags[i] !== '*') {
59591                     s += ' tag-' + i + '-' + p.tags[i];
59592                 }
59593             }
59594             return s;
59595         }
59596
59597
59598         var fill = selection.selectAll('.preset-icon-fill')
59599             .data([0]);
59600
59601         fill = fill.enter()
59602             .append('div')
59603             .merge(fill);
59604
59605         fill
59606             .attr('class', function() {
59607                 return 'preset-icon-fill preset-icon-fill-' + geom + tag_classes(p);
59608             });
59609
59610
59611         var areaFrame = selection.selectAll('.preset-icon-frame')
59612             .data((geom === 'area') ? [0] : []);
59613
59614         areaFrame.exit()
59615             .remove();
59616
59617         areaFrame = areaFrame.enter()
59618             .append('div')
59619             .attr('class', 'preset-icon-frame')
59620             .call(svgIcon('#preset-icon-frame'));
59621
59622
59623         var icon = selection.selectAll('.preset-icon')
59624             .data([0]);
59625
59626         icon = icon.enter()
59627             .append('div')
59628             .attr('class', 'preset-icon')
59629             .call(svgIcon(''))
59630             .merge(icon);
59631
59632         icon
59633             .attr('class', 'preset-icon preset-icon-' +
59634                 ((isMaki || isPoi) ? (isFramed ? '24' : '28') : (isFramed ? '44' : '60'))
59635             );
59636
59637         icon.selectAll('svg')
59638             .attr('class', function() {
59639                 return 'icon ' + picon + (isMaki || isPoi ? '' : tag_classes(p));
59640             });
59641
59642         icon.selectAll('use')
59643             .attr('href', '#' + picon + (isMaki ? '-15' : ''));
59644     }
59645
59646
59647     presetIcon.preset = function(_) {
59648         if (!arguments.length) return preset;
59649         preset = utilFunctor(_);
59650         return presetIcon;
59651     };
59652
59653
59654     presetIcon.geometry = function(_) {
59655         if (!arguments.length) return geometry;
59656         geometry = utilFunctor(_);
59657         return presetIcon;
59658     };
59659
59660     return presetIcon;
59661 }
59662
59663 function d3combobox() {
59664     var dispatch$$1 = dispatch('accept');
59665     var _container = d3_select(document.body);
59666     var _data = [];
59667     var _suggestions = [];
59668     var _minItems = 2;
59669     var _caseSensitive = false;
59670
59671     var _fetcher = function(val, cb) {
59672         cb(_data.filter(function(d) {
59673             return d.value
59674                 .toString()
59675                 .toLowerCase()
59676                 .indexOf(val.toLowerCase()) !== -1;
59677         }));
59678     };
59679
59680     var combobox = function(input, attachTo) {
59681         var idx = -1;
59682         var wrapper = _container
59683             .selectAll('div.combobox')
59684             .filter(function(d) { return d === input.node(); });
59685         var shown = !wrapper.empty();
59686
59687         input
59688             .classed('combobox-input', true)
59689             .on('focus.typeahead', focus)
59690             .on('blur.typeahead', blur)
59691             .on('keydown.typeahead', keydown)
59692             .on('keyup.typeahead', keyup)
59693             .on('input.typeahead', change)
59694             .each(function() {
59695                 var parent = this.parentNode;
59696                 var sibling = this.nextSibling;
59697
59698                 var caret = d3_select(parent).selectAll('.combobox-caret')
59699                     .filter(function(d) { return d === input.node(); })
59700                     .data([input.node()]);
59701
59702                 caret = caret.enter()
59703                     .insert('div', function() { return sibling; })
59704                     .attr('class', 'combobox-caret')
59705                     .merge(caret);
59706
59707                 caret
59708                     .on('mousedown', function () {
59709                         // prevent the form element from blurring. it blurs
59710                         // on mousedown
59711                         event.stopPropagation();
59712                         event.preventDefault();
59713                         if (!shown) {
59714                             input.node().focus();
59715                             fetch('', render);
59716                         } else {
59717                             hide();
59718                         }
59719                     });
59720             });
59721
59722         function focus() {
59723             fetch(value(), render);
59724         }
59725
59726         function blur() {
59727             window.setTimeout(hide, 150);
59728         }
59729
59730         function show() {
59731             if (!shown) {
59732                 wrapper = _container
59733                     .insert('div', ':first-child')
59734                     .datum(input.node())
59735                     .attr('class', 'combobox')
59736                     .style('position', 'absolute')
59737                     .style('display', 'block')
59738                     .style('left', '0px')
59739                     .on('mousedown', function () {
59740                         // prevent moving focus out of the text field
59741                         event.preventDefault();
59742                     });
59743
59744                 d3_select('body')
59745                     .on('scroll.combobox', render, true);
59746
59747                 shown = true;
59748             }
59749         }
59750
59751         function hide() {
59752             if (shown) {
59753                 idx = -1;
59754                 wrapper.remove();
59755
59756                 d3_select('body')
59757                     .on('scroll.combobox', null);
59758
59759                 shown = false;
59760             }
59761         }
59762
59763         function keydown() {
59764            switch (event.keyCode) {
59765                // backspace, delete
59766                case 8:
59767                case 46:
59768                    input.on('input.typeahead', function() {
59769                        idx = -1;
59770                        render();
59771                        var start = input.property('selectionStart');
59772                        input.node().setSelectionRange(start, start);
59773                        input.on('input.typeahead', change);
59774                    });
59775                    break;
59776                // tab
59777                case 9:
59778                    wrapper.selectAll('a.selected').each(function (d) {
59779                        dispatch$$1.call('accept', this, d);
59780                    });
59781                    hide();
59782                    break;
59783                // return
59784                case 13:
59785                    event.preventDefault();
59786                    break;
59787                // up arrow
59788                case 38:
59789                    nav(-1);
59790                    event.preventDefault();
59791                    break;
59792                // down arrow
59793                case 40:
59794                    nav(+1);
59795                    event.preventDefault();
59796                    break;
59797            }
59798            event.stopPropagation();
59799         }
59800
59801         function keyup() {
59802             switch (event.keyCode) {
59803                 // escape
59804                 case 27:
59805                     hide();
59806                     break;
59807                 // return
59808                 case 13:
59809                     wrapper.selectAll('a.selected').each(function (d) {
59810                        dispatch$$1.call('accept', this, d);
59811                     });
59812                     hide();
59813                     break;
59814             }
59815         }
59816
59817         function change() {
59818             fetch(value(), function() {
59819                 if (input.property('selectionEnd') === input.property('value').length) {
59820                     autocomplete();
59821                 }
59822                 render();
59823             });
59824         }
59825
59826         function nav(dir) {
59827             if (!_suggestions.length) return;
59828             idx = Math.max(Math.min(idx + dir, _suggestions.length - 1), 0);
59829             input.property('value', _suggestions[idx].value);
59830             render();
59831             ensureVisible();
59832         }
59833
59834         function value() {
59835             var value = input.property('value');
59836             var start = input.property('selectionStart');
59837             var end = input.property('selectionEnd');
59838
59839             if (start && end) {
59840                 value = value.substring(0, start);
59841             }
59842
59843             return value;
59844         }
59845
59846         function fetch(v, cb) {
59847             _fetcher.call(input, v, function(_) {
59848                 _suggestions = _;
59849                 cb();
59850             });
59851         }
59852
59853         function autocomplete() {
59854             var v = _caseSensitive ? value() : value().toLowerCase();
59855             idx = -1;
59856             if (!v) return;
59857
59858             var best = -1;
59859             var suggestion, compare;
59860
59861             for (var i = 0; i < _suggestions.length; i++) {
59862                 suggestion = _suggestions[i].value;
59863                 compare = _caseSensitive ? suggestion : suggestion.toLowerCase();
59864
59865                 // if search string matches suggestion exactly, pick it..
59866                 if (compare === v) {
59867                     best = i;
59868                     break;
59869
59870                 // otherwise lock in the first result that starts with the search string..
59871                 } else if (best === -1 && compare.indexOf(v) === 0) {
59872                     best = i;
59873                 }
59874             }
59875
59876             if (best !== -1) {
59877                 idx = best;
59878                 suggestion = _suggestions[best].value;
59879                 input.property('value', suggestion);
59880                 input.node().setSelectionRange(v.length, suggestion.length);
59881             }
59882         }
59883
59884         function render() {
59885             if (_suggestions.length >= _minItems && document.activeElement === input.node()) {
59886                 show();
59887             } else {
59888                 hide();
59889                 return;
59890             }
59891
59892             var options = wrapper
59893                 .selectAll('a.combobox-option')
59894                 .data(_suggestions, function(d) { return d.value; });
59895
59896             options.exit()
59897                 .remove();
59898
59899             options.enter()
59900                 .append('a')
59901                 .attr('class', 'combobox-option')
59902                 .text(function(d) { return d.value; })
59903                 .merge(options)
59904                 .attr('title', function(d) { return d.title; })
59905                 .classed('selected', function(d, i) { return i === idx; })
59906                 .on('mouseover', select$$1)
59907                 .on('click', accept)
59908                 .order();
59909
59910
59911             var node = attachTo ? attachTo.node() : input.node();
59912             var rect = node.getBoundingClientRect();
59913
59914             wrapper
59915                 .style('left', rect.left + 'px')
59916                 .style('width', rect.width + 'px')
59917                 .style('top', rect.height + rect.top + 'px');
59918         }
59919
59920         function select$$1(d, i) {
59921             idx = i;
59922             render();
59923         }
59924
59925         function ensureVisible() {
59926             var node = wrapper.selectAll('a.selected').node();
59927             if (node) node.scrollIntoView();
59928         }
59929
59930         function accept(d) {
59931             if (!shown) return;
59932             input.property('value', d.value);
59933             utilTriggerEvent(input, 'change');
59934             dispatch$$1.call('accept', this, d);
59935             hide();
59936         }
59937     };
59938
59939     combobox.fetcher = function(_) {
59940         if (!arguments.length) return _fetcher;
59941         _fetcher = _;
59942         return combobox;
59943     };
59944
59945     combobox.data = function(_) {
59946         if (!arguments.length) return _data;
59947         _data = _;
59948         return combobox;
59949     };
59950
59951     combobox.minItems = function(_) {
59952         if (!arguments.length) return _minItems;
59953         _minItems = _;
59954         return combobox;
59955     };
59956
59957     combobox.caseSensitive = function(_) {
59958         if (!arguments.length) return _caseSensitive;
59959         _caseSensitive = _;
59960         return combobox;
59961     };
59962
59963     combobox.container = function(_) {
59964         if (!arguments.length) return _container;
59965         _container = _;
59966         return combobox;
59967     };
59968
59969     return utilRebind(combobox, dispatch$$1, 'on');
59970 }
59971
59972
59973 d3combobox.off = function(input) {
59974     input
59975         .on('focus.typeahead', null)
59976         .on('blur.typeahead', null)
59977         .on('keydown.typeahead', null)
59978         .on('keyup.typeahead', null)
59979         .on('input.typeahead', null)
59980         .each(function() {
59981             d3_select(this.parentNode).selectAll('.combobox-caret')
59982                 .filter(function(d) { return d === input.node(); })
59983                 .on('mousedown', null);
59984         });
59985
59986     d3_select('body')
59987         .on('scroll.combobox', null);
59988 };
59989
59990 function uiRawMemberEditor(context) {
59991     var taginfo = services.taginfo,
59992         _entityID;
59993
59994
59995     function selectMember(d) {
59996         event.preventDefault();
59997         context.enter(modeSelect(context, [d.id]));
59998     }
59999
60000
60001     function changeRole(d) {
60002         var role = d3_select(this).property('value');
60003         var member = { id: d.id, type: d.type, role: role };
60004         context.perform(
60005             actionChangeMember(d.relation.id, member, d.index),
60006             t('operations.change_role.annotation')
60007         );
60008     }
60009
60010
60011     function deleteMember(d) {
60012         context.perform(
60013             actionDeleteMember(d.relation.id, d.index),
60014             t('operations.delete_member.annotation')
60015         );
60016
60017         if (!context.hasEntity(d.relation.id)) {
60018             context.enter(modeBrowse(context));
60019         }
60020     }
60021
60022
60023     function rawMemberEditor(selection) {
60024         var entity = context.entity(_entityID),
60025             memberships = [];
60026
60027         entity.members.slice(0, 1000).forEach(function(member, index) {
60028             memberships.push({
60029                 index: index,
60030                 id: member.id,
60031                 type: member.type,
60032                 role: member.role,
60033                 relation: entity,
60034                 member: context.hasEntity(member.id)
60035             });
60036         });
60037
60038         var gt = entity.members.length > 1000 ? '>' : '';
60039         selection.call(uiDisclosure(context, 'raw_member_editor', true)
60040             .title(t('inspector.all_members') + ' (' + gt + memberships.length + ')')
60041             .expanded(true)
60042             .updatePreference(false)
60043             .on('toggled', function(expanded) {
60044                 if (expanded) { selection.node().parentNode.scrollTop += 200; }
60045             })
60046             .content(content)
60047         );
60048
60049
60050         function content(wrap) {
60051             var list = wrap.selectAll('.member-list')
60052                 .data([0]);
60053
60054             list = list.enter()
60055                 .append('ul')
60056                 .attr('class', 'member-list')
60057                 .merge(list);
60058
60059
60060             var items = list.selectAll('li')
60061                 .data(memberships, function(d) {
60062                     return osmEntity.key(d.relation) + ',' + d.index + ',' +
60063                         (d.member ? osmEntity.key(d.member) : 'incomplete');
60064                 });
60065
60066             items.exit()
60067                 .each(unbind)
60068                 .remove();
60069
60070             var enter = items.enter()
60071                 .append('li')
60072                 .attr('class', 'member-row form-field')
60073                 .classed('member-incomplete', function(d) { return !d.member; });
60074
60075             enter
60076                 .each(function(d) {
60077                     if (d.member) {
60078                         var label = d3_select(this).append('label')
60079                             .attr('class', 'form-label')
60080                             .append('a')
60081                             .attr('href', '#')
60082                             .on('click', selectMember);
60083
60084                         label.append('span')
60085                             .attr('class', 'member-entity-type')
60086                             .text(function(d) {
60087                                 var matched = context.presets().match(d.member, context.graph());
60088                                 return (matched && matched.name()) || utilDisplayType(d.member.id);
60089                             });
60090
60091                         label.append('span')
60092                             .attr('class', 'member-entity-name')
60093                             .text(function(d) { return utilDisplayName(d.member); });
60094
60095                     } else {
60096                         d3_select(this).append('label')
60097                             .attr('class', 'form-label')
60098                             .text(t('inspector.incomplete', { id: d.id }));
60099                     }
60100                 });
60101
60102             enter
60103                 .append('input')
60104                 .attr('class', 'member-role')
60105                 .property('type', 'text')
60106                 .attr('maxlength', 255)
60107                 .attr('placeholder', t('inspector.role'))
60108                 .call(utilNoAuto)
60109                 .property('value', function(d) { return d.role; })
60110                 .on('change', changeRole);
60111
60112             enter
60113                 .append('button')
60114                 .attr('tabindex', -1)
60115                 .attr('class', 'remove button-input-action member-delete minor')
60116                 .on('click', deleteMember)
60117                 .call(svgIcon('#operation-delete'));
60118
60119             if (taginfo) {
60120                 enter.each(bindTypeahead);
60121             }
60122
60123
60124             function bindTypeahead(d) {
60125                 var row = d3_select(this),
60126                     role = row.selectAll('input.member-role');
60127
60128                 function sort(value, data) {
60129                     var sameletter = [],
60130                         other = [];
60131                     for (var i = 0; i < data.length; i++) {
60132                         if (data[i].value.substring(0, value.length) === value) {
60133                             sameletter.push(data[i]);
60134                         } else {
60135                             other.push(data[i]);
60136                         }
60137                     }
60138                     return sameletter.concat(other);
60139                 }
60140
60141                 role.call(d3combobox()
60142                     .container(context.container())
60143                     .fetcher(function(role, callback) {
60144                         var rtype = entity.tags.type;
60145                         taginfo.roles({
60146                             debounce: true,
60147                             rtype: rtype || '',
60148                             geometry: context.geometry(d.member.id),
60149                             query: role
60150                         }, function(err, data) {
60151                             if (!err) callback(sort(role, data));
60152                         });
60153                     }));
60154             }
60155
60156
60157             function unbind() {
60158                 var row = d3_select(this);
60159
60160                 row.selectAll('input.member-role')
60161                     .call(d3combobox.off);
60162             }
60163         }
60164     }
60165
60166
60167     rawMemberEditor.entityID = function(_) {
60168         if (!arguments.length) return _entityID;
60169         _entityID = _;
60170         return rawMemberEditor;
60171     };
60172
60173
60174     return rawMemberEditor;
60175 }
60176
60177 function uiRawMembershipEditor(context) {
60178     var taginfo = services.taginfo,
60179         _entityID,
60180         _showBlank;
60181
60182
60183     function selectRelation(d) {
60184         event.preventDefault();
60185         context.enter(modeSelect(context, [d.relation.id]));
60186     }
60187
60188
60189     function changeRole(d) {
60190         var role = d3_select(this).property('value');
60191         context.perform(
60192             actionChangeMember(d.relation.id, assignIn({}, d.member, { role: role }), d.index),
60193             t('operations.change_role.annotation')
60194         );
60195     }
60196
60197
60198     function addMembership(d, role) {
60199         _showBlank = false;
60200
60201         var member = { id: _entityID, type: context.entity(_entityID).type, role: role };
60202
60203         if (d.relation) {
60204             context.perform(
60205                 actionAddMember(d.relation.id, member),
60206                 t('operations.add_member.annotation')
60207             );
60208
60209         } else {
60210             var relation = osmRelation();
60211             context.perform(
60212                 actionAddEntity(relation),
60213                 actionAddMember(relation.id, member),
60214                 t('operations.add.annotation.relation')
60215             );
60216
60217             context.enter(modeSelect(context, [relation.id]));
60218         }
60219     }
60220
60221
60222     function deleteMembership(d) {
60223         context.perform(
60224             actionDeleteMember(d.relation.id, d.index),
60225             t('operations.delete_member.annotation')
60226         );
60227     }
60228
60229
60230     function relations(q) {
60231         var newRelation = { relation: null, value: t('inspector.new_relation') };
60232         var result = [];
60233         var graph = context.graph();
60234
60235         context.intersects(context.extent()).forEach(function(entity) {
60236             if (entity.type !== 'relation' || entity.id === _entityID)
60237                 return;
60238
60239             var matched = context.presets().match(entity, graph),
60240                 presetName = (matched && matched.name()) || t('inspector.relation'),
60241                 entityName = utilDisplayName(entity) || '';
60242
60243             var value = presetName + ' ' + entityName;
60244             if (q && value.toLowerCase().indexOf(q.toLowerCase()) === -1)
60245                 return;
60246
60247             result.push({ relation: entity, value: value });
60248         });
60249
60250         result.sort(function(a, b) {
60251             return osmRelation.creationOrder(a.relation, b.relation);
60252         });
60253
60254         // Dedupe identical names by appending relation id - see #2891
60255         var dupeGroups = filter(
60256             groupBy(result, 'value'),
60257             function(v) { return v.length > 1; }
60258         );
60259
60260         dupeGroups.forEach(function(group) {
60261             group.forEach(function(obj) {
60262                 obj.value += ' ' + obj.relation.id;
60263             });
60264         });
60265
60266         result.unshift(newRelation);
60267         return result;
60268     }
60269
60270
60271     function rawMembershipEditor(selection) {
60272         var entity = context.entity(_entityID),
60273             parents = context.graph().parentRelations(entity),
60274             memberships = [];
60275
60276         parents.slice(0, 1000).forEach(function(relation) {
60277             relation.members.forEach(function(member, index) {
60278                 if (member.id === entity.id) {
60279                     memberships.push({ relation: relation, member: member, index: index });
60280                 }
60281             });
60282         });
60283
60284         var gt = parents.length > 1000 ? '>' : '';
60285         selection.call(uiDisclosure(context, 'raw_membership_editor', true)
60286             .title(t('inspector.all_relations') + ' (' + gt + memberships.length + ')')
60287             .expanded(true)
60288             .updatePreference(false)
60289             .on('toggled', function(expanded) {
60290                 if (expanded) { selection.node().parentNode.scrollTop += 200; }
60291             })
60292             .content(content)
60293         );
60294
60295
60296         function content(wrap) {
60297             var list = wrap.selectAll('.member-list')
60298                 .data([0]);
60299
60300             list = list.enter()
60301                 .append('ul')
60302                 .attr('class', 'member-list')
60303                 .merge(list);
60304
60305
60306             var items = list.selectAll('li.member-row-normal')
60307                 .data(memberships, function(d) {
60308                     return osmEntity.key(d.relation) + ',' + d.index;
60309                 });
60310
60311             items.exit()
60312                 .each(unbind)
60313                 .remove();
60314
60315             var enter = items.enter()
60316                 .append('li')
60317                 .attr('class', 'member-row member-row-normal form-field');
60318
60319             var label = enter
60320                 .append('label')
60321                 .attr('class', 'form-label')
60322                 .append('a')
60323                 .attr('href', '#')
60324                 .on('click', selectRelation);
60325
60326             label
60327                 .append('span')
60328                 .attr('class', 'member-entity-type')
60329                 .text(function(d) {
60330                     var matched = context.presets().match(d.relation, context.graph());
60331                     return (matched && matched.name()) || t('inspector.relation');
60332                 });
60333
60334             label
60335                 .append('span')
60336                 .attr('class', 'member-entity-name')
60337                 .text(function(d) { return utilDisplayName(d.relation); });
60338
60339             enter
60340                 .append('input')
60341                 .attr('class', 'member-role')
60342                 .property('type', 'text')
60343                 .attr('maxlength', 255)
60344                 .attr('placeholder', t('inspector.role'))
60345                 .call(utilNoAuto)
60346                 .property('value', function(d) { return d.member.role; })
60347                 .on('change', changeRole);
60348
60349             enter
60350                 .append('button')
60351                 .attr('tabindex', -1)
60352                 .attr('class', 'remove button-input-action member-delete minor')
60353                 .on('click', deleteMembership)
60354                 .call(svgIcon('#operation-delete'));
60355
60356             if (taginfo) {
60357                 enter.each(bindTypeahead);
60358             }
60359
60360
60361             var newrow = list.selectAll('.member-row-new')
60362                 .data(_showBlank ? [0] : []);
60363
60364             newrow.exit()
60365                 .remove();
60366
60367             enter = newrow.enter()
60368                 .append('li')
60369                 .attr('class', 'member-row member-row-new form-field');
60370
60371             enter
60372                 .append('input')
60373                 .attr('type', 'text')
60374                 .attr('class', 'member-entity-input')
60375                 .call(utilNoAuto);
60376
60377             enter
60378                 .append('input')
60379                 .attr('class', 'member-role')
60380                 .property('type', 'text')
60381                 .attr('maxlength', 255)
60382                 .attr('placeholder', t('inspector.role'))
60383                 .call(utilNoAuto)
60384                 .on('change', changeRole);
60385
60386             enter
60387                 .append('button')
60388                 .attr('tabindex', -1)
60389                 .attr('class', 'remove button-input-action member-delete minor')
60390                 .on('click', deleteMembership)
60391                 .call(svgIcon('#operation-delete'));
60392
60393             newrow = newrow
60394                 .merge(enter);
60395
60396             newrow.selectAll('.member-entity-input')
60397                 .call(d3combobox()
60398                     .container(context.container())
60399                     .minItems(1)
60400                     .fetcher(function(value, callback) { callback(relations(value)); })
60401                     .on('accept', onAccept)
60402                 );
60403
60404
60405             var addrel = wrap.selectAll('.add-relation')
60406                 .data([0]);
60407
60408             addrel = addrel.enter()
60409                 .append('button')
60410                 .attr('class', 'add-relation')
60411                 .merge(addrel);
60412
60413             addrel
60414                 .call(svgIcon('#icon-plus', 'light'))
60415                 .on('click', function() {
60416                     _showBlank = true;
60417                     content(wrap);
60418                     list.selectAll('.member-entity-input').node().focus();
60419                 });
60420
60421
60422             function onAccept(d) {
60423                 var role = list.selectAll('.member-row-new .member-role').property('value');
60424                 addMembership(d, role);
60425             }
60426
60427
60428             function bindTypeahead(d) {
60429                 var row = d3_select(this),
60430                     role = row.selectAll('input.member-role');
60431
60432                 function sort(value, data) {
60433                     var sameletter = [],
60434                         other = [];
60435                     for (var i = 0; i < data.length; i++) {
60436                         if (data[i].value.substring(0, value.length) === value) {
60437                             sameletter.push(data[i]);
60438                         } else {
60439                             other.push(data[i]);
60440                         }
60441                     }
60442                     return sameletter.concat(other);
60443                 }
60444
60445                 role.call(d3combobox()
60446                     .container(context.container())
60447                     .fetcher(function(role, callback) {
60448                         var rtype = d.relation.tags.type;
60449                         taginfo.roles({
60450                             debounce: true,
60451                             rtype: rtype || '',
60452                             geometry: context.geometry(_entityID),
60453                             query: role
60454                         }, function(err, data) {
60455                             if (!err) callback(sort(role, data));
60456                         });
60457                     }));
60458             }
60459
60460
60461             function unbind() {
60462                 var row = d3_select(this);
60463
60464                 row.selectAll('input.member-role')
60465                     .call(d3combobox.off);
60466             }
60467         }
60468     }
60469
60470
60471     rawMembershipEditor.entityID = function(_) {
60472         if (!arguments.length) return _entityID;
60473         _entityID = _;
60474         return rawMembershipEditor;
60475     };
60476
60477
60478     return rawMembershipEditor;
60479 }
60480
60481 function uiTagReference(tag) {
60482     var taginfo = services.taginfo,
60483         tagReference = {},
60484         button = d3_select(null),
60485         body = d3_select(null),
60486         loaded,
60487         showing;
60488
60489
60490     function findLocal(data) {
60491         var locale = utilDetect().locale.toLowerCase(),
60492             localized;
60493
60494         if (locale !== 'pt-br') {  // see #3776, prefer 'pt' over 'pt-br'
60495             localized = find$1(data, function(d) {
60496                 return d.lang.toLowerCase() === locale;
60497             });
60498             if (localized) return localized;
60499         }
60500
60501         // try the non-regional version of a language, like
60502         // 'en' if the language is 'en-US'
60503         if (locale.indexOf('-') !== -1) {
60504             var first = locale.split('-')[0];
60505             localized = find$1(data, function(d) {
60506                 return d.lang.toLowerCase() === first;
60507             });
60508             if (localized) return localized;
60509         }
60510
60511         // finally fall back to english
60512         return find$1(data, function(d) {
60513             return d.lang.toLowerCase() === 'en';
60514         });
60515     }
60516
60517
60518     function load(param) {
60519         if (!taginfo) return;
60520
60521         button
60522             .classed('tag-reference-loading', true);
60523
60524         taginfo.docs(param, function show(err, data) {
60525             var docs;
60526             if (!err && data) {
60527                 docs = findLocal(data);
60528             }
60529
60530             body.html('');
60531
60532             if (!docs || !docs.title) {
60533                 if (param.hasOwnProperty('value')) {
60534                     load(omit(param, 'value'));   // retry with key only
60535                 } else {
60536                     body
60537                         .append('p')
60538                         .attr('class', 'tag-reference-description')
60539                         .text(t('inspector.no_documentation_key'));
60540                     done();
60541                 }
60542                 return;
60543             }
60544
60545             if (docs.image && docs.image.thumb_url_prefix) {
60546                 body
60547                     .append('img')
60548                     .attr('class', 'tag-reference-wiki-image')
60549                     .attr('src', docs.image.thumb_url_prefix + '100' + docs.image.thumb_url_suffix)
60550                     .on('load', function() { done(); })
60551                     .on('error', function() { d3_select(this).remove(); done(); });
60552             } else {
60553                 done();
60554             }
60555
60556             body
60557                 .append('p')
60558                 .attr('class', 'tag-reference-description')
60559                 .text(docs.description || t('inspector.documentation_redirect'));
60560
60561             body
60562                 .append('a')
60563                 .attr('class', 'tag-reference-link')
60564                 .attr('target', '_blank')
60565                 .attr('tabindex', -1)
60566                 .attr('href', 'https://wiki.openstreetmap.org/wiki/' + docs.title)
60567                 .call(svgIcon('#icon-out-link', 'inline'))
60568                 .append('span')
60569                 .text(t('inspector.reference'));
60570
60571             // Add link to info about "good changeset comments" - #2923
60572             if (param.key === 'comment') {
60573                 body
60574                     .append('a')
60575                     .attr('class', 'tag-reference-comment-link')
60576                     .attr('target', '_blank')
60577                     .attr('tabindex', -1)
60578                     .call(svgIcon('#icon-out-link', 'inline'))
60579                     .attr('href', t('commit.about_changeset_comments_link'))
60580                     .append('span')
60581                     .text(t('commit.about_changeset_comments'));
60582             }
60583         });
60584     }
60585
60586
60587     function done() {
60588         loaded = true;
60589
60590         button
60591             .classed('tag-reference-loading', false);
60592
60593         body
60594             .classed('expanded', true)
60595             .transition()
60596             .duration(200)
60597             .style('max-height', '200px')
60598             .style('opacity', '1');
60599
60600         showing = true;
60601     }
60602
60603
60604     function hide() {
60605         body
60606             .transition()
60607             .duration(200)
60608             .style('max-height', '0px')
60609             .style('opacity', '0')
60610             .on('end', function () {
60611                 body.classed('expanded', false);
60612             });
60613
60614         showing = false;
60615     }
60616
60617
60618     tagReference.button = function(selection) {
60619         button = selection.selectAll('.tag-reference-button')
60620             .data([0]);
60621
60622         button = button.enter()
60623             .append('button')
60624             .attr('class', 'tag-reference-button')
60625             .attr('tabindex', -1)
60626             .call(svgIcon('#icon-inspect'))
60627             .merge(button);
60628
60629         button
60630             .on('click', function () {
60631                 event.stopPropagation();
60632                 event.preventDefault();
60633                 if (showing) {
60634                     hide();
60635                 } else if (loaded) {
60636                     done();
60637                 } else {
60638                     load(tag);
60639                 }
60640             });
60641     };
60642
60643
60644     tagReference.body = function(selection) {
60645
60646         var tagid = tag.rtype || (tag.key + '-' + tag.value);
60647
60648         body = selection.selectAll('.tag-reference-body')
60649             .data([tagid], function(d) { return d; });
60650
60651         body.exit()
60652             .remove();
60653
60654         body = body.enter()
60655             .append('div')
60656             .attr('class', 'tag-reference-body cf')
60657             .style('max-height', '0')
60658             .style('opacity', '0')
60659             .merge(body);
60660
60661         if (showing === false) {
60662             hide();
60663         }
60664     };
60665
60666
60667     tagReference.showing = function(_) {
60668         if (!arguments.length) return showing;
60669         showing = _;
60670         return tagReference;
60671     };
60672
60673
60674     return tagReference;
60675 }
60676
60677 function uiRawTagEditor(context) {
60678     var taginfo = services.taginfo,
60679         dispatch$$1 = dispatch('change'),
60680         _readOnlyTags = [],
60681         _showBlank = false,
60682         _updatePreference = true,
60683         _expanded = false,
60684         _newRow,
60685         _state,
60686         _preset,
60687         _tags,
60688         _entityID;
60689
60690
60691     function rawTagEditor(selection) {
60692         var count = Object.keys(_tags).filter(function(d) { return d; }).length;
60693
60694         var disclosure = uiDisclosure(context, 'raw_tag_editor', false)
60695             .title(t('inspector.all_tags') + ' (' + count + ')')
60696             .on('toggled', toggled)
60697             .updatePreference(_updatePreference)
60698             .content(content);
60699
60700         // Sometimes we want to force the raw_tag_editor to be opened/closed..
60701         // When undefined, uiDisclosure will use the user's stored preference.
60702         if (_expanded !== undefined) {
60703             disclosure.expanded(_expanded);
60704         }
60705
60706         selection.call(disclosure);
60707
60708         function toggled(expanded) {
60709             _expanded = expanded;
60710             if (expanded) {
60711                 selection.node().parentNode.scrollTop += 200;
60712             }
60713         }
60714     }
60715
60716
60717     function content(wrap) {
60718         var entries = map$4(_tags, function(v, k) {
60719             return { key: k, value: v };
60720         });
60721
60722         if (!entries.length || _showBlank) {
60723             _showBlank = false;
60724             entries.push({key: '', value: ''});
60725             _newRow = '';
60726         }
60727
60728         var list = wrap.selectAll('.tag-list')
60729             .data([0]);
60730
60731         list = list.enter()
60732             .append('ul')
60733             .attr('class', 'tag-list')
60734             .merge(list);
60735
60736         var newTag = wrap.selectAll('.add-tag')
60737             .data([0]);
60738
60739         newTag.enter()
60740             .append('button')
60741             .attr('class', 'add-tag')
60742             .on('click', addTag)
60743             .call(svgIcon('#icon-plus', 'light'));
60744
60745
60746         var items = list.selectAll('.tag-row')
60747             .data(entries, function(d) { return d.key; });
60748
60749         items.exit()
60750             .each(unbind)
60751             .remove();
60752
60753         // Enter
60754
60755         var enter = items.enter()
60756             .append('li')
60757             .attr('class', 'tag-row cf')
60758             .classed('readonly', isReadOnly);
60759
60760         enter
60761             .append('div')
60762             .attr('class', 'key-wrap')
60763             .append('input')
60764             .property('type', 'text')
60765             .attr('class', 'key')
60766             .attr('maxlength', 255)
60767             .call(utilNoAuto)
60768             .on('blur', keyChange)
60769             .on('change', keyChange);
60770
60771         enter
60772             .append('div')
60773             .attr('class', 'input-wrap-position')
60774             .append('input')
60775             .property('type', 'text')
60776             .attr('class', 'value')
60777             .attr('maxlength', 255)
60778             .call(utilNoAuto)
60779             .on('blur', valueChange)
60780             .on('change', valueChange)
60781             .on('keydown.push-more', pushMore);
60782
60783         enter
60784             .append('button')
60785             .attr('tabindex', -1)
60786             .attr('class', 'remove minor')
60787             .call(svgIcon('#operation-delete'));
60788
60789
60790         // Update
60791
60792         items = items
60793             .merge(enter)
60794             .sort(function(a, b) {
60795                 return (a.key === _newRow && b.key !== _newRow) ? 1
60796                     : (a.key !== _newRow && b.key === _newRow) ? -1
60797                     : d3_ascending(a.key, b.key);
60798             });
60799
60800         items
60801             .each(function(tag) {
60802                 var row = d3_select(this),
60803                     key = row.select('input.key'),      // propagate bound data to child
60804                     value = row.select('input.value');  // propagate bound data to child
60805
60806                 if (_entityID && taginfo) {
60807                     bindTypeahead(key, value);
60808                 }
60809
60810                 var isRelation = (_entityID && context.entity(_entityID).type === 'relation'),
60811                     reference;
60812
60813                 if (isRelation && tag.key === 'type') {
60814                     reference = uiTagReference({ rtype: tag.value }, context);
60815                 } else {
60816                     reference = uiTagReference({ key: tag.key, value: tag.value }, context);
60817                 }
60818
60819                 if (_state === 'hover') {
60820                     reference.showing(false);
60821                 }
60822
60823                 row
60824                     .call(reference.button)
60825                     .call(reference.body);
60826             });
60827
60828         items.selectAll('input.key')
60829             .attr('title', function(d) { return d.key; })
60830             .call(utilGetSetValue, function(d) { return d.key; })
60831             .property('disabled', isReadOnly);
60832
60833         items.selectAll('input.value')
60834             .attr('title', function(d) { return d.value; })
60835             .call(utilGetSetValue, function(d) { return d.value; })
60836             .property('disabled', isReadOnly);
60837
60838         items.selectAll('button.remove')
60839             .on('click', removeTag);
60840
60841
60842
60843         function isReadOnly(d) {
60844             for (var i = 0; i < _readOnlyTags.length; i++) {
60845                 if (d.key.match(_readOnlyTags[i]) !== null) {
60846                     return true;
60847                 }
60848             }
60849             return false;
60850         }
60851
60852
60853         function pushMore() {
60854             if (event.keyCode === 9 && !event.shiftKey &&
60855                 list.selectAll('li:last-child input.value').node() === this) {
60856                 addTag();
60857             }
60858         }
60859
60860
60861         function bindTypeahead(key, value) {
60862             if (isReadOnly({ key: key })) return;
60863             var geometry = context.geometry(_entityID);
60864
60865             key.call(d3combobox()
60866                 .container(context.container())
60867                 .fetcher(function(value, callback) {
60868                     taginfo.keys({
60869                         debounce: true,
60870                         geometry: geometry,
60871                         query: value
60872                     }, function(err, data) {
60873                         if (!err) callback(sort(value, data));
60874                     });
60875                 }));
60876
60877             value.call(d3combobox()
60878                 .container(context.container())
60879                 .fetcher(function(value, callback) {
60880                     taginfo.values({
60881                         debounce: true,
60882                         key: utilGetSetValue(key),
60883                         geometry: geometry,
60884                         query: value
60885                     }, function(err, data) {
60886                         if (!err) callback(sort(value, data));
60887                     });
60888                 }));
60889
60890
60891             function sort(value, data) {
60892                 var sameletter = [],
60893                     other = [];
60894                 for (var i = 0; i < data.length; i++) {
60895                     if (data[i].value.substring(0, value.length) === value) {
60896                         sameletter.push(data[i]);
60897                     } else {
60898                         other.push(data[i]);
60899                     }
60900                 }
60901                 return sameletter.concat(other);
60902             }
60903         }
60904
60905
60906         function unbind() {
60907             var row = d3_select(this);
60908
60909             row.selectAll('input.key')
60910                 .call(d3combobox.off);
60911
60912             row.selectAll('input.value')
60913                 .call(d3combobox.off);
60914         }
60915
60916
60917         function keyChange(d) {
60918             var kOld = d.key,
60919                 kNew = this.value.trim(),
60920                 tag = {};
60921
60922
60923             if (isReadOnly({ key: kNew })) {
60924                 this.value = kOld;
60925                 return;
60926             }
60927
60928             if (kNew && kNew !== kOld) {
60929                 var match = kNew.match(/^(.*?)(?:_(\d+))?$/),
60930                     base = match[1],
60931                     suffix = +(match[2] || 1);
60932                 while (_tags[kNew]) {  // rename key if already in use
60933                     kNew = base + '_' + suffix++;
60934                 }
60935             }
60936             tag[kOld] = undefined;
60937             tag[kNew] = d.value;
60938
60939             d.key = kNew; // Maintain DOM identity through the subsequent update.
60940
60941             if (_newRow === kOld) {  // see if this row is still a new row
60942                 _newRow = ((d.value === '' || kNew === '') ? kNew : undefined);
60943             }
60944
60945             this.value = kNew;
60946             dispatch$$1.call('change', this, tag);
60947         }
60948
60949
60950         function valueChange(d) {
60951             if (isReadOnly(d)) return;
60952             var tag = {};
60953             tag[d.key] = this.value;
60954
60955             if (_newRow === d.key && d.key !== '' && d.value !== '') {   // not a new row anymore
60956                 _newRow = undefined;
60957             }
60958
60959             dispatch$$1.call('change', this, tag);
60960         }
60961
60962
60963         function removeTag(d) {
60964             if (isReadOnly(d)) return;
60965             var tag = {};
60966             tag[d.key] = undefined;
60967             dispatch$$1.call('change', this, tag);
60968             d3_select(this.parentNode).remove();
60969         }
60970
60971
60972         function addTag() {
60973             // Wrapped in a setTimeout in case it's being called from a blur
60974             // handler. Without the setTimeout, the call to `content` would
60975             // wipe out the pending value change.
60976             setTimeout(function() {
60977                 _showBlank = true;
60978                 content(wrap);
60979                 list.selectAll('li:last-child input.key').node().focus();
60980             }, 0);
60981         }
60982     }
60983
60984
60985     rawTagEditor.state = function(_) {
60986         if (!arguments.length) return _state;
60987         _state = _;
60988         return rawTagEditor;
60989     };
60990
60991
60992     rawTagEditor.preset = function(_) {
60993         if (!arguments.length) return _preset;
60994         _preset = _;
60995         if (_preset.isFallback()) {
60996             _expanded = true;
60997             _updatePreference = false;
60998         } else {
60999             _expanded = undefined;
61000             _updatePreference = true;
61001         }
61002         return rawTagEditor;
61003     };
61004
61005
61006     rawTagEditor.tags = function(_) {
61007         if (!arguments.length) return _tags;
61008         _tags = _;
61009         return rawTagEditor;
61010     };
61011
61012
61013     rawTagEditor.entityID = function(_) {
61014         if (!arguments.length) return _entityID;
61015         _entityID = _;
61016         return rawTagEditor;
61017     };
61018
61019
61020     rawTagEditor.expanded = function(_) {
61021         if (!arguments.length) return _expanded;
61022         _expanded = _;
61023         _updatePreference = false;
61024         return rawTagEditor;
61025     };
61026
61027
61028     rawTagEditor.readOnlyTags = function(_) {
61029         if (!arguments.length) return _readOnlyTags;
61030         _readOnlyTags = _;
61031         return rawTagEditor;
61032     };
61033
61034
61035     return utilRebind(rawTagEditor, dispatch$$1, 'on');
61036 }
61037
61038 function uiFieldCheck(field, context) {
61039     var dispatch$$1 = dispatch('change');
61040     var options = field.strings && field.strings.options;
61041     var values = [];
61042     var texts = [];
61043
61044     var input = d3_select(null);
61045     var text = d3_select(null);
61046     var label = d3_select(null);
61047     var reverser = d3_select(null);
61048
61049     var _impliedYes;
61050     var _entityID;
61051     var _value;
61052
61053
61054     if (options) {
61055         for (var k in options) {
61056             values.push(k === 'undefined' ? undefined : k);
61057             texts.push(field.t('options.' + k, { 'default': options[k] }));
61058         }
61059     } else {
61060         values = [undefined, 'yes'];
61061         texts = [t('inspector.unknown'), t('inspector.check.yes')];
61062         if (field.type !== 'defaultCheck') {
61063             values.push('no');
61064             texts.push(t('inspector.check.no'));
61065         }
61066     }
61067
61068
61069     // Checks tags to see whether an undefined value is "Assumed to be Yes"
61070     function checkImpliedYes() {
61071         _impliedYes = (field.id === 'oneway_yes');
61072
61073         // hack: pretend `oneway` field is a `oneway_yes` field
61074         // where implied oneway tag exists (e.g. `junction=roundabout`) #2220, #1841
61075         if (field.id === 'oneway') {
61076             var entity = context.entity(_entityID);
61077             for (var key in entity.tags) {
61078                 if (key in osmOneWayTags && (entity.tags[key] in osmOneWayTags[key])) {
61079                     _impliedYes = true;
61080                     texts[0] = t('presets.fields.oneway_yes.options.undefined');
61081                     break;
61082                 }
61083             }
61084         }
61085     }
61086
61087
61088     function reverserHidden() {
61089         if (!d3_select('div.inspector-hover').empty()) return true;
61090         return !(_value === 'yes' || (_impliedYes && !_value));
61091     }
61092
61093
61094     function reverserSetText(selection) {
61095         var entity = context.hasEntity(_entityID);
61096         if (reverserHidden() || !entity) return selection;
61097
61098         var first = entity.first();
61099         var last = entity.isClosed() ? entity.nodes[entity.nodes.length - 2] : entity.last();
61100         var pseudoDirection = first < last;
61101         var icon = pseudoDirection ? '#icon-forward' : '#icon-backward';
61102
61103         selection.selectAll('.reverser-span')
61104             .text(t('inspector.check.reverser'))
61105             .call(svgIcon(icon, 'inline'));
61106
61107         return selection;
61108     }
61109
61110
61111     var check = function(selection) {
61112         checkImpliedYes();
61113         selection.classed('checkselect', 'true');
61114
61115         label = selection.selectAll('.preset-input-wrap')
61116             .data([0]);
61117
61118         var enter = label.enter()
61119             .append('label')
61120             .attr('class', 'preset-input-wrap');
61121
61122         enter
61123             .append('input')
61124             .property('indeterminate', field.type !== 'defaultCheck')
61125             .attr('type', 'checkbox')
61126             .attr('id', 'preset-input-' + field.id);
61127
61128         enter
61129             .append('span')
61130             .text(texts[0])
61131             .attr('class', 'value');
61132
61133         if (field.type === 'onewayCheck') {
61134             enter
61135                 .append('a')
61136                 .attr('id', 'preset-input-' + field.id + '-reverser')
61137                 .attr('class', 'reverser button' + (reverserHidden() ? ' hide' : ''))
61138                 .attr('href', '#')
61139                 .append('span')
61140                 .attr('class', 'reverser-span');
61141         }
61142
61143         label = label.merge(enter);
61144         input = label.selectAll('input');
61145         text = label.selectAll('span.value');
61146
61147         input
61148             .on('click', function() {
61149                 var t$$1 = {};
61150                 t$$1[field.key] = values[(values.indexOf(_value) + 1) % values.length];
61151                 dispatch$$1.call('change', this, t$$1);
61152                 event.stopPropagation();
61153             });
61154
61155         if (field.type === 'onewayCheck') {
61156             reverser = label.selectAll('.reverser');
61157
61158             reverser
61159                 .call(reverserSetText)
61160                 .on('click', function() {
61161                     event.preventDefault();
61162                     event.stopPropagation();
61163                     context.perform(
61164                         actionReverse(_entityID),
61165                         t('operations.reverse.annotation')
61166                     );
61167                     d3_select(this)
61168                         .call(reverserSetText);
61169                 });
61170         }
61171     };
61172
61173
61174     check.entity = function(_) {
61175         if (!arguments.length) return context.hasEntity(_entityID);
61176         _entityID = _.id;
61177         return check;
61178     };
61179
61180
61181     check.tags = function(tags) {
61182
61183         function isChecked(val) {
61184             return val !== 'no' && val !== '' && val !== undefined && val !== null;
61185         }
61186
61187         function textFor(val) {
61188             if (val === '') val = undefined;
61189             var index = values.indexOf(val);
61190             return (index !== -1 ? texts[index] : ('"' + val + '"'));
61191         }
61192
61193         checkImpliedYes();
61194         _value = tags[field.key] && tags[field.key].toLowerCase();
61195
61196         if (field.type === 'onewayCheck' && (_value === '1' || _value === '-1')) {
61197             _value = 'yes';
61198         }
61199
61200         input
61201             .property('indeterminate', field.type !== 'defaultCheck' && !_value)
61202             .property('checked', isChecked(_value));
61203
61204         text
61205             .text(textFor(_value));
61206
61207         label
61208             .classed('set', !!_value);
61209
61210         if (field.type === 'onewayCheck') {
61211             reverser
61212                 .classed('hide', reverserHidden())
61213                 .call(reverserSetText);
61214         }
61215     };
61216
61217
61218     check.focus = function() {
61219         input.node().focus();
61220     };
61221
61222     return utilRebind(check, dispatch$$1, 'on');
61223 }
61224
61225 /** Used for built-in method references. */
61226 var arrayProto$1 = Array.prototype;
61227
61228 /** Built-in value references. */
61229 var splice$1 = arrayProto$1.splice;
61230
61231 /**
61232  * The base implementation of `_.pullAt` without support for individual
61233  * indexes or capturing the removed elements.
61234  *
61235  * @private
61236  * @param {Array} array The array to modify.
61237  * @param {number[]} indexes The indexes of elements to remove.
61238  * @returns {Array} Returns `array`.
61239  */
61240 function basePullAt(array, indexes) {
61241   var length = array ? indexes.length : 0,
61242       lastIndex = length - 1;
61243
61244   while (length--) {
61245     var index = indexes[length];
61246     if (length == lastIndex || index !== previous) {
61247       var previous = index;
61248       if (isIndex(index)) {
61249         splice$1.call(array, index, 1);
61250       } else {
61251         baseUnset(array, index);
61252       }
61253     }
61254   }
61255   return array;
61256 }
61257
61258 /**
61259  * Removes all elements from `array` that `predicate` returns truthy for
61260  * and returns an array of the removed elements. The predicate is invoked
61261  * with three arguments: (value, index, array).
61262  *
61263  * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
61264  * to pull elements from an array by value.
61265  *
61266  * @static
61267  * @memberOf _
61268  * @since 2.0.0
61269  * @category Array
61270  * @param {Array} array The array to modify.
61271  * @param {Function} [predicate=_.identity] The function invoked per iteration.
61272  * @returns {Array} Returns the new array of removed elements.
61273  * @example
61274  *
61275  * var array = [1, 2, 3, 4];
61276  * var evens = _.remove(array, function(n) {
61277  *   return n % 2 == 0;
61278  * });
61279  *
61280  * console.log(array);
61281  * // => [1, 3]
61282  *
61283  * console.log(evens);
61284  * // => [2, 4]
61285  */
61286 function remove$8(array, predicate) {
61287   var result = [];
61288   if (!(array && array.length)) {
61289     return result;
61290   }
61291   var index = -1,
61292       indexes = [],
61293       length = array.length;
61294
61295   predicate = baseIteratee(predicate, 3);
61296   while (++index < length) {
61297     var value = array[index];
61298     if (predicate(value, index, array)) {
61299       result.push(value);
61300       indexes.push(index);
61301     }
61302   }
61303   basePullAt(array, indexes);
61304   return result;
61305 }
61306
61307 function uiFieldCombo(field, context) {
61308     var dispatch$$1 = dispatch('change'),
61309         nominatim = services.geocoder,
61310         taginfo = services.taginfo,
61311         isMulti = (field.type === 'multiCombo'),
61312         isNetwork = (field.type === 'networkCombo'),
61313         isSemi = (field.type === 'semiCombo'),
61314         optstrings = field.strings && field.strings.options,
61315         optarray = field.options,
61316         snake_case = (field.snake_case || (field.snake_case === undefined)),
61317         caseSensitive = field.caseSensitive,
61318         combobox = d3combobox()
61319             .container(context.container())
61320             .caseSensitive(caseSensitive)
61321             .minItems(isMulti || isSemi ? 1 : 2),
61322         comboData = [],
61323         multiData = [],
61324         container,
61325         input,
61326         entity,
61327         country;
61328
61329     // ensure multiCombo field.key ends with a ':'
61330     if (isMulti && field.key.match(/:$/) === null) {
61331         field.key += ':';
61332     }
61333
61334
61335     function snake(s) {
61336         return s.replace(/\s+/g, '_');
61337     }
61338
61339     function unsnake(s) {
61340         return s.replace(/_+/g, ' ');
61341     }
61342
61343     function clean(s) {
61344         return s.split(';')
61345             .map(function(s) { return s.trim(); })
61346             .join(';');
61347     }
61348
61349
61350     // returns the tag value for a display value
61351     // (for multiCombo, dval should be the key suffix, not the entire key)
61352     function tagValue(dval) {
61353         dval = clean(dval || '');
61354
61355         if (optstrings) {
61356             var match = find$1(comboData, function(o) {
61357                 return o.key && clean(o.value) === dval;
61358             });
61359             if (match) {
61360                 return match.key;
61361             }
61362         }
61363
61364         if (field.type === 'typeCombo' && !dval) {
61365             return 'yes';
61366         }
61367
61368         return (snake_case ? snake(dval) : dval) || undefined;
61369     }
61370
61371
61372     // returns the display value for a tag value
61373     // (for multiCombo, tval should be the key suffix, not the entire key)
61374     function displayValue(tval) {
61375         tval = tval || '';
61376
61377         if (optstrings) {
61378             var match = find$1(comboData, function(o) { return o.key === tval && o.value; });
61379             if (match) {
61380                 return match.value;
61381             }
61382         }
61383
61384         if (field.type === 'typeCombo' && tval.toLowerCase() === 'yes') {
61385             return '';
61386         }
61387
61388         return snake_case ? unsnake(tval) : tval;
61389     }
61390
61391
61392     function objectDifference(a, b) {
61393         return reject(a, function(d1) {
61394             return some(b, function(d2) { return d1.value === d2.value; });
61395         });
61396     }
61397
61398
61399     function initCombo(selection, attachTo) {
61400         if (optstrings) {
61401             selection.attr('readonly', 'readonly');
61402             selection.call(combobox, attachTo);
61403             setStaticValues(setPlaceholder);
61404
61405         } else if (optarray) {
61406             selection.call(combobox, attachTo);
61407             setStaticValues(setPlaceholder);
61408
61409         } else if (taginfo) {
61410             selection.call(combobox.fetcher(setTaginfoValues), attachTo);
61411             setTaginfoValues('', setPlaceholder);
61412         }
61413     }
61414
61415
61416     function setStaticValues(callback) {
61417         if (!(optstrings || optarray)) return;
61418
61419         if (optstrings) {
61420             comboData = Object.keys(optstrings).map(function(k) {
61421                 var v = field.t('options.' + k, { 'default': optstrings[k] });
61422                 return {
61423                     key: k,
61424                     value: v,
61425                     title: v
61426                 };
61427             });
61428
61429         } else if (optarray) {
61430             comboData = optarray.map(function(k) {
61431                 var v = snake_case ? unsnake(k) : k;
61432                 return {
61433                     key: k,
61434                     value: v,
61435                     title: v
61436                 };
61437             });
61438         }
61439
61440         combobox.data(objectDifference(comboData, multiData));
61441         if (callback) callback(comboData);
61442     }
61443
61444
61445     function setTaginfoValues(q, callback) {
61446         var fn = isMulti ? 'multikeys' : 'values';
61447         var query = (isMulti ? field.key : '') + q;
61448         var hasCountryPrefix = isNetwork && country && country.indexOf(q.toLowerCase()) === 0;
61449         if (hasCountryPrefix) {
61450             query = country + ':';
61451         }
61452
61453         var params = {
61454             debounce: (q !== ''),
61455             key: field.key,
61456             query: query
61457         };
61458
61459         if (entity) {
61460             params.geometry = context.geometry(entity.id);
61461         }
61462
61463         taginfo[fn](params, function(err, data) {
61464             if (err) return;
61465             if (hasCountryPrefix) {
61466                 data = filter(data, function(d) {
61467                     return d.value.toLowerCase().indexOf(country + ':') === 0;
61468                 });
61469             }
61470
61471             comboData = map$4(data, function(d) {
61472                 var k = d.value;
61473                 if (isMulti) k = k.replace(field.key, '');
61474                 var v = snake_case ? unsnake(k) : k;
61475                 return {
61476                     key: k,
61477                     value: v,
61478                     title: isMulti ? v : d.title
61479                 };
61480             });
61481
61482             comboData = objectDifference(comboData, multiData);
61483             if (callback) callback(comboData);
61484         });
61485     }
61486
61487
61488     function setPlaceholder(d) {
61489         var ph;
61490
61491         if (isMulti || isSemi) {
61492             ph = field.placeholder() || t('inspector.add');
61493         } else {
61494             var vals = map$4(d, 'value').filter(function(s) { return s.length < 20; }),
61495                 placeholders = vals.length > 1 ? vals : map$4(d, 'key');
61496             ph = field.placeholder() || placeholders.slice(0, 3).join(', ');
61497         }
61498
61499         if (ph.match(/(…|\.\.\.)$/) === null) {
61500             ph += '…';
61501         }
61502
61503         container.selectAll('input')
61504             .attr('placeholder', ph);
61505     }
61506
61507
61508     function change() {
61509         var val = tagValue(utilGetSetValue(input)),
61510             t$$1 = {};
61511
61512         if (isMulti || isSemi) {
61513             if (!val) return;
61514             container.classed('active', false);
61515             utilGetSetValue(input, '');
61516             if (isMulti) {
61517                 field.keys.push(field.key + val);
61518                 t$$1[field.key + val] = 'yes';
61519             } else if (isSemi) {
61520                 var arr = multiData.map(function(d) { return d.key; });
61521                 arr.push(val);
61522                 t$$1[field.key] = compact(uniq(arr)).join(';');
61523             }
61524             window.setTimeout(function() { input.node().focus(); }, 10);
61525
61526         } else {
61527             t$$1[field.key] = val;
61528         }
61529
61530         dispatch$$1.call('change', this, t$$1);
61531     }
61532
61533
61534     function removeMultikey(d) {
61535         event.stopPropagation();
61536         var t$$1 = {};
61537         if (isMulti) {
61538             t$$1[d.key] = undefined;
61539         } else if (isSemi) {
61540             remove$8(multiData, function(md) { return md.key === d.key; });
61541             var arr = multiData.map(function(md) { return md.key; });
61542             arr = compact(uniq(arr));
61543             t$$1[field.key] = arr.length ? arr.join(';') : undefined;
61544         }
61545         dispatch$$1.call('change', this, t$$1);
61546     }
61547
61548
61549     function combo(selection) {
61550         if (isMulti || isSemi) {
61551             container = selection.selectAll('ul').data([0]);
61552
61553             container = container.enter()
61554                 .append('ul')
61555                 .attr('class', 'form-field-multicombo')
61556                 .on('click', function() {
61557                     window.setTimeout(function() { input.node().focus(); }, 10);
61558                 })
61559                 .merge(container);
61560
61561         } else {
61562             container = selection;
61563         }
61564
61565         input = container.selectAll('input')
61566             .data([0]);
61567
61568         input = input.enter()
61569             .append('input')
61570             .attr('type', 'text')
61571             .attr('id', 'preset-input-' + field.id)
61572             .call(utilNoAuto)
61573             .call(initCombo, selection)
61574             .merge(input);
61575
61576         if (isNetwork && nominatim && entity) {
61577             var center = entity.extent(context.graph()).center();
61578             nominatim.countryCode(center, function (err, code) {
61579                 country = code;
61580             });
61581         }
61582
61583         input
61584             .on('change', change)
61585             .on('blur', change);
61586
61587         if (isMulti || isSemi) {
61588             combobox
61589                 .on('accept', function() {
61590                     input.node().blur();
61591                     input.node().focus();
61592                 });
61593
61594             input
61595                 .on('focus', function() { container.classed('active', true); });
61596         }
61597     }
61598
61599
61600     combo.tags = function(tags) {
61601         if (isMulti || isSemi) {
61602             multiData = [];
61603
61604             if (isMulti) {
61605                 // Build multiData array containing keys already set..
61606                 Object.keys(tags).forEach(function(key) {
61607                     if (key.indexOf(field.key) !== 0 || tags[key].toLowerCase() !== 'yes') return;
61608
61609                     var suffix = key.substring(field.key.length);
61610                     multiData.push({
61611                         key: key,
61612                         value: displayValue(suffix)
61613                     });
61614                 });
61615
61616                 // Set keys for form-field modified (needed for undo and reset buttons)..
61617                 field.keys = map$4(multiData, 'key');
61618
61619             } else if (isSemi) {
61620                 var arr = compact(uniq((tags[field.key] || '').split(';')));
61621                 multiData = arr.map(function(key) {
61622                     return {
61623                         key: key,
61624                         value: displayValue(key)
61625                     };
61626                 });
61627             }
61628
61629             // Exclude existing multikeys from combo options..
61630             var available = objectDifference(comboData, multiData);
61631             combobox.data(available);
61632
61633             // Hide 'Add' button if this field uses fixed set of
61634             // translateable optstrings and they're all currently used..
61635             container.selectAll('.combobox-input, .combobox-caret')
61636                 .classed('hide', optstrings && !available.length);
61637
61638
61639             // Render chips
61640             var chips = container.selectAll('.chips')
61641                 .data(multiData);
61642
61643             chips.exit()
61644                 .remove();
61645
61646             var enter = chips.enter()
61647                 .insert('li', 'input')
61648                 .attr('class', 'chips');
61649
61650             enter.append('span');
61651             enter.append('a');
61652
61653             chips = chips.merge(enter);
61654
61655             chips.select('span')
61656                 .text(function(d) { return d.value; });
61657
61658             chips.select('a')
61659                 .on('click', removeMultikey)
61660                 .attr('class', 'remove')
61661                 .text('×');
61662
61663         } else {
61664             utilGetSetValue(input, displayValue(tags[field.key]));
61665         }
61666     };
61667
61668
61669     combo.focus = function() {
61670         input.node().focus();
61671     };
61672
61673
61674     combo.entity = function(_) {
61675         if (!arguments.length) return entity;
61676         entity = _;
61677         return combo;
61678     };
61679
61680
61681     return utilRebind(combo, dispatch$$1, 'on');
61682 }
61683
61684 function uiFieldText(field, context) {
61685     var dispatch$$1 = dispatch('change'),
61686         nominatim = services.geocoder,
61687         input,
61688         entity;
61689
61690
61691     function i(selection) {
61692         var fieldId = 'preset-input-' + field.id;
61693
61694         input = selection.selectAll('input')
61695             .data([0]);
61696
61697         input = input.enter()
61698             .append('input')
61699             .attr('type', field.type)
61700             .attr('id', fieldId)
61701             .attr('placeholder', field.placeholder() || t('inspector.unknown'))
61702             .call(utilNoAuto)
61703             .merge(input);
61704
61705         input
61706             .on('input', change(true))
61707             .on('blur', change())
61708             .on('change', change());
61709
61710         if (field.type === 'tel' && nominatim && entity) {
61711             var center = entity.extent(context.graph()).center();
61712             nominatim.countryCode(center, function (err, countryCode) {
61713                 if (err || !dataPhoneFormats[countryCode]) return;
61714                 selection.selectAll('#' + fieldId)
61715                     .attr('placeholder', dataPhoneFormats[countryCode]);
61716             });
61717
61718         } else if (field.type === 'number') {
61719             var rtl = (textDirection === 'rtl');
61720
61721             input.attr('type', 'text');
61722
61723             var spinControl = selection.selectAll('.spin-control')
61724                 .data([0]);
61725
61726             var enter = spinControl.enter()
61727                 .append('div')
61728                 .attr('class', 'spin-control');
61729
61730             enter
61731                 .append('button')
61732                 .datum(rtl ? 1 : -1)
61733                 .attr('class', rtl ? 'increment' : 'decrement')
61734                 .attr('tabindex', -1);
61735
61736             enter
61737                 .append('button')
61738                 .datum(rtl ? -1 : 1)
61739                 .attr('class', rtl ? 'decrement' : 'increment')
61740                 .attr('tabindex', -1);
61741
61742             spinControl = spinControl
61743                 .merge(enter);
61744
61745             spinControl.selectAll('button')
61746                 .on('click', function(d) {
61747                     event.preventDefault();
61748                     var num = parseInt(input.node().value || 0, 10);
61749                     if (!isNaN(num)) input.node().value = num + d;
61750                     change()();
61751                 });
61752         }
61753     }
61754
61755
61756     function change(onInput) {
61757         return function() {
61758             var t$$1 = {};
61759             t$$1[field.key] = utilGetSetValue(input) || undefined;
61760             dispatch$$1.call('change', this, t$$1, onInput);
61761         };
61762     }
61763
61764
61765     i.entity = function(_) {
61766         if (!arguments.length) return entity;
61767         entity = _;
61768         return i;
61769     };
61770
61771
61772     i.tags = function(tags) {
61773         utilGetSetValue(input, tags[field.key] || '');
61774     };
61775
61776
61777     i.focus = function() {
61778         var node = input.node();
61779         if (node) node.focus();
61780     };
61781
61782     return utilRebind(i, dispatch$$1, 'on');
61783 }
61784
61785 function uiFieldAccess(field, context) {
61786     var dispatch$$1 = dispatch('change'),
61787         items;
61788
61789     function access(selection) {
61790         var wrap = selection.selectAll('.preset-input-wrap')
61791             .data([0]);
61792
61793         wrap = wrap.enter()
61794             .append('div')
61795             .attr('class', 'cf preset-input-wrap')
61796             .append('ul')
61797             .merge(wrap);
61798
61799         var list = wrap.selectAll('ul')
61800             .data([0]);
61801
61802         list = list.enter()
61803             .append('ul')
61804             .merge(list);
61805
61806
61807         items = list.selectAll('li')
61808             .data(field.keys);
61809
61810         // Enter
61811         var enter = items.enter()
61812             .append('li')
61813             .attr('class', function(d) { return 'cf preset-access-' + d; });
61814
61815         enter
61816             .append('span')
61817             .attr('class', 'col6 label preset-label-access')
61818             .attr('for', function(d) { return 'preset-input-access-' + d; })
61819             .text(function(d) { return field.t('types.' + d); });
61820
61821         enter
61822             .append('div')
61823             .attr('class', 'col6 preset-input-access-wrap')
61824             .append('input')
61825             .attr('type', 'text')
61826             .attr('class', 'preset-input-access')
61827             .attr('id', function(d) { return 'preset-input-access-' + d; })
61828             .call(utilNoAuto)
61829             .each(function(d) {
61830                 d3_select(this)
61831                     .call(d3combobox()
61832                         .container(context.container())
61833                         .data(access.options(d))
61834                     );
61835             });
61836
61837
61838         // Update
61839         items = items.merge(enter);
61840
61841         wrap.selectAll('.preset-input-access')
61842             .on('change', change)
61843             .on('blur', change);
61844     }
61845
61846
61847     function change(d) {
61848         var tag = {};
61849         tag[d] = utilGetSetValue(d3_select(this)) || undefined;
61850         dispatch$$1.call('change', this, tag);
61851     }
61852
61853
61854     access.options = function(type) {
61855         var options = ['no', 'permissive', 'private', 'destination'];
61856
61857         if (type !== 'access') {
61858             options.unshift('yes');
61859             options.push('designated');
61860
61861             if (type === 'bicycle') {
61862                 options.push('dismount');
61863             }
61864         }
61865
61866         return options.map(function(option) {
61867             return {
61868                 title: field.t('options.' + option + '.description'),
61869                 value: option
61870             };
61871         });
61872     };
61873
61874
61875     var placeholders = {
61876         footway: {
61877             foot: 'designated',
61878             motor_vehicle: 'no'
61879         },
61880         steps: {
61881             foot: 'yes',
61882             motor_vehicle: 'no',
61883             bicycle: 'no',
61884             horse: 'no'
61885         },
61886         pedestrian: {
61887             foot: 'yes',
61888             motor_vehicle: 'no'
61889         },
61890         cycleway: {
61891             motor_vehicle: 'no',
61892             bicycle: 'designated'
61893         },
61894         bridleway: {
61895             motor_vehicle: 'no',
61896             horse: 'designated'
61897         },
61898         path: {
61899             foot: 'yes',
61900             motor_vehicle: 'no',
61901             bicycle: 'yes',
61902             horse: 'yes'
61903         },
61904         motorway: {
61905             foot: 'no',
61906             motor_vehicle: 'yes',
61907             bicycle: 'no',
61908             horse: 'no'
61909         },
61910         trunk: {
61911             motor_vehicle: 'yes'
61912         },
61913         primary: {
61914             foot: 'yes',
61915             motor_vehicle: 'yes',
61916             bicycle: 'yes',
61917             horse: 'yes'
61918         },
61919         secondary: {
61920             foot: 'yes',
61921             motor_vehicle: 'yes',
61922             bicycle: 'yes',
61923             horse: 'yes'
61924         },
61925         tertiary: {
61926             foot: 'yes',
61927             motor_vehicle: 'yes',
61928             bicycle: 'yes',
61929             horse: 'yes'
61930         },
61931         residential: {
61932             foot: 'yes',
61933             motor_vehicle: 'yes',
61934             bicycle: 'yes',
61935             horse: 'yes'
61936         },
61937         unclassified: {
61938             foot: 'yes',
61939             motor_vehicle: 'yes',
61940             bicycle: 'yes',
61941             horse: 'yes'
61942         },
61943         service: {
61944             foot: 'yes',
61945             motor_vehicle: 'yes',
61946             bicycle: 'yes',
61947             horse: 'yes'
61948         },
61949         motorway_link: {
61950             foot: 'no',
61951             motor_vehicle: 'yes',
61952             bicycle: 'no',
61953             horse: 'no'
61954         },
61955         trunk_link: {
61956             motor_vehicle: 'yes'
61957         },
61958         primary_link: {
61959             foot: 'yes',
61960             motor_vehicle: 'yes',
61961             bicycle: 'yes',
61962             horse: 'yes'
61963         },
61964         secondary_link: {
61965             foot: 'yes',
61966             motor_vehicle: 'yes',
61967             bicycle: 'yes',
61968             horse: 'yes'
61969         },
61970         tertiary_link: {
61971             foot: 'yes',
61972             motor_vehicle: 'yes',
61973             bicycle: 'yes',
61974             horse: 'yes'
61975         }
61976     };
61977
61978
61979     access.tags = function(tags) {
61980         utilGetSetValue(items.selectAll('.preset-input-access'),
61981             function(d) { return tags[d] || ''; })
61982             .attr('placeholder', function() {
61983                 return tags.access ? tags.access : field.placeholder();
61984             });
61985
61986         items.selectAll('#preset-input-access-access')
61987             .attr('placeholder', 'yes');
61988
61989         forEach(placeholders[tags.highway], function(v, k) {
61990             items.selectAll('#preset-input-access-' + k)
61991                 .attr('placeholder', function() { return (tags.access || v); });
61992         });
61993     };
61994
61995
61996     access.focus = function() {
61997         items.selectAll('.preset-input-access')
61998             .node().focus();
61999     };
62000
62001
62002     return utilRebind(access, dispatch$$1, 'on');
62003 }
62004
62005 function uiFieldAddress(field, context) {
62006     var dispatch$$1 = dispatch('init', 'change'),
62007         nominatim = services.geocoder,
62008         wrap = d3_select(null),
62009         isInitialized = false,
62010         entity;
62011
62012     function getNearStreets() {
62013         var extent = entity.extent(context.graph()),
62014             l = extent.center(),
62015             box = geoExtent(l).padByMeters(200);
62016
62017         var streets = context.intersects(box)
62018             .filter(isAddressable)
62019             .map(function(d) {
62020                 var loc = context.projection([
62021                     (extent[0][0] + extent[1][0]) / 2,
62022                     (extent[0][1] + extent[1][1]) / 2]),
62023                     choice = geoChooseEdge(context.childNodes(d), loc, context.projection);
62024                 return {
62025                     title: d.tags.name,
62026                     value: d.tags.name,
62027                     dist: choice.distance
62028                 };
62029             })
62030             .sort(function(a, b) {
62031                 return a.dist - b.dist;
62032             });
62033
62034         return uniqBy(streets, 'value');
62035
62036         function isAddressable(d) {
62037             return d.tags.highway && d.tags.name && d.type === 'way';
62038         }
62039     }
62040
62041
62042     function getNearCities() {
62043         var extent = entity.extent(context.graph()),
62044             l = extent.center(),
62045             box = geoExtent(l).padByMeters(200);
62046
62047         var cities = context.intersects(box)
62048             .filter(isAddressable)
62049             .map(function(d) {
62050                 return {
62051                     title: d.tags['addr:city'] || d.tags.name,
62052                     value: d.tags['addr:city'] || d.tags.name,
62053                     dist: geoSphericalDistance(d.extent(context.graph()).center(), l)
62054                 };
62055             })
62056             .sort(function(a, b) {
62057                 return a.dist - b.dist;
62058             });
62059
62060         return uniqBy(cities, 'value');
62061
62062
62063         function isAddressable(d) {
62064             if (d.tags.name &&
62065                 (d.tags.admin_level === '8' || d.tags.border_type === 'city'))
62066                 return true;
62067
62068             if (d.tags.place && d.tags.name && (
62069                     d.tags.place === 'city' ||
62070                     d.tags.place === 'town' ||
62071                     d.tags.place === 'village'))
62072                 return true;
62073
62074             if (d.tags['addr:city']) return true;
62075
62076             return false;
62077         }
62078     }
62079
62080     function getNearValues(key) {
62081         var extent = entity.extent(context.graph()),
62082             l = extent.center(),
62083             box = geoExtent(l).padByMeters(200);
62084
62085         var results = context.intersects(box)
62086             .filter(function hasTag(d) {
62087                 return d.tags[key];
62088             })
62089             .map(function(d) {
62090                 return {
62091                     title: d.tags[key],
62092                     value: d.tags[key],
62093                     dist: geoSphericalDistance(d.extent(context.graph()).center(), l)
62094                 };
62095             })
62096             .sort(function(a, b) {
62097                 return a.dist - b.dist;
62098             });
62099
62100         return uniqBy(results, 'value');
62101     }
62102
62103
62104     function initCallback(err, countryCode) {
62105         if (err) return;
62106
62107         var addressFormat = find$1(dataAddressFormats, function (a) {
62108             return a && a.countryCodes && includes(a.countryCodes, countryCode.toLowerCase());
62109         }) || dataAddressFormats[0];
62110
62111         var widths = addressFormat.widths || {
62112             housenumber: 1/3, street: 2/3,
62113             city: 2/3, state: 1/4, postcode: 1/3
62114         };
62115
62116         function row(r) {
62117             // Normalize widths.
62118             var total = reduce(r, function(sum, field) {
62119                 return sum + (widths[field] || 0.5);
62120             }, 0);
62121
62122             return r.map(function (field) {
62123                 return {
62124                     id: field,
62125                     width: (widths[field] || 0.5) / total
62126                 };
62127             });
62128         }
62129
62130         wrap.selectAll('div.addr-row')
62131             .data(addressFormat.format)
62132             .enter()
62133             .append('div')
62134             .attr('class', 'addr-row')
62135             .selectAll('input')
62136             .data(row)
62137             .enter()
62138             .append('input')
62139             .property('type', 'text')
62140             .attr('placeholder', function (d) {
62141                 var localkey = d.id + '!' + countryCode.toLowerCase(),
62142                     tkey = field.strings.placeholders[localkey] ? localkey : d.id;
62143                 return field.t('placeholders.' + tkey);
62144             })
62145             .attr('class', function (d) { return 'addr-' + d.id; })
62146             .call(utilNoAuto)
62147             .style('width', function (d) { return d.width * 100 + '%'; });
62148
62149         // Update
62150
62151         // setup dropdowns for common address tags
62152         var dropdowns = addressFormat.dropdowns || [
62153             'city', 'county', 'country', 'district', 'hamlet',
62154             'neighbourhood', 'place', 'postcode', 'province',
62155             'quarter', 'state', 'street', 'subdistrict', 'suburb'
62156         ];
62157
62158         // If fields exist for any of these tags, create dropdowns to pick nearby values..
62159         dropdowns.forEach(function(tag) {
62160             var nearValues = (tag === 'street') ? getNearStreets
62161                     : (tag === 'city') ? getNearCities
62162                     : getNearValues;
62163
62164             wrap.selectAll('input.addr-' + tag)
62165                 .call(d3combobox()
62166                     .container(context.container())
62167                     .minItems(1)
62168                     .fetcher(function(value, callback) {
62169                         callback(nearValues('addr:' + tag));
62170                     })
62171                 );
62172         });
62173
62174         wrap.selectAll('input')
62175             .on('blur', change())
62176             .on('change', change());
62177
62178         wrap.selectAll('input:not(.combobox-input)')
62179             .on('input', change(true));
62180
62181         dispatch$$1.call('init');
62182         isInitialized = true;
62183     }
62184
62185
62186     function address(selection) {
62187         isInitialized = false;
62188
62189         wrap = selection.selectAll('.preset-input-wrap')
62190             .data([0]);
62191
62192         wrap = wrap.enter()
62193             .append('div')
62194             .attr('class', 'preset-input-wrap')
62195             .merge(wrap);
62196
62197         if (nominatim && entity) {
62198             var center = entity.extent(context.graph()).center();
62199             nominatim.countryCode(center, initCallback);
62200         }
62201     }
62202
62203
62204     function change(onInput) {
62205         return function() {
62206             var tags = {};
62207
62208             wrap.selectAll('input')
62209                 .each(function (field) {
62210                     tags['addr:' + field.id] = this.value || undefined;
62211                 });
62212
62213             dispatch$$1.call('change', this, tags, onInput);
62214         };
62215     }
62216
62217
62218     function updateTags(tags) {
62219         utilGetSetValue(wrap.selectAll('input'), function (field) {
62220             return tags['addr:' + field.id] || '';
62221         });
62222     }
62223
62224
62225     address.entity = function(_) {
62226         if (!arguments.length) return entity;
62227         entity = _;
62228         return address;
62229     };
62230
62231
62232     address.tags = function(tags) {
62233         if (isInitialized) {
62234             updateTags(tags);
62235         } else {
62236             dispatch$$1.on('init', function () {
62237                 dispatch$$1.on('init', null);
62238                 updateTags(tags);
62239             });
62240         }
62241     };
62242
62243
62244     address.focus = function() {
62245         var node = wrap.selectAll('input').node();
62246         if (node) node.focus();
62247     };
62248
62249
62250     return utilRebind(address, dispatch$$1, 'on');
62251 }
62252
62253 function uiFieldCycleway(field, context) {
62254     var dispatch$$1 = dispatch('change'),
62255         items = d3_select(null);
62256
62257
62258     function cycleway(selection) {
62259
62260         function stripcolon(s) {
62261             return s.replace(':', '');
62262         }
62263
62264
62265         var wrap = selection.selectAll('.preset-input-wrap')
62266             .data([0]);
62267
62268         wrap = wrap.enter()
62269             .append('div')
62270             .attr('class', 'cf preset-input-wrap')
62271             .merge(wrap);
62272
62273
62274         var div = wrap.selectAll('ul')
62275             .data([0]);
62276
62277         div = div.enter()
62278             .append('ul')
62279             .merge(div);
62280
62281
62282         items = div.selectAll('li')
62283             .data(field.keys);
62284
62285         var enter = items.enter()
62286             .append('li')
62287             .attr('class', function(d) { return 'cf preset-cycleway-' + stripcolon(d); });
62288
62289         enter
62290             .append('span')
62291             .attr('class', 'col6 label preset-label-cycleway')
62292             .attr('for', function(d) { return 'preset-input-cycleway-' + stripcolon(d); })
62293             .text(function(d) { return field.t('types.' + d); });
62294
62295         enter
62296             .append('div')
62297             .attr('class', 'col6 preset-input-cycleway-wrap')
62298             .append('input')
62299             .attr('type', 'text')
62300             .attr('class', function(d) { return 'preset-input-cycleway preset-input-' + stripcolon(d); })
62301             .call(utilNoAuto)
62302             .each(function(d) {
62303                 d3_select(this)
62304                     .call(d3combobox()
62305                         .container(context.container())
62306                         .data(cycleway.options(d))
62307                     );
62308             });
62309
62310
62311         // Update
62312         wrap.selectAll('.preset-input-cycleway')
62313             .on('change', change)
62314             .on('blur', change);
62315     }
62316
62317
62318     function change() {
62319         var left = utilGetSetValue(d3_select('.preset-input-cyclewayleft')),
62320             right = utilGetSetValue(d3_select('.preset-input-cyclewayright')),
62321             tag = {};
62322
62323         if (left === 'none' || left === '') { left = undefined; }
62324         if (right === 'none' || right === '') { right = undefined; }
62325
62326         // Always set both left and right as changing one can affect the other
62327         tag = {
62328             cycleway: undefined,
62329             'cycleway:left': left,
62330             'cycleway:right': right
62331         };
62332
62333         // If the left and right tags match, use the cycleway tag to tag both
62334         // sides the same way
62335         if (left === right) {
62336             tag = {
62337                 cycleway: left,
62338                 'cycleway:left': undefined,
62339                 'cycleway:right': undefined
62340             };
62341         }
62342
62343         dispatch$$1.call('change', this, tag);
62344     }
62345
62346
62347     cycleway.options = function() {
62348         return keys$1(field.strings.options).map(function(option) {
62349             return {
62350                 title: field.t('options.' + option + '.description'),
62351                 value: option
62352             };
62353         });
62354     };
62355
62356
62357     cycleway.tags = function(tags) {
62358         utilGetSetValue(items.selectAll('.preset-input-cycleway'), function(d) {
62359                 // If cycleway is set, always return that
62360                 if (tags.cycleway) {
62361                     return tags.cycleway;
62362                 }
62363                 return tags[d] || '';
62364             })
62365             .attr('placeholder', field.placeholder());
62366     };
62367
62368
62369     cycleway.focus = function() {
62370         items.selectAll('.preset-input-cycleway')
62371             .node().focus();
62372     };
62373
62374
62375     return utilRebind(cycleway, dispatch$$1, 'on');
62376 }
62377
62378 function uiFieldLanes(field, context) {
62379     var dispatch$$1 = dispatch('change'),
62380         LANE_WIDTH = 40,
62381         LANE_HEIGHT = 200,
62382         wayID,
62383         lanesData;
62384
62385     function lanes(selection) {
62386         lanesData = context.entity(wayID).lanes();
62387
62388         if (!d3_select('.inspector-wrap.inspector-hidden').empty() || !selection.node().parentNode) {
62389             selection.call(lanes.off);
62390             return;
62391         }
62392
62393         var wrap = selection.selectAll('.preset-input-wrap')
62394             .data([0]);
62395
62396         wrap = wrap.enter()
62397             .append('div')
62398             .attr('class', 'preset-input-wrap')
62399             .merge(wrap);
62400
62401         var surface =  wrap.selectAll('.surface')
62402             .data([0]);
62403
62404         var d = utilGetDimensions(wrap);
62405         var freeSpace = d[0] - lanesData.lanes.length * LANE_WIDTH * 1.5 + LANE_WIDTH * 0.5;
62406
62407         surface = surface.enter()
62408             .append('svg')
62409             .attr('width', d[0])
62410             .attr('height', 300)
62411             .attr('class', 'surface')
62412             .merge(surface);
62413
62414
62415         var lanesSelection = surface.selectAll('.lanes')
62416             .data([0]);
62417
62418         lanesSelection = lanesSelection.enter()
62419             .append('g')
62420             .attr('class', 'lanes')
62421             .merge(lanesSelection);
62422
62423         lanesSelection
62424             .attr('transform', function () {
62425                 return 'translate(' + (freeSpace / 2) + ', 0)';
62426             });
62427
62428
62429         var lane = lanesSelection.selectAll('.lane')
62430            .data(lanesData.lanes);
62431
62432         lane.exit()
62433             .remove();
62434
62435         var enter = lane.enter()
62436             .append('g')
62437             .attr('class', 'lane');
62438
62439         enter
62440             .append('g')
62441             .append('rect')
62442             .attr('y', 50)
62443             .attr('width', LANE_WIDTH)
62444             .attr('height', LANE_HEIGHT);
62445
62446         enter
62447             .append('g')
62448             .attr('class', 'forward')
62449             .append('text')
62450             .attr('y', 40)
62451             .attr('x', 14)
62452             .text('▲');
62453
62454         enter
62455             .append('g')
62456             .attr('class', 'bothways')
62457             .append('text')
62458             .attr('y', 40)
62459             .attr('x', 14)
62460             .text('▲▼');
62461
62462         enter
62463             .append('g')
62464             .attr('class', 'backward')
62465             .append('text')
62466             .attr('y', 40)
62467             .attr('x', 14)
62468             .text('▼');
62469
62470
62471         lane = lane
62472             .merge(enter);
62473
62474         lane
62475             .attr('transform', function(d) {
62476                 return 'translate(' + (LANE_WIDTH * d.index * 1.5) + ', 0)';
62477             });
62478
62479         lane.select('.forward')
62480             .style('visibility', function(d) {
62481                 return d.direction === 'forward' ? 'visible' : 'hidden';
62482             });
62483
62484         lane.select('.bothways')
62485             .style('visibility', function(d) {
62486                 return d.direction === 'bothways' ? 'visible' : 'hidden';
62487             });
62488
62489         lane.select('.backward')
62490             .style('visibility', function(d) {
62491                 return d.direction === 'backward' ? 'visible' : 'hidden';
62492             });
62493     }
62494
62495
62496     lanes.entity = function(_) {
62497         if (!wayID || wayID !== _.id) {
62498             wayID = _.id;
62499         }
62500     };
62501
62502     lanes.tags = function() {};
62503     lanes.focus = function() {};
62504     lanes.off = function() {};
62505
62506     return utilRebind(lanes, dispatch$$1, 'on');
62507 }
62508
62509 function uiFieldLocalized(field, context) {
62510     var dispatch$$1 = dispatch('change', 'input'),
62511         wikipedia = services.wikipedia,
62512         input = d3_select(null),
62513         localizedInputs = d3_select(null),
62514         wikiTitles,
62515         entity;
62516
62517
62518     function localized(selection) {
62519         input = selection.selectAll('.localized-main')
62520             .data([0]);
62521
62522         input = input.enter()
62523             .append('input')
62524             .attr('type', 'text')
62525             .attr('id', 'preset-input-' + field.id)
62526             .attr('class', 'localized-main')
62527             .attr('placeholder', field.placeholder())
62528             .call(utilNoAuto)
62529             .merge(input);
62530
62531         if (field.id === 'name') {
62532             var preset = context.presets().match(entity, context.graph());
62533             input
62534                 .call(d3combobox()
62535                     .container(context.container())
62536                     .fetcher(utilSuggestNames(preset, dataSuggestions))
62537                 );
62538         }
62539
62540         input
62541             .on('input', change(true))
62542             .on('blur', change())
62543             .on('change', change());
62544
62545
62546         var translateButton = selection.selectAll('.localized-add')
62547             .data([0]);
62548
62549         translateButton = translateButton.enter()
62550             .append('button')
62551             .attr('class', 'button-input-action localized-add minor')
62552             .attr('tabindex', -1)
62553             .call(svgIcon('#icon-plus'))
62554             .call(tooltip()
62555                 .title(t('translate.translate'))
62556                 .placement('left'))
62557             .merge(translateButton);
62558
62559         translateButton
62560             .on('click', addNew);
62561
62562
62563         localizedInputs = selection.selectAll('.localized-wrap')
62564             .data([0]);
62565
62566         localizedInputs = localizedInputs.enter().append('div')
62567             .attr('class', 'localized-wrap')
62568             .merge(localizedInputs);
62569     }
62570
62571
62572     function addNew() {
62573         event.preventDefault();
62574         var data$$1 = localizedInputs.selectAll('div.entry').data();
62575         var defaultLang = utilDetect().locale.toLowerCase().split('-')[0];
62576         var langExists = find$1(data$$1, function(datum) { return datum.lang === defaultLang;});
62577         var isLangEn = defaultLang.indexOf('en') > -1;
62578         if (isLangEn || langExists) {
62579             defaultLang = '';
62580         }
62581         data$$1.push({ lang: defaultLang, value: '' });
62582         localizedInputs.call(render, data$$1);
62583     }
62584
62585
62586     function change(onInput) {
62587         return function() {
62588             var t$$1 = {};
62589             t$$1[field.key] = utilGetSetValue(d3_select(this)) || undefined;
62590             dispatch$$1.call('change', this, t$$1, onInput);
62591         };
62592     }
62593
62594
62595     function key(lang) {
62596         return field.key + ':' + lang;
62597     }
62598
62599
62600     function changeLang(d) {
62601         var lang = utilGetSetValue(d3_select(this)),
62602             t$$1 = {},
62603             language = find$1(wikipedia$2, function(d) {
62604                 return d[0].toLowerCase() === lang.toLowerCase() ||
62605                     d[1].toLowerCase() === lang.toLowerCase();
62606             });
62607
62608         if (language) lang = language[2];
62609
62610         if (d.lang && d.lang !== lang) {
62611             t$$1[key(d.lang)] = undefined;
62612         }
62613
62614         var value = utilGetSetValue(d3_select(this.parentNode)
62615             .selectAll('.localized-value'));
62616
62617         if (lang && value) {
62618             t$$1[key(lang)] = value;
62619         } else if (lang && wikiTitles && wikiTitles[d.lang]) {
62620             t$$1[key(lang)] = wikiTitles[d.lang];
62621         }
62622
62623         d.lang = lang;
62624         dispatch$$1.call('change', this, t$$1);
62625     }
62626
62627
62628     function changeValue(d) {
62629         if (!d.lang) return;
62630         var t$$1 = {};
62631         t$$1[key(d.lang)] = utilGetSetValue(d3_select(this)) || undefined;
62632         dispatch$$1.call('change', this, t$$1);
62633     }
62634
62635
62636     function fetcher(value, cb) {
62637         var v = value.toLowerCase();
62638
62639         cb(wikipedia$2.filter(function(d) {
62640             return d[0].toLowerCase().indexOf(v) >= 0 ||
62641             d[1].toLowerCase().indexOf(v) >= 0 ||
62642             d[2].toLowerCase().indexOf(v) >= 0;
62643         }).map(function(d) {
62644             return { value: d[1] };
62645         }));
62646     }
62647
62648
62649     function render(selection, data$$1) {
62650         var wraps = selection.selectAll('div.entry').
62651             data(data$$1, function(d) { return d.lang; });
62652
62653         wraps.exit()
62654             .transition()
62655             .duration(200)
62656             .style('max-height','0px')
62657             .style('opacity', '0')
62658             .style('top','-10px')
62659             .remove();
62660
62661         var innerWrap = wraps.enter()
62662             .insert('div', ':first-child');
62663
62664         innerWrap.attr('class', 'entry')
62665             .each(function() {
62666                 var wrap = d3_select(this);
62667                 var langcombo = d3combobox()
62668                     .container(context.container())
62669                     .fetcher(fetcher)
62670                     .minItems(0);
62671
62672                 var label = wrap
62673                     .append('label')
62674                     .attr('class','form-label')
62675                     .text(t('translate.localized_translation_label'))
62676                     .attr('for','localized-lang');
62677
62678                 label
62679                     .append('button')
62680                     .attr('class', 'minor remove')
62681                     .on('click', function(d){
62682                         event.preventDefault();
62683                         var t$$1 = {};
62684                         t$$1[key(d.lang)] = undefined;
62685                         dispatch$$1.call('change', this, t$$1);
62686                         d3_select(this.parentNode.parentNode)
62687                             .style('top','0')
62688                             .style('max-height','240px')
62689                             .transition()
62690                             .style('opacity', '0')
62691                             .style('max-height','0px')
62692                             .remove();
62693                     })
62694                     .call(svgIcon('#operation-delete'));
62695
62696                 wrap
62697                     .append('input')
62698                     .attr('class', 'localized-lang')
62699                     .attr('type', 'text')
62700                     .attr('placeholder',t('translate.localized_translation_language'))
62701                     .on('blur', changeLang)
62702                     .on('change', changeLang)
62703                     .call(langcombo);
62704
62705                 wrap
62706                     .append('input')
62707                     .on('blur', changeValue)
62708                     .on('change', changeValue)
62709                     .attr('type', 'text')
62710                     .attr('placeholder', t('translate.localized_translation_name'))
62711                     .attr('class', 'localized-value');
62712             });
62713
62714         innerWrap
62715             .style('margin-top', '0px')
62716             .style('max-height', '0px')
62717             .style('opacity', '0')
62718             .transition()
62719             .duration(200)
62720             .style('margin-top', '10px')
62721             .style('max-height', '240px')
62722             .style('opacity', '1')
62723             .on('end', function() {
62724                 d3_select(this)
62725                     .style('max-height', '')
62726                     .style('overflow', 'visible');
62727             });
62728
62729
62730         var entry = selection.selectAll('.entry');
62731
62732         utilGetSetValue(entry.select('.localized-lang'), function(d) {
62733                 var lang = find$1(wikipedia$2, function(lang) { return lang[2] === d.lang; });
62734                 return lang ? lang[1] : d.lang;
62735             });
62736
62737         utilGetSetValue(entry.select('.localized-value'),
62738             function(d) { return d.value; });
62739     }
62740
62741
62742     localized.tags = function(tags) {
62743         // Fetch translations from wikipedia
62744         if (tags.wikipedia && !wikiTitles) {
62745             wikiTitles = {};
62746             var wm = tags.wikipedia.match(/([^:]+):(.+)/);
62747             if (wm && wm[0] && wm[1]) {
62748                 wikipedia.translations(wm[1], wm[2], function(d) {
62749                     wikiTitles = d;
62750                 });
62751             }
62752         }
62753
62754         utilGetSetValue(input, tags[field.key] || '');
62755
62756         var postfixed = [], k, m;
62757         for (k in tags) {
62758             m = k.match(/^(.*):([a-zA-Z_-]+)$/);
62759             if (m && m[1] === field.key && m[2]) {
62760                 postfixed.push({ lang: m[2], value: tags[k] });
62761             }
62762         }
62763
62764         localizedInputs.call(render, postfixed.reverse());
62765     };
62766
62767
62768     localized.focus = function() {
62769         input.node().focus();
62770     };
62771
62772
62773     localized.entity = function(_) {
62774         if (!arguments.length) return entity;
62775         entity = _;
62776         return localized;
62777     };
62778
62779     return utilRebind(localized, dispatch$$1, 'on');
62780 }
62781
62782 function uiFieldMaxspeed(field, context) {
62783     var dispatch$$1 = dispatch('change'),
62784         entity,
62785         isImperial,
62786         unitInput = d3_select(null),
62787         input = d3_select(null),
62788         combobox;
62789
62790     var metricValues = [20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120],
62791         imperialValues = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80];
62792
62793
62794     function maxspeed(selection) {
62795         combobox = d3combobox()
62796             .container(context.container());
62797
62798         var unitCombobox = d3combobox()
62799             .container(context.container())
62800             .data(['km/h', 'mph'].map(comboValues));
62801
62802         input = selection.selectAll('#preset-input-' + field.id)
62803             .data([0]);
62804
62805         input = input.enter()
62806             .append('input')
62807             .attr('type', 'text')
62808             .attr('id', 'preset-input-' + field.id)
62809             .attr('placeholder', field.placeholder())
62810             .call(utilNoAuto)
62811             .call(combobox)
62812             .merge(input);
62813
62814         input
62815             .on('change', change)
62816             .on('blur', change);
62817
62818         var childNodes = context.graph().childNodes(context.entity(entity.id)),
62819             loc = childNodes[~~(childNodes.length/2)].loc;
62820
62821         isImperial = some(dataImperial.features, function(f) {
62822             return some(f.geometry.coordinates, function(d) {
62823                 return geoPointInPolygon(loc, d);
62824             });
62825         });
62826
62827         unitInput = selection.selectAll('input.maxspeed-unit')
62828             .data([0]);
62829
62830         unitInput = unitInput.enter()
62831             .append('input')
62832             .attr('type', 'text')
62833             .attr('class', 'maxspeed-unit')
62834             .call(unitCombobox)
62835             .merge(unitInput);
62836
62837         unitInput
62838             .on('blur', changeUnits)
62839             .on('change', changeUnits);
62840
62841
62842         function changeUnits() {
62843             isImperial = utilGetSetValue(unitInput) === 'mph';
62844             utilGetSetValue(unitInput, isImperial ? 'mph' : 'km/h');
62845             setSuggestions();
62846             change();
62847         }
62848     }
62849
62850
62851     function setSuggestions() {
62852         combobox.data((isImperial ? imperialValues : metricValues).map(comboValues));
62853         utilGetSetValue(unitInput, isImperial ? 'mph' : 'km/h');
62854     }
62855
62856
62857     function comboValues(d) {
62858         return {
62859             value: d.toString(),
62860             title: d.toString()
62861         };
62862     }
62863
62864
62865     function change() {
62866         var tag = {},
62867             value = utilGetSetValue(input);
62868
62869         if (!value) {
62870             tag[field.key] = undefined;
62871         } else if (isNaN(value) || !isImperial) {
62872             tag[field.key] = value;
62873         } else {
62874             tag[field.key] = value + ' mph';
62875         }
62876
62877         dispatch$$1.call('change', this, tag);
62878     }
62879
62880
62881     maxspeed.tags = function(tags) {
62882         var value = tags[field.key];
62883
62884         if (value && value.indexOf('mph') >= 0) {
62885             value = parseInt(value, 10);
62886             isImperial = true;
62887         } else if (value) {
62888             isImperial = false;
62889         }
62890
62891         setSuggestions();
62892         utilGetSetValue(input, value || '');
62893     };
62894
62895
62896     maxspeed.focus = function() {
62897         input.node().focus();
62898     };
62899
62900
62901     maxspeed.entity = function(_) {
62902         entity = _;
62903     };
62904
62905
62906     return utilRebind(maxspeed, dispatch$$1, 'on');
62907 }
62908
62909 /**
62910  * This function is like `baseIndexOf` except that it accepts a comparator.
62911  *
62912  * @private
62913  * @param {Array} array The array to inspect.
62914  * @param {*} value The value to search for.
62915  * @param {number} fromIndex The index to search from.
62916  * @param {Function} comparator The comparator invoked per element.
62917  * @returns {number} Returns the index of the matched value, else `-1`.
62918  */
62919 function baseIndexOfWith(array, value, fromIndex, comparator) {
62920   var index = fromIndex - 1,
62921       length = array.length;
62922
62923   while (++index < length) {
62924     if (comparator(array[index], value)) {
62925       return index;
62926     }
62927   }
62928   return -1;
62929 }
62930
62931 /** Used for built-in method references. */
62932 var arrayProto$2 = Array.prototype;
62933
62934 /** Built-in value references. */
62935 var splice$2 = arrayProto$2.splice;
62936
62937 /**
62938  * The base implementation of `_.pullAllBy` without support for iteratee
62939  * shorthands.
62940  *
62941  * @private
62942  * @param {Array} array The array to modify.
62943  * @param {Array} values The values to remove.
62944  * @param {Function} [iteratee] The iteratee invoked per element.
62945  * @param {Function} [comparator] The comparator invoked per element.
62946  * @returns {Array} Returns `array`.
62947  */
62948 function basePullAll(array, values, iteratee, comparator) {
62949   var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
62950       index = -1,
62951       length = values.length,
62952       seen = array;
62953
62954   if (array === values) {
62955     values = copyArray(values);
62956   }
62957   if (iteratee) {
62958     seen = arrayMap(array, baseUnary(iteratee));
62959   }
62960   while (++index < length) {
62961     var fromIndex = 0,
62962         value = values[index],
62963         computed = iteratee ? iteratee(value) : value;
62964
62965     while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
62966       if (seen !== array) {
62967         splice$2.call(seen, fromIndex, 1);
62968       }
62969       splice$2.call(array, fromIndex, 1);
62970     }
62971   }
62972   return array;
62973 }
62974
62975 /**
62976  * This method is like `_.pull` except that it accepts an array of values to remove.
62977  *
62978  * **Note:** Unlike `_.difference`, this method mutates `array`.
62979  *
62980  * @static
62981  * @memberOf _
62982  * @since 4.0.0
62983  * @category Array
62984  * @param {Array} array The array to modify.
62985  * @param {Array} values The values to remove.
62986  * @returns {Array} Returns `array`.
62987  * @example
62988  *
62989  * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
62990  *
62991  * _.pullAll(array, ['a', 'c']);
62992  * console.log(array);
62993  * // => ['b', 'b']
62994  */
62995 function pullAll(array, values) {
62996   return (array && array.length && values && values.length)
62997     ? basePullAll(array, values)
62998     : array;
62999 }
63000
63001 /**
63002  * Removes all given values from `array` using
63003  * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
63004  * for equality comparisons.
63005  *
63006  * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
63007  * to remove elements from an array by predicate.
63008  *
63009  * @static
63010  * @memberOf _
63011  * @since 2.0.0
63012  * @category Array
63013  * @param {Array} array The array to modify.
63014  * @param {...*} [values] The values to remove.
63015  * @returns {Array} Returns `array`.
63016  * @example
63017  *
63018  * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
63019  *
63020  * _.pull(array, 'a', 'c');
63021  * console.log(array);
63022  * // => ['b', 'b']
63023  */
63024 var pull = baseRest(pullAll);
63025
63026 function uiFieldRadio(field, context) {
63027     var dispatch$$1 = dispatch('change'),
63028         placeholder = d3_select(null),
63029         wrap = d3_select(null),
63030         labels = d3_select(null),
63031         radios = d3_select(null),
63032         radioData = clone(field.options || field.keys),
63033         typeField,
63034         layerField,
63035         oldType = {},
63036         entity;
63037
63038
63039     function selectedKey() {
63040         var node = wrap.selectAll('.toggle-list label.active input');
63041         return !node.empty() && node.datum();
63042     }
63043
63044
63045     function radio(selection) {
63046         selection.classed('preset-radio', true);
63047
63048         wrap = selection.selectAll('.preset-input-wrap')
63049             .data([0]);
63050
63051         var enter = wrap.enter()
63052             .append('div')
63053             .attr('class', 'preset-input-wrap toggle-list');
63054
63055         enter
63056             .append('span')
63057             .attr('class', 'placeholder');
63058
63059         wrap = wrap
63060             .merge(enter);
63061
63062
63063         placeholder = wrap.selectAll('.placeholder');
63064
63065         labels = wrap.selectAll('label')
63066             .data(radioData);
63067
63068         enter = labels.enter()
63069             .append('label');
63070
63071         enter
63072             .append('input')
63073             .attr('type', 'radio')
63074             .attr('name', field.id)
63075             .attr('value', function(d) { return field.t('options.' + d, { 'default': d }); })
63076             .attr('checked', false);
63077
63078         enter
63079             .append('span')
63080             .text(function(d) { return field.t('options.' + d, { 'default': d }); });
63081
63082         labels = labels
63083             .merge(enter);
63084
63085         radios = labels.selectAll('input')
63086             .on('change', changeRadio);
63087
63088     }
63089
63090
63091     function structureExtras(selection, tags) {
63092         var selected = selectedKey(),
63093             type = context.presets().field(selected),
63094             layer = context.presets().field('layer'),
63095             showLayer = (selected === 'bridge' || selected === 'tunnel');
63096
63097
63098         var extrasWrap = selection.selectAll('.structure-extras-wrap')
63099             .data(selected ? [0] : []);
63100
63101         extrasWrap.exit()
63102             .remove();
63103
63104         extrasWrap = extrasWrap.enter()
63105             .append('div')
63106             .attr('class', 'structure-extras-wrap')
63107             .merge(extrasWrap);
63108
63109         var list = extrasWrap.selectAll('ul')
63110             .data([0]);
63111
63112         list = list.enter()
63113             .append('ul')
63114             .merge(list);
63115
63116
63117         // Type
63118         if (type) {
63119             if (!typeField || typeField.id !== selected) {
63120                 typeField = uiField(context, type, entity, { wrap: false })
63121                     .on('change', changeType);
63122             }
63123             typeField.tags(tags);
63124         } else {
63125             typeField = null;
63126         }
63127
63128         var typeItem = list.selectAll('.structure-type-item')
63129             .data(typeField ? [typeField] : [], function(d) { return d.id; });
63130
63131         // Exit
63132         typeItem.exit()
63133             .remove();
63134
63135         // Enter
63136         var typeEnter = typeItem.enter()
63137             .insert('li', ':first-child')
63138             .attr('class', 'cf structure-type-item');
63139
63140         typeEnter
63141             .append('span')
63142             .attr('class', 'col6 label structure-label-type')
63143             .attr('for', 'preset-input-' + selected)
63144             .text(t('inspector.radio.structure.type'));
63145
63146         typeEnter
63147             .append('div')
63148             .attr('class', 'col6 structure-input-type-wrap');
63149
63150         // Update
63151         typeItem = typeItem
63152             .merge(typeEnter);
63153
63154         if (typeField) {
63155             typeItem.selectAll('.structure-input-type-wrap')
63156                 .call(typeField.render);
63157         }
63158
63159
63160         // Layer
63161         if (layer && showLayer) {
63162             if (!layerField) {
63163                 layerField = uiField(context, layer, entity, { wrap: false })
63164                     .on('change', changeLayer);
63165             }
63166             layerField.tags(tags);
63167             field.keys = union(field.keys, ['layer']);
63168         } else {
63169             layerField = null;
63170             pull(field.keys, 'layer');
63171         }
63172
63173         var layerItem = list.selectAll('.structure-layer-item')
63174             .data(layerField ? [layerField] : []);
63175
63176         // Exit
63177         layerItem.exit()
63178             .remove();
63179
63180         // Enter
63181         var layerEnter = layerItem.enter()
63182             .append('li')
63183             .attr('class', 'cf structure-layer-item');
63184
63185         layerEnter
63186             .append('span')
63187             .attr('class', 'col6 label structure-label-layer')
63188             .attr('for', 'preset-input-layer')
63189             .text(t('inspector.radio.structure.layer'));
63190
63191         layerEnter
63192             .append('div')
63193             .attr('class', 'col6 structure-input-layer-wrap');
63194
63195         // Update
63196         layerItem = layerItem
63197             .merge(layerEnter);
63198
63199         if (layerField) {
63200             layerItem.selectAll('.structure-input-layer-wrap')
63201                 .call(layerField.render);
63202         }
63203     }
63204
63205
63206     function changeType(t$$1, onInput) {
63207         var key = selectedKey();
63208         if (!key) return;
63209
63210         var val = t$$1[key];
63211         if (val !== 'no') {
63212             oldType[key] = val;
63213         }
63214
63215         if (field.type === 'structureRadio') {
63216             // remove layer if it should not be set
63217             if (val === 'no' ||
63218                 (key !== 'bridge' && key !== 'tunnel') ||
63219                 (key === 'tunnel' && val === 'building_passage')) {
63220                 t$$1.layer = undefined;
63221             }
63222             // add layer if it should be set
63223             if (t$$1.layer === undefined) {
63224                 if (key === 'bridge' && val !== 'no') {
63225                     t$$1.layer = '1';
63226                 }
63227                 if (key === 'tunnel' && val !== 'no' && val !== 'building_passage') {
63228                     t$$1.layer = '-1';
63229                 }
63230             }
63231          }
63232
63233         dispatch$$1.call('change', this, t$$1, onInput);
63234     }
63235
63236
63237     function changeLayer(t$$1, onInput) {
63238         if (t$$1.layer === '0') {
63239             t$$1.layer = undefined;
63240         }
63241         dispatch$$1.call('change', this, t$$1, onInput);
63242     }
63243
63244
63245     function changeRadio() {
63246         var t$$1 = {},
63247             activeKey;
63248
63249         if (field.key) {
63250             t$$1[field.key] = undefined;
63251         }
63252
63253         radios.each(function(d) {
63254             var active = d3_select(this).property('checked');
63255             if (active) activeKey = d;
63256
63257             if (field.key) {
63258                 if (active) t$$1[field.key] = d;
63259             } else {
63260                 var val = oldType[activeKey] || 'yes';
63261                 t$$1[d] = active ? val : undefined;
63262             }
63263         });
63264
63265         if (field.type === 'structureRadio') {
63266             if (activeKey === 'bridge') {
63267                 t$$1.layer = '1';
63268             } else if (activeKey === 'tunnel' && t$$1.tunnel !== 'building_passage') {
63269                 t$$1.layer = '-1';
63270             } else {
63271                 t$$1.layer = undefined;
63272             }
63273         }
63274
63275         dispatch$$1.call('change', this, t$$1);
63276     }
63277
63278
63279     radio.tags = function(tags) {
63280         function checked(d) {
63281             if (field.key) {
63282                 return tags[field.key] === d;
63283             } else {
63284                 return !!(tags[d] && tags[d].toLowerCase() !== 'no');
63285             }
63286         }
63287
63288         labels.classed('active', checked);
63289         radios.property('checked', checked);
63290
63291         var selection = radios.filter(function() { return this.checked; });
63292
63293         if (selection.empty()) {
63294             placeholder.text(t('inspector.none'));
63295         } else {
63296             placeholder.text(selection.attr('value'));
63297             oldType[selection.datum()] = tags[selection.datum()];
63298         }
63299
63300         if (field.type === 'structureRadio') {
63301             // For waterways without a tunnel tag, set 'culvert' as
63302             // the oldType to default to if the user picks 'tunnel'
63303             if (!!tags.waterway && !oldType.tunnel) {
63304                 oldType.tunnel = 'culvert';
63305             }
63306
63307             wrap.call(structureExtras, tags);
63308         }
63309     };
63310
63311
63312     radio.focus = function() {
63313         radios.node().focus();
63314     };
63315
63316
63317     radio.entity = function(_) {
63318         if (!arguments.length) return entity;
63319         entity = _;
63320         oldType = {};
63321         return radio;
63322     };
63323
63324
63325     return utilRebind(radio, dispatch$$1, 'on');
63326 }
63327
63328 function uiFieldRestrictions(field, context) {
63329     var dispatch$$1 = dispatch('change');
63330     var breathe = behaviorBreathe(context);
63331     var hover = behaviorHover(context);
63332     var initialized = false;
63333     var vertexID;
63334     var fromNodeID;
63335
63336
63337     function restrictions(selection) {
63338         // if form field is hidden or has detached from dom, clean up.
63339         if (!d3_select('.inspector-wrap.inspector-hidden').empty() || !selection.node().parentNode) {
63340             selection.call(restrictions.off);
63341             return;
63342         }
63343
63344         var wrap = selection.selectAll('.preset-input-wrap')
63345             .data([0]);
63346
63347         var enter = wrap.enter()
63348             .append('div')
63349             .attr('class', 'preset-input-wrap');
63350
63351         enter
63352             .append('div')
63353             .attr('class', 'restriction-help');
63354
63355
63356         var intersection = osmIntersection(context.graph(), vertexID);
63357         var graph = intersection.graph;
63358         var vertex = graph.entity(vertexID);
63359         var filter = utilFunctor(true);
63360         var projection = geoRawMercator();
63361
63362         var d = utilGetDimensions(wrap.merge(enter));
63363         var c = [d[0] / 2, d[1] / 2];
63364         var z = 24;
63365
63366         projection
63367             .scale(geoZoomToScale(z));
63368
63369         var s = projection(vertex.loc);
63370
63371         projection
63372             .translate([c[0] - s[0], c[1] - s[1]])
63373             .clipExtent([[0, 0], d]);
63374
63375         var extent = geoExtent(projection.invert([0, d[1]]), projection.invert([d[0], 0]));
63376
63377         var drawLayers = svgLayers(projection, context).only('osm').dimensions(d);
63378         var drawVertices = svgVertices(projection, context);
63379         var drawLines = svgLines(projection, context);
63380         var drawTurns = svgTurns(projection, context);
63381
63382         enter
63383             .call(drawLayers);
63384
63385         wrap = wrap
63386             .merge(enter);
63387
63388         var surface = wrap.selectAll('.surface');
63389
63390         if (!enter.empty()) {
63391             initialized = true;
63392             surface
63393                 .call(breathe)
63394                 .call(hover);
63395         }
63396
63397         surface
63398             .call(utilSetDimensions, d)
63399             .call(drawVertices, graph, [vertex], filter, extent, true)
63400             .call(drawLines, graph, intersection.ways, filter)
63401             .call(drawTurns, graph, intersection.turns(fromNodeID));
63402
63403         surface
63404             .on('click.restrictions', click)
63405             .on('mouseover.restrictions', mouseover)
63406             .on('mouseout.restrictions', mouseout);
63407
63408         surface
63409             .selectAll('.selected')
63410             .classed('selected', false);
63411
63412         if (fromNodeID) {
63413             surface
63414                 .selectAll('.' + intersection.highways[fromNodeID].id)
63415                 .classed('selected', true);
63416         }
63417
63418         mouseout();
63419
63420         context.history()
63421             .on('change.restrictions', render);
63422
63423         d3_select(window)
63424             .on('resize.restrictions', function() {
63425                 utilSetDimensions(wrap, null);
63426                 render();
63427             });
63428
63429
63430         function click() {
63431             surface
63432                 .call(breathe.off)
63433                 .call(breathe);
63434
63435             var datum = event.target.__data__;
63436             var entity = datum && datum.properties && datum.properties.entity;
63437             if (entity) datum = entity;
63438
63439             if (datum instanceof osmEntity) {
63440                 fromNodeID = intersection.adjacentNodeId(datum.id);
63441                 render();
63442
63443             } else if (datum instanceof osmTurn) {
63444                 if (datum.restriction) {
63445                     context.perform(
63446                         actionUnrestrictTurn(datum, projection),
63447                         t('operations.restriction.annotation.delete')
63448                     );
63449                 } else {
63450                     context.perform(
63451                         actionRestrictTurn(datum, projection),
63452                         t('operations.restriction.annotation.create')
63453                     );
63454                 }
63455             }
63456         }
63457
63458
63459         function mouseover() {
63460             var datum = event.target.__data__;
63461             if (datum instanceof osmTurn) {
63462                 var graph = context.graph();
63463                 var presets = context.presets();
63464                 var preset;
63465
63466                 if (datum.restriction) {
63467                     preset = presets.match(graph.entity(datum.restriction), graph);
63468                 } else {
63469                     preset = presets.item('type/restriction/' +
63470                         osmInferRestriction(
63471                             graph,
63472                             datum.from,
63473                             datum.via,
63474                             datum.to,
63475                             projection
63476                         )
63477                     );
63478                 }
63479
63480                 wrap.selectAll('.restriction-help')
63481                     .text(t('operations.restriction.help.' +
63482                         (datum.restriction ? 'toggle_off' : 'toggle_on'),
63483                         { restriction: preset.name() })
63484                     );
63485             }
63486         }
63487
63488
63489         function mouseout() {
63490             wrap.selectAll('.restriction-help')
63491                 .text(t('operations.restriction.help.' +
63492                     (fromNodeID ? 'toggle' : 'select'))
63493                 );
63494         }
63495
63496
63497         function render() {
63498             if (context.hasEntity(vertexID)) {
63499                 restrictions(selection);
63500             }
63501         }
63502     }
63503
63504
63505     restrictions.entity = function(_) {
63506         if (!vertexID || vertexID !== _.id) {
63507             fromNodeID = null;
63508             vertexID = _.id;
63509         }
63510     };
63511
63512
63513     restrictions.tags = function() {};
63514     restrictions.focus = function() {};
63515
63516
63517     restrictions.off = function(selection) {
63518         if (!initialized) return;
63519
63520         selection.selectAll('.surface')
63521             .call(hover.off)
63522             .call(breathe.off)
63523             .on('click.restrictions', null)
63524             .on('mouseover.restrictions', null)
63525             .on('mouseout.restrictions', null);
63526
63527         context.history()
63528             .on('change.restrictions', null);
63529
63530         d3_select(window)
63531             .on('resize.restrictions', null);
63532     };
63533
63534
63535     return utilRebind(restrictions, dispatch$$1, 'on');
63536 }
63537
63538 function uiFieldTextarea(field) {
63539     var dispatch$$1 = dispatch('change'),
63540         input = d3_select(null);
63541
63542
63543     function textarea(selection) {
63544         input = selection.selectAll('textarea')
63545             .data([0]);
63546
63547         input = input.enter()
63548             .append('textarea')
63549             .attr('id', 'preset-input-' + field.id)
63550             .attr('placeholder', field.placeholder() || t('inspector.unknown'))
63551             .attr('maxlength', 255)
63552             .call(utilNoAuto)
63553             .on('input', change(true))
63554             .on('blur', change())
63555             .on('change', change())
63556             .merge(input);
63557     }
63558
63559
63560     function change(onInput) {
63561         return function() {
63562             var t$$1 = {};
63563             t$$1[field.key] = utilGetSetValue(input) || undefined;
63564             dispatch$$1.call('change', this, t$$1, onInput);
63565         };
63566     }
63567
63568
63569     textarea.tags = function(tags) {
63570         utilGetSetValue(input, tags[field.key] || '');
63571     };
63572
63573
63574     textarea.focus = function() {
63575         input.node().focus();
63576     };
63577
63578
63579     return utilRebind(textarea, dispatch$$1, 'on');
63580 }
63581
63582 function uiFieldWikipedia(field, context) {
63583     var dispatch$$1 = dispatch('change'),
63584         wikipedia = services.wikipedia,
63585         wikidata = services.wikidata,
63586         link = d3_select(null),
63587         lang = d3_select(null),
63588         title = d3_select(null),
63589         wikiURL = '',
63590         entity;
63591
63592
63593     function wiki(selection) {
63594         var langcombo = d3combobox()
63595             .container(context.container())
63596             .fetcher(function(value, cb) {
63597                 var v = value.toLowerCase();
63598
63599                 cb(wikipedia$2.filter(function(d) {
63600                     return d[0].toLowerCase().indexOf(v) >= 0 ||
63601                         d[1].toLowerCase().indexOf(v) >= 0 ||
63602                         d[2].toLowerCase().indexOf(v) >= 0;
63603                 }).map(function(d) {
63604                     return { value: d[1] };
63605                 }));
63606             });
63607
63608         var titlecombo = d3combobox()
63609             .container(context.container())
63610             .fetcher(function(value, cb) {
63611                 if (!value) {
63612                     value = context.entity(entity.id).tags.name || '';
63613                 }
63614
63615                 var searchfn = value.length > 7 ? wikipedia.search : wikipedia.suggestions;
63616                 searchfn(language()[2], value, function(query, data$$1) {
63617                     cb(data$$1.map(function(d) {
63618                         return { value: d };
63619                     }));
63620                 });
63621             });
63622
63623
63624         lang = selection.selectAll('input.wiki-lang')
63625             .data([0]);
63626
63627         lang = lang.enter()
63628             .append('input')
63629             .attr('type', 'text')
63630             .attr('class', 'wiki-lang')
63631             .attr('placeholder', t('translate.localized_translation_language'))
63632             .call(utilNoAuto)
63633             .merge(lang);
63634
63635         utilGetSetValue(lang, language()[1]);
63636
63637         lang
63638             .call(langcombo)
63639             .on('blur', changeLang)
63640             .on('change', changeLang);
63641
63642
63643         title = selection.selectAll('input.wiki-title')
63644             .data([0]);
63645
63646         title = title.enter()
63647             .append('input')
63648             .attr('type', 'text')
63649             .attr('class', 'wiki-title')
63650             .attr('id', 'preset-input-' + field.id)
63651             .call(utilNoAuto)
63652             .merge(title);
63653
63654         title
63655             .call(titlecombo)
63656             .on('blur', blur)
63657             .on('change', change);
63658
63659
63660         link = selection.selectAll('.wiki-link')
63661             .data([0]);
63662
63663         link = link.enter()
63664             .append('button')
63665             .attr('class', 'button-input-action wiki-link minor')
63666             .attr('tabindex', -1)
63667             .call(svgIcon('#icon-out-link'))
63668             .merge(link);
63669
63670         link
63671             .on('click', function() {
63672                 event.preventDefault();
63673                 if (wikiURL) window.open(wikiURL, '_blank');
63674             });
63675     }
63676
63677
63678     function language() {
63679         var value = utilGetSetValue(lang).toLowerCase();
63680         var locale = utilDetect().locale.toLowerCase();
63681         var localeLanguage;
63682         return find$1(wikipedia$2, function(d) {
63683             if (d[2] === locale) localeLanguage = d;
63684             return d[0].toLowerCase() === value ||
63685                 d[1].toLowerCase() === value ||
63686                 d[2] === value;
63687         }) || localeLanguage || ['English', 'English', 'en'];
63688     }
63689
63690
63691     function changeLang() {
63692         utilGetSetValue(lang, language()[1]);
63693         change(true);
63694     }
63695
63696
63697     function blur() {
63698         change(true);
63699     }
63700
63701
63702     function change(skipWikidata) {
63703         var value = utilGetSetValue(title),
63704             m = value.match(/https?:\/\/([-a-z]+)\.wikipedia\.org\/(?:wiki|\1-[-a-z]+)\/([^#]+)(?:#(.+))?/),
63705             l = m && find$1(wikipedia$2, function(d) { return m[1] === d[2]; }),
63706             syncTags = {};
63707
63708         if (l) {
63709             // Normalize title http://www.mediawiki.org/wiki/API:Query#Title_normalization
63710             value = decodeURIComponent(m[2]).replace(/_/g, ' ');
63711             if (m[3]) {
63712                 var anchor;
63713                 try {
63714                     // Best-effort `anchordecode:` implementation
63715                     anchor = decodeURIComponent(m[3].replace(/\.([0-9A-F]{2})/g, '%$1'));
63716                 } catch (e) {
63717                     anchor = decodeURIComponent(m[3]);
63718                 }
63719                 value += '#' + anchor.replace(/_/g, ' ');
63720             }
63721             value = value.slice(0, 1).toUpperCase() + value.slice(1);
63722             utilGetSetValue(lang, l[1]);
63723             utilGetSetValue(title, value);
63724         }
63725
63726         if (value) {
63727             syncTags.wikipedia = language()[2] + ':' + value;
63728         } else {
63729             syncTags.wikipedia = undefined;
63730             syncTags.wikidata = undefined;
63731         }
63732
63733         dispatch$$1.call('change', this, syncTags);
63734
63735
63736         if (skipWikidata || !value || !language()[2]) return;
63737
63738         // attempt asynchronous update of wikidata tag..
63739         var initGraph = context.graph(),
63740             initEntityId = entity.id;
63741
63742         wikidata.itemsByTitle(language()[2], value, function(title, data$$1) {
63743             // If graph has changed, we can't apply this update.
63744             if (context.graph() !== initGraph) return;
63745
63746             if (!data$$1 || !Object.keys(data$$1).length) return;
63747
63748             var qids = Object.keys(data$$1);
63749             var value = qids && find$1(qids, function(id) { return id.match(/^Q\d+$/); });
63750             var currTags = clone(context.entity(initEntityId).tags);
63751
63752             currTags.wikidata = value;
63753
63754             // Coalesce the update of wikidata tag into the previous tag change
63755             context.overwrite(
63756                 actionChangeTags(initEntityId, currTags),
63757                 context.history().undoAnnotation()
63758             );
63759
63760             // do not dispatch.call('change') here, because entity_editor
63761             // changeTags() is not intended to be called asynchronously
63762         });
63763     }
63764
63765
63766     wiki.tags = function(tags) {
63767         var value = tags[field.key] || '',
63768             m = value.match(/([^:]+):([^#]+)(?:#(.+))?/),
63769             l = m && find$1(wikipedia$2, function(d) { return m[1] === d[2]; }),
63770             anchor = m && m[3];
63771
63772         // value in correct format
63773         if (l) {
63774             utilGetSetValue(lang, l[1]);
63775             utilGetSetValue(title, m[2] + (anchor ? ('#' + anchor) : ''));
63776             if (anchor) {
63777                 try {
63778                     // Best-effort `anchorencode:` implementation
63779                     anchor = encodeURIComponent(anchor.replace(/ /g, '_')).replace(/%/g, '.');
63780                 } catch (e) {
63781                     anchor = anchor.replace(/ /g, '_');
63782                 }
63783             }
63784             wikiURL = 'https://' + m[1] + '.wikipedia.org/wiki/' +
63785                 m[2].replace(/ /g, '_') + (anchor ? ('#' + anchor) : '');
63786
63787         // unrecognized value format
63788         } else {
63789             utilGetSetValue(title, value);
63790             if (value && value !== '') {
63791                 utilGetSetValue(lang, '');
63792                 wikiURL = 'https://en.wikipedia.org/wiki/Special:Search?search=' + value;
63793             } else {
63794                 wikiURL = '';
63795             }
63796         }
63797     };
63798
63799
63800     wiki.entity = function(_) {
63801         if (!arguments.length) return entity;
63802         entity = _;
63803         return wiki;
63804     };
63805
63806
63807     wiki.focus = function() {
63808         title.node().focus();
63809     };
63810
63811
63812     return utilRebind(wiki, dispatch$$1, 'on');
63813 }
63814
63815 var uiFields = {
63816     access: uiFieldAccess,
63817     address: uiFieldAddress,
63818     check: uiFieldCheck,
63819     combo: uiFieldCombo,
63820     cycleway: uiFieldCycleway,
63821     defaultCheck: uiFieldCheck,
63822     email: uiFieldText,
63823     lanes: uiFieldLanes,
63824     localized: uiFieldLocalized,
63825     maxspeed: uiFieldMaxspeed,
63826     multiCombo: uiFieldCombo,
63827     networkCombo: uiFieldCombo,
63828     number: uiFieldText,
63829     onewayCheck: uiFieldCheck,
63830     radio: uiFieldRadio,
63831     restrictions: uiFieldRestrictions,
63832     semiCombo: uiFieldCombo,
63833     structureRadio: uiFieldRadio,
63834     tel: uiFieldText,
63835     text: uiFieldText,
63836     textarea: uiFieldTextarea,
63837     typeCombo: uiFieldCombo,
63838     url: uiFieldText,
63839     wikipedia: uiFieldWikipedia
63840 };
63841
63842 function uiField(context, presetField, entity, options) {
63843     options = assignIn({
63844         show: true,
63845         wrap: true,
63846         remove: true,
63847         revert: true,
63848         info: true
63849     }, options);
63850
63851     var dispatch$$1 = dispatch('change'),
63852         field = clone(presetField),
63853         show = options.show,
63854         state = '',
63855         tags = {};
63856
63857
63858     field.impl = uiFields[field.type](field, context)
63859         .on('change', function(t$$1, onInput) {
63860             dispatch$$1.call('change', field, t$$1, onInput);
63861         });
63862
63863     if (entity && field.impl.entity) {
63864         field.impl.entity(entity);
63865     }
63866
63867     field.keys = field.keys || [field.key];
63868
63869
63870     function isModified() {
63871         if (!entity) return false;
63872         var original = context.graph().base().entities[entity.id];
63873         return some(field.keys, function(key) {
63874             return original ? tags[key] !== original.tags[key] : tags[key];
63875         });
63876     }
63877
63878
63879     function isPresent() {
63880         return some(field.keys, function(key) {
63881             return tags[key];
63882         });
63883     }
63884
63885
63886     function revert(d) {
63887         event.stopPropagation();
63888         event.preventDefault();
63889         if (!entity) return false;
63890
63891         var original = context.graph().base().entities[entity.id],
63892             t$$1 = {};
63893         d.keys.forEach(function(key) {
63894             t$$1[key] = original ? original.tags[key] : undefined;
63895         });
63896
63897         dispatch$$1.call('change', d, t$$1);
63898     }
63899
63900
63901     function remove(d) {
63902         event.stopPropagation();
63903         event.preventDefault();
63904
63905         var t$$1 = {};
63906         d.keys.forEach(function(key) {
63907             t$$1[key] = undefined;
63908         });
63909
63910         dispatch$$1.call('change', d, t$$1);
63911     }
63912
63913
63914     field.render = function(selection) {
63915         var container = selection.selectAll('.form-field')
63916             .data([field]);
63917
63918         // Enter
63919         var enter = container.enter()
63920             .append('div')
63921             .attr('class', function(d) { return 'form-field form-field-' + d.id; })
63922             .classed('nowrap', !options.wrap);
63923
63924         if (options.wrap) {
63925             var label = enter
63926                 .append('label')
63927                 .attr('class', 'form-label')
63928                 .attr('for', function(d) { return 'preset-input-' + d.id; })
63929                 .text(function(d) { return d.label(); });
63930
63931             var wrap = label
63932                 .append('div')
63933                 .attr('class', 'form-label-button-wrap');
63934
63935             if (options.remove) {
63936                 wrap
63937                     .append('button')
63938                     .attr('class', 'remove-icon')
63939                     .attr('tabindex', -1)
63940                     .call(svgIcon('#operation-delete'));
63941             }
63942
63943             if (options.revert) {
63944                 wrap
63945                     .append('button')
63946                     .attr('class', 'modified-icon')
63947                     .attr('tabindex', -1)
63948                     .call(
63949                         (textDirection === 'rtl') ? svgIcon('#icon-redo') : svgIcon('#icon-undo')
63950                     );
63951             }
63952         }
63953
63954
63955         // Update
63956         container = container
63957             .merge(enter);
63958
63959         container.selectAll('.form-label-button-wrap .remove-icon')
63960             .on('click', remove);
63961
63962         container.selectAll('.form-label-button-wrap .modified-icon')
63963             .on('click', revert);
63964
63965         container
63966             .classed('modified', isModified())
63967             .classed('present', isPresent())
63968             .each(function(d) {
63969                 if (options.wrap && options.info) {
63970                     var referenceKey = d.key;
63971                     if (d.type === 'multiCombo') {   // lookup key without the trailing ':'
63972                         referenceKey = referenceKey.replace(/:$/, '');
63973                     }
63974                     var reference = uiTagReference(d.reference || { key: referenceKey }, context);
63975
63976                     if (state === 'hover') {
63977                         reference.showing(false);
63978                     }
63979                 }
63980
63981                 d3_select(this)
63982                     .call(d.impl);
63983
63984                 if (options.wrap && options.info) {
63985                     d3_select(this)
63986                         .call(reference.body)
63987                         .select('.form-label-button-wrap')
63988                         .call(reference.button);
63989                 }
63990
63991                 d.impl.tags(tags);
63992             });
63993     };
63994
63995
63996     field.state = function(_) {
63997         if (!arguments.length) return state;
63998         state = _;
63999         return field;
64000     };
64001
64002
64003     field.tags = function(_) {
64004         if (!arguments.length) return tags;
64005         tags = _;
64006         return field;
64007     };
64008
64009
64010     field.show = function() {
64011         show = true;
64012         if (field.default && field.key && tags[field.key] !== field.default) {
64013             var t$$1 = {};
64014             t$$1[field.key] = field.default;
64015             dispatch$$1.call('change', this, t$$1);
64016         }
64017     };
64018
64019
64020     field.isShown = function() {
64021         return show || some(field.keys, function(key) { return !!tags[key]; });
64022     };
64023
64024
64025     field.focus = function() {
64026         field.impl.focus();
64027     };
64028
64029
64030     return utilRebind(field, dispatch$$1, 'on');
64031 }
64032
64033 function uiFormFields(context) {
64034     var fieldsArr;
64035
64036
64037     function formFields(selection, klass) {
64038         render(selection, klass);
64039     }
64040
64041
64042     function render(selection, klass) {
64043
64044         var shown = fieldsArr.filter(function(field) { return field.isShown(); }),
64045             notShown = fieldsArr.filter(function(field) { return !field.isShown(); });
64046
64047         var container = selection.selectAll('.form-fields-container')
64048             .data([0]);
64049
64050         container = container.enter()
64051             .append('div')
64052             .attr('class', 'form-fields-container ' + (klass || ''))
64053             .merge(container);
64054
64055
64056         var fields = container.selectAll('.wrap-form-field')
64057             .data(shown, function(d) { return d.id; });
64058
64059         fields.exit()
64060             .remove();
64061
64062         // Enter
64063         var enter = fields.enter()
64064             .append('div')
64065             .attr('class', function(d) { return 'wrap-form-field wrap-form-field-' + d.id; });
64066
64067         // Update
64068         fields = fields
64069             .merge(enter);
64070
64071         fields
64072             .order()
64073             .each(function(d) {
64074                 d3_select(this)
64075                     .call(d.render);
64076             });
64077
64078
64079         notShown = notShown.map(function(field) {
64080             return {
64081                 title: field.label(),
64082                 value: field.label(),
64083                 field: field
64084             };
64085         });
64086
64087
64088         var more = selection.selectAll('.more-fields')
64089             .data((notShown.length > 0) ? [0] : []);
64090
64091         more.exit()
64092             .remove();
64093
64094         more = more.enter()
64095             .append('div')
64096             .attr('class', 'more-fields')
64097             .append('label')
64098             .text(t('inspector.add_fields'))
64099             .merge(more);
64100
64101
64102         var input = more.selectAll('.value')
64103             .data([0]);
64104
64105         input.exit()
64106             .remove();
64107
64108         input = input.enter()
64109             .append('input')
64110             .attr('class', 'value')
64111             .attr('type', 'text')
64112             .call(utilNoAuto)
64113             .merge(input);
64114
64115         input
64116             .call(utilGetSetValue, '')
64117             .attr('placeholder', function() {
64118                 var placeholder = [];
64119                 for (var field in notShown) {
64120                     placeholder.push(notShown[field].title);
64121                 }
64122                 return placeholder.slice(0,3).join(', ') + ((placeholder.length > 3) ? '…' : '');
64123             })
64124             .call(d3combobox()
64125                 .container(context.container())
64126                 .data(notShown)
64127                 .minItems(1)
64128                 .on('accept', function (d) {
64129                     var field = d.field;
64130                     field.show();
64131                     render(selection);
64132                     if (field.type !== 'semiCombo' && field.type !== 'multiCombo') {
64133                         field.focus();
64134                     }
64135                 })
64136             );
64137     }
64138
64139
64140     formFields.fieldsArr = function(_) {
64141         if (!arguments.length) return fieldsArr;
64142         fieldsArr = _;
64143         return formFields;
64144     };
64145
64146
64147     return formFields;
64148 }
64149
64150 function uiPresetEditor(context) {
64151     var dispatch$$1 = dispatch('change'),
64152         formFields = uiFormFields(context),
64153         state,
64154         fieldsArr,
64155         preset,
64156         tags,
64157         entityId;
64158
64159
64160     function presetEditor(selection) {
64161         selection.call(uiDisclosure(context, 'preset_fields', true)
64162             .title(t('inspector.all_fields'))
64163             .content(render)
64164         );
64165     }
64166
64167
64168     function render(selection) {
64169         if (!fieldsArr) {
64170             var entity = context.entity(entityId),
64171                 geometry = context.geometry(entityId),
64172                 presets = context.presets();
64173
64174             fieldsArr = [];
64175
64176             preset.fields.forEach(function(field) {
64177                 if (field.matchGeometry(geometry)) {
64178                     fieldsArr.push(
64179                         uiField(context, field, entity)
64180                     );
64181                 }
64182             });
64183
64184             if (entity.isHighwayIntersection(context.graph()) && presets.field('restrictions')) {
64185                 fieldsArr.push(
64186                     uiField(context, presets.field('restrictions'), entity)
64187                 );
64188             }
64189
64190             presets.universal().forEach(function(field) {
64191                 if (preset.fields.indexOf(field) === -1) {
64192                     fieldsArr.push(
64193                         uiField(context, field, entity, { show: false })
64194                     );
64195                 }
64196             });
64197
64198             fieldsArr.forEach(function(field) {
64199                 field
64200                     .on('change', function(t$$1, onInput) {
64201                         dispatch$$1.call('change', field, t$$1, onInput);
64202                     });
64203             });
64204         }
64205
64206         fieldsArr.forEach(function(field) {
64207             field
64208                 .state(state)
64209                 .tags(tags);
64210         });
64211
64212
64213         selection
64214             .call(formFields.fieldsArr(fieldsArr), 'inspector-inner fillL3');
64215
64216
64217         selection.selectAll('.wrap-form-field input')
64218             .on('keydown', function() {
64219                 // if user presses enter, and combobox is not active, accept edits..
64220                 if (event.keyCode === 13 && d3_select('.combobox').empty()) {
64221                     context.enter(modeBrowse(context));
64222                 }
64223             });
64224     }
64225
64226
64227     presetEditor.preset = function(_) {
64228         if (!arguments.length) return preset;
64229         if (preset && preset.id === _.id) return presetEditor;
64230         preset = _;
64231         fieldsArr = null;
64232         return presetEditor;
64233     };
64234
64235
64236     presetEditor.state = function(_) {
64237         if (!arguments.length) return state;
64238         state = _;
64239         return presetEditor;
64240     };
64241
64242
64243     presetEditor.tags = function(_) {
64244         if (!arguments.length) return tags;
64245         tags = _;
64246         // Don't reset fieldsArr here.
64247         return presetEditor;
64248     };
64249
64250
64251     presetEditor.entityID = function(_) {
64252         if (!arguments.length) return entityId;
64253         if (entityId === _) return presetEditor;
64254         entityId = _;
64255         fieldsArr = null;
64256         return presetEditor;
64257     };
64258
64259
64260     return utilRebind(presetEditor, dispatch$$1, 'on');
64261 }
64262
64263 function uiEntityEditor(context) {
64264     var dispatch$$1 = dispatch('choose'),
64265         state = 'select',
64266         coalesceChanges = false,
64267         modified = false,
64268         base,
64269         entityId,
64270         activePreset,
64271         reference;
64272
64273     var presetEditor = uiPresetEditor(context)
64274         .on('change', changeTags);
64275     var rawTagEditor = uiRawTagEditor(context)
64276         .on('change', changeTags);
64277
64278
64279     function entityEditor(selection) {
64280         var entity = context.entity(entityId),
64281             tags = clone(entity.tags);
64282
64283         // Header
64284         var header = selection.selectAll('.header')
64285             .data([0]);
64286
64287         // Enter
64288         var enter = header.enter()
64289             .append('div')
64290             .attr('class', 'header fillL cf');
64291
64292         enter
64293             .append('button')
64294             .attr('class', 'fl preset-reset preset-choose')
64295             .call(svgIcon((textDirection === 'rtl') ? '#icon-forward' : '#icon-backward'));
64296
64297         enter
64298             .append('button')
64299             .attr('class', 'fr preset-close')
64300             .on('click', function() { context.enter(modeBrowse(context)); })
64301             .call(svgIcon(modified ? '#icon-apply' : '#icon-close'));
64302
64303         enter
64304             .append('h3')
64305             .text(t('inspector.edit'));
64306
64307         // Update
64308         header = header
64309             .merge(enter);
64310
64311         header.selectAll('.preset-reset')
64312             .on('click', function() {
64313                 dispatch$$1.call('choose', this, activePreset);
64314             });
64315
64316
64317         // Body
64318         var body = selection.selectAll('.inspector-body')
64319             .data([0]);
64320
64321         // Enter
64322         enter = body.enter()
64323             .append('div')
64324             .attr('class', 'inspector-body');
64325
64326         enter
64327             .append('div')
64328             .attr('class', 'preset-list-item inspector-inner')
64329             .append('div')
64330             .attr('class', 'preset-list-button-wrap')
64331             .append('button')
64332             .attr('class', 'preset-list-button preset-reset')
64333             .call(tooltip().title(t('inspector.back_tooltip')).placement('bottom'))
64334             .append('div')
64335             .attr('class', 'label');
64336
64337         enter
64338             .append('div')
64339             .attr('class', 'inspector-border preset-editor');
64340
64341         enter
64342             .append('div')
64343             .attr('class', 'inspector-border raw-tag-editor inspector-inner');
64344
64345         enter
64346             .append('div')
64347             .attr('class', 'inspector-border raw-member-editor inspector-inner');
64348
64349         enter
64350             .append('div')
64351             .attr('class', 'raw-membership-editor inspector-inner');
64352
64353         enter
64354             .append('input')
64355             .attr('type', 'text')
64356             .attr('class', 'key-trap');
64357
64358
64359         // Update
64360         body = body
64361             .merge(enter);
64362
64363         body.selectAll('.preset-list-button-wrap')
64364             .call(reference.button);
64365
64366         body.selectAll('.preset-list-item')
64367             .call(reference.body);
64368
64369         body.selectAll('.preset-reset')
64370             .on('click', function() {
64371                 dispatch$$1.call('choose', this, activePreset);
64372             });
64373
64374         body.select('.preset-list-item button')
64375             .call(uiPresetIcon()
64376                 .geometry(context.geometry(entityId))
64377                 .preset(activePreset)
64378             );
64379
64380         body.select('.preset-list-item .label')
64381             .text(activePreset.name());
64382
64383         body.select('.preset-editor')
64384             .call(presetEditor
64385                 .preset(activePreset)
64386                 .entityID(entityId)
64387                 .tags(tags)
64388                 .state(state)
64389             );
64390
64391         body.select('.raw-tag-editor')
64392             .call(rawTagEditor
64393                 .preset(activePreset)
64394                 .entityID(entityId)
64395                 .tags(tags)
64396                 .state(state)
64397             );
64398
64399         if (entity.type === 'relation') {
64400             body.select('.raw-member-editor')
64401                 .style('display', 'block')
64402                 .call(uiRawMemberEditor(context)
64403                     .entityID(entityId)
64404                 );
64405         } else {
64406             body.select('.raw-member-editor')
64407                 .style('display', 'none');
64408         }
64409
64410         body.select('.raw-membership-editor')
64411             .call(uiRawMembershipEditor(context)
64412                 .entityID(entityId)
64413             );
64414
64415         body.select('.key-trap')
64416             .on('keydown.key-trap', function() {
64417                 // On tabbing, send focus back to the first field on the inspector-body
64418                 // (probably the `name` field) #4159
64419                 if (event.keyCode === 9 && !event.shiftKey) {
64420                     event.preventDefault();
64421                     body.select('input').node().focus();
64422                 }
64423             });
64424
64425         context.history()
64426             .on('change.entity-editor', historyChanged);
64427
64428
64429         function historyChanged() {
64430             if (state === 'hide') return;
64431
64432             var entity = context.hasEntity(entityId);
64433             var graph = context.graph();
64434             if (!entity) return;
64435
64436             var match = context.presets().match(entity, graph);
64437             var activePreset = entityEditor.preset();
64438             var weakPreset = activePreset && isEmpty(activePreset.addTags);
64439
64440             // A "weak" preset doesn't set any tags. (e.g. "Address")
64441             // Don't replace a weak preset with a fallback preset (e.g. "Point")
64442             if (!(weakPreset && match.isFallback())) {
64443                 entityEditor.preset(match);
64444             }
64445             entityEditor.modified(base !== graph);
64446             entityEditor(selection);
64447         }
64448     }
64449
64450
64451     function clean(o) {
64452
64453         function cleanVal(k, v) {
64454             function keepSpaces(k) {
64455                 return k.match(/_hours|_times/) !== null;
64456             }
64457
64458             var blacklist = ['description', 'note', 'fixme'];
64459             if (some(blacklist, function(s) { return k.indexOf(s) !== -1; })) return v;
64460
64461             var cleaned = v.split(';')
64462                 .map(function(s) { return s.trim(); })
64463                 .join(keepSpaces(k) ? '; ' : ';');
64464
64465             // The code below is not intended to validate websites and emails.
64466             // It is only intended to prevent obvious copy-paste errors. (#2323)
64467             // clean website- and email-like tags
64468             if (k.indexOf('website') !== -1 ||
64469                 k.indexOf('email') !== -1 ||
64470                 cleaned.indexOf('http') === 0) {
64471                 cleaned = cleaned
64472                     .replace(/[\u200B-\u200F\uFEFF]/g, '');  // strip LRM and other zero width chars
64473
64474             }
64475
64476             return cleaned;
64477         }
64478
64479         var out = {}, k, v;
64480         for (k in o) {
64481             if (k && (v = o[k]) !== undefined) {
64482                 out[k] = cleanVal(k, v);
64483             }
64484         }
64485         return out;
64486     }
64487
64488
64489     // Tag changes that fire on input can all get coalesced into a single
64490     // history operation when the user leaves the field.  #2342
64491     function changeTags(changed, onInput) {
64492         var entity = context.entity(entityId),
64493             annotation = t('operations.change_tags.annotation'),
64494             tags = clone(entity.tags);
64495
64496         forEach(changed, function(v, k) {
64497             if (v !== undefined || tags.hasOwnProperty(k)) {
64498                 tags[k] = v;
64499             }
64500         });
64501
64502         if (!onInput) {
64503             tags = clean(tags);
64504         }
64505
64506         if (!isEqual(entity.tags, tags)) {
64507             if (coalesceChanges) {
64508                 context.overwrite(actionChangeTags(entityId, tags), annotation);
64509             } else {
64510                 context.perform(actionChangeTags(entityId, tags), annotation);
64511                 coalesceChanges = !!onInput;
64512             }
64513         }
64514     }
64515
64516
64517     entityEditor.modified = function(_) {
64518         if (!arguments.length) return modified;
64519         modified = _;
64520         d3_selectAll('button.preset-close use')
64521             .attr('xlink:href', (modified ? '#icon-apply' : '#icon-close'));
64522     };
64523
64524
64525     entityEditor.state = function(_) {
64526         if (!arguments.length) return state;
64527         state = _;
64528         return entityEditor;
64529     };
64530
64531
64532     entityEditor.entityID = function(_) {
64533         if (!arguments.length) return entityId;
64534         entityId = _;
64535         base = context.graph();
64536         entityEditor.preset(context.presets().match(context.entity(entityId), base));
64537         entityEditor.modified(false);
64538         coalesceChanges = false;
64539         return entityEditor;
64540     };
64541
64542
64543     entityEditor.preset = function(_) {
64544         if (!arguments.length) return activePreset;
64545         if (_ !== activePreset) {
64546             activePreset = _;
64547             reference = uiTagReference(activePreset.reference(context.geometry(entityId)), context)
64548                 .showing(false);
64549         }
64550         return entityEditor;
64551     };
64552
64553
64554     return utilRebind(entityEditor, dispatch$$1, 'on');
64555 }
64556
64557 function uiPresetList(context) {
64558     var dispatch$$1 = dispatch('choose'),
64559         id,
64560         currentPreset,
64561         autofocus = false;
64562
64563
64564     function presetList(selection) {
64565         var entity = context.entity(id),
64566             geometry = context.geometry(id);
64567
64568         // Treat entities on addr:interpolation lines as points, not vertices (#3241)
64569         if (geometry === 'vertex' && entity.isOnAddressLine(context.graph())) {
64570             geometry = 'point';
64571         }
64572
64573         var presets = context.presets().matchGeometry(geometry);
64574
64575         selection.html('');
64576
64577         var messagewrap = selection
64578             .append('div')
64579             .attr('class', 'header fillL cf');
64580
64581         var message = messagewrap
64582             .append('h3')
64583             .text(t('inspector.choose'));
64584
64585         if (context.entity(id).isUsed(context.graph())) {
64586             messagewrap
64587                 .append('button')
64588                 .attr('class', 'preset-choose')
64589                 .on('click', function() { dispatch$$1.call('choose', this, currentPreset); })
64590                 .call(svgIcon((textDirection === 'rtl') ? '#icon-backward' : '#icon-forward'));
64591         } else {
64592             messagewrap
64593                 .append('button')
64594                 .attr('class', 'close')
64595                 .on('click', function() {
64596                     context.enter(modeBrowse(context));
64597                 })
64598                 .call(svgIcon('#icon-close'));
64599         }
64600
64601         function keydown() {
64602             // hack to let delete shortcut work when search is autofocused
64603             if (search.property('value').length === 0 &&
64604                 (event.keyCode === d3keybinding.keyCodes['⌫'] ||
64605                  event.keyCode === d3keybinding.keyCodes['⌦'])) {
64606                 event.preventDefault();
64607                 event.stopPropagation();
64608                 operationDelete([id], context)();
64609             } else if (search.property('value').length === 0 &&
64610                 (event.ctrlKey || event.metaKey) &&
64611                 event.keyCode === d3keybinding.keyCodes.z) {
64612                 event.preventDefault();
64613                 event.stopPropagation();
64614                 context.undo();
64615             } else if (!event.ctrlKey && !event.metaKey) {
64616                 d3_select(this).on('keydown', null);
64617             }
64618         }
64619
64620         function keypress() {
64621             // enter
64622             var value = search.property('value');
64623             if (event.keyCode === 13 && value.length) {
64624                 list.selectAll('.preset-list-item:first-child').datum().choose();
64625             }
64626         }
64627
64628         function inputevent() {
64629             var value = search.property('value');
64630             list.classed('filtered', value.length);
64631             if (value.length) {
64632                 var results = presets.search(value, geometry);
64633                 message.text(t('inspector.results', {
64634                     n: results.collection.length,
64635                     search: value
64636                 }));
64637                 list.call(drawList, results);
64638             } else {
64639                 list.call(drawList, context.presets().defaults(geometry, 36));
64640                 message.text(t('inspector.choose'));
64641             }
64642         }
64643
64644         var searchWrap = selection
64645             .append('div')
64646             .attr('class', 'search-header');
64647
64648         var search = searchWrap
64649             .append('input')
64650             .attr('class', 'preset-search-input')
64651             .attr('placeholder', t('inspector.search'))
64652             .attr('type', 'search')
64653             .call(utilNoAuto)
64654             .on('keydown', keydown)
64655             .on('keypress', keypress)
64656             .on('input', inputevent);
64657
64658         searchWrap
64659             .call(svgIcon('#icon-search', 'pre-text'));
64660
64661         if (autofocus) {
64662             search.node().focus();
64663         }
64664
64665         var listWrap = selection
64666             .append('div')
64667             .attr('class', 'inspector-body');
64668
64669         var list = listWrap
64670             .append('div')
64671             .attr('class', 'preset-list fillL cf')
64672             .call(drawList, context.presets().defaults(geometry, 36));
64673     }
64674
64675
64676     function drawList(list, presets) {
64677         var collection = presets.collection.map(function(preset) {
64678             return preset.members ? CategoryItem(preset) : PresetItem(preset);
64679         });
64680
64681         var items = list.selectAll('.preset-list-item')
64682             .data(collection, function(d) { return d.preset.id; });
64683
64684         items.order();
64685
64686         items.exit()
64687             .remove();
64688
64689         items.enter()
64690             .append('div')
64691             .attr('class', function(item) { return 'preset-list-item preset-' + item.preset.id.replace('/', '-'); })
64692             .classed('current', function(item) { return item.preset === currentPreset; })
64693             .each(function(item) { d3_select(this).call(item); })
64694             .style('opacity', 0)
64695             .transition()
64696             .style('opacity', 1);
64697     }
64698
64699
64700     function CategoryItem(preset) {
64701         var box, sublist, shown = false;
64702
64703         function item(selection) {
64704             var wrap = selection.append('div')
64705                 .attr('class', 'preset-list-button-wrap category col12');
64706
64707             var button = wrap
64708                 .append('button')
64709                 .attr('class', 'preset-list-button')
64710                 .classed('expanded', false)
64711                 .call(uiPresetIcon()
64712                     .geometry(context.geometry(id))
64713                     .preset(preset))
64714                 .on('click', function() {
64715                     var isExpanded = d3_select(this).classed('expanded');
64716                     var iconName = isExpanded ?
64717                         (textDirection === 'rtl' ? '#icon-backward' : '#icon-forward') : '#icon-down';
64718                     d3_select(this)
64719                         .classed('expanded', !isExpanded);
64720                     d3_select(this).selectAll('div.label svg.icon use')
64721                         .attr('href', iconName);
64722                     item.choose();
64723                 });
64724
64725             var label = button
64726                 .append('div')
64727                 .attr('class', 'label');
64728
64729             label
64730                 .call(svgIcon((textDirection === 'rtl' ? '#icon-backward' : '#icon-forward'), 'inline'))
64731                 .append('span')
64732                 .html(function() { return preset.name() + '&hellip;'; });
64733
64734             box = selection.append('div')
64735                 .attr('class', 'subgrid col12')
64736                 .style('max-height', '0px')
64737                 .style('opacity', 0);
64738
64739             box.append('div')
64740                 .attr('class', 'arrow');
64741
64742             sublist = box.append('div')
64743                 .attr('class', 'preset-list fillL3 cf fl');
64744         }
64745
64746
64747         item.choose = function() {
64748             if (!box || !sublist) return;
64749
64750             if (shown) {
64751                 shown = false;
64752                 box.transition()
64753                     .duration(200)
64754                     .style('opacity', '0')
64755                     .style('max-height', '0px')
64756                     .style('padding-bottom', '0px');
64757             } else {
64758                 shown = true;
64759                 sublist.call(drawList, preset.members);
64760                 box.transition()
64761                     .duration(200)
64762                     .style('opacity', '1')
64763                     .style('max-height', 200 + preset.members.collection.length * 190 + 'px')
64764                     .style('padding-bottom', '20px');
64765             }
64766         };
64767
64768         item.preset = preset;
64769
64770         return item;
64771     }
64772
64773
64774     function PresetItem(preset) {
64775         function item(selection) {
64776             var wrap = selection.append('div')
64777                 .attr('class', 'preset-list-button-wrap col12');
64778
64779             wrap.append('button')
64780                 .attr('class', 'preset-list-button')
64781                 .call(uiPresetIcon()
64782                     .geometry(context.geometry(id))
64783                     .preset(preset))
64784                 .on('click', item.choose)
64785                 .append('div')
64786                 .attr('class', 'label')
64787                 .text(preset.name());
64788
64789             wrap.call(item.reference.button);
64790             selection.call(item.reference.body);
64791         }
64792
64793         item.choose = function() {
64794             context.presets().choose(preset);
64795
64796             context.perform(
64797                 actionChangePreset(id, currentPreset, preset),
64798                 t('operations.change_tags.annotation')
64799             );
64800
64801             dispatch$$1.call('choose', this, preset);
64802         };
64803
64804         item.help = function() {
64805             event.stopPropagation();
64806             item.reference.toggle();
64807         };
64808
64809         item.preset = preset;
64810         item.reference = uiTagReference(preset.reference(context.geometry(id)), context);
64811
64812         return item;
64813     }
64814
64815
64816     presetList.autofocus = function(_) {
64817         if (!arguments.length) return autofocus;
64818         autofocus = _;
64819         return presetList;
64820     };
64821
64822
64823     presetList.entityID = function(_) {
64824         if (!arguments.length) return id;
64825         id = _;
64826         presetList.preset(context.presets().match(context.entity(id), context.graph()));
64827         return presetList;
64828     };
64829
64830
64831     presetList.preset = function(_) {
64832         if (!arguments.length) return currentPreset;
64833         currentPreset = _;
64834         return presetList;
64835     };
64836
64837
64838     return utilRebind(presetList, dispatch$$1, 'on');
64839 }
64840
64841 function uiViewOnOSM(context) {
64842     var id;
64843
64844     function viewOnOSM(selection) {
64845         var entity = context.entity(id);
64846
64847         selection.style('display', entity.isNew() ? 'none' : null);
64848
64849         var link = selection.selectAll('.view-on-osm')
64850             .data([0]);
64851
64852         var enter = link.enter()
64853             .append('a')
64854             .attr('class', 'view-on-osm')
64855             .attr('target', '_blank')
64856             .call(svgIcon('#icon-out-link', 'inline'));
64857
64858         enter
64859             .append('span')
64860             .text(t('inspector.view_on_osm'));
64861
64862         link
64863             .merge(enter)
64864             .attr('href', context.connection().entityURL(entity));
64865     }
64866
64867
64868     viewOnOSM.entityID = function(_) {
64869         if (!arguments.length) return id;
64870         id = _;
64871         return viewOnOSM;
64872     };
64873
64874     return viewOnOSM;
64875 }
64876
64877 function uiInspector(context) {
64878     var presetList = uiPresetList(context),
64879         entityEditor = uiEntityEditor(context),
64880         state = 'select',
64881         entityID,
64882         newFeature = false;
64883
64884
64885     function inspector(selection) {
64886         presetList
64887             .entityID(entityID)
64888             .autofocus(newFeature)
64889             .on('choose', setPreset);
64890
64891         entityEditor
64892             .state(state)
64893             .entityID(entityID)
64894             .on('choose', showList);
64895
64896         var wrap = selection.selectAll('.panewrap')
64897             .data([0]);
64898
64899         var enter = wrap.enter()
64900             .append('div')
64901             .attr('class', 'panewrap');
64902
64903         enter
64904             .append('div')
64905             .attr('class', 'preset-list-pane pane');
64906
64907         enter
64908             .append('div')
64909             .attr('class', 'entity-editor-pane pane');
64910
64911         wrap = wrap.merge(enter);
64912         var presetPane = wrap.selectAll('.preset-list-pane');
64913         var editorPane = wrap.selectAll('.entity-editor-pane');
64914
64915         var graph = context.graph(),
64916             entity = context.entity(entityID),
64917             showEditor = state === 'hover' ||
64918                 entity.isUsed(graph) ||
64919                 entity.isHighwayIntersection(graph);
64920
64921         if (showEditor) {
64922             wrap.style('right', '0%');
64923             editorPane.call(entityEditor);
64924         } else {
64925             wrap.style('right', '-100%');
64926             presetPane.call(presetList);
64927         }
64928
64929         var footer = selection.selectAll('.footer')
64930             .data([0]);
64931
64932         footer = footer.enter()
64933             .append('div')
64934             .attr('class', 'footer')
64935             .merge(footer);
64936
64937         footer
64938             .call(uiViewOnOSM(context).entityID(entityID));
64939
64940
64941         function showList(preset) {
64942             wrap.transition()
64943                 .styleTween('right', function() { return d3_interpolate('0%', '-100%'); });
64944
64945             presetPane
64946                 .call(presetList.preset(preset).autofocus(true));
64947         }
64948
64949
64950         function setPreset(preset) {
64951             wrap.transition()
64952                 .styleTween('right', function() { return d3_interpolate('-100%', '0%'); });
64953
64954             editorPane
64955                 .call(entityEditor.preset(preset));
64956         }
64957     }
64958
64959
64960     inspector.state = function(_) {
64961         if (!arguments.length) return state;
64962         state = _;
64963         entityEditor.state(state);
64964         return inspector;
64965     };
64966
64967
64968     inspector.entityID = function(_) {
64969         if (!arguments.length) return entityID;
64970         entityID = _;
64971         return inspector;
64972     };
64973
64974
64975     inspector.newFeature = function(_) {
64976         if (!arguments.length) return newFeature;
64977         newFeature = _;
64978         return inspector;
64979     };
64980
64981
64982     return inspector;
64983 }
64984
64985 function uiSidebar(context) {
64986     var inspector = uiInspector(context),
64987         current;
64988
64989
64990     function sidebar(selection) {
64991         var featureListWrap = selection
64992             .append('div')
64993             .attr('class', 'feature-list-pane')
64994             .call(uiFeatureList(context));
64995
64996
64997         var inspectorWrap = selection
64998             .append('div')
64999             .attr('class', 'inspector-hidden inspector-wrap fr');
65000
65001
65002         function hover(id) {
65003             if (!current && context.hasEntity(id)) {
65004                 featureListWrap
65005                     .classed('inspector-hidden', true);
65006
65007                 inspectorWrap
65008                     .classed('inspector-hidden', false)
65009                     .classed('inspector-hover', true);
65010
65011                 if (inspector.entityID() !== id || inspector.state() !== 'hover') {
65012                     inspector
65013                         .state('hover')
65014                         .entityID(id);
65015
65016                     inspectorWrap
65017                         .call(inspector);
65018                 }
65019
65020             } else if (!current) {
65021                 featureListWrap
65022                     .classed('inspector-hidden', false);
65023                 inspectorWrap
65024                     .classed('inspector-hidden', true);
65025                 inspector
65026                     .state('hide');
65027             }
65028         }
65029
65030
65031         sidebar.hover = throttle(hover, 200);
65032
65033
65034         sidebar.select = function(id, newFeature) {
65035             if (!current && id) {
65036                 featureListWrap
65037                     .classed('inspector-hidden', true);
65038
65039                 inspectorWrap
65040                     .classed('inspector-hidden', false)
65041                     .classed('inspector-hover', false);
65042
65043                 if (inspector.entityID() !== id || inspector.state() !== 'select') {
65044                     inspector
65045                         .state('select')
65046                         .entityID(id)
65047                         .newFeature(newFeature);
65048
65049                     inspectorWrap
65050                         .call(inspector);
65051                 }
65052
65053             } else if (!current) {
65054                 featureListWrap
65055                     .classed('inspector-hidden', false);
65056                 inspectorWrap
65057                     .classed('inspector-hidden', true);
65058                 inspector
65059                     .state('hide');
65060             }
65061         };
65062
65063
65064         sidebar.show = function(component) {
65065             featureListWrap
65066                 .classed('inspector-hidden', true);
65067             inspectorWrap
65068                 .classed('inspector-hidden', true);
65069
65070             if (current) current.remove();
65071             current = selection
65072                 .append('div')
65073                 .attr('class', 'sidebar-component')
65074                 .call(component);
65075         };
65076
65077
65078         sidebar.hide = function() {
65079             featureListWrap
65080                 .classed('inspector-hidden', false);
65081             inspectorWrap
65082                 .classed('inspector-hidden', true);
65083
65084             if (current) current.remove();
65085             current = null;
65086         };
65087     }
65088
65089
65090     sidebar.hover = function() {};
65091     sidebar.hover.cancel = function() {};
65092     sidebar.select = function() {};
65093     sidebar.show = function() {};
65094     sidebar.hide = function() {};
65095
65096     return sidebar;
65097 }
65098
65099 function uiSpinner(context) {
65100     var osm = context.connection();
65101
65102
65103     return function(selection) {
65104         var img = selection
65105             .append('img')
65106             .attr('src', context.imagePath('loader-black.gif'))
65107             .style('opacity', 0);
65108
65109         if (osm) {
65110             osm
65111                 .on('loading.spinner', function() {
65112                     img.transition()
65113                         .style('opacity', 1);
65114                 })
65115                 .on('loaded.spinner', function() {
65116                     img.transition()
65117                         .style('opacity', 0);
65118                 });
65119         }
65120     };
65121 }
65122
65123 function uiSplash(context) {
65124
65125     return function(selection) {
65126         if (context.storage('sawSplash'))
65127              return;
65128
65129         context.storage('sawSplash', true);
65130
65131         var modalSelection = uiModal(selection);
65132
65133         modalSelection.select('.modal')
65134             .attr('class', 'modal-splash modal col6');
65135
65136         var introModal = modalSelection.select('.content')
65137             .append('div')
65138             .attr('class', 'fillL');
65139
65140         introModal
65141             .append('div')
65142             .attr('class','modal-section cf')
65143             .append('h3').text(t('splash.welcome'));
65144
65145         introModal
65146             .append('div')
65147             .attr('class','modal-section')
65148             .append('p')
65149             .html(t('splash.text', {
65150                 version: context.version,
65151                 website: '<a href="http://ideditor.com/">ideditor.com</a>',
65152                 github: '<a href="https://github.com/openstreetmap/iD">github.com</a>'
65153             }));
65154
65155         var buttonWrap = introModal
65156             .append('div')
65157             .attr('class', 'modal-actions cf');
65158
65159         var walkthrough = buttonWrap
65160             .append('button')
65161             .attr('class', 'walkthrough col6')
65162             .on('click', function() {
65163                 context.container().call(uiIntro(context));
65164                 modalSelection.close();
65165             });
65166
65167         walkthrough
65168             .append('svg')
65169             .attr('class', 'logo logo-walkthrough')
65170             .append('use')
65171             .attr('xlink:href', '#logo-walkthrough');
65172
65173         walkthrough
65174             .append('div')
65175             .text(t('splash.walkthrough'));
65176
65177         var startEditing = buttonWrap
65178             .append('button')
65179             .attr('class', 'start-editing col6')
65180             .on('click', modalSelection.close);
65181
65182         startEditing
65183             .append('svg')
65184             .attr('class', 'logo logo-features')
65185             .append('use')
65186             .attr('xlink:href', '#logo-features');
65187
65188         startEditing
65189             .append('div')
65190             .text(t('splash.start'));
65191
65192
65193         modalSelection.select('button.close')
65194             .attr('class','hide');
65195
65196     };
65197 }
65198
65199 function uiStatus(context) {
65200     var osm = context.connection();
65201
65202
65203     return function(selection) {
65204         if (!osm) return;
65205
65206         function update() {
65207             osm.status(function(err, apiStatus) {
65208                 selection.html('');
65209
65210                 if (err) {
65211                     if (apiStatus === 'connectionSwitched') {
65212                         // if the connection was just switched, we can't rely on
65213                         // the status (we're getting the status of the previous api)
65214                         return;
65215
65216                     } else if (apiStatus === 'rateLimited') {
65217                         selection
65218                             .text(t('status.rateLimit'))
65219                             .append('a')
65220                             .attr('class', 'api-status-login')
65221                             .attr('target', '_blank')
65222                             .call(svgIcon('#icon-out-link', 'inline'))
65223                             .append('span')
65224                             .text(t('login'))
65225                             .on('click.login', function() {
65226                                 event.preventDefault();
65227                                 osm.authenticate();
65228                             });
65229                     } else {
65230                         // eslint-disable-next-line no-warning-comments
65231                         // TODO: nice messages for different error types
65232                         selection.text(t('status.error'));
65233                     }
65234
65235                 } else if (apiStatus === 'readonly') {
65236                     selection.text(t('status.readonly'));
65237                 } else if (apiStatus === 'offline') {
65238                     selection.text(t('status.offline'));
65239                 }
65240
65241                 selection.attr('class', 'api-status ' + (err ? 'error' : apiStatus));
65242             });
65243         }
65244
65245         osm.on('change', function() { update(selection); });
65246
65247         window.setInterval(update, 90000);
65248         update(selection);
65249     };
65250 }
65251
65252 function uiUndoRedo(context) {
65253     var commands = [{
65254         id: 'undo',
65255         cmd: uiCmd('⌘Z'),
65256         action: function() { if (editable()) context.undo(); },
65257         annotation: function() { return context.history().undoAnnotation(); }
65258     }, {
65259         id: 'redo',
65260         cmd: uiCmd('⌘⇧Z'),
65261         action: function() { if (editable()) context.redo(); },
65262         annotation: function() { return context.history().redoAnnotation(); }
65263     }];
65264
65265
65266     function editable() {
65267         var mode = context.mode();
65268         return context.editable() && mode && mode.id !== 'save';
65269     }
65270
65271
65272     return function(selection) {
65273         var tooltipBehavior = tooltip()
65274             .placement('bottom')
65275             .html(true)
65276             .title(function (d) {
65277                 return uiTooltipHtml(d.annotation() ?
65278                     t(d.id + '.tooltip', {action: d.annotation()}) :
65279                     t(d.id + '.nothing'), d.cmd);
65280             });
65281
65282         var buttons = selection.selectAll('button')
65283             .data(commands)
65284             .enter()
65285             .append('button')
65286             .attr('class', function(d) { return 'col6 disabled ' + d.id + '-button'; })
65287             .on('click', function(d) { return d.action(); })
65288             .call(tooltipBehavior);
65289
65290         buttons.each(function(d) {
65291             var iconName = d.id;
65292             if (textDirection === 'rtl') {
65293                 if (iconName === 'undo') {
65294                     iconName = 'redo';
65295                 } else if (iconName === 'redo') {
65296                     iconName = 'undo';
65297                 }
65298             }
65299             d3_select(this)
65300                 .call(svgIcon('#icon-' + iconName));
65301         });
65302
65303         var keybinding = d3keybinding('undo')
65304             .on(commands[0].cmd, function() { event.preventDefault(); commands[0].action(); })
65305             .on(commands[1].cmd, function() { event.preventDefault(); commands[1].action(); });
65306
65307         d3_select(document)
65308             .call(keybinding);
65309
65310
65311         var debouncedUpdate = debounce(update, 500, { leading: true, trailing: true });
65312
65313         context.map()
65314             .on('move.undo_redo', debouncedUpdate)
65315             .on('drawn.undo_redo', debouncedUpdate);
65316
65317         context.history()
65318             .on('change.undo_redo', update);
65319
65320         context
65321             .on('enter.undo_redo', update);
65322
65323
65324         function update() {
65325             buttons
65326                 .property('disabled', !editable())
65327                 .classed('disabled', function(d) { return !d.annotation(); })
65328                 .each(function() {
65329                     var selection = d3_select(this);
65330                     if (selection.property('tooltipVisible')) {
65331                         selection.call(tooltipBehavior.show);
65332                     }
65333                 });
65334         }
65335     };
65336 }
65337
65338 // these are module variables so they are preserved through a ui.restart()
65339 var sawVersion = null;
65340 var isNewVersion = false;
65341 var isNewUser = false;
65342
65343
65344 function uiVersion(context) {
65345
65346     var currVersion = context.version,
65347         matchedVersion = currVersion.match(/\d\.\d\.\d.*/);
65348
65349     if (sawVersion === null && matchedVersion !== null) {
65350         isNewVersion = (context.storage('sawVersion') !== currVersion);
65351         isNewUser = !context.storage('sawSplash');
65352         context.storage('sawVersion', currVersion);
65353         sawVersion = currVersion;
65354     }
65355
65356     return function(selection) {
65357         selection
65358             .append('a')
65359             .attr('target', '_blank')
65360             .attr('tabindex', -1)
65361             .attr('href', 'https://github.com/openstreetmap/iD')
65362             .text(currVersion);
65363
65364         // only show new version indicator to users that have used iD before
65365         if (isNewVersion && !isNewUser) {
65366             selection
65367                 .append('div')
65368                 .attr('class', 'badge')
65369                 .append('a')
65370                 .attr('target', '_blank')
65371                 .attr('tabindex', -1)
65372                 .attr('href', 'https://github.com/openstreetmap/iD/blob/master/CHANGELOG.md#whats-new')
65373                 .call(svgIcon('#gift-11'))
65374                 .call(tooltip()
65375                     .title(t('version.whats_new', { version: currVersion }))
65376                     .placement('top')
65377                 );
65378         }
65379     };
65380 }
65381
65382 function uiZoom(context) {
65383     var zooms = [{
65384         id: 'zoom-in',
65385         icon: 'plus',
65386         title: t('zoom.in'),
65387         action: context.zoomIn,
65388         key: '+'
65389     }, {
65390         id: 'zoom-out',
65391         icon: 'minus',
65392         title: t('zoom.out'),
65393         action: context.zoomOut,
65394         key: '-'
65395     }];
65396
65397
65398     function zoomIn() {
65399         event.preventDefault();
65400         context.zoomIn();
65401     }
65402
65403
65404     function zoomOut() {
65405         event.preventDefault();
65406         context.zoomOut();
65407     }
65408
65409
65410     function zoomInFurther() {
65411         event.preventDefault();
65412         context.zoomInFurther();
65413     }
65414
65415
65416     function zoomOutFurther() {
65417         event.preventDefault();
65418         context.zoomOutFurther();
65419     }
65420
65421
65422     return function(selection) {
65423         var button = selection.selectAll('button')
65424             .data(zooms)
65425             .enter()
65426             .append('button')
65427             .attr('tabindex', -1)
65428             .attr('class', function(d) { return d.id; })
65429             .on('click.editor', function(d) { d.action(); })
65430             .call(tooltip()
65431                 .placement((textDirection === 'rtl') ? 'right' : 'left')
65432                 .html(true)
65433                 .title(function(d) {
65434                     return uiTooltipHtml(d.title, d.key);
65435                 })
65436             );
65437
65438         button.each(function(d) {
65439             d3_select(this)
65440                 .call(svgIcon('#icon-' + d.icon, 'light'));
65441         });
65442
65443         var keybinding = d3keybinding('zoom');
65444
65445         ['plus', 'ffplus', '=', 'ffequals'].forEach(function(key) {
65446             keybinding.on([key], zoomIn);
65447             keybinding.on([uiCmd('⌘' + key)], zoomInFurther);
65448         });
65449
65450         ['_', '-', 'ffminus', 'dash'].forEach(function(key) {
65451             keybinding.on([key], zoomOut);
65452             keybinding.on([uiCmd('⌘' + key)], zoomOutFurther);
65453         });
65454
65455         d3_select(document)
65456             .call(keybinding);
65457     };
65458 }
65459
65460 function uiInit(context) {
65461     var uiInitCounter = 0;
65462
65463
65464     function render(container) {
65465         container
65466             .attr('dir', textDirection);
65467
65468         var map = context.map();
65469
65470         var hash = behaviorHash(context);
65471         hash();
65472
65473         if (!hash.hadHash) {
65474             map.centerZoom([0, 0], 2);
65475         }
65476
65477         container
65478             .append('svg')
65479             .attr('id', 'defs')
65480             .call(svgDefs(context));
65481
65482         container
65483             .append('div')
65484             .attr('id', 'sidebar')
65485             .attr('class', 'col4')
65486             .call(ui.sidebar);
65487
65488         var content = container
65489             .append('div')
65490             .attr('id', 'content')
65491             .attr('class', 'active');
65492
65493         var bar = content
65494             .append('div')
65495             .attr('id', 'bar')
65496             .attr('class', 'fillD');
65497
65498         content
65499             .append('div')
65500             .attr('id', 'map')
65501             .attr('dir', 'ltr')
65502             .call(map);
65503
65504         content
65505             .call(uiMapInMap(context))
65506             .call(uiInfo(context))
65507             .call(uiNotice(context));
65508
65509         bar
65510             .append('div')
65511             .attr('class', 'spacer col4');
65512
65513         var limiter = bar.append('div')
65514             .attr('class', 'limiter');
65515
65516         limiter
65517             .append('div')
65518             .attr('class', 'button-wrap joined col3')
65519             .call(uiModes(context), limiter);
65520
65521         limiter
65522             .append('div')
65523             .attr('class', 'button-wrap joined col1')
65524             .call(uiUndoRedo(context));
65525
65526         limiter
65527             .append('div')
65528             .attr('class', 'button-wrap col1')
65529             .call(uiSave(context));
65530
65531         bar
65532             .append('div')
65533             .attr('class', 'full-screen')
65534             .call(uiFullScreen(context));
65535
65536         bar
65537             .append('div')
65538             .attr('class', 'spinner')
65539             .call(uiSpinner(context));
65540
65541
65542         var controls = bar
65543             .append('div')
65544             .attr('class', 'map-controls');
65545
65546         controls
65547             .append('div')
65548             .attr('class', 'map-control zoombuttons')
65549             .call(uiZoom(context));
65550
65551         controls
65552             .append('div')
65553             .attr('class', 'map-control geolocate-control')
65554             .call(uiGeolocate(context));
65555
65556         controls
65557             .append('div')
65558             .attr('class', 'map-control background-control')
65559             .call(uiBackground(context));
65560
65561         controls
65562             .append('div')
65563             .attr('class', 'map-control map-data-control')
65564             .call(uiMapData(context));
65565
65566         controls
65567             .append('div')
65568             .attr('class', 'map-control help-control')
65569             .call(uiHelp(context));
65570
65571
65572         var about = content
65573             .append('div')
65574             .attr('id', 'about');
65575
65576         about
65577             .append('div')
65578             .attr('id', 'attrib')
65579             .attr('dir', 'ltr')
65580             .call(uiAttribution(context));
65581
65582         about
65583             .append('div')
65584             .attr('class', 'api-status')
65585             .call(uiStatus(context));
65586
65587
65588         var footer = about
65589             .append('div')
65590             .attr('id', 'footer')
65591             .attr('class', 'fillD');
65592
65593         footer
65594             .append('div')
65595             .attr('id', 'flash-wrap')
65596             .attr('class', 'footer-hide');
65597
65598         var footerWrap = footer
65599             .append('div')
65600             .attr('id', 'footer-wrap')
65601             .attr('class', 'footer-show');
65602
65603         footerWrap
65604             .append('div')
65605             .attr('id', 'scale-block')
65606             .call(uiScale(context));
65607
65608         var aboutList = footerWrap
65609             .append('div')
65610             .attr('id', 'info-block')
65611             .append('ul')
65612             .attr('id', 'about-list');
65613
65614         if (!context.embed()) {
65615             aboutList
65616                 .call(uiAccount(context));
65617         }
65618
65619         aboutList
65620             .append('li')
65621             .attr('class', 'version')
65622             .call(uiVersion(context));
65623
65624         var issueLinks = aboutList
65625             .append('li');
65626
65627         issueLinks
65628             .append('a')
65629             .attr('target', '_blank')
65630             .attr('tabindex', -1)
65631             .attr('href', 'https://github.com/openstreetmap/iD/issues')
65632             .call(svgIcon('#icon-bug', 'light'))
65633             .call(tooltip().title(t('report_a_bug')).placement('top'));
65634
65635         issueLinks
65636             .append('a')
65637             .attr('target', '_blank')
65638             .attr('tabindex', -1)
65639             .attr('href', 'https://github.com/openstreetmap/iD/blob/master/CONTRIBUTING.md#translating')
65640             .call(svgIcon('#icon-translate', 'light'))
65641             .call(tooltip().title(t('help_translate')).placement('top'));
65642
65643         aboutList
65644             .append('li')
65645             .attr('class', 'feature-warning')
65646             .attr('tabindex', -1)
65647             .call(uiFeatureInfo(context));
65648
65649         aboutList
65650             .append('li')
65651             .attr('class', 'user-list')
65652             .attr('tabindex', -1)
65653             .call(uiContributors(context));
65654
65655
65656         var photoviewer = content
65657             .append('div')
65658             .attr('id', 'photoviewer')
65659             .classed('al', true)       // 'al'=left,  'ar'=right
65660             .classed('hide', true);
65661
65662         photoviewer
65663             .append('button')
65664             .attr('class', 'thumb-hide')
65665             .on('click', function () {
65666                 if (services.mapillary) { services.mapillary.hideViewer(); }
65667                 if (services.openstreetcam) { services.openstreetcam.hideViewer(); }
65668             })
65669             .append('div')
65670             .call(svgIcon('#icon-close'));
65671
65672
65673         window.onbeforeunload = function() {
65674             return context.save();
65675         };
65676
65677         window.onunload = function() {
65678             context.history().unlock();
65679         };
65680
65681         var mapDimensions = map.dimensions();
65682
65683
65684         function onResize() {
65685             mapDimensions = utilGetDimensions(content, true);
65686             map.dimensions(mapDimensions);
65687         }
65688
65689         d3_select(window)
65690             .on('resize.editor', onResize);
65691
65692         onResize();
65693
65694         function pan(d) {
65695             return function() {
65696                 event.preventDefault();
65697                 context.pan(d, 100);
65698             };
65699         }
65700
65701
65702         // pan amount
65703         var pa = 80;
65704
65705         var keybinding = d3keybinding('main')
65706             .on('⌫', function() { event.preventDefault(); })
65707             .on('←', pan([pa, 0]))
65708             .on('↑', pan([0, pa]))
65709             .on('→', pan([-pa, 0]))
65710             .on('↓', pan([0, -pa]))
65711             .on(['⇧←', uiCmd('⌘←')], pan([mapDimensions[0], 0]))
65712             .on(['⇧↑', uiCmd('⌘↑')], pan([0, mapDimensions[1]]))
65713             .on(['⇧→', uiCmd('⌘→')], pan([-mapDimensions[0], 0]))
65714             .on(['⇧↓', uiCmd('⌘↓')], pan([0, -mapDimensions[1]]));
65715
65716         d3_select(document)
65717             .call(keybinding);
65718
65719         context.enter(modeBrowse(context));
65720
65721         if (!uiInitCounter++) {
65722             if (!hash.startWalkthrough) {
65723                 context.container()
65724                     .call(uiSplash(context))
65725                     .call(uiRestore(context));
65726             }
65727
65728             context.container()
65729                 .call(uiShortcuts(context));
65730         }
65731
65732         var osm = context.connection(),
65733             auth = uiLoading(context).message(t('loading_auth')).blocking(true);
65734
65735         if (osm && auth) {
65736             osm
65737                 .on('authLoading.ui', function() {
65738                     context.container()
65739                         .call(auth);
65740                 })
65741                 .on('authDone.ui', function() {
65742                     auth.close();
65743                 });
65744         }
65745
65746         uiInitCounter++;
65747
65748         if (hash.startWalkthrough) {
65749             hash.startWalkthrough = false;
65750             context.container().call(uiIntro(context));
65751         }
65752     }
65753
65754
65755     var renderCallback;
65756
65757     function ui(node, callback) {
65758         renderCallback = callback;
65759         var container = d3_select(node);
65760         context.container(container);
65761         context.loadLocale(function(err) {
65762             if (!err) {
65763                 render(container);
65764             }
65765             if (callback) {
65766                 callback(err);
65767             }
65768         });
65769     }
65770
65771
65772     ui.restart = function(arg) {
65773         context.locale(arg);
65774         context.loadLocale(function(err) {
65775             if (!err) {
65776                 context.container().selectAll('*').remove();
65777                 render(context.container());
65778                 if (renderCallback) renderCallback();
65779             }
65780         });
65781     };
65782
65783
65784     ui.sidebar = uiSidebar(context);
65785
65786     return ui;
65787 }
65788
65789 function uiChangesetEditor(context) {
65790     var dispatch$$1 = dispatch('change'),
65791         formFields = uiFormFields(context),
65792         fieldsArr,
65793         tags,
65794         changesetId;
65795
65796
65797
65798     function changesetEditor(selection) {
65799         render(selection);
65800     }
65801
65802
65803     function render(selection) {
65804         var initial = false;
65805
65806         if (!fieldsArr) {
65807             initial = true;
65808             var presets = context.presets();
65809
65810             fieldsArr = [
65811                 uiField(context, presets.field('comment'), null, { show: true, revert: false }),
65812                 uiField(context, presets.field('source'), null, { show: false, revert: false }),
65813                 uiField(context, presets.field('hashtags'), null, { show: false, revert: false }),
65814             ];
65815
65816             fieldsArr.forEach(function(field) {
65817                 field
65818                     .on('change', function(t$$1, onInput) {
65819                         dispatch$$1.call('change', field, t$$1, onInput);
65820                     });
65821             });
65822         }
65823
65824         fieldsArr.forEach(function(field) {
65825             field
65826                 .tags(tags);
65827         });
65828
65829
65830         selection
65831             .call(formFields.fieldsArr(fieldsArr));
65832
65833
65834         if (initial) {
65835             var commentField = selection.select('#preset-input-comment'),
65836                 commentNode = commentField.node();
65837
65838             if (commentNode) {
65839                 commentNode.focus();
65840                 commentNode.select();
65841             }
65842
65843             // trigger a 'blur' event so that comment field can be cleaned
65844             // and checked for hashtags, even if retrieved from localstorage
65845             utilTriggerEvent(commentField, 'blur');
65846
65847             var osm = context.connection();
65848             if (osm) {
65849                 osm.userChangesets(function (err, changesets) {
65850                     if (err) return;
65851
65852                     var comments = changesets.map(function(changeset) {
65853                         return {
65854                             title: changeset.tags.comment,
65855                             value: changeset.tags.comment
65856                         };
65857                     });
65858
65859                     commentField
65860                         .call(d3combobox()
65861                             .container(context.container())
65862                             .caseSensitive(true)
65863                             .data(uniqBy(comments, 'title'))
65864                         );
65865                 });
65866             }
65867         }
65868
65869         // Add warning if comment mentions Google
65870         var hasGoogle = tags.comment.match(/google/i);
65871         var commentWarning = selection.select('.form-field-comment').selectAll('.comment-warning')
65872             .data(hasGoogle ? [0] : []);
65873
65874         commentWarning.exit()
65875             .transition()
65876             .duration(200)
65877             .style('opacity', 0)
65878             .remove();
65879
65880         var commentEnter = commentWarning.enter()
65881             .insert('div', '.tag-reference-body')
65882             .attr('class', 'field-warning comment-warning')
65883             .style('opacity', 0);
65884
65885         commentEnter
65886             .append('a')
65887             .attr('target', '_blank')
65888             .attr('tabindex', -1)
65889             .call(svgIcon('#icon-alert', 'inline'))
65890             .attr('href', t('commit.google_warning_link'))
65891             .append('span')
65892             .text(t('commit.google_warning'));
65893
65894         commentEnter
65895             .transition()
65896             .duration(200)
65897             .style('opacity', 1);
65898     }
65899
65900
65901     changesetEditor.tags = function(_) {
65902         if (!arguments.length) return tags;
65903         tags = _;
65904         // Don't reset fieldsArr here.
65905         return changesetEditor;
65906     };
65907
65908
65909     changesetEditor.changesetID = function(_) {
65910         if (!arguments.length) return changesetId;
65911         if (changesetId === _) return changesetEditor;
65912         changesetId = _;
65913         fieldsArr = null;
65914         return changesetEditor;
65915     };
65916
65917
65918     return utilRebind(changesetEditor, dispatch$$1, 'on');
65919 }
65920
65921 /**
65922  * This method is like `_.union` except that it accepts `iteratee` which is
65923  * invoked for each element of each `arrays` to generate the criterion by
65924  * which uniqueness is computed. Result values are chosen from the first
65925  * array in which the value occurs. The iteratee is invoked with one argument:
65926  * (value).
65927  *
65928  * @static
65929  * @memberOf _
65930  * @since 4.0.0
65931  * @category Array
65932  * @param {...Array} [arrays] The arrays to inspect.
65933  * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
65934  * @returns {Array} Returns the new array of combined values.
65935  * @example
65936  *
65937  * _.unionBy([2.1], [1.2, 2.3], Math.floor);
65938  * // => [2.1, 1.2]
65939  *
65940  * // The `_.property` iteratee shorthand.
65941  * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
65942  * // => [{ 'x': 1 }, { 'x': 2 }]
65943  */
65944 var unionBy = baseRest(function(arrays) {
65945   var iteratee = last(arrays);
65946   if (isArrayLikeObject(iteratee)) {
65947     iteratee = undefined;
65948   }
65949   return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), baseIteratee(iteratee, 2));
65950 });
65951
65952 function uiCommitChanges(context) {
65953     var _entityID;
65954     var detected = utilDetect();
65955
65956
65957     function commitChanges(selection) {
65958
65959         var history = context.history(),
65960             summary = history.difference().summary();
65961
65962         var container = selection.selectAll('.modal-section.commit-section')
65963             .data([0]);
65964
65965         var containerEnter = container.enter()
65966             .append('div')
65967             .attr('class', 'commit-section modal-section fillL2');
65968
65969         containerEnter
65970             .append('h3')
65971             .text(t('commit.changes', { count: summary.length }));
65972
65973         containerEnter
65974             .append('ul')
65975             .attr('class', 'changeset-list');
65976
65977         container = containerEnter
65978             .merge(container);
65979
65980
65981         var items = container.select('ul').selectAll('li')
65982             .data(summary);
65983
65984         var itemsEnter = items.enter()
65985             .append('li')
65986             .attr('class', 'change-item');
65987
65988         itemsEnter
65989             .each(function(d) {
65990                 d3_select(this)
65991                     .call(svgIcon('#icon-' + d.entity.geometry(d.graph), 'pre-text ' + d.changeType));
65992             });
65993
65994         itemsEnter
65995             .append('span')
65996             .attr('class', 'change-type')
65997             .text(function(d) { return t('commit.' + d.changeType) + ' '; });
65998
65999         itemsEnter
66000             .append('strong')
66001             .attr('class', 'entity-type')
66002             .text(function(d) {
66003                 var matched = context.presets().match(d.entity, d.graph);
66004                 return (matched && matched.name()) || utilDisplayType(d.entity.id);
66005             });
66006
66007         itemsEnter
66008             .append('span')
66009             .attr('class', 'entity-name')
66010             .text(function(d) {
66011                 var name = utilDisplayName(d.entity) || '',
66012                     string = '';
66013                 if (name !== '') {
66014                     string += ':';
66015                 }
66016                 return string += ' ' + name;
66017             });
66018
66019         itemsEnter
66020             .style('opacity', 0)
66021             .transition()
66022             .style('opacity', 1);
66023
66024         items = itemsEnter
66025             .merge(items);
66026
66027         items
66028             .on('mouseover', mouseover)
66029             .on('mouseout', mouseout)
66030             .on('click', click);
66031
66032
66033         // Download changeset link
66034         var changeset = new osmChangeset().update({ id: undefined }),
66035             changes = history.changes(actionDiscardTags(history.difference()));
66036
66037         delete changeset.id;  // Export without chnageset_id
66038
66039         var data = JXON.stringify(changeset.osmChangeJXON(changes)),
66040             blob = new Blob([data], {type: 'text/xml;charset=utf-8;'}),
66041             fileName = 'changes.osc';
66042
66043         var linkEnter = container.selectAll('.download-changes')
66044             .data([0])
66045             .enter()
66046             .append('a')
66047             .attr('class', 'download-changes');
66048
66049         if (detected.download) {      // All except IE11 and Edge
66050             linkEnter                 // download the data as a file
66051                 .attr('href', window.URL.createObjectURL(blob))
66052                 .attr('download', fileName);
66053
66054         } else {                      // IE11 and Edge
66055             linkEnter                 // open data uri in a new tab
66056                 .attr('target', '_blank')
66057                 .on('click.download', function() {
66058                     navigator.msSaveBlob(blob, fileName);
66059                 });
66060         }
66061
66062         linkEnter
66063             .call(svgIcon('#icon-load', 'inline'))
66064             .append('span')
66065             .text(t('commit.download_changes'));
66066
66067
66068         function mouseover(d) {
66069             if (d.entity) {
66070                 context.surface().selectAll(
66071                     utilEntityOrMemberSelector([d.entity.id], context.graph())
66072                 ).classed('hover', true);
66073             }
66074         }
66075
66076
66077         function mouseout() {
66078             context.surface().selectAll('.hover')
66079                 .classed('hover', false);
66080         }
66081
66082
66083         function click(change) {
66084             if (change.changeType === 'deleted') {
66085                 _entityID = null;
66086             } else {
66087                 var entity = change.entity;
66088                 _entityID = change.entity.id;
66089                 context.map().zoomTo(entity);
66090                 context.surface().selectAll(utilEntityOrMemberSelector([_entityID], context.graph()))
66091                     .classed('hover', true);
66092             }
66093         }
66094     }
66095
66096
66097     commitChanges.entityID = function(_) {
66098         if (!arguments.length) return _entityID;
66099         _entityID = _;
66100         return commitChanges;
66101     };
66102
66103
66104
66105     return commitChanges;
66106 }
66107
66108 function uiCommitWarnings(context) {
66109
66110     function commitWarnings(selection) {
66111
66112         var changes = context.history().changes();
66113         var warnings = context.history().validate(changes);
66114
66115         var container = selection.selectAll('.warning-section')
66116             .data(warnings.length ? [0] : []);
66117
66118         container.exit()
66119             .remove();
66120
66121         var containerEnter = container.enter()
66122             .append('div')
66123             .attr('class', 'modal-section warning-section fillL2');
66124
66125         containerEnter
66126             .append('h3')
66127             .text(t('commit.warnings'));
66128
66129         containerEnter
66130             .append('ul')
66131             .attr('class', 'changeset-list');
66132
66133         container = containerEnter
66134             .merge(container);
66135
66136
66137         var items = container.select('ul').selectAll('li')
66138             .data(warnings);
66139
66140         items.exit()
66141             .remove();
66142
66143         var itemsEnter = items.enter()
66144             .append('li')
66145             .attr('class', 'warning-item');
66146
66147         itemsEnter
66148             .call(svgIcon('#icon-alert', 'pre-text'));
66149
66150         itemsEnter
66151             .append('strong')
66152             .text(function(d) { return d.message; });
66153
66154         itemsEnter.filter(function(d) { return d.tooltip; })
66155             .call(tooltip()
66156                 .title(function(d) { return d.tooltip; })
66157                 .placement('top')
66158             );
66159
66160         items = itemsEnter
66161             .merge(items);
66162
66163         items
66164             .on('mouseover', mouseover)
66165             .on('mouseout', mouseout)
66166             .on('click', warningClick);
66167
66168
66169         function mouseover(d) {
66170             if (d.entity) {
66171                 context.surface().selectAll(
66172                     utilEntityOrMemberSelector([d.entity.id], context.graph())
66173                 ).classed('hover', true);
66174             }
66175         }
66176
66177
66178         function mouseout() {
66179             context.surface().selectAll('.hover')
66180                 .classed('hover', false);
66181         }
66182
66183
66184         function warningClick(d) {
66185             if (d.entity) {
66186                 context.map().zoomTo(d.entity);
66187                 context.enter(modeSelect(context, [d.entity.id]));
66188             }
66189         }
66190
66191     }
66192
66193
66194     return commitWarnings;
66195 }
66196
66197 var _changeset$1;
66198 var readOnlyTags = [
66199     /^_changesets_count$/,
66200     /^created_by$/,
66201     /^ideditor:/,
66202     /^imagery_used$/,
66203     /^host$/,
66204     /^locale$/
66205 ];
66206
66207 // treat most punctuation (except -, _, +, &) as hashtag delimiters - #4398
66208 // from https://stackoverflow.com/a/25575009
66209 var hashtagRegex = /(#[^\u2000-\u206F\u2E00-\u2E7F\s\\'!"#$%()*,.\/:;<=>?@\[\]^`{|}~]+)/g;
66210
66211
66212 function uiCommit(context) {
66213     var dispatch$$1 = dispatch('cancel', 'save');
66214     var _userDetails;
66215     var _selection;
66216
66217     var changesetEditor = uiChangesetEditor(context)
66218         .on('change', changeTags);
66219     var rawTagEditor = uiRawTagEditor(context)
66220         .on('change', changeTags);
66221     var commitChanges = uiCommitChanges(context);
66222     var commitWarnings = uiCommitWarnings(context);
66223
66224
66225     function commit(selection) {
66226         _selection = selection;
66227
66228         var osm = context.connection();
66229         if (!osm) return;
66230
66231         // expire stored comment and hashtags after cutoff datetime - #3947
66232         var commentDate = +context.storage('commentDate') || 0;
66233         var currDate = Date.now();
66234         var cutoff = 2 * 86400 * 1000;   // 2 days
66235         if (commentDate > currDate || currDate - commentDate > cutoff) {
66236             context.storage('comment', null);
66237             context.storage('hashtags', null);
66238         }
66239
66240         var tags;
66241         if (!_changeset$1) {
66242             var detected = utilDetect();
66243             tags = {
66244                 comment: context.storage('comment') || '',
66245                 created_by: ('iD ' + context.version).substr(0, 255),
66246                 host: detected.host.substr(0, 255),
66247                 locale: detected.locale.substr(0, 255)
66248             };
66249
66250             // call findHashtags initially - this will remove stored
66251             // hashtags if any hashtags are found in the comment - #4304
66252             findHashtags(tags, true);
66253
66254             var hashtags = context.storage('hashtags');
66255             if (hashtags) {
66256                 tags.hashtags = hashtags;
66257             }
66258
66259             _changeset$1 = new osmChangeset({ tags: tags });
66260         }
66261
66262         tags = clone(_changeset$1.tags);
66263         tags.imagery_used = context.history().imageryUsed().join(';').substr(0, 255);
66264         _changeset$1 = _changeset$1.update({ tags: tags });
66265
66266         var header = selection.selectAll('.header')
66267             .data([0]);
66268
66269         header.enter()
66270             .append('div')
66271             .attr('class', 'header fillL')
66272             .append('h3')
66273             .text(t('commit.title'));
66274
66275         var body = selection.selectAll('.body')
66276             .data([0]);
66277
66278         body = body.enter()
66279             .append('div')
66280             .attr('class', 'body')
66281             .merge(body);
66282
66283
66284         // Changeset Section
66285         var changesetSection = body.selectAll('.changeset-editor')
66286             .data([0]);
66287
66288         changesetSection = changesetSection.enter()
66289             .append('div')
66290             .attr('class', 'modal-section changeset-editor')
66291             .merge(changesetSection);
66292
66293         changesetSection
66294             .call(changesetEditor
66295                 .changesetID(_changeset$1.id)
66296                 .tags(tags)
66297             );
66298
66299
66300         // Warnings
66301         body.call(commitWarnings);
66302
66303
66304         // Upload Explanation
66305         var saveSection = body.selectAll('.save-section')
66306             .data([0]);
66307
66308         saveSection = saveSection.enter()
66309             .append('div')
66310             .attr('class','modal-section save-section fillL cf')
66311             .merge(saveSection);
66312
66313         var prose = saveSection.selectAll('.commit-info')
66314             .data([0]);
66315
66316         prose = prose.enter()
66317             .append('p')
66318             .attr('class', 'commit-info')
66319             .text(t('commit.upload_explanation'))
66320             .merge(prose);
66321
66322         osm.userDetails(function(err, user) {
66323             if (err) return;
66324
66325             var userLink = d3_select(document.createElement('div'));
66326
66327             _userDetails = user;
66328
66329             if (user.image_url) {
66330                 userLink
66331                     .append('img')
66332                     .attr('src', user.image_url)
66333                     .attr('class', 'icon pre-text user-icon');
66334             }
66335
66336             userLink
66337                 .append('a')
66338                 .attr('class','user-info')
66339                 .text(user.display_name)
66340                 .attr('href', osm.userURL(user.display_name))
66341                 .attr('tabindex', -1)
66342                 .attr('target', '_blank');
66343
66344             prose
66345                 .html(t('commit.upload_explanation_with_user', { user: userLink.html() }));
66346         });
66347
66348
66349         // Request Review
66350         var requestReview = saveSection.selectAll('.request-review')
66351             .data([0]);
66352
66353         // Enter
66354         var requestReviewEnter = requestReview.enter()
66355             .append('div')
66356             .attr('class', 'request-review');
66357
66358         var labelEnter = requestReviewEnter
66359             .append('label')
66360             .attr('for', 'commit-input-request-review');
66361
66362         labelEnter
66363             .append('input')
66364             .attr('type', 'checkbox')
66365             .attr('id', 'commit-input-request-review');
66366
66367         labelEnter
66368             .append('span')
66369             .text(t('commit.request_review'));
66370
66371         // Update
66372         requestReview = requestReview
66373             .merge(requestReviewEnter);
66374
66375         var requestReviewInput = requestReview.selectAll('input')
66376             .property('checked', isReviewRequested(_changeset$1.tags))
66377             .on('change', toggleRequestReview);
66378
66379
66380         // Buttons
66381         var buttonSection = saveSection.selectAll('.buttons')
66382             .data([0]);
66383
66384         // enter
66385         var buttonEnter = buttonSection.enter()
66386             .append('div')
66387             .attr('class', 'buttons fillL cf');
66388
66389         buttonEnter
66390             .append('button')
66391             .attr('class', 'secondary-action col5 button cancel-button')
66392             .append('span')
66393             .attr('class', 'label')
66394             .text(t('commit.cancel'));
66395
66396         buttonEnter
66397             .append('button')
66398             .attr('class', 'action col5 button save-button')
66399             .append('span')
66400             .attr('class', 'label')
66401             .text(t('commit.save'));
66402
66403         // update
66404         buttonSection = buttonSection
66405             .merge(buttonEnter);
66406
66407         buttonSection.selectAll('.cancel-button')
66408             .on('click.cancel', function() {
66409                 var selectedID = commitChanges.entityID();
66410                 dispatch$$1.call('cancel', this, selectedID);
66411             });
66412
66413         buttonSection.selectAll('.save-button')
66414             .attr('disabled', function() {
66415                 var n = d3_select('#preset-input-comment').node();
66416                 return (n && n.value.length) ? null : true;
66417             })
66418             .on('click.save', function() {
66419                 this.blur();    // avoid keeping focus on the button - #4641
66420                 dispatch$$1.call('save', this, _changeset$1);
66421             });
66422
66423
66424         // Raw Tag Editor
66425         var tagSection = body.selectAll('.tag-section.raw-tag-editor')
66426             .data([0]);
66427
66428         tagSection = tagSection.enter()
66429             .append('div')
66430             .attr('class', 'modal-section tag-section raw-tag-editor')
66431             .merge(tagSection);
66432
66433         var expanded = !tagSection.selectAll('a.hide-toggle.expanded').empty();
66434         tagSection
66435             .call(rawTagEditor
66436                 .expanded(expanded)
66437                 .readOnlyTags(readOnlyTags)
66438                 .tags(clone(_changeset$1.tags))
66439             );
66440
66441
66442         // Change summary
66443         body.call(commitChanges);
66444
66445
66446         function toggleRequestReview() {
66447             var rr = requestReviewInput.property('checked');
66448             updateChangeset({ review_requested: (rr ? 'yes' : undefined) });
66449
66450             var expanded = !tagSection.selectAll('a.hide-toggle.expanded').empty();
66451             tagSection
66452                 .call(rawTagEditor
66453                     .expanded(expanded)
66454                     .readOnlyTags(readOnlyTags)
66455                     .tags(clone(_changeset$1.tags))
66456                 );
66457         }
66458     }
66459
66460
66461     function changeTags(changed, onInput) {
66462         if (changed.hasOwnProperty('comment')) {
66463             if (changed.comment === undefined) {
66464                 changed.comment = '';
66465             }
66466             if (!onInput) {
66467                 context.storage('comment', changed.comment);
66468                 context.storage('commentDate', Date.now());
66469             }
66470         }
66471
66472         updateChangeset(changed, onInput);
66473
66474         if (_selection) {
66475             _selection.call(commit);
66476         }
66477     }
66478
66479
66480     function findHashtags(tags, commentOnly) {
66481         var inComment = commentTags();
66482         var inHashTags = hashTags();
66483
66484         if (inComment !== null) {                    // when hashtags are detected in comment...
66485             context.storage('hashtags', null);       // always remove stored hashtags - #4304
66486             if (commentOnly) { inHashTags = null; }  // optionally override hashtags field
66487         }
66488         return unionBy(inComment, inHashTags, function (s) {
66489             return s.toLowerCase();
66490         });
66491
66492         // Extract hashtags from `comment`
66493         function commentTags() {
66494             return tags.comment
66495                 .replace(/http\S*/g, '')  // drop anything that looks like a URL - #4289
66496                 .match(hashtagRegex);
66497         }
66498
66499         // Extract and clean hashtags from `hashtags`
66500         function hashTags() {
66501             var t$$1 = tags.hashtags || '';
66502             return t$$1
66503                 .split(/[,;\s]+/)
66504                 .map(function (s) {
66505                     if (s[0] !== '#') { s = '#' + s; }    // prepend '#'
66506                     var matched = s.match(hashtagRegex);
66507                     return matched && matched[0];
66508                 }).filter(Boolean);                       // exclude falsey
66509         }
66510     }
66511
66512
66513     function isReviewRequested(tags) {
66514         var rr = tags.review_requested;
66515         if (rr === undefined) return false;
66516         rr = rr.trim().toLowerCase();
66517         return !(rr === '' || rr === 'no');
66518     }
66519
66520
66521     function updateChangeset(changed, onInput) {
66522         var tags = clone(_changeset$1.tags);
66523
66524         forEach(changed, function(v, k) {
66525             k = k.trim().substr(0, 255);
66526             if (readOnlyTags.indexOf(k) !== -1) return;
66527
66528             if (k !== '' && v !== undefined) {
66529                 if (onInput) {
66530                     tags[k] = v;
66531                 } else {
66532                     tags[k] = v.trim().substr(0, 255);
66533                 }
66534             } else {
66535                 delete tags[k];
66536             }
66537         });
66538
66539         if (!onInput) {
66540             // when changing the comment, override hashtags with any found in comment.
66541             var commentOnly = changed.hasOwnProperty('comment') && (changed.comment !== '');
66542             var arr = findHashtags(tags, commentOnly);
66543             if (arr.length) {
66544                 tags.hashtags = arr.join(';').substr(0, 255);
66545                 context.storage('hashtags', tags.hashtags);
66546             } else {
66547                 delete tags.hashtags;
66548                 context.storage('hashtags', null);
66549             }
66550         }
66551
66552         // always update userdetails, just in case user reauthenticates as someone else
66553         if (_userDetails && _userDetails.changesets_count !== undefined) {
66554             var changesetsCount = parseInt(_userDetails.changesets_count, 10) + 1;  // #4283
66555             tags.changesets_count = String(changesetsCount);
66556
66557             // first 100 edits - new user
66558             if (changesetsCount <= 100) {
66559                 var s;
66560                 s = context.storage('walkthrough_completed');
66561                 if (s) {
66562                     tags['ideditor:walkthrough_completed'] = s;
66563                 }
66564
66565                 s = context.storage('walkthrough_progress');
66566                 if (s) {
66567                     tags['ideditor:walkthrough_progress'] = s;
66568                 }
66569
66570                 s = context.storage('walkthrough_started');
66571                 if (s) {
66572                     tags['ideditor:walkthrough_started'] = s;
66573                 }
66574             }
66575         } else {
66576             delete tags.changesets_count;
66577         }
66578
66579         if (!isEqual(_changeset$1.tags, tags)) {
66580             _changeset$1 = _changeset$1.update({ tags: tags });
66581         }
66582     }
66583
66584
66585     commit.reset = function() {
66586         _changeset$1 = null;
66587     };
66588
66589
66590     return utilRebind(commit, dispatch$$1, 'on');
66591 }
66592
66593 function uiConfirm(selection) {
66594     var modalSelection = uiModal(selection);
66595
66596     modalSelection.select('.modal')
66597         .classed('modal-alert', true);
66598
66599     var section = modalSelection.select('.content');
66600
66601     section.append('div')
66602         .attr('class', 'modal-section header');
66603
66604     section.append('div')
66605         .attr('class', 'modal-section message-text');
66606
66607     var buttons = section.append('div')
66608         .attr('class', 'modal-section buttons cf');
66609
66610
66611     modalSelection.okButton = function() {
66612         buttons
66613             .append('button')
66614             .attr('class', 'action col4')
66615             .on('click.confirm', function() {
66616                 modalSelection.remove();
66617             })
66618             .text(t('confirm.okay'))
66619             .node()
66620             .focus();
66621
66622         return modalSelection;
66623     };
66624
66625
66626     return modalSelection;
66627 }
66628
66629 function uiConflicts(context) {
66630     var dispatch$$1 = dispatch('cancel', 'save');
66631     var keybinding = d3keybinding('conflicts');
66632     var _origChanges;
66633     var _conflictList;
66634
66635
66636     function keybindingOn() {
66637         d3_select(document)
66638             .call(keybinding.on('⎋', cancel, true));
66639     }
66640
66641     function keybindingOff() {
66642         d3_select(document)
66643             .call(keybinding.off);
66644     }
66645
66646     function tryAgain() {
66647         keybindingOff();
66648         dispatch$$1.call('save');
66649     }
66650
66651     function cancel() {
66652         keybindingOff();
66653         dispatch$$1.call('cancel');
66654     }
66655
66656
66657     function conflicts(selection) {
66658         keybindingOn();
66659
66660         var headerEnter = selection.selectAll('.header')
66661             .data([0])
66662             .enter()
66663             .append('div')
66664             .attr('class', 'header fillL');
66665
66666         headerEnter
66667             .append('button')
66668             .attr('class', 'fr')
66669             .on('click', cancel)
66670             .call(svgIcon('#icon-close'));
66671
66672         headerEnter
66673             .append('h3')
66674             .text(t('save.conflict.header'));
66675
66676         var bodyEnter = selection.selectAll('.body')
66677             .data([0])
66678             .enter()
66679             .append('div')
66680             .attr('class', 'body fillL');
66681
66682         var conflictsHelpEnter = bodyEnter
66683             .append('div')
66684             .attr('class', 'conflicts-help')
66685             .text(t('save.conflict.help'));
66686
66687
66688         // Download changes link
66689         var detected = utilDetect();
66690         var changeset = new osmChangeset();
66691
66692         delete changeset.id;  // Export without changeset_id
66693
66694         var data = JXON.stringify(changeset.osmChangeJXON(_origChanges));
66695         var blob = new Blob([data], { type: 'text/xml;charset=utf-8;' });
66696         var fileName = 'changes.osc';
66697
66698         var linkEnter = conflictsHelpEnter.selectAll('.download-changes')
66699             .append('a')
66700             .attr('class', 'download-changes');
66701
66702         if (detected.download) {      // All except IE11 and Edge
66703             linkEnter                 // download the data as a file
66704                 .attr('href', window.URL.createObjectURL(blob))
66705                 .attr('download', fileName);
66706
66707         } else {                      // IE11 and Edge
66708             linkEnter                 // open data uri in a new tab
66709                 .attr('target', '_blank')
66710                 .on('click.download', function() {
66711                     navigator.msSaveBlob(blob, fileName);
66712                 });
66713         }
66714
66715         linkEnter
66716             .call(svgIcon('#icon-load', 'inline'))
66717             .append('span')
66718             .text(t('save.conflict.download_changes'));
66719
66720
66721         bodyEnter
66722             .append('div')
66723             .attr('class', 'conflict-container fillL3')
66724             .call(showConflict, 0);
66725
66726         bodyEnter
66727             .append('div')
66728             .attr('class', 'conflicts-done')
66729             .attr('opacity', 0)
66730             .style('display', 'none')
66731             .text(t('save.conflict.done'));
66732
66733         var buttonsEnter = bodyEnter
66734             .append('div')
66735             .attr('class','buttons col12 joined conflicts-buttons');
66736
66737         buttonsEnter
66738             .append('button')
66739             .attr('disabled', _conflictList.length > 1)
66740             .attr('class', 'action conflicts-button col6')
66741             .text(t('save.title'))
66742             .on('click.try_again', tryAgain);
66743
66744         buttonsEnter
66745             .append('button')
66746             .attr('class', 'secondary-action conflicts-button col6')
66747             .text(t('confirm.cancel'))
66748             .on('click.cancel', cancel);
66749     }
66750
66751
66752     function showConflict(selection, index) {
66753         index = utilWrap(index, _conflictList.length);
66754
66755         var parent = d3_select(selection.node().parentNode);
66756
66757         // enable save button if this is the last conflict being reviewed..
66758         if (index === _conflictList.length - 1) {
66759             window.setTimeout(function() {
66760                 parent.select('.conflicts-button')
66761                     .attr('disabled', null);
66762
66763                 parent.select('.conflicts-done')
66764                     .transition()
66765                     .attr('opacity', 1)
66766                     .style('display', 'block');
66767             }, 250);
66768         }
66769
66770         var conflict = selection
66771             .selectAll('.conflict')
66772             .data([_conflictList[index]]);
66773
66774         conflict.exit()
66775             .remove();
66776
66777         var conflictEnter = conflict.enter()
66778             .append('div')
66779             .attr('class', 'conflict');
66780
66781         conflictEnter
66782             .append('h4')
66783             .attr('class', 'conflict-count')
66784             .text(t('save.conflict.count', { num: index + 1, total: _conflictList.length }));
66785
66786         conflictEnter
66787             .append('a')
66788             .attr('class', 'conflict-description')
66789             .attr('href', '#')
66790             .text(function(d) { return d.name; })
66791             .on('click', function(d) {
66792                 event.preventDefault();
66793                 zoomToEntity(d.id);
66794             });
66795
66796         var details = conflictEnter
66797             .append('div')
66798             .attr('class', 'conflict-detail-container');
66799
66800         details
66801             .append('ul')
66802             .attr('class', 'conflict-detail-list')
66803             .selectAll('li')
66804             .data(function(d) { return d.details || []; })
66805             .enter()
66806             .append('li')
66807             .attr('class', 'conflict-detail-item')
66808             .html(function(d) { return d; });
66809
66810         details
66811             .append('div')
66812             .attr('class', 'conflict-choices')
66813             .call(addChoices);
66814
66815         details
66816             .append('div')
66817             .attr('class', 'conflict-nav-buttons joined cf')
66818             .selectAll('button')
66819             .data(['previous', 'next'])
66820             .enter()
66821             .append('button')
66822             .text(function(d) { return t('save.conflict.' + d); })
66823             .attr('class', 'conflict-nav-button action col6')
66824             .attr('disabled', function(d, i) {
66825                 return (i === 0 && index === 0) ||
66826                     (i === 1 && index === _conflictList.length - 1) || null;
66827             })
66828             .on('click', function(d, i) {
66829                 event.preventDefault();
66830
66831                 var container = parent.selectAll('.conflict-container');
66832                 var sign = (i === 0 ? -1 : 1);
66833
66834                 container
66835                     .selectAll('.conflict')
66836                     .remove();
66837
66838                 container
66839                     .call(showConflict, index + sign);
66840             });
66841
66842     }
66843
66844
66845     function addChoices(selection) {
66846         var choices = selection
66847             .append('ul')
66848             .attr('class', 'layer-list')
66849             .selectAll('li')
66850             .data(function(d) { return d.choices || []; });
66851
66852         // enter
66853         var choicesEnter = choices.enter()
66854             .append('li')
66855             .attr('class', 'layer');
66856
66857         var labelEnter = choicesEnter
66858             .append('label');
66859
66860         labelEnter
66861             .append('input')
66862             .attr('type', 'radio')
66863             .attr('name', function(d) { return d.id; })
66864             .on('change', function(d, i) {
66865                 var ul = this.parentNode.parentNode.parentNode;
66866                 ul.__data__.chosen = i;
66867                 choose(ul, d);
66868             });
66869
66870         labelEnter
66871             .append('span')
66872             .text(function(d) { return d.text; });
66873
66874         // update
66875         choicesEnter
66876             .merge(choices)
66877             .each(function(d, i) {
66878                 var ul = this.parentNode;
66879                 if (ul.__data__.chosen === i) {
66880                     choose(ul, d);
66881                 }
66882             });
66883     }
66884
66885
66886     function choose(ul, datum) {
66887         if (event) event.preventDefault();
66888
66889         d3_select(ul)
66890             .selectAll('li')
66891             .classed('active', function(d) { return d === datum; })
66892             .selectAll('input')
66893             .property('checked', function(d) { return d === datum; });
66894
66895         var extent = geoExtent();
66896         var entity;
66897
66898         entity = context.graph().hasEntity(datum.id);
66899         if (entity) extent._extend(entity.extent(context.graph()));
66900
66901         datum.action();
66902
66903         entity = context.graph().hasEntity(datum.id);
66904         if (entity) extent._extend(entity.extent(context.graph()));
66905
66906         zoomToEntity(datum.id, extent);
66907     }
66908
66909
66910     function zoomToEntity(id, extent) {
66911         context.surface().selectAll('.hover')
66912             .classed('hover', false);
66913
66914         var entity = context.graph().hasEntity(id);
66915         if (entity) {
66916             if (extent) {
66917                 context.map().trimmedExtent(extent);
66918             } else {
66919                 context.map().zoomTo(entity);
66920             }
66921             context.surface().selectAll(utilEntityOrMemberSelector([entity.id], context.graph()))
66922                 .classed('hover', true);
66923         }
66924     }
66925
66926
66927     // The conflict list should be an array of objects like:
66928     // {
66929     //     id: id,
66930     //     name: entityName(local),
66931     //     details: merge.conflicts(),
66932     //     chosen: 1,
66933     //     choices: [
66934     //         choice(id, keepMine, forceLocal),
66935     //         choice(id, keepTheirs, forceRemote)
66936     //     ]
66937     // }
66938     conflicts.conflictList = function(_) {
66939         if (!arguments.length) return _conflictList;
66940         _conflictList = _;
66941         return conflicts;
66942     };
66943
66944
66945     conflicts.origChanges = function(_) {
66946         if (!arguments.length) return _origChanges;
66947         _origChanges = _;
66948         return conflicts;
66949     };
66950
66951
66952     return utilRebind(conflicts, dispatch$$1, 'on');
66953 }
66954
66955 function uiEditMenu(context, operations) {
66956     var menu,
66957         center = [0, 0],
66958         offset = [0, 0],
66959         tooltip;
66960
66961     var p = 8,               // top padding
66962         m = 4,               // top margin
66963         h = 15,              // height of icon
66964         vpBottomMargin = 45, // viewport bottom margin
66965         vpSideMargin = 35,   // viewport side margin
66966         buttonWidth = 44,
66967         buttonHeight = (2 * p + h),
66968         menuWidth = buttonWidth,
66969         menuHeight = (2 * m) + operations.length * buttonHeight,
66970         menuSideMargin = 10,
66971         tooltipWidth = 200,
66972         tooltipHeight = 200;  // a reasonable guess, real height depends on tooltip contents
66973
66974
66975     var editMenu = function (selection) {
66976         if (!operations.length) return;
66977
66978         selection.node().parentNode.focus();
66979
66980         var isRTL = textDirection === 'rtl',
66981             viewport = context.surfaceRect();
66982
66983         if (!isRTL && (center[0] + menuSideMargin + menuWidth) > (viewport.width - vpSideMargin)) {
66984             // menu is going left-to-right and near right viewport edge, go left instead
66985             isRTL = true;
66986         } else if (isRTL && (center[0] - menuSideMargin - menuWidth) < vpSideMargin) {
66987             // menu is going right-to-left and near left viewport edge, go right instead
66988             isRTL = false;
66989         }
66990
66991         offset[0] = (isRTL ? -1 * (menuSideMargin + menuWidth) : menuSideMargin);
66992
66993         if (center[1] + menuHeight > (viewport.height - vpBottomMargin)) {
66994             // menu is near bottom viewport edge, shift upwards
66995             offset[1] = -1 * (center[1] + menuHeight - viewport.height + vpBottomMargin);
66996         }
66997
66998         var origin = [ center[0] + offset[0], center[1] + offset[1] ];
66999
67000         menu = selection
67001             .append('g')
67002             .attr('class', 'edit-menu')
67003             .attr('transform', 'translate(' + origin + ')')
67004             .attr('opacity', 0);
67005
67006         menu
67007             .transition()
67008             .attr('opacity', 1);
67009
67010         menu
67011             .append('rect')
67012             .attr('class', 'edit-menu-background')
67013             .attr('x', 4)
67014             .attr('rx', 4)
67015             .attr('ry', 4)
67016             .attr('width', menuWidth)
67017             .attr('height', menuHeight)
67018             .attr('stroke-linecap', 'round');
67019
67020
67021         var button = menu.selectAll('.edit-menu-item')
67022             .data(operations)
67023             .enter()
67024             .append('g')
67025             .attr('class', function (d) { return 'edit-menu-item edit-menu-item-' + d.id; })
67026             .classed('disabled', function (d) { return d.disabled(); })
67027             .attr('transform', function (d, i) {
67028                 return 'translate(' + geoVecFloor([
67029                     0,
67030                     m + i * buttonHeight
67031                 ]).join(',') + ')';
67032             });
67033
67034         button
67035             .append('rect')
67036             .attr('x', 4)
67037             .attr('width', buttonWidth)
67038             .attr('height', buttonHeight)
67039             .on('click', click)
67040             .on('mousedown', mousedown)
67041             .on('mouseover', mouseover)
67042             .on('mouseout', mouseout);
67043
67044         button
67045             .append('use')
67046             .attr('width', '20')
67047             .attr('height', '20')
67048             .attr('transform', function () {
67049                 return 'translate(' + [2 * p, 5] + ')';
67050             })
67051             .attr('xlink:href', function (d) { return '#operation-' + d.id; });
67052
67053         tooltip = d3_select(document.body)
67054             .append('div')
67055             .attr('class', 'tooltip-inner edit-menu-tooltip');
67056
67057
67058         function click(operation) {
67059             event.stopPropagation();
67060             if (operation.disabled()) return;
67061             operation();
67062             editMenu.close();
67063         }
67064
67065         function mousedown() {
67066             event.stopPropagation();  // https://github.com/openstreetmap/iD/issues/1869
67067         }
67068
67069         function mouseover(d, i) {
67070             var tipX, tipY;
67071
67072             if (!isRTL) {
67073                 tipX = viewport.left + origin[0] + menuSideMargin + menuWidth;
67074             } else {
67075                 tipX = viewport.left + origin[0] - 4 - tooltipWidth;
67076             }
67077
67078             if (tipX + tooltipWidth > viewport.right) {
67079                 // tip is going left-to-right and near right viewport edge, go left instead
67080                 tipX = viewport.left + origin[0] - 4 - tooltipWidth;
67081             } else if (tipX < viewport.left) {
67082                 // tip is going right-to-left and near left viewport edge, go right instead
67083                 tipX = viewport.left + origin[0] + menuSideMargin + menuWidth;
67084             }
67085
67086             tipY = viewport.top + origin[1] + (i * buttonHeight);
67087             if (tipY + tooltipHeight > viewport.bottom) {
67088                 // tip is near bottom viewport edge, shift upwards
67089                 tipY -= tipY + tooltipHeight - viewport.bottom;
67090             }
67091
67092             tooltip
67093                 .style('left', tipX + 'px')
67094                 .style('top', tipY + 'px')
67095                 .style('display', 'block')
67096                 .html(uiTooltipHtml(d.tooltip(), d.keys[0], d.title));
67097         }
67098
67099         function mouseout() {
67100             tooltip.style('display', 'none');
67101         }
67102     };
67103
67104
67105     editMenu.close = function () {
67106         if (menu) {
67107             menu
67108                 .style('pointer-events', 'none')
67109                 .transition()
67110                 .attr('opacity', 0)
67111                 .remove();
67112         }
67113
67114         if (tooltip) {
67115             tooltip.remove();
67116         }
67117     };
67118
67119
67120     editMenu.center = function (_) {
67121         if (!arguments.length) return center;
67122         center = _;
67123         return editMenu;
67124     };
67125
67126
67127     return editMenu;
67128 }
67129
67130 var _flashTimer;
67131
67132
67133 function uiFlash() {
67134     var _duration = 2000;
67135     var _iconName = '#icon-no';
67136     var _iconClass = 'disabled';
67137     var _text = '';
67138     var _textClass;
67139
67140
67141     function flash() {
67142         if (_flashTimer) {
67143             _flashTimer.stop();
67144         }
67145
67146         d3_select('#footer-wrap')
67147             .attr('class', 'footer-hide');
67148         d3_select('#flash-wrap')
67149             .attr('class', 'footer-show');
67150
67151         var content = d3_select('#flash-wrap').selectAll('.flash-content')
67152             .data([0]);
67153
67154         // Enter
67155         var contentEnter = content.enter()
67156             .append('div')
67157             .attr('class', 'flash-content');
67158
67159         var iconEnter = contentEnter
67160             .append('svg')
67161             .attr('class', 'flash-icon')
67162             .append('g')
67163             .attr('transform', 'translate(10,10)');
67164
67165         iconEnter
67166             .append('circle')
67167             .attr('r', 9);
67168
67169         iconEnter
67170             .append('use')
67171             .attr('transform', 'translate(-7,-7)')
67172             .attr('width', '14')
67173             .attr('height', '14');
67174
67175         contentEnter
67176             .append('div')
67177             .attr('class', 'flash-text');
67178
67179
67180         // Update
67181         content = content
67182             .merge(contentEnter);
67183
67184         content
67185             .selectAll('.flash-icon')
67186             .attr('class', 'flash-icon ' + (_iconClass || ''));
67187
67188         content
67189             .selectAll('.flash-icon use')
67190             .attr('xlink:href', _iconName);
67191
67192         content
67193             .selectAll('.flash-text')
67194             .attr('class', 'flash-text ' + (_textClass || ''))
67195             .text(_text);
67196
67197
67198         _flashTimer = d3_timeout(function() {
67199             _flashTimer = null;
67200             d3_select('#footer-wrap')
67201                 .attr('class', 'footer-show');
67202             d3_select('#flash-wrap')
67203                 .attr('class', 'footer-hide');
67204         }, _duration);
67205
67206         return content;
67207     }
67208
67209
67210     flash.duration = function(_) {
67211         if (!arguments.length) return _duration;
67212         _duration = _;
67213         return flash;
67214     };
67215
67216     flash.text = function(_) {
67217         if (!arguments.length) return _text;
67218         _text = _;
67219         return flash;
67220     };
67221
67222     flash.textClass = function(_) {
67223         if (!arguments.length) return _textClass;
67224         _textClass = _;
67225         return flash;
67226     };
67227
67228     flash.iconName = function(_) {
67229         if (!arguments.length) return _iconName;
67230         _iconName = _;
67231         return flash;
67232     };
67233
67234     flash.iconClass = function(_) {
67235         if (!arguments.length) return _iconClass;
67236         _iconClass = _;
67237         return flash;
67238     };
67239
67240     return flash;
67241 }
67242
67243 function uiLasso(context) {
67244     var group, polygon;
67245
67246     lasso.coordinates = [];
67247
67248     function lasso(selection) {
67249         context.container()
67250             .classed('lasso', true);
67251
67252         group = selection
67253             .append('g')
67254             .attr('class', 'lasso hide');
67255
67256         polygon = group
67257             .append('path')
67258             .attr('class', 'lasso-path');
67259
67260         group
67261             .call(uiToggle(true));
67262     }
67263
67264
67265     function draw() {
67266         if (polygon) {
67267             polygon.data([lasso.coordinates])
67268                 .attr('d', function(d) { return 'M' + d.join(' L') + ' Z'; });
67269         }
67270     }
67271
67272
67273     lasso.extent = function () {
67274         return lasso.coordinates.reduce(function(extent, point) {
67275             return extent.extend(geoExtent(point));
67276         }, geoExtent());
67277     };
67278
67279
67280     lasso.p = function(_) {
67281         if (!arguments.length) return lasso;
67282         lasso.coordinates.push(_);
67283         draw();
67284         return lasso;
67285     };
67286
67287
67288     lasso.close = function() {
67289         if (group) {
67290             group.call(uiToggle(false, function() {
67291                 d3_select(this).remove();
67292             }));
67293         }
67294         context.container().classed('lasso', false);
67295     };
67296
67297
67298     return lasso;
67299 }
67300
67301 function uiRadialMenu(context, operations) {
67302     var menu,
67303         center = [0, 0],
67304         tooltip;
67305
67306
67307     var radialMenu = function(selection) {
67308         if (!operations.length) return;
67309
67310         selection.node().parentNode.focus();
67311
67312         function click(operation) {
67313             event.stopPropagation();
67314             if (operation.disabled()) return;
67315             operation();
67316             radialMenu.close();
67317         }
67318
67319         menu = selection
67320             .append('g')
67321             .attr('class', 'radial-menu')
67322             .attr('transform', 'translate(' + center + ')')
67323             .attr('opacity', 0);
67324
67325         menu
67326             .transition()
67327             .attr('opacity', 1);
67328
67329         var r = 50,
67330             a = Math.PI / 4,
67331             a0 = -Math.PI / 4,
67332             a1 = a0 + (operations.length - 1) * a;
67333
67334         menu
67335             .append('path')
67336             .attr('class', 'radial-menu-background')
67337             .attr('d', 'M' + r * Math.sin(a0) + ',' +
67338                              r * Math.cos(a0) +
67339                       ' A' + r + ',' + r + ' 0 ' + (operations.length > 5 ? '1' : '0') + ',0 ' +
67340                              (r * Math.sin(a1) + 1e-3) + ',' +
67341                              (r * Math.cos(a1) + 1e-3)) // Force positive-length path (#1305)
67342             .attr('stroke-width', 50)
67343             .attr('stroke-linecap', 'round');
67344
67345         var button = menu.selectAll()
67346             .data(operations)
67347             .enter()
67348             .append('g')
67349             .attr('class', function(d) { return 'radial-menu-item radial-menu-item-' + d.id; })
67350             .classed('disabled', function(d) { return d.disabled(); })
67351             .attr('transform', function(d, i) {
67352                 return 'translate(' + geoVecFloor([
67353                         r * Math.sin(a0 + i * a),
67354                         r * Math.cos(a0 + i * a)]).join(',') + ')';
67355             });
67356
67357         button
67358             .append('circle')
67359             .attr('r', 15)
67360             .on('click', click)
67361             .on('mousedown', mousedown)
67362             .on('mouseover', mouseover)
67363             .on('mouseout', mouseout);
67364
67365         button
67366             .append('use')
67367             .attr('transform', 'translate(-10,-10)')
67368             .attr('width', '20')
67369             .attr('height', '20')
67370             .attr('xlink:href', function(d) { return '#operation-' + d.id; });
67371
67372         tooltip = d3_select(document.body)
67373             .append('div')
67374             .attr('class', 'tooltip-inner radial-menu-tooltip');
67375
67376         function mousedown() {
67377             event.stopPropagation(); // https://github.com/openstreetmap/iD/issues/1869
67378         }
67379
67380         function mouseover(d, i) {
67381             var rect = context.surfaceRect(),
67382                 angle = a0 + i * a,
67383                 top = rect.top + (r + 25) * Math.cos(angle) + center[1] + 'px',
67384                 left = rect.left + (r + 25) * Math.sin(angle) + center[0] + 'px',
67385                 bottom = rect.height - (r + 25) * Math.cos(angle) - center[1] + 'px',
67386                 right = rect.width - (r + 25) * Math.sin(angle) - center[0] + 'px';
67387
67388             tooltip
67389                 .style('top', null)
67390                 .style('left', null)
67391                 .style('bottom', null)
67392                 .style('right', null)
67393                 .style('display', 'block')
67394                 .html(uiTooltipHtml(d.tooltip(), d.keys[0]));
67395
67396             if (i === 0) {
67397                 tooltip
67398                     .style('right', right)
67399                     .style('top', top);
67400             } else if (i >= 4) {
67401                 tooltip
67402                     .style('left', left)
67403                     .style('bottom', bottom);
67404             } else {
67405                 tooltip
67406                     .style('left', left)
67407                     .style('top', top);
67408             }
67409         }
67410
67411         function mouseout() {
67412             tooltip.style('display', 'none');
67413         }
67414     };
67415
67416
67417     radialMenu.close = function() {
67418         if (menu) {
67419             menu
67420                 .style('pointer-events', 'none')
67421                 .transition()
67422                 .attr('opacity', 0)
67423                 .remove();
67424         }
67425
67426         if (tooltip) {
67427             tooltip.remove();
67428         }
67429     };
67430
67431
67432     radialMenu.center = function(_) {
67433         if (!arguments.length) return center;
67434         center = _;
67435         return radialMenu;
67436     };
67437
67438
67439     return radialMenu;
67440 }
67441
67442 function uiSelectionList(context, selectedIDs) {
67443
67444     function selectEntity(entity) {
67445         context.enter(modeSelect(context, [entity.id]));
67446     }
67447
67448
67449     function deselectEntity(entity) {
67450         event.stopPropagation();
67451         var index = selectedIDs.indexOf(entity.id);
67452         if (index > -1) {
67453             selectedIDs.splice(index, 1);
67454         }
67455         context.enter(modeSelect(context, selectedIDs));
67456     }
67457
67458
67459     function selectionList(selection) {
67460         selection.classed('selection-list-pane', true);
67461
67462         var header = selection
67463             .append('div')
67464             .attr('class', 'header fillL cf');
67465
67466         header
67467             .append('h3')
67468             .text(t('inspector.multiselect'));
67469
67470         var listWrap = selection
67471             .append('div')
67472             .attr('class', 'inspector-body');
67473
67474         var list = listWrap
67475             .append('div')
67476             .attr('class', 'feature-list cf');
67477
67478         context.history().on('change.selection-list', drawList);
67479         drawList();
67480
67481
67482         function drawList() {
67483             var entities = selectedIDs
67484                 .map(function(id) { return context.hasEntity(id); })
67485                 .filter(function(entity) { return entity; });
67486
67487             var items = list.selectAll('.feature-list-item')
67488                 .data(entities, osmEntity.key);
67489
67490             items.exit()
67491                 .remove();
67492
67493             // Enter
67494             var enter = items.enter()
67495                 .append('div')
67496                 .attr('class', 'feature-list-item')
67497                 .on('click', selectEntity);
67498
67499             var label = enter
67500                 .append('button')
67501                 .attr('class', 'label');
67502
67503             enter
67504                 .append('button')
67505                 .attr('class', 'close')
67506                 .on('click', deselectEntity)
67507                 .call(svgIcon('#icon-close'));
67508
67509             label
67510                 .append('span')
67511                 .attr('class', 'entity-geom-icon')
67512                 .call(svgIcon('', 'pre-text'));
67513
67514             label
67515                 .append('span')
67516                 .attr('class', 'entity-type');
67517
67518             label
67519                 .append('span')
67520                 .attr('class', 'entity-name');
67521
67522             // Update
67523             items = items.merge(enter);
67524
67525             items.selectAll('.entity-geom-icon use')
67526                 .attr('href', function() {
67527                     var entity = this.parentNode.parentNode.__data__;
67528                     return '#icon-' + context.geometry(entity.id);
67529                 });
67530
67531             items.selectAll('.entity-type')
67532                 .text(function(entity) { return context.presets().match(entity, context.graph()).name(); });
67533
67534             items.selectAll('.entity-name')
67535                 .text(function(entity) { return utilDisplayName(entity); });
67536         }
67537     }
67538
67539     return selectionList;
67540 }
67541
67542 function uiSourceSwitch(context) {
67543     var keys;
67544
67545
67546     function click() {
67547         event.preventDefault();
67548
67549         var osm = context.connection();
67550         if (!osm) return;
67551
67552         if (context.inIntro()) return;
67553
67554         if (context.history().hasChanges() &&
67555             !window.confirm(t('source_switch.lose_changes'))) return;
67556
67557         var isLive = d3_select(this)
67558             .classed('live');
67559
67560         isLive = !isLive;
67561         context.enter(modeBrowse(context));
67562         context.history().clearSaved();          // remove saved history
67563         context.flush();                         // remove stored data
67564
67565         d3_select(this)
67566             .text(isLive ? t('source_switch.live') : t('source_switch.dev'))
67567             .classed('live', isLive);
67568
67569         osm.switch(isLive ? keys[0] : keys[1]);  // switch connection (warning: dispatches 'change' event)
67570     }
67571
67572     var sourceSwitch = function(selection) {
67573         selection
67574             .append('a')
67575             .attr('href', '#')
67576             .text(t('source_switch.live'))
67577             .classed('live', true)
67578             .attr('tabindex', -1)
67579             .on('click', click);
67580     };
67581
67582
67583     sourceSwitch.keys = function(_) {
67584         if (!arguments.length) return keys;
67585         keys = _;
67586         return sourceSwitch;
67587     };
67588
67589
67590     return sourceSwitch;
67591 }
67592
67593 function uiSuccess(context) {
67594     var dispatch$$1 = dispatch('cancel'),
67595         changeset;
67596
67597
67598     function success(selection) {
67599         var header = selection
67600             .append('div')
67601             .attr('class', 'header fillL');
67602
67603         header
67604             .append('button')
67605             .attr('class', 'fr')
67606             .on('click', function() { dispatch$$1.call('cancel'); })
67607             .call(svgIcon('#icon-close'));
67608
67609         header
67610             .append('h3')
67611             .text(t('success.just_edited'));
67612
67613         var body = selection
67614             .append('div')
67615             .attr('class', 'body save-success fillL');
67616
67617         body
67618             .append('p')
67619             .html(t('success.help_html'));
67620
67621         body
67622             .append('a')
67623             .attr('class', 'details')
67624             .attr('target', '_blank')
67625             .attr('tabindex', -1)
67626             .call(svgIcon('#icon-out-link', 'inline'))
67627             .attr('href', t('success.help_link_url'))
67628             .append('span')
67629             .text(t('success.help_link_text'));
67630
67631         var osm = context.connection();
67632         if (!osm) return;
67633
67634         var changesetURL = osm.changesetURL(changeset.id);
67635
67636         var viewOnOsm = body
67637             .append('a')
67638             .attr('class', 'button col12 osm')
67639             .attr('target', '_blank')
67640             .attr('href', changesetURL);
67641
67642         viewOnOsm
67643             .append('svg')
67644             .attr('class', 'logo logo-osm')
67645             .append('use')
67646             .attr('xlink:href', '#logo-osm');
67647
67648         viewOnOsm
67649             .append('div')
67650             .text(t('success.view_on_osm'));
67651
67652         var message = (changeset.tags.comment || t('success.edited_osm')).substring(0, 130) +
67653             ' ' + changesetURL;
67654
67655         var sharing = [
67656             { key: 'facebook', value: 'https://facebook.com/sharer/sharer.php?u=' + encodeURIComponent(changesetURL) },
67657             { key: 'twitter', value: 'https://twitter.com/intent/tweet?source=webclient&text=' + encodeURIComponent(message) },
67658             { key: 'google', value: 'https://plus.google.com/share?url=' + encodeURIComponent(changesetURL) }
67659         ];
67660
67661         body.selectAll('.button.social')
67662             .data(sharing)
67663             .enter()
67664             .append('a')
67665             .attr('class', 'button social col4')
67666             .attr('target', '_blank')
67667             .attr('href', function(d) { return d.value; })
67668             .call(tooltip()
67669                 .title(function(d) { return t('success.' + d.key); })
67670                 .placement('bottom'))
67671             .each(function(d) { d3_select(this).call(svgIcon('#logo-' + d.key, 'social')); });
67672     }
67673
67674
67675     success.changeset = function(_) {
67676         if (!arguments.length) return changeset;
67677         changeset = _;
67678         return success;
67679     };
67680
67681
67682     return utilRebind(success, dispatch$$1, 'on');
67683 }
67684
67685 function coreHistory(context) {
67686     var imageryUsed = ['Bing'],
67687         dispatch$$1 = dispatch('change', 'undone', 'redone'),
67688         lock = utilSessionMutex('lock'),
67689         duration = 150,
67690         checkpoints = {},
67691         stack, index, tree;
67692
67693
67694     // internal _act, accepts list of actions and eased time
67695     function _act(actions, t) {
67696         actions = Array.prototype.slice.call(actions);
67697
67698         var annotation;
67699
67700         if (!isFunction(actions[actions.length - 1])) {
67701             annotation = actions.pop();
67702         }
67703
67704         stack[index].transform = context.projection.transform();
67705         stack[index].selectedIDs = context.selectedIDs();
67706
67707         var graph = stack[index].graph;
67708         for (var i = 0; i < actions.length; i++) {
67709             graph = actions[i](graph, t);
67710         }
67711
67712         return {
67713             graph: graph,
67714             annotation: annotation,
67715             imageryUsed: imageryUsed
67716         };
67717     }
67718
67719
67720     // internal _perform with eased time
67721     function _perform(args, t) {
67722         var previous = stack[index].graph;
67723         stack = stack.slice(0, index + 1);
67724         stack.push(_act(args, t));
67725         index++;
67726         return change(previous);
67727     }
67728
67729
67730     // internal _replace with eased time
67731     function _replace(args, t) {
67732         var previous = stack[index].graph;
67733         // assert(index == stack.length - 1)
67734         stack[index] = _act(args, t);
67735         return change(previous);
67736     }
67737
67738
67739     // internal _overwrite with eased time
67740     function _overwrite(args, t) {
67741         var previous = stack[index].graph;
67742         if (index > 0) {
67743             index--;
67744             stack.pop();
67745         }
67746         stack = stack.slice(0, index + 1);
67747         stack.push(_act(args, t));
67748         index++;
67749         return change(previous);
67750     }
67751
67752
67753     // determine diffrence and dispatch a change event
67754     function change(previous) {
67755         var difference$$1 = coreDifference(previous, history.graph());
67756         dispatch$$1.call('change', this, difference$$1);
67757         return difference$$1;
67758     }
67759
67760
67761     // iD uses namespaced keys so multiple installations do not conflict
67762     function getKey(n) {
67763         return 'iD_' + window.location.origin + '_' + n;
67764     }
67765
67766
67767     var history = {
67768
67769         graph: function() {
67770             return stack[index].graph;
67771         },
67772
67773
67774         base: function() {
67775             return stack[0].graph;
67776         },
67777
67778
67779         merge: function(entities, extent) {
67780             stack[0].graph.rebase(entities, map$4(stack, 'graph'), false);
67781             tree.rebase(entities, false);
67782
67783             dispatch$$1.call('change', this, undefined, extent);
67784         },
67785
67786
67787         perform: function() {
67788             // complete any transition already in progress
67789             d3_select(document).interrupt('history.perform');
67790
67791             var transitionable = false,
67792                 action0 = arguments[0];
67793
67794             if (arguments.length === 1 ||
67795                 arguments.length === 2 && !isFunction(arguments[1])) {
67796                 transitionable = !!action0.transitionable;
67797             }
67798
67799             if (transitionable) {
67800                 var origArguments = arguments;
67801                 d3_select(document)
67802                     .transition('history.perform')
67803                     .duration(duration)
67804                     .ease(linear$1)
67805                     .tween('history.tween', function() {
67806                         return function(t) {
67807                             if (t < 1) _overwrite([action0], t);
67808                         };
67809                     })
67810                     .on('start', function() {
67811                         _perform([action0], 0);
67812                     })
67813                     .on('end interrupt', function() {
67814                         _overwrite(origArguments, 1);
67815                     });
67816
67817             } else {
67818                 return _perform(arguments);
67819             }
67820         },
67821
67822
67823         replace: function() {
67824             d3_select(document).interrupt('history.perform');
67825             return _replace(arguments, 1);
67826         },
67827
67828
67829         // Same as calling pop and then perform
67830         overwrite: function() {
67831             d3_select(document).interrupt('history.perform');
67832             return _overwrite(arguments, 1);
67833         },
67834
67835
67836         pop: function(n) {
67837             d3_select(document).interrupt('history.perform');
67838
67839             var previous = stack[index].graph;
67840             if (isNaN(+n) || +n < 0) {
67841                 n = 1;
67842             }
67843             while (n-- > 0 && index > 0) {
67844                 index--;
67845                 stack.pop();
67846             }
67847             return change(previous);
67848         },
67849
67850
67851         // Back to the previous annotated state or index = 0.
67852         undo: function() {
67853             d3_select(document).interrupt('history.perform');
67854
67855             var previous = stack[index].graph;
67856             while (index > 0) {
67857                 index--;
67858                 if (stack[index].annotation) break;
67859             }
67860
67861             dispatch$$1.call('undone', this, stack[index]);
67862             return change(previous);
67863         },
67864
67865
67866         // Forward to the next annotated state.
67867         redo: function() {
67868             d3_select(document).interrupt('history.perform');
67869
67870             var previous = stack[index].graph;
67871             var tryIndex = index;
67872             while (tryIndex < stack.length - 1) {
67873                 tryIndex++;
67874                 if (stack[tryIndex].annotation) {
67875                     index = tryIndex;
67876                     dispatch$$1.call('redone', this, stack[index]);
67877                     break;
67878                 }
67879             }
67880
67881             return change(previous);
67882         },
67883
67884
67885         undoAnnotation: function() {
67886             var i = index;
67887             while (i >= 0) {
67888                 if (stack[i].annotation) return stack[i].annotation;
67889                 i--;
67890             }
67891         },
67892
67893
67894         redoAnnotation: function() {
67895             var i = index + 1;
67896             while (i <= stack.length - 1) {
67897                 if (stack[i].annotation) return stack[i].annotation;
67898                 i++;
67899             }
67900         },
67901
67902
67903         intersects: function(extent) {
67904             return tree.intersects(extent, stack[index].graph);
67905         },
67906
67907
67908         difference: function() {
67909             var base = stack[0].graph,
67910                 head = stack[index].graph;
67911             return coreDifference(base, head);
67912         },
67913
67914
67915         changes: function(action) {
67916             var base = stack[0].graph,
67917                 head = stack[index].graph;
67918
67919             if (action) {
67920                 head = action(head);
67921             }
67922
67923             var difference$$1 = coreDifference(base, head);
67924
67925             return {
67926                 modified: difference$$1.modified(),
67927                 created: difference$$1.created(),
67928                 deleted: difference$$1.deleted()
67929             };
67930         },
67931
67932
67933         validate: function(changes) {
67934             return flatten(
67935                 map$4(Validations, function(fn) { return fn()(changes, stack[index].graph); })
67936             );
67937         },
67938
67939
67940         hasChanges: function() {
67941             return this.difference().length() > 0;
67942         },
67943
67944
67945         imageryUsed: function(sources) {
67946             if (sources) {
67947                 imageryUsed = sources;
67948                 return history;
67949             } else {
67950                 var arr = map$4(stack.slice(1, index + 1), 'imageryUsed');
67951                 return without(uniq(flatten(arr)), 'Custom');
67952             }
67953         },
67954
67955
67956         // save the current history state
67957         checkpoint: function(key) {
67958             checkpoints[key] = {
67959                 stack: cloneDeep(stack),
67960                 index: index
67961             };
67962             return history;
67963         },
67964
67965
67966         // restore history state to a given checkpoint or reset completely
67967         reset: function(key) {
67968             if (key !== undefined && checkpoints.hasOwnProperty(key)) {
67969                 stack = cloneDeep(checkpoints[key].stack);
67970                 index = checkpoints[key].index;
67971             } else {
67972                 stack = [{graph: coreGraph()}];
67973                 index = 0;
67974                 tree = coreTree(stack[0].graph);
67975                 checkpoints = {};
67976             }
67977             dispatch$$1.call('change');
67978             return history;
67979         },
67980
67981
67982         toIntroGraph: function() {
67983             var nextId = { n: 0, r: 0, w: 0 },
67984                 permIds = {},
67985                 graph = this.graph(),
67986                 baseEntities = {};
67987
67988             // clone base entities..
67989             forEach(graph.base().entities, function(entity) {
67990                 var copy = cloneDeepWith(entity, customizer);
67991                 baseEntities[copy.id] = copy;
67992             });
67993
67994             // replace base entities with head entities..
67995             forEach(graph.entities, function(entity, id) {
67996                 if (entity) {
67997                     var copy = cloneDeepWith(entity, customizer);
67998                     baseEntities[copy.id] = copy;
67999                 } else {
68000                     delete baseEntities[id];
68001                 }
68002             });
68003
68004             // swap temporary for permanent ids..
68005             forEach(baseEntities, function(entity) {
68006                 if (Array.isArray(entity.nodes)) {
68007                     entity.nodes = entity.nodes.map(function(node) {
68008                         return permIds[node] || node;
68009                     });
68010                 }
68011                 if (Array.isArray(entity.members)) {
68012                     entity.members = entity.members.map(function(member) {
68013                         member.id = permIds[member.id] || member.id;
68014                         return member;
68015                     });
68016                 }
68017             });
68018
68019             return JSON.stringify({ dataIntroGraph: baseEntities });
68020
68021
68022             function customizer(src) {
68023                 var copy = omit(cloneDeep(src), ['type', 'user', 'v', 'version', 'visible']);
68024                 if (isEmpty(copy.tags)) {
68025                     delete copy.tags;
68026                 }
68027
68028                 if (Array.isArray(copy.loc)) {
68029                     copy.loc[0] = +copy.loc[0].toFixed(6);
68030                     copy.loc[1] = +copy.loc[1].toFixed(6);
68031                 }
68032
68033                 var match = src.id.match(/([nrw])-\d*/);  // temporary id
68034                 if (match !== null) {
68035                     var nrw = match[1], permId;
68036                     do { permId = nrw + (++nextId[nrw]); }
68037                     while (baseEntities.hasOwnProperty(permId));
68038
68039                     copy.id = permIds[src.id] = permId;
68040                 }
68041                 return copy;
68042             }
68043         },
68044
68045
68046         toJSON: function() {
68047             if (!this.hasChanges()) return;
68048
68049             var allEntities = {},
68050                 baseEntities = {},
68051                 base = stack[0];
68052
68053             var s = stack.map(function(i) {
68054                 var modified = [], deleted = [];
68055
68056                 forEach(i.graph.entities, function(entity, id) {
68057                     if (entity) {
68058                         var key = osmEntity.key(entity);
68059                         allEntities[key] = entity;
68060                         modified.push(key);
68061                     } else {
68062                         deleted.push(id);
68063                     }
68064
68065                     // make sure that the originals of changed or deleted entities get merged
68066                     // into the base of the stack after restoring the data from JSON.
68067                     if (id in base.graph.entities) {
68068                         baseEntities[id] = base.graph.entities[id];
68069                     }
68070                     // get originals of parent entities too
68071                     forEach(base.graph._parentWays[id], function(parentId) {
68072                         if (parentId in base.graph.entities) {
68073                             baseEntities[parentId] = base.graph.entities[parentId];
68074                         }
68075                     });
68076                 });
68077
68078                 var x = {};
68079
68080                 if (modified.length) x.modified = modified;
68081                 if (deleted.length) x.deleted = deleted;
68082                 if (i.imageryUsed) x.imageryUsed = i.imageryUsed;
68083                 if (i.annotation) x.annotation = i.annotation;
68084
68085                 return x;
68086             });
68087
68088             return JSON.stringify({
68089                 version: 3,
68090                 entities: values$1(allEntities),
68091                 baseEntities: values$1(baseEntities),
68092                 stack: s,
68093                 nextIDs: osmEntity.id.next,
68094                 index: index
68095             });
68096         },
68097
68098
68099         fromJSON: function(json, loadChildNodes) {
68100             var h = JSON.parse(json),
68101                 loadComplete = true;
68102
68103             osmEntity.id.next = h.nextIDs;
68104             index = h.index;
68105
68106             if (h.version === 2 || h.version === 3) {
68107                 var allEntities = {};
68108
68109                 h.entities.forEach(function(entity) {
68110                     allEntities[osmEntity.key(entity)] = osmEntity(entity);
68111                 });
68112
68113                 if (h.version === 3) {
68114                     // This merges originals for changed entities into the base of
68115                     // the stack even if the current stack doesn't have them (for
68116                     // example when iD has been restarted in a different region)
68117                     var baseEntities = h.baseEntities.map(function(d) { return osmEntity(d); });
68118                     stack[0].graph.rebase(baseEntities, map$4(stack, 'graph'), true);
68119                     tree.rebase(baseEntities, true);
68120
68121                     // When we restore a modified way, we also need to fetch any missing
68122                     // childnodes that would normally have been downloaded with it.. #2142
68123                     if (loadChildNodes) {
68124                         var osm = context.connection();
68125                         var nodes = flatten(uniq(map$4(filter(baseEntities, { type: 'way' }), 'nodes')));
68126                         var missing = reject(nodes, function(n) { return stack[0].graph.hasEntity(n); });
68127
68128                         if (!isEmpty(missing) && osm) {
68129                             loadComplete = false;
68130                             context.redrawEnable(false);
68131
68132                             var loading = uiLoading(context).blocking(true);
68133                             context.container().call(loading);
68134
68135                             var childNodesLoaded = function(err, result) {
68136                                 if (!err) {
68137                                     var visible = groupBy(result.data, 'visible');
68138                                     if (!isEmpty(visible.true)) {
68139                                         missing = difference(missing, map$4(visible.true, 'id'));
68140                                         stack[0].graph.rebase(visible.true, map$4(stack, 'graph'), true);
68141                                         tree.rebase(visible.true, true);
68142                                     }
68143
68144                                     // fetch older versions of nodes that were deleted..
68145                                     forEach(visible.false, function(entity) {
68146                                         osm.loadEntityVersion(entity.id, +entity.version - 1, childNodesLoaded);
68147                                     });
68148                                 }
68149
68150                                 if (err || isEmpty(missing)) {
68151                                     loading.close();
68152                                     context.redrawEnable(true);
68153                                     dispatch$$1.call('change');
68154                                 }
68155                             };
68156
68157                             osm.loadMultiple(missing, childNodesLoaded);
68158                         }
68159                     }
68160                 }
68161
68162                 stack = h.stack.map(function(d) {
68163                     var entities = {}, entity;
68164
68165                     if (d.modified) {
68166                         d.modified.forEach(function(key) {
68167                             entity = allEntities[key];
68168                             entities[entity.id] = entity;
68169                         });
68170                     }
68171
68172                     if (d.deleted) {
68173                         d.deleted.forEach(function(id) {
68174                             entities[id] = undefined;
68175                         });
68176                     }
68177
68178                     return {
68179                         graph: coreGraph(stack[0].graph).load(entities),
68180                         annotation: d.annotation,
68181                         imageryUsed: d.imageryUsed
68182                     };
68183                 });
68184
68185             } else { // original version
68186                 stack = h.stack.map(function(d) {
68187                     var entities = {};
68188
68189                     for (var i in d.entities) {
68190                         var entity = d.entities[i];
68191                         entities[i] = entity === 'undefined' ? undefined : osmEntity(entity);
68192                     }
68193
68194                     d.graph = coreGraph(stack[0].graph).load(entities);
68195                     return d;
68196                 });
68197             }
68198
68199             if (loadComplete) {
68200                 dispatch$$1.call('change');
68201             }
68202
68203             return history;
68204         },
68205
68206
68207         save: function() {
68208             if (lock.locked()) context.storage(getKey('saved_history'), history.toJSON() || null);
68209             return history;
68210         },
68211
68212
68213         clearSaved: function() {
68214             context.debouncedSave.cancel();
68215             if (lock.locked()) context.storage(getKey('saved_history'), null);
68216             return history;
68217         },
68218
68219
68220         lock: function() {
68221             return lock.lock();
68222         },
68223
68224
68225         unlock: function() {
68226             lock.unlock();
68227         },
68228
68229
68230         // is iD not open in another window and it detects that
68231         // there's a history stored in localStorage that's recoverable?
68232         restorableChanges: function() {
68233             return lock.locked() && !!context.storage(getKey('saved_history'));
68234         },
68235
68236
68237         // load history from a version stored in localStorage
68238         restore: function() {
68239             if (!lock.locked()) return;
68240
68241             var json = context.storage(getKey('saved_history'));
68242             if (json) history.fromJSON(json, true);
68243         },
68244
68245
68246         _getKey: getKey
68247
68248     };
68249
68250
68251     history.reset();
68252
68253     return utilRebind(history, dispatch$$1, 'on');
68254 }
68255
68256 /** Used to store function metadata. */
68257 var metaMap = WeakMap && new WeakMap;
68258
68259 /**
68260  * The base implementation of `setData` without support for hot loop shorting.
68261  *
68262  * @private
68263  * @param {Function} func The function to associate metadata with.
68264  * @param {*} data The metadata.
68265  * @returns {Function} Returns `func`.
68266  */
68267 var baseSetData = !metaMap ? identity$8 : function(func, data) {
68268   metaMap.set(func, data);
68269   return func;
68270 };
68271
68272 /**
68273  * Creates a function that produces an instance of `Ctor` regardless of
68274  * whether it was invoked as part of a `new` expression or by `call` or `apply`.
68275  *
68276  * @private
68277  * @param {Function} Ctor The constructor to wrap.
68278  * @returns {Function} Returns the new wrapped function.
68279  */
68280 function createCtor(Ctor) {
68281   return function() {
68282     // Use a `switch` statement to work with class constructors. See
68283     // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
68284     // for more details.
68285     var args = arguments;
68286     switch (args.length) {
68287       case 0: return new Ctor;
68288       case 1: return new Ctor(args[0]);
68289       case 2: return new Ctor(args[0], args[1]);
68290       case 3: return new Ctor(args[0], args[1], args[2]);
68291       case 4: return new Ctor(args[0], args[1], args[2], args[3]);
68292       case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
68293       case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
68294       case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
68295     }
68296     var thisBinding = baseCreate(Ctor.prototype),
68297         result = Ctor.apply(thisBinding, args);
68298
68299     // Mimic the constructor's `return` behavior.
68300     // See https://es5.github.io/#x13.2.2 for more details.
68301     return isObject(result) ? result : thisBinding;
68302   };
68303 }
68304
68305 /** Used to compose bitmasks for function metadata. */
68306 var WRAP_BIND_FLAG = 1;
68307
68308 /**
68309  * Creates a function that wraps `func` to invoke it with the optional `this`
68310  * binding of `thisArg`.
68311  *
68312  * @private
68313  * @param {Function} func The function to wrap.
68314  * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
68315  * @param {*} [thisArg] The `this` binding of `func`.
68316  * @returns {Function} Returns the new wrapped function.
68317  */
68318 function createBind(func, bitmask, thisArg) {
68319   var isBind = bitmask & WRAP_BIND_FLAG,
68320       Ctor = createCtor(func);
68321
68322   function wrapper() {
68323     var fn = (this && this !== root$2 && this instanceof wrapper) ? Ctor : func;
68324     return fn.apply(isBind ? thisArg : this, arguments);
68325   }
68326   return wrapper;
68327 }
68328
68329 /* Built-in method references for those with the same name as other `lodash` methods. */
68330 var nativeMax$5 = Math.max;
68331
68332 /**
68333  * Creates an array that is the composition of partially applied arguments,
68334  * placeholders, and provided arguments into a single array of arguments.
68335  *
68336  * @private
68337  * @param {Array} args The provided arguments.
68338  * @param {Array} partials The arguments to prepend to those provided.
68339  * @param {Array} holders The `partials` placeholder indexes.
68340  * @params {boolean} [isCurried] Specify composing for a curried function.
68341  * @returns {Array} Returns the new array of composed arguments.
68342  */
68343 function composeArgs(args, partials, holders, isCurried) {
68344   var argsIndex = -1,
68345       argsLength = args.length,
68346       holdersLength = holders.length,
68347       leftIndex = -1,
68348       leftLength = partials.length,
68349       rangeLength = nativeMax$5(argsLength - holdersLength, 0),
68350       result = Array(leftLength + rangeLength),
68351       isUncurried = !isCurried;
68352
68353   while (++leftIndex < leftLength) {
68354     result[leftIndex] = partials[leftIndex];
68355   }
68356   while (++argsIndex < holdersLength) {
68357     if (isUncurried || argsIndex < argsLength) {
68358       result[holders[argsIndex]] = args[argsIndex];
68359     }
68360   }
68361   while (rangeLength--) {
68362     result[leftIndex++] = args[argsIndex++];
68363   }
68364   return result;
68365 }
68366
68367 /* Built-in method references for those with the same name as other `lodash` methods. */
68368 var nativeMax$6 = Math.max;
68369
68370 /**
68371  * This function is like `composeArgs` except that the arguments composition
68372  * is tailored for `_.partialRight`.
68373  *
68374  * @private
68375  * @param {Array} args The provided arguments.
68376  * @param {Array} partials The arguments to append to those provided.
68377  * @param {Array} holders The `partials` placeholder indexes.
68378  * @params {boolean} [isCurried] Specify composing for a curried function.
68379  * @returns {Array} Returns the new array of composed arguments.
68380  */
68381 function composeArgsRight(args, partials, holders, isCurried) {
68382   var argsIndex = -1,
68383       argsLength = args.length,
68384       holdersIndex = -1,
68385       holdersLength = holders.length,
68386       rightIndex = -1,
68387       rightLength = partials.length,
68388       rangeLength = nativeMax$6(argsLength - holdersLength, 0),
68389       result = Array(rangeLength + rightLength),
68390       isUncurried = !isCurried;
68391
68392   while (++argsIndex < rangeLength) {
68393     result[argsIndex] = args[argsIndex];
68394   }
68395   var offset = argsIndex;
68396   while (++rightIndex < rightLength) {
68397     result[offset + rightIndex] = partials[rightIndex];
68398   }
68399   while (++holdersIndex < holdersLength) {
68400     if (isUncurried || argsIndex < argsLength) {
68401       result[offset + holders[holdersIndex]] = args[argsIndex++];
68402     }
68403   }
68404   return result;
68405 }
68406
68407 /**
68408  * Gets the number of `placeholder` occurrences in `array`.
68409  *
68410  * @private
68411  * @param {Array} array The array to inspect.
68412  * @param {*} placeholder The placeholder to search for.
68413  * @returns {number} Returns the placeholder count.
68414  */
68415 function countHolders(array, placeholder) {
68416   var length = array.length,
68417       result = 0;
68418
68419   while (length--) {
68420     if (array[length] === placeholder) {
68421       ++result;
68422     }
68423   }
68424   return result;
68425 }
68426
68427 /**
68428  * The function whose prototype chain sequence wrappers inherit from.
68429  *
68430  * @private
68431  */
68432 function baseLodash() {
68433   // No operation performed.
68434 }
68435
68436 /** Used as references for the maximum length and index of an array. */
68437 var MAX_ARRAY_LENGTH = 4294967295;
68438
68439 /**
68440  * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
68441  *
68442  * @private
68443  * @constructor
68444  * @param {*} value The value to wrap.
68445  */
68446 function LazyWrapper(value) {
68447   this.__wrapped__ = value;
68448   this.__actions__ = [];
68449   this.__dir__ = 1;
68450   this.__filtered__ = false;
68451   this.__iteratees__ = [];
68452   this.__takeCount__ = MAX_ARRAY_LENGTH;
68453   this.__views__ = [];
68454 }
68455
68456 // Ensure `LazyWrapper` is an instance of `baseLodash`.
68457 LazyWrapper.prototype = baseCreate(baseLodash.prototype);
68458 LazyWrapper.prototype.constructor = LazyWrapper;
68459
68460 /**
68461  * Gets metadata for `func`.
68462  *
68463  * @private
68464  * @param {Function} func The function to query.
68465  * @returns {*} Returns the metadata for `func`.
68466  */
68467 var getData = !metaMap ? noop$3 : function(func) {
68468   return metaMap.get(func);
68469 };
68470
68471 /** Used to lookup unminified function names. */
68472 var realNames = {};
68473
68474 /** Used for built-in method references. */
68475 var objectProto$19 = Object.prototype;
68476
68477 /** Used to check objects for own properties. */
68478 var hasOwnProperty$17 = objectProto$19.hasOwnProperty;
68479
68480 /**
68481  * Gets the name of `func`.
68482  *
68483  * @private
68484  * @param {Function} func The function to query.
68485  * @returns {string} Returns the function name.
68486  */
68487 function getFuncName(func) {
68488   var result = (func.name + ''),
68489       array = realNames[result],
68490       length = hasOwnProperty$17.call(realNames, result) ? array.length : 0;
68491
68492   while (length--) {
68493     var data = array[length],
68494         otherFunc = data.func;
68495     if (otherFunc == null || otherFunc == func) {
68496       return data.name;
68497     }
68498   }
68499   return result;
68500 }
68501
68502 /**
68503  * The base constructor for creating `lodash` wrapper objects.
68504  *
68505  * @private
68506  * @param {*} value The value to wrap.
68507  * @param {boolean} [chainAll] Enable explicit method chain sequences.
68508  */
68509 function LodashWrapper(value, chainAll) {
68510   this.__wrapped__ = value;
68511   this.__actions__ = [];
68512   this.__chain__ = !!chainAll;
68513   this.__index__ = 0;
68514   this.__values__ = undefined;
68515 }
68516
68517 LodashWrapper.prototype = baseCreate(baseLodash.prototype);
68518 LodashWrapper.prototype.constructor = LodashWrapper;
68519
68520 /**
68521  * Creates a clone of `wrapper`.
68522  *
68523  * @private
68524  * @param {Object} wrapper The wrapper to clone.
68525  * @returns {Object} Returns the cloned wrapper.
68526  */
68527 function wrapperClone(wrapper) {
68528   if (wrapper instanceof LazyWrapper) {
68529     return wrapper.clone();
68530   }
68531   var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
68532   result.__actions__ = copyArray(wrapper.__actions__);
68533   result.__index__  = wrapper.__index__;
68534   result.__values__ = wrapper.__values__;
68535   return result;
68536 }
68537
68538 /** Used for built-in method references. */
68539 var objectProto$20 = Object.prototype;
68540
68541 /** Used to check objects for own properties. */
68542 var hasOwnProperty$18 = objectProto$20.hasOwnProperty;
68543
68544 /**
68545  * Creates a `lodash` object which wraps `value` to enable implicit method
68546  * chain sequences. Methods that operate on and return arrays, collections,
68547  * and functions can be chained together. Methods that retrieve a single value
68548  * or may return a primitive value will automatically end the chain sequence
68549  * and return the unwrapped value. Otherwise, the value must be unwrapped
68550  * with `_#value`.
68551  *
68552  * Explicit chain sequences, which must be unwrapped with `_#value`, may be
68553  * enabled using `_.chain`.
68554  *
68555  * The execution of chained methods is lazy, that is, it's deferred until
68556  * `_#value` is implicitly or explicitly called.
68557  *
68558  * Lazy evaluation allows several methods to support shortcut fusion.
68559  * Shortcut fusion is an optimization to merge iteratee calls; this avoids
68560  * the creation of intermediate arrays and can greatly reduce the number of
68561  * iteratee executions. Sections of a chain sequence qualify for shortcut
68562  * fusion if the section is applied to an array and iteratees accept only
68563  * one argument. The heuristic for whether a section qualifies for shortcut
68564  * fusion is subject to change.
68565  *
68566  * Chaining is supported in custom builds as long as the `_#value` method is
68567  * directly or indirectly included in the build.
68568  *
68569  * In addition to lodash methods, wrappers have `Array` and `String` methods.
68570  *
68571  * The wrapper `Array` methods are:
68572  * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
68573  *
68574  * The wrapper `String` methods are:
68575  * `replace` and `split`
68576  *
68577  * The wrapper methods that support shortcut fusion are:
68578  * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
68579  * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
68580  * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
68581  *
68582  * The chainable wrapper methods are:
68583  * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
68584  * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
68585  * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
68586  * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
68587  * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
68588  * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
68589  * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
68590  * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
68591  * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
68592  * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
68593  * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
68594  * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
68595  * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
68596  * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
68597  * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
68598  * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
68599  * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
68600  * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
68601  * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
68602  * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
68603  * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
68604  * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
68605  * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
68606  * `zipObject`, `zipObjectDeep`, and `zipWith`
68607  *
68608  * The wrapper methods that are **not** chainable by default are:
68609  * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
68610  * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
68611  * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
68612  * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
68613  * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
68614  * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
68615  * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
68616  * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
68617  * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
68618  * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
68619  * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
68620  * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
68621  * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
68622  * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
68623  * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
68624  * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
68625  * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
68626  * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
68627  * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
68628  * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
68629  * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
68630  * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
68631  * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
68632  * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
68633  * `upperFirst`, `value`, and `words`
68634  *
68635  * @name _
68636  * @constructor
68637  * @category Seq
68638  * @param {*} value The value to wrap in a `lodash` instance.
68639  * @returns {Object} Returns the new `lodash` wrapper instance.
68640  * @example
68641  *
68642  * function square(n) {
68643  *   return n * n;
68644  * }
68645  *
68646  * var wrapped = _([1, 2, 3]);
68647  *
68648  * // Returns an unwrapped value.
68649  * wrapped.reduce(_.add);
68650  * // => 6
68651  *
68652  * // Returns a wrapped value.
68653  * var squares = wrapped.map(square);
68654  *
68655  * _.isArray(squares);
68656  * // => false
68657  *
68658  * _.isArray(squares.value());
68659  * // => true
68660  */
68661 function lodash(value) {
68662   if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
68663     if (value instanceof LodashWrapper) {
68664       return value;
68665     }
68666     if (hasOwnProperty$18.call(value, '__wrapped__')) {
68667       return wrapperClone(value);
68668     }
68669   }
68670   return new LodashWrapper(value);
68671 }
68672
68673 // Ensure wrappers are instances of `baseLodash`.
68674 lodash.prototype = baseLodash.prototype;
68675 lodash.prototype.constructor = lodash;
68676
68677 /**
68678  * Checks if `func` has a lazy counterpart.
68679  *
68680  * @private
68681  * @param {Function} func The function to check.
68682  * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
68683  *  else `false`.
68684  */
68685 function isLaziable(func) {
68686   var funcName = getFuncName(func),
68687       other = lodash[funcName];
68688
68689   if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
68690     return false;
68691   }
68692   if (func === other) {
68693     return true;
68694   }
68695   var data = getData(other);
68696   return !!data && func === data[0];
68697 }
68698
68699 /**
68700  * Sets metadata for `func`.
68701  *
68702  * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
68703  * period of time, it will trip its breaker and transition to an identity
68704  * function to avoid garbage collection pauses in V8. See
68705  * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
68706  * for more details.
68707  *
68708  * @private
68709  * @param {Function} func The function to associate metadata with.
68710  * @param {*} data The metadata.
68711  * @returns {Function} Returns `func`.
68712  */
68713 var setData = shortOut(baseSetData);
68714
68715 /** Used to match wrap detail comments. */
68716 var reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/;
68717 var reSplitDetails = /,? & /;
68718
68719 /**
68720  * Extracts wrapper details from the `source` body comment.
68721  *
68722  * @private
68723  * @param {string} source The source to inspect.
68724  * @returns {Array} Returns the wrapper details.
68725  */
68726 function getWrapDetails(source) {
68727   var match = source.match(reWrapDetails);
68728   return match ? match[1].split(reSplitDetails) : [];
68729 }
68730
68731 /** Used to match wrap detail comments. */
68732 var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/;
68733
68734 /**
68735  * Inserts wrapper `details` in a comment at the top of the `source` body.
68736  *
68737  * @private
68738  * @param {string} source The source to modify.
68739  * @returns {Array} details The details to insert.
68740  * @returns {string} Returns the modified source.
68741  */
68742 function insertWrapDetails(source, details) {
68743   var length = details.length;
68744   if (!length) {
68745     return source;
68746   }
68747   var lastIndex = length - 1;
68748   details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
68749   details = details.join(length > 2 ? ', ' : ' ');
68750   return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
68751 }
68752
68753 /** Used to compose bitmasks for function metadata. */
68754 var WRAP_BIND_FLAG$1 = 1;
68755 var WRAP_BIND_KEY_FLAG = 2;
68756 var WRAP_CURRY_FLAG = 8;
68757 var WRAP_CURRY_RIGHT_FLAG = 16;
68758 var WRAP_PARTIAL_FLAG = 32;
68759 var WRAP_PARTIAL_RIGHT_FLAG = 64;
68760 var WRAP_ARY_FLAG = 128;
68761 var WRAP_REARG_FLAG = 256;
68762 var WRAP_FLIP_FLAG = 512;
68763
68764 /** Used to associate wrap methods with their bit flags. */
68765 var wrapFlags = [
68766   ['ary', WRAP_ARY_FLAG],
68767   ['bind', WRAP_BIND_FLAG$1],
68768   ['bindKey', WRAP_BIND_KEY_FLAG],
68769   ['curry', WRAP_CURRY_FLAG],
68770   ['curryRight', WRAP_CURRY_RIGHT_FLAG],
68771   ['flip', WRAP_FLIP_FLAG],
68772   ['partial', WRAP_PARTIAL_FLAG],
68773   ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
68774   ['rearg', WRAP_REARG_FLAG]
68775 ];
68776
68777 /**
68778  * Updates wrapper `details` based on `bitmask` flags.
68779  *
68780  * @private
68781  * @returns {Array} details The details to modify.
68782  * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
68783  * @returns {Array} Returns `details`.
68784  */
68785 function updateWrapDetails(details, bitmask) {
68786   arrayEach(wrapFlags, function(pair) {
68787     var value = '_.' + pair[0];
68788     if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
68789       details.push(value);
68790     }
68791   });
68792   return details.sort();
68793 }
68794
68795 /**
68796  * Sets the `toString` method of `wrapper` to mimic the source of `reference`
68797  * with wrapper details in a comment at the top of the source body.
68798  *
68799  * @private
68800  * @param {Function} wrapper The function to modify.
68801  * @param {Function} reference The reference function.
68802  * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
68803  * @returns {Function} Returns `wrapper`.
68804  */
68805 function setWrapToString(wrapper, reference, bitmask) {
68806   var source = (reference + '');
68807   return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
68808 }
68809
68810 /** Used to compose bitmasks for function metadata. */
68811 var WRAP_BIND_FLAG$2 = 1;
68812 var WRAP_BIND_KEY_FLAG$1 = 2;
68813 var WRAP_CURRY_BOUND_FLAG = 4;
68814 var WRAP_CURRY_FLAG$1 = 8;
68815 var WRAP_PARTIAL_FLAG$1 = 32;
68816 var WRAP_PARTIAL_RIGHT_FLAG$1 = 64;
68817
68818 /**
68819  * Creates a function that wraps `func` to continue currying.
68820  *
68821  * @private
68822  * @param {Function} func The function to wrap.
68823  * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
68824  * @param {Function} wrapFunc The function to create the `func` wrapper.
68825  * @param {*} placeholder The placeholder value.
68826  * @param {*} [thisArg] The `this` binding of `func`.
68827  * @param {Array} [partials] The arguments to prepend to those provided to
68828  *  the new function.
68829  * @param {Array} [holders] The `partials` placeholder indexes.
68830  * @param {Array} [argPos] The argument positions of the new function.
68831  * @param {number} [ary] The arity cap of `func`.
68832  * @param {number} [arity] The arity of `func`.
68833  * @returns {Function} Returns the new wrapped function.
68834  */
68835 function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
68836   var isCurry = bitmask & WRAP_CURRY_FLAG$1,
68837       newHolders = isCurry ? holders : undefined,
68838       newHoldersRight = isCurry ? undefined : holders,
68839       newPartials = isCurry ? partials : undefined,
68840       newPartialsRight = isCurry ? undefined : partials;
68841
68842   bitmask |= (isCurry ? WRAP_PARTIAL_FLAG$1 : WRAP_PARTIAL_RIGHT_FLAG$1);
68843   bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG$1 : WRAP_PARTIAL_FLAG$1);
68844
68845   if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
68846     bitmask &= ~(WRAP_BIND_FLAG$2 | WRAP_BIND_KEY_FLAG$1);
68847   }
68848   var newData = [
68849     func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
68850     newHoldersRight, argPos, ary, arity
68851   ];
68852
68853   var result = wrapFunc.apply(undefined, newData);
68854   if (isLaziable(func)) {
68855     setData(result, newData);
68856   }
68857   result.placeholder = placeholder;
68858   return setWrapToString(result, func, bitmask);
68859 }
68860
68861 /**
68862  * Gets the argument placeholder value for `func`.
68863  *
68864  * @private
68865  * @param {Function} func The function to inspect.
68866  * @returns {*} Returns the placeholder value.
68867  */
68868 function getHolder(func) {
68869   var object = func;
68870   return object.placeholder;
68871 }
68872
68873 /* Built-in method references for those with the same name as other `lodash` methods. */
68874 var nativeMin$2 = Math.min;
68875
68876 /**
68877  * Reorder `array` according to the specified indexes where the element at
68878  * the first index is assigned as the first element, the element at
68879  * the second index is assigned as the second element, and so on.
68880  *
68881  * @private
68882  * @param {Array} array The array to reorder.
68883  * @param {Array} indexes The arranged array indexes.
68884  * @returns {Array} Returns `array`.
68885  */
68886 function reorder(array, indexes) {
68887   var arrLength = array.length,
68888       length = nativeMin$2(indexes.length, arrLength),
68889       oldArray = copyArray(array);
68890
68891   while (length--) {
68892     var index = indexes[length];
68893     array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
68894   }
68895   return array;
68896 }
68897
68898 /** Used as the internal argument placeholder. */
68899 var PLACEHOLDER = '__lodash_placeholder__';
68900
68901 /**
68902  * Replaces all `placeholder` elements in `array` with an internal placeholder
68903  * and returns an array of their indexes.
68904  *
68905  * @private
68906  * @param {Array} array The array to modify.
68907  * @param {*} placeholder The placeholder to replace.
68908  * @returns {Array} Returns the new array of placeholder indexes.
68909  */
68910 function replaceHolders(array, placeholder) {
68911   var index = -1,
68912       length = array.length,
68913       resIndex = 0,
68914       result = [];
68915
68916   while (++index < length) {
68917     var value = array[index];
68918     if (value === placeholder || value === PLACEHOLDER) {
68919       array[index] = PLACEHOLDER;
68920       result[resIndex++] = index;
68921     }
68922   }
68923   return result;
68924 }
68925
68926 /** Used to compose bitmasks for function metadata. */
68927 var WRAP_BIND_FLAG$3 = 1;
68928 var WRAP_BIND_KEY_FLAG$2 = 2;
68929 var WRAP_CURRY_FLAG$2 = 8;
68930 var WRAP_CURRY_RIGHT_FLAG$1 = 16;
68931 var WRAP_ARY_FLAG$1 = 128;
68932 var WRAP_FLIP_FLAG$1 = 512;
68933
68934 /**
68935  * Creates a function that wraps `func` to invoke it with optional `this`
68936  * binding of `thisArg`, partial application, and currying.
68937  *
68938  * @private
68939  * @param {Function|string} func The function or method name to wrap.
68940  * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
68941  * @param {*} [thisArg] The `this` binding of `func`.
68942  * @param {Array} [partials] The arguments to prepend to those provided to
68943  *  the new function.
68944  * @param {Array} [holders] The `partials` placeholder indexes.
68945  * @param {Array} [partialsRight] The arguments to append to those provided
68946  *  to the new function.
68947  * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
68948  * @param {Array} [argPos] The argument positions of the new function.
68949  * @param {number} [ary] The arity cap of `func`.
68950  * @param {number} [arity] The arity of `func`.
68951  * @returns {Function} Returns the new wrapped function.
68952  */
68953 function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
68954   var isAry = bitmask & WRAP_ARY_FLAG$1,
68955       isBind = bitmask & WRAP_BIND_FLAG$3,
68956       isBindKey = bitmask & WRAP_BIND_KEY_FLAG$2,
68957       isCurried = bitmask & (WRAP_CURRY_FLAG$2 | WRAP_CURRY_RIGHT_FLAG$1),
68958       isFlip = bitmask & WRAP_FLIP_FLAG$1,
68959       Ctor = isBindKey ? undefined : createCtor(func);
68960
68961   function wrapper() {
68962     var length = arguments.length,
68963         args = Array(length),
68964         index = length;
68965
68966     while (index--) {
68967       args[index] = arguments[index];
68968     }
68969     if (isCurried) {
68970       var placeholder = getHolder(wrapper),
68971           holdersCount = countHolders(args, placeholder);
68972     }
68973     if (partials) {
68974       args = composeArgs(args, partials, holders, isCurried);
68975     }
68976     if (partialsRight) {
68977       args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
68978     }
68979     length -= holdersCount;
68980     if (isCurried && length < arity) {
68981       var newHolders = replaceHolders(args, placeholder);
68982       return createRecurry(
68983         func, bitmask, createHybrid, wrapper.placeholder, thisArg,
68984         args, newHolders, argPos, ary, arity - length
68985       );
68986     }
68987     var thisBinding = isBind ? thisArg : this,
68988         fn = isBindKey ? thisBinding[func] : func;
68989
68990     length = args.length;
68991     if (argPos) {
68992       args = reorder(args, argPos);
68993     } else if (isFlip && length > 1) {
68994       args.reverse();
68995     }
68996     if (isAry && ary < length) {
68997       args.length = ary;
68998     }
68999     if (this && this !== root$2 && this instanceof wrapper) {
69000       fn = Ctor || createCtor(fn);
69001     }
69002     return fn.apply(thisBinding, args);
69003   }
69004   return wrapper;
69005 }
69006
69007 /**
69008  * Creates a function that wraps `func` to enable currying.
69009  *
69010  * @private
69011  * @param {Function} func The function to wrap.
69012  * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
69013  * @param {number} arity The arity of `func`.
69014  * @returns {Function} Returns the new wrapped function.
69015  */
69016 function createCurry(func, bitmask, arity) {
69017   var Ctor = createCtor(func);
69018
69019   function wrapper() {
69020     var length = arguments.length,
69021         args = Array(length),
69022         index = length,
69023         placeholder = getHolder(wrapper);
69024
69025     while (index--) {
69026       args[index] = arguments[index];
69027     }
69028     var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
69029       ? []
69030       : replaceHolders(args, placeholder);
69031
69032     length -= holders.length;
69033     if (length < arity) {
69034       return createRecurry(
69035         func, bitmask, createHybrid, wrapper.placeholder, undefined,
69036         args, holders, undefined, undefined, arity - length);
69037     }
69038     var fn = (this && this !== root$2 && this instanceof wrapper) ? Ctor : func;
69039     return apply(fn, this, args);
69040   }
69041   return wrapper;
69042 }
69043
69044 /** Used to compose bitmasks for function metadata. */
69045 var WRAP_BIND_FLAG$4 = 1;
69046
69047 /**
69048  * Creates a function that wraps `func` to invoke it with the `this` binding
69049  * of `thisArg` and `partials` prepended to the arguments it receives.
69050  *
69051  * @private
69052  * @param {Function} func The function to wrap.
69053  * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
69054  * @param {*} thisArg The `this` binding of `func`.
69055  * @param {Array} partials The arguments to prepend to those provided to
69056  *  the new function.
69057  * @returns {Function} Returns the new wrapped function.
69058  */
69059 function createPartial(func, bitmask, thisArg, partials) {
69060   var isBind = bitmask & WRAP_BIND_FLAG$4,
69061       Ctor = createCtor(func);
69062
69063   function wrapper() {
69064     var argsIndex = -1,
69065         argsLength = arguments.length,
69066         leftIndex = -1,
69067         leftLength = partials.length,
69068         args = Array(leftLength + argsLength),
69069         fn = (this && this !== root$2 && this instanceof wrapper) ? Ctor : func;
69070
69071     while (++leftIndex < leftLength) {
69072       args[leftIndex] = partials[leftIndex];
69073     }
69074     while (argsLength--) {
69075       args[leftIndex++] = arguments[++argsIndex];
69076     }
69077     return apply(fn, isBind ? thisArg : this, args);
69078   }
69079   return wrapper;
69080 }
69081
69082 /** Used as the internal argument placeholder. */
69083 var PLACEHOLDER$1 = '__lodash_placeholder__';
69084
69085 /** Used to compose bitmasks for function metadata. */
69086 var WRAP_BIND_FLAG$5 = 1;
69087 var WRAP_BIND_KEY_FLAG$3 = 2;
69088 var WRAP_CURRY_BOUND_FLAG$1 = 4;
69089 var WRAP_CURRY_FLAG$3 = 8;
69090 var WRAP_ARY_FLAG$2 = 128;
69091 var WRAP_REARG_FLAG$1 = 256;
69092
69093 /* Built-in method references for those with the same name as other `lodash` methods. */
69094 var nativeMin$3 = Math.min;
69095
69096 /**
69097  * Merges the function metadata of `source` into `data`.
69098  *
69099  * Merging metadata reduces the number of wrappers used to invoke a function.
69100  * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
69101  * may be applied regardless of execution order. Methods like `_.ary` and
69102  * `_.rearg` modify function arguments, making the order in which they are
69103  * executed important, preventing the merging of metadata. However, we make
69104  * an exception for a safe combined case where curried functions have `_.ary`
69105  * and or `_.rearg` applied.
69106  *
69107  * @private
69108  * @param {Array} data The destination metadata.
69109  * @param {Array} source The source metadata.
69110  * @returns {Array} Returns `data`.
69111  */
69112 function mergeData(data, source) {
69113   var bitmask = data[1],
69114       srcBitmask = source[1],
69115       newBitmask = bitmask | srcBitmask,
69116       isCommon = newBitmask < (WRAP_BIND_FLAG$5 | WRAP_BIND_KEY_FLAG$3 | WRAP_ARY_FLAG$2);
69117
69118   var isCombo =
69119     ((srcBitmask == WRAP_ARY_FLAG$2) && (bitmask == WRAP_CURRY_FLAG$3)) ||
69120     ((srcBitmask == WRAP_ARY_FLAG$2) && (bitmask == WRAP_REARG_FLAG$1) && (data[7].length <= source[8])) ||
69121     ((srcBitmask == (WRAP_ARY_FLAG$2 | WRAP_REARG_FLAG$1)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG$3));
69122
69123   // Exit early if metadata can't be merged.
69124   if (!(isCommon || isCombo)) {
69125     return data;
69126   }
69127   // Use source `thisArg` if available.
69128   if (srcBitmask & WRAP_BIND_FLAG$5) {
69129     data[2] = source[2];
69130     // Set when currying a bound function.
69131     newBitmask |= bitmask & WRAP_BIND_FLAG$5 ? 0 : WRAP_CURRY_BOUND_FLAG$1;
69132   }
69133   // Compose partial arguments.
69134   var value = source[3];
69135   if (value) {
69136     var partials = data[3];
69137     data[3] = partials ? composeArgs(partials, value, source[4]) : value;
69138     data[4] = partials ? replaceHolders(data[3], PLACEHOLDER$1) : source[4];
69139   }
69140   // Compose partial right arguments.
69141   value = source[5];
69142   if (value) {
69143     partials = data[5];
69144     data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
69145     data[6] = partials ? replaceHolders(data[5], PLACEHOLDER$1) : source[6];
69146   }
69147   // Use source `argPos` if available.
69148   value = source[7];
69149   if (value) {
69150     data[7] = value;
69151   }
69152   // Use source `ary` if it's smaller.
69153   if (srcBitmask & WRAP_ARY_FLAG$2) {
69154     data[8] = data[8] == null ? source[8] : nativeMin$3(data[8], source[8]);
69155   }
69156   // Use source `arity` if one is not provided.
69157   if (data[9] == null) {
69158     data[9] = source[9];
69159   }
69160   // Use source `func` and merge bitmasks.
69161   data[0] = source[0];
69162   data[1] = newBitmask;
69163
69164   return data;
69165 }
69166
69167 /** Error message constants. */
69168 var FUNC_ERROR_TEXT$4 = 'Expected a function';
69169
69170 /** Used to compose bitmasks for function metadata. */
69171 var WRAP_BIND_FLAG$6 = 1;
69172 var WRAP_BIND_KEY_FLAG$4 = 2;
69173 var WRAP_CURRY_FLAG$4 = 8;
69174 var WRAP_CURRY_RIGHT_FLAG$2 = 16;
69175 var WRAP_PARTIAL_FLAG$2 = 32;
69176 var WRAP_PARTIAL_RIGHT_FLAG$2 = 64;
69177
69178 /* Built-in method references for those with the same name as other `lodash` methods. */
69179 var nativeMax$7 = Math.max;
69180
69181 /**
69182  * Creates a function that either curries or invokes `func` with optional
69183  * `this` binding and partially applied arguments.
69184  *
69185  * @private
69186  * @param {Function|string} func The function or method name to wrap.
69187  * @param {number} bitmask The bitmask flags.
69188  *    1 - `_.bind`
69189  *    2 - `_.bindKey`
69190  *    4 - `_.curry` or `_.curryRight` of a bound function
69191  *    8 - `_.curry`
69192  *   16 - `_.curryRight`
69193  *   32 - `_.partial`
69194  *   64 - `_.partialRight`
69195  *  128 - `_.rearg`
69196  *  256 - `_.ary`
69197  *  512 - `_.flip`
69198  * @param {*} [thisArg] The `this` binding of `func`.
69199  * @param {Array} [partials] The arguments to be partially applied.
69200  * @param {Array} [holders] The `partials` placeholder indexes.
69201  * @param {Array} [argPos] The argument positions of the new function.
69202  * @param {number} [ary] The arity cap of `func`.
69203  * @param {number} [arity] The arity of `func`.
69204  * @returns {Function} Returns the new wrapped function.
69205  */
69206 function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
69207   var isBindKey = bitmask & WRAP_BIND_KEY_FLAG$4;
69208   if (!isBindKey && typeof func != 'function') {
69209     throw new TypeError(FUNC_ERROR_TEXT$4);
69210   }
69211   var length = partials ? partials.length : 0;
69212   if (!length) {
69213     bitmask &= ~(WRAP_PARTIAL_FLAG$2 | WRAP_PARTIAL_RIGHT_FLAG$2);
69214     partials = holders = undefined;
69215   }
69216   ary = ary === undefined ? ary : nativeMax$7(toInteger(ary), 0);
69217   arity = arity === undefined ? arity : toInteger(arity);
69218   length -= holders ? holders.length : 0;
69219
69220   if (bitmask & WRAP_PARTIAL_RIGHT_FLAG$2) {
69221     var partialsRight = partials,
69222         holdersRight = holders;
69223
69224     partials = holders = undefined;
69225   }
69226   var data = isBindKey ? undefined : getData(func);
69227
69228   var newData = [
69229     func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
69230     argPos, ary, arity
69231   ];
69232
69233   if (data) {
69234     mergeData(newData, data);
69235   }
69236   func = newData[0];
69237   bitmask = newData[1];
69238   thisArg = newData[2];
69239   partials = newData[3];
69240   holders = newData[4];
69241   arity = newData[9] = newData[9] === undefined
69242     ? (isBindKey ? 0 : func.length)
69243     : nativeMax$7(newData[9] - length, 0);
69244
69245   if (!arity && bitmask & (WRAP_CURRY_FLAG$4 | WRAP_CURRY_RIGHT_FLAG$2)) {
69246     bitmask &= ~(WRAP_CURRY_FLAG$4 | WRAP_CURRY_RIGHT_FLAG$2);
69247   }
69248   if (!bitmask || bitmask == WRAP_BIND_FLAG$6) {
69249     var result = createBind(func, bitmask, thisArg);
69250   } else if (bitmask == WRAP_CURRY_FLAG$4 || bitmask == WRAP_CURRY_RIGHT_FLAG$2) {
69251     result = createCurry(func, bitmask, arity);
69252   } else if ((bitmask == WRAP_PARTIAL_FLAG$2 || bitmask == (WRAP_BIND_FLAG$6 | WRAP_PARTIAL_FLAG$2)) && !holders.length) {
69253     result = createPartial(func, bitmask, thisArg, partials);
69254   } else {
69255     result = createHybrid.apply(undefined, newData);
69256   }
69257   var setter = data ? baseSetData : setData;
69258   return setWrapToString(setter(result, newData), func, bitmask);
69259 }
69260
69261 /** Used to compose bitmasks for function metadata. */
69262 var WRAP_BIND_FLAG$7 = 1;
69263 var WRAP_PARTIAL_FLAG$3 = 32;
69264
69265 /**
69266  * Creates a function that invokes `func` with the `this` binding of `thisArg`
69267  * and `partials` prepended to the arguments it receives.
69268  *
69269  * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
69270  * may be used as a placeholder for partially applied arguments.
69271  *
69272  * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
69273  * property of bound functions.
69274  *
69275  * @static
69276  * @memberOf _
69277  * @since 0.1.0
69278  * @category Function
69279  * @param {Function} func The function to bind.
69280  * @param {*} thisArg The `this` binding of `func`.
69281  * @param {...*} [partials] The arguments to be partially applied.
69282  * @returns {Function} Returns the new bound function.
69283  * @example
69284  *
69285  * function greet(greeting, punctuation) {
69286  *   return greeting + ' ' + this.user + punctuation;
69287  * }
69288  *
69289  * var object = { 'user': 'fred' };
69290  *
69291  * var bound = _.bind(greet, object, 'hi');
69292  * bound('!');
69293  * // => 'hi fred!'
69294  *
69295  * // Bound with placeholders.
69296  * var bound = _.bind(greet, object, _, '!');
69297  * bound('hi');
69298  * // => 'hi fred!'
69299  */
69300 var bind$2 = baseRest(function(func, thisArg, partials) {
69301   var bitmask = WRAP_BIND_FLAG$7;
69302   if (partials.length) {
69303     var holders = replaceHolders(partials, getHolder(bind$2));
69304     bitmask |= WRAP_PARTIAL_FLAG$3;
69305   }
69306   return createWrap(func, bitmask, thisArg, partials, holders);
69307 });
69308
69309 // Assign default placeholders.
69310 bind$2.placeholder = {};
69311
69312 function presetCollection(collection) {
69313     var maxSearchResults = 50,
69314         maxSuggestionResults = 10;
69315
69316     var presets = {
69317
69318         collection: collection,
69319
69320
69321         item: function(id) {
69322             return find$1(this.collection, function(d) {
69323                 return d.id === id;
69324             });
69325         },
69326
69327
69328         matchGeometry: function(geometry) {
69329             return presetCollection(this.collection.filter(function(d) {
69330                 return d.matchGeometry(geometry);
69331             }));
69332         },
69333
69334
69335         search: function(value, geometry) {
69336             if (!value) return this;
69337
69338             function leading(a) {
69339                 var index = a.indexOf(value);
69340                 return index === 0 || a[index - 1] === ' ';
69341             }
69342
69343             function suggestionName(name) {
69344                 var nameArray = name.split(' - ');
69345                 if (nameArray.length > 1) {
69346                     name = nameArray.slice(0, nameArray.length - 1).join(' - ');
69347                 }
69348                 return name.toLowerCase();
69349             }
69350
69351
69352             value = value.toLowerCase();
69353
69354             var searchable = filter(this.collection, function(a) {
69355                     return a.searchable !== false && a.suggestion !== true;
69356                 }),
69357                 suggestions = filter(this.collection, function(a) {
69358                     return a.suggestion === true;
69359                 });
69360
69361
69362             // matches value to preset.name
69363             var leading_name = filter(searchable, function(a) {
69364                     return leading(a.name().toLowerCase());
69365                 }).sort(function(a, b) {
69366                     var aCompare = a.name().toLowerCase(),
69367                         bCompare = b.name().toLowerCase(),
69368                         i;
69369
69370                     // priority if search string matches preset name exactly - #4325
69371                     if (value === aCompare) return -1;
69372                     if (value === bCompare) return 1;
69373
69374                     // priority for higher matchScore
69375                     i = b.originalScore - a.originalScore;
69376                     if (i !== 0) return i;
69377
69378                     // priority if search string appears earlier in preset name
69379                     i = aCompare.indexOf(value) - bCompare.indexOf(value);
69380                     if (i !== 0) return i;
69381
69382                     // priority for shorter preset names
69383                     return a.name().length - b.name().length;
69384                 });
69385
69386             // matches value to preset.terms values
69387             var leading_terms = filter(searchable, function(a) {
69388                     return some(a.terms() || [], leading);
69389                 });
69390
69391             // matches value to preset.tags values
69392             var leading_tag_values = filter(searchable, function(a) {
69393                     return some(without(values$1(a.tags || {}), '*'), leading);
69394                 });
69395
69396
69397             // finds close matches to value in preset.name
69398             var similar_name = searchable.map(function(a) {
69399                     return {
69400                         preset: a,
69401                         dist: utilEditDistance(value, a.name())
69402                     };
69403                 }).filter(function(a) {
69404                     return a.dist + Math.min(value.length - a.preset.name().length, 0) < 3;
69405                 }).sort(function(a, b) {
69406                     return a.dist - b.dist;
69407                 }).map(function(a) {
69408                     return a.preset;
69409                 });
69410
69411             // finds close matches to value in preset.terms
69412             var similar_terms = filter(searchable, function(a) {
69413                     return some(a.terms() || [], function(b) {
69414                         return utilEditDistance(value, b) + Math.min(value.length - b.length, 0) < 3;
69415                     });
69416                 });
69417
69418             var leading_suggestions = filter(suggestions, function(a) {
69419                     return leading(suggestionName(a.name()));
69420                 }).sort(function(a, b) {
69421                     a = suggestionName(a.name());
69422                     b = suggestionName(b.name());
69423                     var i = a.indexOf(value) - b.indexOf(value);
69424                     if (i === 0) return a.length - b.length;
69425                     else return i;
69426                 });
69427
69428             var similar_suggestions = suggestions.map(function(a) {
69429                     return {
69430                         preset: a,
69431                         dist: utilEditDistance(value, suggestionName(a.name()))
69432                     };
69433                 }).filter(function(a) {
69434                     return a.dist + Math.min(value.length - suggestionName(a.preset.name()).length, 0) < 1;
69435                 }).sort(function(a, b) {
69436                     return a.dist - b.dist;
69437                 }).map(function(a) {
69438                     return a.preset;
69439                 });
69440
69441             var other = presets.item(geometry);
69442
69443             var results = leading_name.concat(
69444                     leading_terms,
69445                     leading_tag_values,
69446                     leading_suggestions.slice(0, maxSuggestionResults + 5),
69447                     similar_name,
69448                     similar_terms,
69449                     similar_suggestions.slice(0, maxSuggestionResults)
69450                 ).slice(0, maxSearchResults - 1);
69451
69452             return presetCollection(uniq(results.concat(other)));
69453         }
69454     };
69455
69456
69457     return presets;
69458 }
69459
69460 function presetCategory(id, category, all) {
69461     category = clone(category);
69462
69463     category.id = id;
69464
69465
69466     category.members = presetCollection(category.members.map(function(id) {
69467         return all.item(id);
69468     }));
69469
69470
69471     category.matchGeometry = function(geometry) {
69472         return category.geometry.indexOf(geometry) >= 0;
69473     };
69474
69475
69476     category.matchScore = function() {
69477         return -1;
69478     };
69479
69480
69481     category.name = function() {
69482         return t('presets.categories.' + id + '.name', {'default': id});
69483     };
69484
69485
69486     category.terms = function() {
69487         return [];
69488     };
69489
69490
69491     return category;
69492 }
69493
69494 function presetField(id, field) {
69495     field = clone(field);
69496
69497     field.id = id;
69498
69499
69500     field.matchGeometry = function(geometry) {
69501         return !field.geometry || field.geometry === geometry;
69502     };
69503
69504
69505     field.t = function(scope, options) {
69506         return t('presets.fields.' + id + '.' + scope, options);
69507     };
69508
69509
69510     field.label = function() {
69511         return field.t('label', {'default': id});
69512     };
69513
69514
69515     var placeholder = field.placeholder;
69516     field.placeholder = function() {
69517         return field.t('placeholder', {'default': placeholder});
69518     };
69519
69520
69521     return field;
69522 }
69523
69524 function presetPreset(id, preset, fields) {
69525     preset = clone(preset);
69526
69527     preset.id = id;
69528     preset.fields = (preset.fields || []).map(getFields);
69529     preset.geometry = (preset.geometry || []);
69530
69531
69532     function getFields(f) {
69533         return fields[f];
69534     }
69535
69536
69537     preset.matchGeometry = function(geometry) {
69538         return preset.geometry.indexOf(geometry) >= 0;
69539     };
69540
69541
69542     preset.originalScore = preset.matchScore || 1;
69543
69544
69545     preset.matchScore = function(entity) {
69546         var tags = preset.tags,
69547             score = 0;
69548
69549         for (var t$$1 in tags) {
69550             if (entity.tags[t$$1] === tags[t$$1]) {
69551                 score += preset.originalScore;
69552             } else if (tags[t$$1] === '*' && t$$1 in entity.tags) {
69553                 score += preset.originalScore / 2;
69554             } else {
69555                 return -1;
69556             }
69557         }
69558
69559         return score;
69560     };
69561
69562
69563     preset.t = function(scope, options) {
69564         return t('presets.presets.' + id + '.' + scope, options);
69565     };
69566
69567
69568     var origName = preset.name || '';
69569     preset.name = function() {
69570         if (preset.suggestion) {
69571             id = id.split('/');
69572             id = id[0] + '/' + id[1];
69573             return origName + ' - ' + t('presets.presets.' + id + '.name');
69574         }
69575         return preset.t('name', { 'default': origName });
69576     };
69577
69578     var origTerms = (preset.terms || []).join();
69579     preset.terms = function() {
69580         return preset.t('terms', { 'default': origTerms }).toLowerCase().trim().split(/\s*,+\s*/);
69581     };
69582
69583
69584     preset.isFallback = function() {
69585         var tagCount = Object.keys(preset.tags).length;
69586         return tagCount === 0 || (tagCount === 1 && preset.tags.hasOwnProperty('area'));
69587     };
69588
69589
69590     var reference = preset.reference || {};
69591     preset.reference = function(geometry) {
69592         var key = reference.key || Object.keys(omit(preset.tags, 'name'))[0],
69593             value = reference.value || preset.tags[key];
69594
69595         if (geometry === 'relation' && key === 'type') {
69596             if (value in preset.tags) {
69597                 key = value;
69598                 value = preset.tags[key];
69599             } else {
69600                 return { rtype: value };
69601             }
69602         }
69603
69604         if (value === '*') {
69605             return { key: key };
69606         } else {
69607             return { key: key, value: value };
69608         }
69609     };
69610
69611
69612     var removeTags = preset.removeTags || preset.tags || {};
69613     preset.removeTags = function(tags, geometry) {
69614         tags = omit(tags, keys$1(removeTags));
69615
69616         for (var f in preset.fields) {
69617             var field = preset.fields[f];
69618             if (field.matchGeometry(geometry) && field.default === tags[field.key]) {
69619                 delete tags[field.key];
69620             }
69621         }
69622
69623         delete tags.area;
69624         return tags;
69625     };
69626
69627
69628     var applyTags = preset.addTags || preset.tags || {};
69629     preset.applyTags = function(tags, geometry) {
69630         var k;
69631
69632         tags = clone(tags);
69633
69634         for (k in applyTags) {
69635             if (applyTags[k] === '*') {
69636                 tags[k] = 'yes';
69637             } else {
69638                 tags[k] = applyTags[k];
69639             }
69640         }
69641
69642         // Add area=yes if necessary.
69643         // This is necessary if the geometry is already an area (e.g. user drew an area) AND any of:
69644         // 1. chosen preset could be either an area or a line (`barrier=city_wall`)
69645         // 2. chosen preset doesn't have a key in areaKeys (`railway=station`)
69646         if (!applyTags.hasOwnProperty('area')) {
69647             delete tags.area;
69648             if (geometry === 'area') {
69649                 var needsAreaTag = true;
69650                 if (preset.geometry.indexOf('line') === -1) {
69651                     for (k in applyTags) {
69652                         if (k in areaKeys) {
69653                             needsAreaTag = false;
69654                             break;
69655                         }
69656                     }
69657                 }
69658                 if (needsAreaTag) {
69659                     tags.area = 'yes';
69660                 }
69661             }
69662         }
69663
69664         for (var f in preset.fields) {
69665             var field = preset.fields[f];
69666             if (field.matchGeometry(geometry) && field.key && !tags[field.key] && field.default) {
69667                 tags[field.key] = field.default;
69668             }
69669         }
69670
69671         return tags;
69672     };
69673
69674
69675     return preset;
69676 }
69677
69678 function presetIndex() {
69679     // a presetCollection with methods for
69680     // loading new data and returning defaults
69681
69682     var all = presetCollection([]);
69683     var _defaults = { area: all, line: all, point: all, vertex: all, relation: all };
69684     var _fields = {};
69685     var _universal = [];
69686     var _recent = presetCollection([]);
69687
69688     // Index of presets by (geometry, tag key).
69689     var _index = {
69690         point: {},
69691         vertex: {},
69692         line: {},
69693         area: {},
69694         relation: {}
69695     };
69696
69697     all.match = function(entity, resolver) {
69698         var geometry = entity.geometry(resolver);
69699         var address;
69700
69701         // Treat entities on addr:interpolation lines as points, not vertices - #3241
69702         if (geometry === 'vertex' && entity.isOnAddressLine(resolver)) {
69703             geometry = 'point';
69704         }
69705
69706         var geometryMatches = _index[geometry];
69707         var best = -1;
69708         var match;
69709
69710         for (var k in entity.tags) {
69711             // If any part of an address is present,
69712             // allow fallback to "Address" preset - #4353
69713             if (k.match(/^addr:/) !== null && geometryMatches['addr:*']) {
69714                 address = geometryMatches['addr:*'][0];
69715             }
69716
69717             var keyMatches = geometryMatches[k];
69718             if (!keyMatches) continue;
69719
69720             for (var i = 0; i < keyMatches.length; i++) {
69721                 var score = keyMatches[i].matchScore(entity);
69722                 if (score > best) {
69723                     best = score;
69724                     match = keyMatches[i];
69725                 }
69726             }
69727         }
69728
69729         if (address && (!match || match.isFallback())) {
69730             match = address;
69731         }
69732
69733         return match || all.item(geometry);
69734     };
69735
69736
69737     // Because of the open nature of tagging, iD will never have a complete
69738     // list of tags used in OSM, so we want it to have logic like "assume
69739     // that a closed way with an amenity tag is an area, unless the amenity
69740     // is one of these specific types". This function computes a structure
69741     // that allows testing of such conditions, based on the presets designated
69742     // as as supporting (or not supporting) the area geometry.
69743     //
69744     // The returned object L is a whitelist/blacklist of tags. A closed way
69745     // with a tag (k, v) is considered to be an area if `k in L && !(v in L[k])`
69746     // (see `Way#isArea()`). In other words, the keys of L form the whitelist,
69747     // and the subkeys form the blacklist.
69748     all.areaKeys = function() {
69749         var areaKeys = {};
69750         var ignore = ['barrier', 'highway', 'footway', 'railway', 'type'];  // probably a line..
69751         var presets = reject(all.collection, 'suggestion');
69752
69753         // whitelist
69754         presets.forEach(function(d) {
69755             for (var key in d.tags) break;
69756             if (!key) return;
69757             if (ignore.indexOf(key) !== -1) return;
69758
69759             if (d.geometry.indexOf('area') !== -1) {    // probably an area..
69760                 areaKeys[key] = areaKeys[key] || {};
69761             }
69762         });
69763
69764         // blacklist
69765         presets.forEach(function(d) {
69766             for (var key in d.tags) break;
69767             if (!key) return;
69768             if (ignore.indexOf(key) !== -1) return;
69769
69770             var value = d.tags[key];
69771             if (key in areaKeys &&                      // probably an area...
69772                 d.geometry.indexOf('line') !== -1 &&    // but sometimes a line
69773                 value !== '*') {
69774                 areaKeys[key][value] = true;
69775             }
69776         });
69777
69778         return areaKeys;
69779     };
69780
69781
69782     all.init = function() {
69783         var d = data.presets;
69784
69785         all.collection = [];
69786         _recent.collection = [];
69787         _fields = {};
69788         _universal = [];
69789         _index = { point: {}, vertex: {}, line: {}, area: {}, relation: {} };
69790
69791         if (d.fields) {
69792             forEach(d.fields, function(d, id) {
69793                 _fields[id] = presetField(id, d);
69794                 if (d.universal) {
69795                     _universal.push(_fields[id]);
69796                 }
69797             });
69798         }
69799
69800         if (d.presets) {
69801             forEach(d.presets, function(d, id) {
69802                 all.collection.push(presetPreset(id, d, _fields));
69803             });
69804         }
69805
69806         if (d.categories) {
69807             forEach(d.categories, function(d, id) {
69808                 all.collection.push(presetCategory(id, d, all));
69809             });
69810         }
69811
69812         if (d.defaults) {
69813             var getItem = bind$2(all.item, all);
69814             _defaults = {
69815                 area: presetCollection(d.defaults.area.map(getItem)),
69816                 line: presetCollection(d.defaults.line.map(getItem)),
69817                 point: presetCollection(d.defaults.point.map(getItem)),
69818                 vertex: presetCollection(d.defaults.vertex.map(getItem)),
69819                 relation: presetCollection(d.defaults.relation.map(getItem))
69820             };
69821         }
69822
69823         for (var i = 0; i < all.collection.length; i++) {
69824             var preset = all.collection[i];
69825             var geometry = preset.geometry;
69826
69827             for (var j = 0; j < geometry.length; j++) {
69828                 var g = _index[geometry[j]];
69829                 for (var k in preset.tags) {
69830                     (g[k] = g[k] || []).push(preset);
69831                 }
69832             }
69833         }
69834
69835         return all;
69836     };
69837
69838     all.field = function(id) {
69839         return _fields[id];
69840     };
69841
69842     all.universal = function() {
69843         return _universal;
69844     };
69845
69846     all.defaults = function(geometry, n) {
69847         var rec = _recent.matchGeometry(geometry).collection.slice(0, 4);
69848         var def = uniq(rec.concat(_defaults[geometry].collection)).slice(0, n - 1);
69849         return presetCollection(uniq(rec.concat(def).concat(all.item(geometry))));
69850     };
69851
69852     all.choose = function(preset) {
69853         _recent = presetCollection(uniq([preset].concat(_recent.collection)));
69854         return all;
69855     };
69856
69857     return all;
69858 }
69859
69860 var areaKeys = {};
69861
69862 function setAreaKeys(value) {
69863     areaKeys = value;
69864 }
69865
69866
69867 function coreContext() {
69868     var context = {};
69869     context.version = '2.6.0';
69870
69871     // create a special translation that contains the keys in place of the strings
69872     var tkeys = cloneDeep(en);
69873     var parents = [];
69874
69875     function traverser(v, k, obj) {
69876         parents.push(k);
69877         if (isObject(v)) {
69878             forOwn(v, traverser);
69879         } else if (isString(v)) {
69880             obj[k] = parents.join('.');
69881         }
69882         parents.pop();
69883     }
69884
69885     forOwn(tkeys, traverser);
69886     addTranslation('_tkeys_', tkeys);
69887
69888     addTranslation('en', en);
69889     setLocale('en');
69890
69891     var dispatch$$1 = dispatch('enter', 'exit', 'change');
69892
69893     // https://github.com/openstreetmap/iD/issues/772
69894     // http://mathiasbynens.be/notes/localstorage-pattern#comment-9
69895     var storage;
69896     try { storage = localStorage; } catch (e) {}  // eslint-disable-line no-empty
69897     storage = storage || (function() {
69898         var s = {};
69899         return {
69900             getItem: function(k) { return s[k]; },
69901             setItem: function(k, v) { s[k] = v; },
69902             removeItem: function(k) { delete s[k]; }
69903         };
69904     })();
69905
69906     context.storage = function(k, v) {
69907         try {
69908             if (arguments.length === 1) return storage.getItem(k);
69909             else if (v === null) storage.removeItem(k);
69910             else storage.setItem(k, v);
69911         } catch (e) {
69912             // localstorage quota exceeded
69913             /* eslint-disable no-console */
69914             if (typeof console !== 'undefined') console.error('localStorage quota exceeded');
69915             /* eslint-enable no-console */
69916         }
69917     };
69918
69919
69920     /* Straight accessors. Avoid using these if you can. */
69921     var ui, connection, history;
69922     context.ui = function() { return ui; };
69923     context.connection = function() { return connection; };
69924     context.history = function() { return history; };
69925
69926
69927     /* Connection */
69928     context.preauth = function(options) {
69929         if (connection) {
69930             connection.switch(options);
69931         }
69932         return context;
69933     };
69934
69935     context.loadTiles = utilCallWhenIdle(function(projection, dimensions, callback) {
69936         var cid;
69937         function done(err, result) {
69938             if (connection.getConnectionId() !== cid) {
69939                 if (callback) callback({ message: 'Connection Switched', status: -1 });
69940                 return;
69941             }
69942             if (!err) history.merge(result.data, result.extent);
69943             if (callback) callback(err, result);
69944         }
69945         if (connection && context.editable()) {
69946             cid = connection.getConnectionId();
69947             connection.loadTiles(projection, dimensions, done);
69948         }
69949     });
69950
69951     context.loadEntity = function(entityId, callback) {
69952         var cid;
69953         function done(err, result) {
69954             if (connection.getConnectionId() !== cid) {
69955                 if (callback) callback({ message: 'Connection Switched', status: -1 });
69956                 return;
69957             }
69958             if (!err) history.merge(result.data, result.extent);
69959             if (callback) callback(err, result);
69960         }
69961         if (connection) {
69962             cid = connection.getConnectionId();
69963             connection.loadEntity(entityId, done);
69964         }
69965     };
69966
69967     context.zoomToEntity = function(entityId, zoomTo) {
69968         if (zoomTo !== false) {
69969             this.loadEntity(entityId, function(err, result) {
69970                 if (err) return;
69971                 var entity = find$1(result.data, function(e) { return e.id === entityId; });
69972                 if (entity) { map.zoomTo(entity); }
69973             });
69974         }
69975
69976         map.on('drawn.zoomToEntity', function() {
69977             if (!context.hasEntity(entityId)) return;
69978             map.on('drawn.zoomToEntity', null);
69979             context.on('enter.zoomToEntity', null);
69980             context.enter(modeSelect(context, [entityId]));
69981         });
69982
69983         context.on('enter.zoomToEntity', function() {
69984             if (mode.id !== 'browse') {
69985                 map.on('drawn.zoomToEntity', null);
69986                 context.on('enter.zoomToEntity', null);
69987             }
69988         });
69989     };
69990
69991     var minEditableZoom = 16;
69992     context.minEditableZoom = function(_) {
69993         if (!arguments.length) return minEditableZoom;
69994         minEditableZoom = _;
69995         if (connection) {
69996             connection.tileZoom(_);
69997         }
69998         return context;
69999     };
70000
70001
70002     /* History */
70003     var inIntro = false;
70004     context.inIntro = function(_) {
70005         if (!arguments.length) return inIntro;
70006         inIntro = _;
70007         return context;
70008     };
70009
70010     context.save = function() {
70011         // no history save, no message onbeforeunload
70012         if (inIntro || d3_select('.modal').size()) return;
70013
70014         var canSave;
70015         if (mode && mode.id === 'save') {
70016             canSave = false;
70017         } else {
70018             canSave = context.selectedIDs().every(function(id) {
70019                 var entity = context.hasEntity(id);
70020                 return entity && !entity.isDegenerate();
70021             });
70022         }
70023
70024         if (canSave) {
70025             history.save();
70026         }
70027         if (history.hasChanges()) {
70028             return t('save.unsaved_changes');
70029         }
70030     };
70031
70032
70033     /* Graph */
70034     context.hasEntity = function(id) {
70035         return history.graph().hasEntity(id);
70036     };
70037     context.entity = function(id) {
70038         return history.graph().entity(id);
70039     };
70040     context.childNodes = function(way) {
70041         return history.graph().childNodes(way);
70042     };
70043     context.geometry = function(id) {
70044         return context.entity(id).geometry(history.graph());
70045     };
70046
70047
70048     /* Modes */
70049     var mode;
70050     context.mode = function() {
70051         return mode;
70052     };
70053     context.enter = function(newMode) {
70054         if (mode) {
70055             mode.exit();
70056             dispatch$$1.call('exit', this, mode);
70057         }
70058
70059         mode = newMode;
70060         mode.enter();
70061         dispatch$$1.call('enter', this, mode);
70062     };
70063
70064     context.selectedIDs = function() {
70065         if (mode && mode.selectedIDs) {
70066             return mode.selectedIDs();
70067         } else {
70068             return [];
70069         }
70070     };
70071     context.activeID = function() {
70072         return mode && mode.activeID && mode.activeID();
70073     };
70074
70075
70076     /* Behaviors */
70077     context.install = function(behavior) {
70078         context.surface().call(behavior);
70079     };
70080     context.uninstall = function(behavior) {
70081         context.surface().call(behavior.off);
70082     };
70083
70084
70085     /* Copy/Paste */
70086     var copyIDs = [], copyGraph;
70087     context.copyGraph = function() { return copyGraph; };
70088     context.copyIDs = function(_) {
70089         if (!arguments.length) return copyIDs;
70090         copyIDs = _;
70091         copyGraph = history.graph();
70092         return context;
70093     };
70094
70095
70096     /* Background */
70097     var background;
70098     context.background = function() { return background; };
70099
70100
70101     /* Features */
70102     var features;
70103     context.features = function() { return features; };
70104     context.hasHiddenConnections = function(id) {
70105         var graph = history.graph(),
70106             entity = graph.entity(id);
70107         return features.hasHiddenConnections(entity, graph);
70108     };
70109
70110
70111     /* Presets */
70112     var presets;
70113     context.presets = function() { return presets; };
70114
70115
70116     /* Map */
70117     var map;
70118     context.map = function() { return map; };
70119     context.layers = function() { return map.layers; };
70120     context.surface = function() { return map.surface; };
70121     context.editable = function() { return map.editable(); };
70122     context.surfaceRect = function() {
70123         return map.surface.node().getBoundingClientRect();
70124     };
70125
70126
70127     /* Debug */
70128     var debugFlags = {
70129         tile: false,        // tile boundaries
70130         collision: false,   // label collision bounding boxes
70131         imagery: false,     // imagery bounding polygons
70132         imperial: false,    // imperial (not metric) bounding polygons
70133         driveLeft: false,   // driveLeft bounding polygons
70134         target: false       // touch targets
70135     };
70136     context.debugFlags = function() {
70137         return debugFlags;
70138     };
70139     context.setDebug = function(flag, val) {
70140         if (arguments.length === 1) val = true;
70141         debugFlags[flag] = val;
70142         dispatch$$1.call('change');
70143         return context;
70144     };
70145     context.getDebug = function(flag) {
70146         return flag && debugFlags[flag];
70147     };
70148
70149
70150     /* Container */
70151     var container = d3_select(document.body);
70152     context.container = function(_) {
70153         if (!arguments.length) return container;
70154         container = _;
70155         container.classed('id-container', true);
70156         return context;
70157     };
70158     var embed;
70159     context.embed = function(_) {
70160         if (!arguments.length) return embed;
70161         embed = _;
70162         return context;
70163     };
70164
70165
70166     /* Assets */
70167     var assetPath = '';
70168     context.assetPath = function(_) {
70169         if (!arguments.length) return assetPath;
70170         assetPath = _;
70171         return context;
70172     };
70173
70174     var assetMap = {};
70175     context.assetMap = function(_) {
70176         if (!arguments.length) return assetMap;
70177         assetMap = _;
70178         return context;
70179     };
70180
70181     context.asset = function(_) {
70182         var filename = assetPath + _;
70183         return assetMap[filename] || filename;
70184     };
70185
70186     context.imagePath = function(_) {
70187         return context.asset('img/' + _);
70188     };
70189
70190
70191     /* locales */
70192     // `locale` variable contains a "requested locale".
70193     // It won't become the `currentLocale` until after loadLocale() is called.
70194     var locale, localePath;
70195
70196     context.locale = function(loc, path) {
70197         if (!arguments.length) return currentLocale;
70198         locale = loc;
70199         localePath = path;
70200         return context;
70201     };
70202
70203     context.loadLocale = function(callback) {
70204         if (locale && locale !== 'en' && dataLocales.hasOwnProperty(locale)) {
70205             localePath = localePath || context.asset('locales/' + locale + '.json');
70206             d3_json(localePath, function(err, result) {
70207                 if (!err) {
70208                     addTranslation(locale, result[locale]);
70209                     setLocale(locale);
70210                     utilDetect(true);
70211                 }
70212                 if (callback) {
70213                     callback(err);
70214                 }
70215             });
70216         } else {
70217             if (locale) {
70218                 setLocale(locale);
70219                 utilDetect(true);
70220             }
70221             if (callback) {
70222                 callback();
70223             }
70224         }
70225     };
70226
70227
70228     /* reset (aka flush) */
70229     context.reset = context.flush = function() {
70230         context.debouncedSave.cancel();
70231         forEach(services, function(service) {
70232             if (service && typeof service.reset === 'function') {
70233                 service.reset(context);
70234             }
70235         });
70236         features.reset();
70237         history.reset();
70238         return context;
70239     };
70240
70241
70242     /* Init */
70243
70244     context.projection = geoRawMercator();
70245     context.curtainProjection = geoRawMercator();
70246
70247     locale = utilDetect().locale;
70248     if (locale && !dataLocales.hasOwnProperty(locale)) {
70249         locale = locale.split('-')[0];
70250     }
70251
70252     history = coreHistory(context);
70253     context.graph = history.graph;
70254     context.changes = history.changes;
70255     context.intersects = history.intersects;
70256
70257     // Debounce save, since it's a synchronous localStorage write,
70258     // and history changes can happen frequently (e.g. when dragging).
70259     context.debouncedSave = debounce(context.save, 350);
70260     function withDebouncedSave(fn) {
70261         return function() {
70262             var result = fn.apply(history, arguments);
70263             context.debouncedSave();
70264             return result;
70265         };
70266     }
70267
70268     context.perform = withDebouncedSave(history.perform);
70269     context.replace = withDebouncedSave(history.replace);
70270     context.pop = withDebouncedSave(history.pop);
70271     context.overwrite = withDebouncedSave(history.overwrite);
70272     context.undo = withDebouncedSave(history.undo);
70273     context.redo = withDebouncedSave(history.redo);
70274
70275     ui = uiInit(context);
70276
70277     connection = services.osm;
70278     background = rendererBackground(context);
70279     features = rendererFeatures(context);
70280     presets = presetIndex();
70281
70282     map = rendererMap(context);
70283     context.mouse = map.mouse;
70284     context.extent = map.extent;
70285     context.pan = map.pan;
70286     context.zoomIn = map.zoomIn;
70287     context.zoomOut = map.zoomOut;
70288     context.zoomInFurther = map.zoomInFurther;
70289     context.zoomOutFurther = map.zoomOutFurther;
70290     context.redrawEnable = map.redrawEnable;
70291
70292     forEach(services, function(service) {
70293         if (service && typeof service.init === 'function') {
70294             service.init(context);
70295         }
70296     });
70297
70298     background.init();
70299     features.init();
70300     presets.init();
70301     areaKeys = presets.areaKeys();
70302
70303
70304     return utilRebind(context, dispatch$$1, 'on');
70305 }
70306
70307 function osmWay() {
70308     if (!(this instanceof osmWay)) {
70309         return (new osmWay()).initialize(arguments);
70310     } else if (arguments.length) {
70311         this.initialize(arguments);
70312     }
70313 }
70314
70315
70316 osmEntity.way = osmWay;
70317
70318 osmWay.prototype = Object.create(osmEntity.prototype);
70319
70320
70321 assignIn(osmWay.prototype, {
70322     type: 'way',
70323     nodes: [],
70324
70325
70326     copy: function(resolver, copies) {
70327         if (copies[this.id])
70328             return copies[this.id];
70329
70330         var copy = osmEntity.prototype.copy.call(this, resolver, copies);
70331
70332         var nodes = this.nodes.map(function(id) {
70333             return resolver.entity(id).copy(resolver, copies).id;
70334         });
70335
70336         copy = copy.update({ nodes: nodes });
70337         copies[this.id] = copy;
70338
70339         return copy;
70340     },
70341
70342
70343     extent: function(resolver) {
70344         return resolver.transient(this, 'extent', function() {
70345             var extent = geoExtent();
70346             for (var i = 0; i < this.nodes.length; i++) {
70347                 var node = resolver.hasEntity(this.nodes[i]);
70348                 if (node) {
70349                     extent._extend(node.extent());
70350                 }
70351             }
70352             return extent;
70353         });
70354     },
70355
70356
70357     first: function() {
70358         return this.nodes[0];
70359     },
70360
70361
70362     last: function() {
70363         return this.nodes[this.nodes.length - 1];
70364     },
70365
70366
70367     contains: function(node) {
70368         return this.nodes.indexOf(node) >= 0;
70369     },
70370
70371
70372     affix: function(node) {
70373         if (this.nodes[0] === node) return 'prefix';
70374         if (this.nodes[this.nodes.length - 1] === node) return 'suffix';
70375     },
70376
70377
70378     layer: function() {
70379         // explicit layer tag, clamp between -10, 10..
70380         if (isFinite(this.tags.layer)) {
70381             return Math.max(-10, Math.min(+(this.tags.layer), 10));
70382         }
70383
70384         // implied layer tag..
70385         if (this.tags.location === 'overground') return 1;
70386         if (this.tags.location === 'underground') return -1;
70387         if (this.tags.location === 'underwater') return -10;
70388
70389         if (this.tags.power === 'line') return 10;
70390         if (this.tags.power === 'minor_line') return 10;
70391         if (this.tags.aerialway) return 10;
70392         if (this.tags.bridge) return 1;
70393         if (this.tags.cutting) return -1;
70394         if (this.tags.tunnel) return -1;
70395         if (this.tags.waterway) return -1;
70396         if (this.tags.man_made === 'pipeline') return -10;
70397         if (this.tags.boundary) return -10;
70398         return 0;
70399     },
70400
70401
70402     isOneWay: function() {
70403         // explicit oneway tag..
70404         var values = {
70405             'yes': true,
70406             '1': true,
70407             '-1': true,
70408             'reversible': true,
70409             'alternating': true,
70410             'no': false,
70411             '0': false
70412         };
70413         if (values[this.tags.oneway] !== undefined) {
70414             return values[this.tags.oneway];
70415         }
70416
70417         // implied oneway tag..
70418         for (var key in this.tags) {
70419             if (key in osmOneWayTags && (this.tags[key] in osmOneWayTags[key]))
70420                 return true;
70421         }
70422         return false;
70423     },
70424
70425
70426     lanes: function() {
70427         return osmLanes(this);
70428     },
70429
70430
70431     isClosed: function() {
70432         return this.nodes.length > 1 && this.first() === this.last();
70433     },
70434
70435
70436     isConvex: function(resolver) {
70437         if (!this.isClosed() || this.isDegenerate()) return null;
70438
70439         var nodes = uniq(resolver.childNodes(this));
70440         var coords = map$4(nodes, 'loc');
70441         var curr = 0;
70442         var prev = 0;
70443
70444         for (var i = 0; i < coords.length; i++) {
70445             var o = coords[(i+1) % coords.length];
70446             var a = coords[i];
70447             var b = coords[(i+2) % coords.length];
70448             var res = geoVecCross(a, b, o);
70449
70450             curr = (res > 0) ? 1 : (res < 0) ? -1 : 0;
70451             if (curr === 0) {
70452                 continue;
70453             } else if (prev && curr !== prev) {
70454                 return false;
70455             }
70456             prev = curr;
70457         }
70458         return true;
70459     },
70460
70461
70462     isArea: function() {
70463         // `highway` and `railway` are typically linear features, but there
70464         // are a few exceptions that should be treated as areas, even in the
70465         // absence of a proper `area=yes` or `areaKeys` tag.. see #4194
70466         var lineKeys = {
70467             highway: {
70468                 rest_area: true,
70469                 services: true
70470             },
70471             railway: {
70472                 roundhouse: true,
70473                 station: true,
70474                 traverser: true,
70475                 turntable: true,
70476                 wash: true
70477             }
70478         };
70479
70480         if (this.tags.area === 'yes')
70481             return true;
70482         if (!this.isClosed() || this.tags.area === 'no')
70483             return false;
70484         for (var key in this.tags) {
70485             if (key in areaKeys && !(this.tags[key] in areaKeys[key])) {
70486                 return true;
70487             }
70488             if (key in lineKeys && this.tags[key] in lineKeys[key]) {
70489                 return true;
70490             }
70491         }
70492         return false;
70493     },
70494
70495
70496     isDegenerate: function() {
70497         return uniq(this.nodes).length < (this.isArea() ? 3 : 2);
70498     },
70499
70500
70501     areAdjacent: function(n1, n2) {
70502         for (var i = 0; i < this.nodes.length; i++) {
70503             if (this.nodes[i] === n1) {
70504                 if (this.nodes[i - 1] === n2) return true;
70505                 if (this.nodes[i + 1] === n2) return true;
70506             }
70507         }
70508         return false;
70509     },
70510
70511
70512     geometry: function(graph) {
70513         return graph.transient(this, 'geometry', function() {
70514             return this.isArea() ? 'area' : 'line';
70515         });
70516     },
70517
70518
70519     // If this way is not closed, append the beginning node to the end of the nodelist to close it.
70520     close: function() {
70521         if (this.isClosed() || !this.nodes.length) return this;
70522
70523         var nodes = this.nodes.slice();
70524         nodes = nodes.filter(noRepeatNodes);
70525         nodes.push(nodes[0]);
70526         return this.update({ nodes: nodes });
70527     },
70528
70529
70530     // If this way is closed, remove any connector nodes from the end of the nodelist to unclose it.
70531     unclose: function() {
70532         if (!this.isClosed()) return this;
70533
70534         var nodes = this.nodes.slice(),
70535             connector = this.first(),
70536             i = nodes.length - 1;
70537
70538         // remove trailing connectors..
70539         while (i > 0 && nodes.length > 1 && nodes[i] === connector) {
70540             nodes.splice(i, 1);
70541             i = nodes.length - 1;
70542         }
70543
70544         nodes = nodes.filter(noRepeatNodes);
70545         return this.update({ nodes: nodes });
70546     },
70547
70548
70549     // Adds a node (id) in front of the node which is currently at position index.
70550     // If index is undefined, the node will be added to the end of the way for linear ways,
70551     //   or just before the final connecting node for circular ways.
70552     // Consecutive duplicates are eliminated including existing ones.
70553     // Circularity is always preserved when adding a node.
70554     addNode: function(id, index) {
70555         var nodes = this.nodes.slice(),
70556             isClosed = this.isClosed(),
70557             max = isClosed ? nodes.length - 1 : nodes.length;
70558
70559         if (index === undefined) {
70560             index = max;
70561         }
70562
70563         if (index < 0 || index > max) {
70564             throw new RangeError('index ' + index + ' out of range 0..' + max);
70565         }
70566
70567         // If this is a closed way, remove all connector nodes except the first one
70568         // (there may be duplicates) and adjust index if necessary..
70569         if (isClosed) {
70570             var connector = this.first();
70571
70572             // leading connectors..
70573             var i = 1;
70574             while (i < nodes.length && nodes.length > 2 && nodes[i] === connector) {
70575                 nodes.splice(i, 1);
70576                 if (index > i) index--;
70577             }
70578
70579             // trailing connectors..
70580             i = nodes.length - 1;
70581             while (i > 0 && nodes.length > 1 && nodes[i] === connector) {
70582                 nodes.splice(i, 1);
70583                 if (index > i) index--;
70584                 i = nodes.length - 1;
70585             }
70586         }
70587
70588         nodes.splice(index, 0, id);
70589         nodes = nodes.filter(noRepeatNodes);
70590
70591         // If the way was closed before, append a connector node to keep it closed..
70592         if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
70593             nodes.push(nodes[0]);
70594         }
70595
70596         return this.update({ nodes: nodes });
70597     },
70598
70599
70600     // Replaces the node which is currently at position index with the given node (id).
70601     // Consecutive duplicates are eliminated including existing ones.
70602     // Circularity is preserved when updating a node.
70603     updateNode: function(id, index) {
70604         var nodes = this.nodes.slice(),
70605             isClosed = this.isClosed(),
70606             max = nodes.length - 1;
70607
70608         if (index === undefined || index < 0 || index > max) {
70609             throw new RangeError('index ' + index + ' out of range 0..' + max);
70610         }
70611
70612         // If this is a closed way, remove all connector nodes except the first one
70613         // (there may be duplicates) and adjust index if necessary..
70614         if (isClosed) {
70615             var connector = this.first();
70616
70617             // leading connectors..
70618             var i = 1;
70619             while (i < nodes.length && nodes.length > 2 && nodes[i] === connector) {
70620                 nodes.splice(i, 1);
70621                 if (index > i) index--;
70622             }
70623
70624             // trailing connectors..
70625             i = nodes.length - 1;
70626             while (i > 0 && nodes.length > 1 && nodes[i] === connector) {
70627                 nodes.splice(i, 1);
70628                 if (index === i) index = 0;  // update leading connector instead
70629                 i = nodes.length - 1;
70630             }
70631         }
70632
70633         nodes.splice(index, 1, id);
70634         nodes = nodes.filter(noRepeatNodes);
70635
70636         // If the way was closed before, append a connector node to keep it closed..
70637         if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
70638             nodes.push(nodes[0]);
70639         }
70640
70641         return this.update({nodes: nodes});
70642     },
70643
70644
70645     // Replaces each occurrence of node id needle with replacement.
70646     // Consecutive duplicates are eliminated including existing ones.
70647     // Circularity is preserved.
70648     replaceNode: function(needle, replacement) {
70649         var nodes = this.nodes.slice(),
70650             isClosed = this.isClosed();
70651
70652         for (var i = 0; i < nodes.length; i++) {
70653             if (nodes[i] === needle) {
70654                 nodes[i] = replacement;
70655             }
70656         }
70657
70658         nodes = nodes.filter(noRepeatNodes);
70659
70660         // If the way was closed before, append a connector node to keep it closed..
70661         if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
70662             nodes.push(nodes[0]);
70663         }
70664
70665         return this.update({nodes: nodes});
70666     },
70667
70668
70669     // Removes each occurrence of node id needle with replacement.
70670     // Consecutive duplicates are eliminated including existing ones.
70671     // Circularity is preserved.
70672     removeNode: function(id) {
70673         var nodes = this.nodes.slice(),
70674             isClosed = this.isClosed();
70675
70676         nodes = nodes
70677             .filter(function(node) { return node !== id; })
70678             .filter(noRepeatNodes);
70679
70680         // If the way was closed before, append a connector node to keep it closed..
70681         if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
70682             nodes.push(nodes[0]);
70683         }
70684
70685         return this.update({nodes: nodes});
70686     },
70687
70688
70689     asJXON: function(changeset_id) {
70690         var r = {
70691             way: {
70692                 '@id': this.osmId(),
70693                 '@version': this.version || 0,
70694                 nd: map$4(this.nodes, function(id) {
70695                     return { keyAttributes: { ref: osmEntity.id.toOSM(id) } };
70696                 }),
70697                 tag: map$4(this.tags, function(v, k) {
70698                     return { keyAttributes: { k: k, v: v } };
70699                 })
70700             }
70701         };
70702         if (changeset_id) {
70703             r.way['@changeset'] = changeset_id;
70704         }
70705         return r;
70706     },
70707
70708
70709     asGeoJSON: function(resolver) {
70710         return resolver.transient(this, 'GeoJSON', function() {
70711             var coordinates = map$4(resolver.childNodes(this), 'loc');
70712             if (this.isArea() && this.isClosed()) {
70713                 return {
70714                     type: 'Polygon',
70715                     coordinates: [coordinates]
70716                 };
70717             } else {
70718                 return {
70719                     type: 'LineString',
70720                     coordinates: coordinates
70721                 };
70722             }
70723         });
70724     },
70725
70726
70727     area: function(resolver) {
70728         return resolver.transient(this, 'area', function() {
70729             var nodes = resolver.childNodes(this);
70730
70731             var json = {
70732                 type: 'Polygon',
70733                 coordinates: [map$4(nodes, 'loc')]
70734             };
70735
70736             if (!this.isClosed() && nodes.length) {
70737                 json.coordinates[0].push(nodes[0].loc);
70738             }
70739
70740             var area = d3_geoArea(json);
70741
70742             // Heuristic for detecting counterclockwise winding order. Assumes
70743             // that OpenStreetMap polygons are not hemisphere-spanning.
70744             if (area > 2 * Math.PI) {
70745                 json.coordinates[0] = json.coordinates[0].reverse();
70746                 area = d3_geoArea(json);
70747             }
70748
70749             return isNaN(area) ? 0 : area;
70750         });
70751     }
70752 });
70753
70754
70755 // Filter function to eliminate consecutive duplicates.
70756 function noRepeatNodes(node, i, arr) {
70757     return i === 0 || node !== arr[i - 1];
70758 }
70759
70760 // For fixing up rendering of multipolygons with tags on the outer member.
70761 // https://github.com/openstreetmap/iD/issues/613
70762 function osmIsSimpleMultipolygonOuterMember(entity, graph) {
70763     if (entity.type !== 'way' || Object.keys(entity.tags).filter(osmIsInterestingTag).length === 0)
70764         return false;
70765
70766     var parents = graph.parentRelations(entity);
70767     if (parents.length !== 1)
70768         return false;
70769
70770     var parent = parents[0];
70771     if (!parent.isMultipolygon() || Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1)
70772         return false;
70773
70774     var members = parent.members, member;
70775     for (var i = 0; i < members.length; i++) {
70776         member = members[i];
70777         if (member.id === entity.id && member.role && member.role !== 'outer')
70778             return false; // Not outer member
70779         if (member.id !== entity.id && (!member.role || member.role === 'outer'))
70780             return false; // Not a simple multipolygon
70781     }
70782
70783     return parent;
70784 }
70785
70786
70787 function osmSimpleMultipolygonOuterMember(entity, graph) {
70788     if (entity.type !== 'way')
70789         return false;
70790
70791     var parents = graph.parentRelations(entity);
70792     if (parents.length !== 1)
70793         return false;
70794
70795     var parent = parents[0];
70796     if (!parent.isMultipolygon() || Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1)
70797         return false;
70798
70799     var members = parent.members, member, outerMember;
70800     for (var i = 0; i < members.length; i++) {
70801         member = members[i];
70802         if (!member.role || member.role === 'outer') {
70803             if (outerMember)
70804                 return false; // Not a simple multipolygon
70805             outerMember = member;
70806         }
70807     }
70808
70809     if (!outerMember)
70810         return false;
70811
70812     var outerEntity = graph.hasEntity(outerMember.id);
70813     if (!outerEntity || !Object.keys(outerEntity.tags).filter(osmIsInterestingTag).length)
70814         return false;
70815
70816     return outerEntity;
70817 }
70818
70819
70820 // Join `toJoin` array into sequences of connecting ways.
70821
70822 // Segments which share identical start/end nodes will, as much as possible,
70823 // be connected with each other.
70824 //
70825 // The return value is a nested array. Each constituent array contains elements
70826 // of `toJoin` which have been determined to connect.
70827 //
70828 // Each consitituent array also has a `nodes` property whose value is an
70829 // ordered array of member nodes, with appropriate order reversal and
70830 // start/end coordinate de-duplication.
70831 //
70832 // Members of `toJoin` must have, at minimum, `type` and `id` properties.
70833 // Thus either an array of `osmWay`s or a relation member array may be used.
70834 //
70835 // If an member is an `osmWay`, its tags and childnodes may be reversed via
70836 // `actionReverse` in the output.
70837 //
70838 // The returned sequences array also has an `actions` array property, containing
70839 // any reversal actions that should be applied to the graph, should the calling
70840 // code attempt to actually join the given ways.
70841 //
70842 // Incomplete members (those for which `graph.hasEntity(element.id)` returns
70843 // false) and non-way members are ignored.
70844 //
70845 function osmJoinWays(toJoin, graph) {
70846     function resolve(member) {
70847         return graph.childNodes(graph.entity(member.id));
70848     }
70849
70850     function reverse(item) {
70851         var action = actionReverse(item.id, { reverseOneway: true });
70852         sequences.actions.push(action);
70853         return (item instanceof osmWay) ? action(graph).entity(item.id) : item;
70854     }
70855
70856     // make a copy containing only the items to join
70857     toJoin = toJoin.filter(function(member) {
70858         return member.type === 'way' && graph.hasEntity(member.id);
70859     });
70860
70861
70862     var sequences = [];
70863     sequences.actions = [];
70864
70865     while (toJoin.length) {
70866         // start a new sequence
70867         var item = toJoin.shift();
70868         var currWays = [item];
70869         var currNodes = resolve(item).slice();
70870         var doneSequence = false;
70871
70872         // add to it
70873         while (toJoin.length && !doneSequence) {
70874             var start = currNodes[0];
70875             var end = currNodes[currNodes.length - 1];
70876             var fn = null;
70877             var nodes = null;
70878             var i;
70879
70880             // Find the next way/member to join.
70881             for (i = 0; i < toJoin.length; i++) {
70882                 item = toJoin[i];
70883                 nodes = resolve(item);
70884
70885                 // Strongly prefer to generate a forward path that preserves the order
70886                 // of the members array. For multipolygons and most relations, member
70887                 // order does not matter - but for routes, it does. If we started this
70888                 // sequence backwards (i.e. next member way attaches to the start node
70889                 // and not the end node), reverse the initial way before continuing.
70890                 if (currWays.length === 1 && nodes[0] !== end && nodes[nodes.length - 1] !== end &&
70891                     (nodes[nodes.length - 1] === start || nodes[0] === start)
70892                 ) {
70893                     currWays[0] = reverse(currWays[0]);
70894                     currNodes.reverse();
70895                     start = currNodes[0];
70896                     end = currNodes[currNodes.length - 1];
70897                 }
70898
70899                 if (nodes[0] === end) {
70900                     fn = currNodes.push;               // join to end
70901                     nodes = nodes.slice(1);
70902                     break;
70903                 } else if (nodes[nodes.length - 1] === end) {
70904                     fn = currNodes.push;               // join to end
70905                     nodes = nodes.slice(0, -1).reverse();
70906                     item = reverse(item);
70907                     break;
70908                 } else if (nodes[nodes.length - 1] === start) {
70909                     fn = currNodes.unshift;            // join to beginning
70910                     nodes = nodes.slice(0, -1);
70911                     break;
70912                 } else if (nodes[0] === start) {
70913                     fn = currNodes.unshift;            // join to beginning
70914                     nodes = nodes.slice(1).reverse();
70915                     item = reverse(item);
70916                     break;
70917                 } else {
70918                     fn = nodes = null;
70919                 }
70920             }
70921
70922             if (!nodes) {     // couldn't find a joinable way/member
70923                 doneSequence = true;
70924                 break;
70925             }
70926
70927             fn.apply(currWays, [item]);
70928             fn.apply(currNodes, nodes);
70929
70930             toJoin.splice(i, 1);
70931         }
70932
70933         currWays.nodes = currNodes;
70934         sequences.push(currWays);
70935     }
70936
70937     return sequences;
70938 }
70939
70940 function osmRelation() {
70941     if (!(this instanceof osmRelation)) {
70942         return (new osmRelation()).initialize(arguments);
70943     } else if (arguments.length) {
70944         this.initialize(arguments);
70945     }
70946 }
70947
70948
70949 osmEntity.relation = osmRelation;
70950
70951 osmRelation.prototype = Object.create(osmEntity.prototype);
70952
70953
70954 osmRelation.creationOrder = function(a, b) {
70955     var aId = parseInt(osmEntity.id.toOSM(a.id), 10);
70956     var bId = parseInt(osmEntity.id.toOSM(b.id), 10);
70957
70958     if (aId < 0 || bId < 0) return aId - bId;
70959     return bId - aId;
70960 };
70961
70962
70963 assignIn(osmRelation.prototype, {
70964     type: 'relation',
70965     members: [],
70966
70967
70968     copy: function(resolver, copies) {
70969         if (copies[this.id])
70970             return copies[this.id];
70971
70972         var copy = osmEntity.prototype.copy.call(this, resolver, copies);
70973
70974         var members = this.members.map(function(member) {
70975             return assignIn({}, member, { id: resolver.entity(member.id).copy(resolver, copies).id });
70976         });
70977
70978         copy = copy.update({members: members});
70979         copies[this.id] = copy;
70980
70981         return copy;
70982     },
70983
70984
70985     extent: function(resolver, memo) {
70986         return resolver.transient(this, 'extent', function() {
70987             if (memo && memo[this.id]) return geoExtent();
70988             memo = memo || {};
70989             memo[this.id] = true;
70990
70991             var extent = geoExtent();
70992             for (var i = 0; i < this.members.length; i++) {
70993                 var member = resolver.hasEntity(this.members[i].id);
70994                 if (member) {
70995                     extent._extend(member.extent(resolver, memo));
70996                 }
70997             }
70998             return extent;
70999         });
71000     },
71001
71002
71003     geometry: function(graph) {
71004         return graph.transient(this, 'geometry', function() {
71005             return this.isMultipolygon() ? 'area' : 'relation';
71006         });
71007     },
71008
71009
71010     isDegenerate: function() {
71011         return this.members.length === 0;
71012     },
71013
71014
71015     // Return an array of members, each extended with an 'index' property whose value
71016     // is the member index.
71017     indexedMembers: function() {
71018         var result = new Array(this.members.length);
71019         for (var i = 0; i < this.members.length; i++) {
71020             result[i] = assignIn({}, this.members[i], {index: i});
71021         }
71022         return result;
71023     },
71024
71025
71026     // Return the first member with the given role. A copy of the member object
71027     // is returned, extended with an 'index' property whose value is the member index.
71028     memberByRole: function(role) {
71029         for (var i = 0; i < this.members.length; i++) {
71030             if (this.members[i].role === role) {
71031                 return assignIn({}, this.members[i], {index: i});
71032             }
71033         }
71034     },
71035
71036
71037     // Return the first member with the given id. A copy of the member object
71038     // is returned, extended with an 'index' property whose value is the member index.
71039     memberById: function(id) {
71040         for (var i = 0; i < this.members.length; i++) {
71041             if (this.members[i].id === id) {
71042                 return assignIn({}, this.members[i], {index: i});
71043             }
71044         }
71045     },
71046
71047
71048     // Return the first member with the given id and role. A copy of the member object
71049     // is returned, extended with an 'index' property whose value is the member index.
71050     memberByIdAndRole: function(id, role) {
71051         for (var i = 0; i < this.members.length; i++) {
71052             if (this.members[i].id === id && this.members[i].role === role) {
71053                 return assignIn({}, this.members[i], {index: i});
71054             }
71055         }
71056     },
71057
71058
71059     addMember: function(member, index) {
71060         var members = this.members.slice();
71061         members.splice(index === undefined ? members.length : index, 0, member);
71062         return this.update({members: members});
71063     },
71064
71065
71066     updateMember: function(member, index) {
71067         var members = this.members.slice();
71068         members.splice(index, 1, assignIn({}, members[index], member));
71069         return this.update({members: members});
71070     },
71071
71072
71073     removeMember: function(index) {
71074         var members = this.members.slice();
71075         members.splice(index, 1);
71076         return this.update({members: members});
71077     },
71078
71079
71080     removeMembersWithID: function(id) {
71081         var members = reject(this.members, function(m) { return m.id === id; });
71082         return this.update({members: members});
71083     },
71084
71085
71086     // Wherever a member appears with id `needle.id`, replace it with a member
71087     // with id `replacement.id`, type `replacement.type`, and the original role,
71088     // By default, adding a duplicate member (by id and role) is prevented.
71089     // Return an updated relation.
71090     replaceMember: function(needle, replacement, keepDuplicates) {
71091         if (!this.memberById(needle.id))
71092             return this;
71093
71094         var members = [];
71095
71096         for (var i = 0; i < this.members.length; i++) {
71097             var member = this.members[i];
71098             if (member.id !== needle.id) {
71099                 members.push(member);
71100             } else if (keepDuplicates || !this.memberByIdAndRole(replacement.id, member.role)) {
71101                 members.push({id: replacement.id, type: replacement.type, role: member.role});
71102             }
71103         }
71104
71105         return this.update({members: members});
71106     },
71107
71108
71109     asJXON: function(changeset_id) {
71110         var r = {
71111             relation: {
71112                 '@id': this.osmId(),
71113                 '@version': this.version || 0,
71114                 member: map$4(this.members, function(member) {
71115                     return {
71116                         keyAttributes: {
71117                             type: member.type,
71118                             role: member.role,
71119                             ref: osmEntity.id.toOSM(member.id)
71120                         }
71121                     };
71122                 }),
71123                 tag: map$4(this.tags, function(v, k) {
71124                     return { keyAttributes: { k: k, v: v } };
71125                 })
71126             }
71127         };
71128         if (changeset_id) r.relation['@changeset'] = changeset_id;
71129         return r;
71130     },
71131
71132
71133     asGeoJSON: function(resolver) {
71134         return resolver.transient(this, 'GeoJSON', function () {
71135             if (this.isMultipolygon()) {
71136                 return {
71137                     type: 'MultiPolygon',
71138                     coordinates: this.multipolygon(resolver)
71139                 };
71140             } else {
71141                 return {
71142                     type: 'FeatureCollection',
71143                     properties: this.tags,
71144                     features: this.members.map(function (member) {
71145                         return assignIn({role: member.role}, resolver.entity(member.id).asGeoJSON(resolver));
71146                     })
71147                 };
71148             }
71149         });
71150     },
71151
71152
71153     area: function(resolver) {
71154         return resolver.transient(this, 'area', function() {
71155             return d3_geoArea(this.asGeoJSON(resolver));
71156         });
71157     },
71158
71159
71160     isMultipolygon: function() {
71161         return this.tags.type === 'multipolygon';
71162     },
71163
71164
71165     isComplete: function(resolver) {
71166         for (var i = 0; i < this.members.length; i++) {
71167             if (!resolver.hasEntity(this.members[i].id)) {
71168                 return false;
71169             }
71170         }
71171         return true;
71172     },
71173
71174
71175     isRestriction: function() {
71176         return !!(this.tags.type && this.tags.type.match(/^restriction:?/));
71177     },
71178
71179
71180     // Returns an array [A0, ... An], each Ai being an array of node arrays [Nds0, ... Ndsm],
71181     // where Nds0 is an outer ring and subsequent Ndsi's (if any i > 0) being inner rings.
71182     //
71183     // This corresponds to the structure needed for rendering a multipolygon path using a
71184     // `evenodd` fill rule, as well as the structure of a GeoJSON MultiPolygon geometry.
71185     //
71186     // In the case of invalid geometries, this function will still return a result which
71187     // includes the nodes of all way members, but some Nds may be unclosed and some inner
71188     // rings not matched with the intended outer ring.
71189     //
71190     multipolygon: function(resolver) {
71191         var outers = this.members.filter(function(m) { return 'outer' === (m.role || 'outer'); }),
71192             inners = this.members.filter(function(m) { return 'inner' === m.role; });
71193
71194         outers = osmJoinWays(outers, resolver);
71195         inners = osmJoinWays(inners, resolver);
71196
71197         outers = outers.map(function(outer) { return map$4(outer.nodes, 'loc'); });
71198         inners = inners.map(function(inner) { return map$4(inner.nodes, 'loc'); });
71199
71200         var result = outers.map(function(o) {
71201             // Heuristic for detecting counterclockwise winding order. Assumes
71202             // that OpenStreetMap polygons are not hemisphere-spanning.
71203             return [d3_geoArea({ type: 'Polygon', coordinates: [o] }) > 2 * Math.PI ? o.reverse() : o];
71204         });
71205
71206         function findOuter(inner) {
71207             var o, outer;
71208
71209             for (o = 0; o < outers.length; o++) {
71210                 outer = outers[o];
71211                 if (geoPolygonContainsPolygon(outer, inner))
71212                     return o;
71213             }
71214
71215             for (o = 0; o < outers.length; o++) {
71216                 outer = outers[o];
71217                 if (geoPolygonIntersectsPolygon(outer, inner, false))
71218                     return o;
71219             }
71220         }
71221
71222         for (var i = 0; i < inners.length; i++) {
71223             var inner = inners[i];
71224
71225             if (d3_geoArea({ type: 'Polygon', coordinates: [inner] }) < 2 * Math.PI) {
71226                 inner = inner.reverse();
71227             }
71228
71229             var o = findOuter(inners[i]);
71230             if (o !== undefined)
71231                 result[o].push(inners[i]);
71232             else
71233                 result.push([inners[i]]); // Invalid geometry
71234         }
71235
71236         return result;
71237     }
71238 });
71239
71240 /* Built-in method references for those with the same name as other `lodash` methods. */
71241 var nativeMax$8 = Math.max;
71242
71243 /**
71244  * Gets the index at which the first occurrence of `value` is found in `array`
71245  * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
71246  * for equality comparisons. If `fromIndex` is negative, it's used as the
71247  * offset from the end of `array`.
71248  *
71249  * @static
71250  * @memberOf _
71251  * @since 0.1.0
71252  * @category Array
71253  * @param {Array} array The array to inspect.
71254  * @param {*} value The value to search for.
71255  * @param {number} [fromIndex=0] The index to search from.
71256  * @returns {number} Returns the index of the matched value, else `-1`.
71257  * @example
71258  *
71259  * _.indexOf([1, 2, 1, 2], 2);
71260  * // => 1
71261  *
71262  * // Search from the `fromIndex`.
71263  * _.indexOf([1, 2, 1, 2], 2, 2);
71264  * // => 3
71265  */
71266 function indexOf(array, value, fromIndex) {
71267   var length = array == null ? 0 : array.length;
71268   if (!length) {
71269     return -1;
71270   }
71271   var index = fromIndex == null ? 0 : toInteger(fromIndex);
71272   if (index < 0) {
71273     index = nativeMax$8(length + index, 0);
71274   }
71275   return baseIndexOf(array, value, index);
71276 }
71277
71278 function osmTurn(turn) {
71279     if (!(this instanceof osmTurn))
71280         return new osmTurn(turn);
71281     assignIn(this, turn);
71282 }
71283
71284
71285 function osmIntersection(graph, vertexId) {
71286     var vertex = graph.entity(vertexId),
71287         parentWays = graph.parentWays(vertex),
71288         coincident = [],
71289         highways = {};
71290
71291     function addHighway(way, adjacentNodeId) {
71292         if (highways[adjacentNodeId]) {
71293             coincident.push(adjacentNodeId);
71294         } else {
71295             highways[adjacentNodeId] = way;
71296         }
71297     }
71298
71299     // Pre-split ways that would need to be split in
71300     // order to add a restriction. The real split will
71301     // happen when the restriction is added.
71302     parentWays.forEach(function(way) {
71303         if (!way.tags.highway || way.isArea() || way.isDegenerate())
71304             return;
71305
71306         var isFirst = (vertexId === way.first()),
71307             isLast = (vertexId === way.last()),
71308             isAffix = (isFirst || isLast),
71309             isClosingNode = (isFirst && isLast);
71310
71311         if (isAffix && !isClosingNode) {
71312             var index = (isFirst ? 1 : way.nodes.length - 2);
71313             addHighway(way, way.nodes[index]);
71314
71315         } else {
71316             var splitIndex, wayA, wayB, indexA, indexB;
71317             if (isClosingNode) {
71318                 splitIndex = Math.ceil(way.nodes.length / 2);  // split at midpoint
71319                 wayA = osmWay({id: way.id + '-a', tags: way.tags, nodes: way.nodes.slice(0, splitIndex)});
71320                 wayB = osmWay({id: way.id + '-b', tags: way.tags, nodes: way.nodes.slice(splitIndex)});
71321                 indexA = 1;
71322                 indexB = way.nodes.length - 2;
71323             } else {
71324                 splitIndex = indexOf(way.nodes, vertex.id, 1);  // split at vertexid
71325                 wayA = osmWay({id: way.id + '-a', tags: way.tags, nodes: way.nodes.slice(0, splitIndex + 1)});
71326                 wayB = osmWay({id: way.id + '-b', tags: way.tags, nodes: way.nodes.slice(splitIndex)});
71327                 indexA = splitIndex - 1;
71328                 indexB = splitIndex + 1;
71329             }
71330             graph = graph.replace(wayA).replace(wayB);
71331             addHighway(wayA, way.nodes[indexA]);
71332             addHighway(wayB, way.nodes[indexB]);
71333         }
71334     });
71335
71336     // remove any ways from this intersection that are coincident
71337     // (i.e. any adjacent node used by more than one intersecting way)
71338     coincident.forEach(function (n) {
71339         delete highways[n];
71340     });
71341
71342
71343     var intersection = {
71344         highways: highways,
71345         ways: values$1(highways),
71346         graph: graph
71347     };
71348
71349
71350     intersection.adjacentNodeId = function(fromWayId) {
71351         return find$1(keys$1(highways), function(k) {
71352             return highways[k].id === fromWayId;
71353         });
71354     };
71355
71356
71357     intersection.turns = function(fromNodeId) {
71358         var start = highways[fromNodeId];
71359         if (!start)
71360             return [];
71361
71362         if (start.first() === vertex.id && start.tags.oneway === 'yes')
71363             return [];
71364         if (start.last() === vertex.id && start.tags.oneway === '-1')
71365             return [];
71366
71367         function withRestriction(turn) {
71368             graph.parentRelations(graph.entity(turn.from.way)).forEach(function(relation) {
71369                 if (relation.tags.type !== 'restriction')
71370                     return;
71371
71372                 var f = relation.memberByRole('from'),
71373                     t = relation.memberByRole('to'),
71374                     v = relation.memberByRole('via');
71375
71376                 if (f && f.id === turn.from.way &&
71377                     v && v.id === turn.via.node &&
71378                     t && t.id === turn.to.way) {
71379                     turn.restriction = relation.id;
71380                 } else if (/^only_/.test(relation.tags.restriction) &&
71381                     f && f.id === turn.from.way &&
71382                     v && v.id === turn.via.node &&
71383                     t && t.id !== turn.to.way) {
71384                     turn.restriction = relation.id;
71385                     turn.indirect_restriction = true;
71386                 }
71387             });
71388
71389             return osmTurn(turn);
71390         }
71391
71392
71393         var from = {
71394                 node: fromNodeId,
71395                 way: start.id.split(/-(a|b)/)[0]
71396             },
71397             via = { node: vertex.id },
71398             turns = [];
71399
71400         forEach(highways, function(end, adjacentNodeId) {
71401             if (end === start)
71402                 return;
71403
71404             // backward
71405             if (end.first() !== vertex.id && end.tags.oneway !== 'yes') {
71406                 turns.push(withRestriction({
71407                     from: from,
71408                     via: via,
71409                     to: {
71410                         node: adjacentNodeId,
71411                         way: end.id.split(/-(a|b)/)[0]
71412                     }
71413                 }));
71414             }
71415
71416             // forward
71417             if (end.last() !== vertex.id && end.tags.oneway !== '-1') {
71418                 turns.push(withRestriction({
71419                     from: from,
71420                     via: via,
71421                     to: {
71422                         node: adjacentNodeId,
71423                         way: end.id.split(/-(a|b)/)[0]
71424                     }
71425                 }));
71426             }
71427
71428         });
71429
71430         // U-turn
71431         if (start.tags.oneway !== 'yes' && start.tags.oneway !== '-1') {
71432             turns.push(withRestriction({
71433                 from: from,
71434                 via: via,
71435                 to: from,
71436                 u: true
71437             }));
71438         }
71439
71440         return turns;
71441     };
71442
71443     return intersection;
71444 }
71445
71446
71447 function osmInferRestriction(graph, from, via, to, projection) {
71448     var fromWay = graph.entity(from.way),
71449         fromNode = graph.entity(from.node),
71450         toWay = graph.entity(to.way),
71451         toNode = graph.entity(to.node),
71452         viaNode = graph.entity(via.node),
71453         fromOneWay = (fromWay.tags.oneway === 'yes' && fromWay.last() === via.node) ||
71454             (fromWay.tags.oneway === '-1' && fromWay.first() === via.node),
71455         toOneWay = (toWay.tags.oneway === 'yes' && toWay.first() === via.node) ||
71456             (toWay.tags.oneway === '-1' && toWay.last() === via.node),
71457         angle = geoAngle(viaNode, fromNode, projection) -
71458                 geoAngle(viaNode, toNode, projection);
71459
71460     angle = angle * 180 / Math.PI;
71461
71462     while (angle < 0)
71463         angle += 360;
71464
71465     if (fromNode === toNode)
71466         return 'no_u_turn';
71467     if ((angle < 23 || angle > 336) && fromOneWay && toOneWay)
71468         return 'no_u_turn';
71469     if (angle < 158)
71470         return 'no_right_turn';
71471     if (angle > 202)
71472         return 'no_left_turn';
71473
71474     return 'no_straight_on';
71475 }
71476
71477 function actionAddMember(relationId, member, memberIndex, insertPair) {
71478
71479     return function action(graph) {
71480         var relation = graph.entity(relationId);
71481
71482         if ((isNaN(memberIndex) || insertPair) && member.type === 'way') {
71483             // Try to perform sensible inserts based on how the ways join together
71484             graph = addWayMember(relation, graph);
71485         } else {
71486             graph = graph.replace(relation.addMember(member, memberIndex));
71487         }
71488
71489         return graph;
71490     };
71491
71492
71493     // Add a way member into the relation "wherever it makes sense".
71494     // In this situation we were not supplied a memberIndex.
71495     function addWayMember(relation, graph) {
71496         var groups, tempWay, item, i, j, k;
71497
71498         if (insertPair) {
71499             // We're adding a member that must stay paired with an existing member.
71500             // (This feature is used by `actionSplit`)
71501             //
71502             // This is tricky because the members may exist multiple times in the
71503             // member list, and with different A-B/B-A ordering and different roles.
71504             // (e.g. a bus route that loops out and back - #4589).
71505             //
71506             // Replace the existing member with a temporary way,
71507             // so that `osmJoinWays` can treat the pair like a single way.
71508             tempWay = osmWay({ id: 'wTemp', nodes: insertPair.nodes });
71509             graph = graph.replace(tempWay);
71510             var tempMember = { id: tempWay.id, type: 'way', role: member.role };
71511             var tempRelation = relation.replaceMember({id: insertPair.originalID}, tempMember, true);
71512             groups = groupBy(tempRelation.members, function(m) { return m.type; });
71513             groups.way = groups.way || [];
71514
71515         } else {
71516             // Add the member anywhere, one time. Just push and let `osmJoinWays` decide where to put it.
71517             groups = groupBy(relation.members, function(m) { return m.type; });
71518             groups.way = groups.way || [];
71519             groups.way.push(member);
71520         }
71521
71522         var members = withIndex(groups.way);
71523         var joined = osmJoinWays(members, graph);
71524
71525         // `joined` might not contain all of the way members,
71526         // But will contain only the completed (downloaded) members
71527         for (i = 0; i < joined.length; i++) {
71528             var segment = joined[i];
71529             var nodes = segment.nodes.slice();
71530             var startIndex = segment[0].index;
71531
71532             // j = array index in `members` where this segment starts
71533             for (j = 0; j < members.length; j++) {
71534                 if (members[j].index === startIndex) {
71535                     break;
71536                 }
71537             }
71538
71539             // k = each member in segment
71540             for (k = 0; k < segment.length; k++) {
71541                 item = segment[k];
71542                 var way = graph.entity(item.id);
71543
71544                 // If this is a paired item, generate members in correct order and role
71545                 if (tempWay && item.id === tempWay.id) {
71546                     if (nodes[0].id === insertPair.nodes[0]) {
71547                         item.pair = [
71548                             { id: insertPair.originalID, type: 'way', role: item.role },
71549                             { id: insertPair.insertedID, type: 'way', role: item.role }
71550                         ];
71551                     } else {
71552                         item.pair = [
71553                             { id: insertPair.insertedID, type: 'way', role: item.role },
71554                             { id: insertPair.originalID, type: 'way', role: item.role }
71555                         ];
71556                     }
71557                 }
71558
71559                 // reorder `members` if necessary
71560                 if (k > 0) {
71561                     if (j+k >= members.length || item.index !== members[j+k].index) {
71562                         moveMember(members, item.index, j+k);
71563                     }
71564                 }
71565
71566                 nodes.splice(0, way.nodes.length - 1);
71567             }
71568         }
71569
71570         if (tempWay) {
71571             graph = graph.remove(tempWay);
71572         }
71573
71574         // Final pass: skip dead items, split pairs, remove index properties
71575         var wayMembers = [];
71576         for (i = 0; i < members.length; i++) {
71577             item = members[i];
71578             if (item.index === -1) continue;
71579
71580             if (item.pair) {
71581                 wayMembers.push(item.pair[0]);
71582                 wayMembers.push(item.pair[1]);
71583             } else {
71584                 wayMembers.push(omit(item, 'index'));
71585             }
71586         }
71587
71588         // Write members in the order: nodes, ways, relations
71589         // This is reccomended for Public Transport routes:
71590         // see https://wiki.openstreetmap.org/wiki/Public_transport#Service_routes
71591         var newMembers = (groups.node || []).concat(wayMembers, (groups.relation || []));
71592
71593         return graph.replace(relation.update({members: newMembers}));
71594
71595
71596         // `moveMember()` changes the `members` array in place by splicing
71597         // the item with `.index = findIndex` to where it belongs,
71598         // and marking the old position as "dead" with `.index = -1`
71599         //
71600         // j=5, k=0                jk
71601         // segment                 5 4 7 6
71602         // members       0 1 2 3 4 5 6 7 8 9        keep 5 in j+k
71603         //
71604         // j=5, k=1                j k
71605         // segment                 5 4 7 6
71606         // members       0 1 2 3 4 5 6 7 8 9        move 4 to j+k
71607         // members       0 1 2 3 x 5 4 6 7 8 9      moved
71608         //
71609         // j=5, k=2                j   k
71610         // segment                 5 4 7 6
71611         // members       0 1 2 3 x 5 4 6 7 8 9      move 7 to j+k
71612         // members       0 1 2 3 x 5 4 7 6 x 8 9    moved
71613         //
71614         // j=5, k=3                j     k
71615         // segment                 5 4 7 6
71616         // members       0 1 2 3 x 5 4 7 6 x 8 9    keep 6 in j+k
71617         //
71618         function moveMember(arr, findIndex, toIndex) {
71619             for (var i = 0; i < arr.length; i++) {
71620                 if (arr[i].index === findIndex) {
71621                     break;
71622                 }
71623             }
71624
71625             var item = clone(arr[i]);
71626             arr[i].index = -1;   // mark as dead
71627             item.index = toIndex;
71628             arr.splice(toIndex, 0, item);
71629         }
71630
71631
71632         // This is the same as `Relation.indexedMembers`,
71633         // Except we don't want to index all the members, only the ways
71634         function withIndex(arr) {
71635             var result = new Array(arr.length);
71636             for (var i = 0; i < arr.length; i++) {
71637                 result[i] = arr[i];
71638                 result[i].index = i;
71639             }
71640             return result;
71641         }
71642     }
71643
71644 }
71645
71646 function actionAddMidpoint(midpoint, node) {
71647     return function(graph) {
71648         graph = graph.replace(node.move(midpoint.loc));
71649
71650         var parents = intersection(
71651             graph.parentWays(graph.entity(midpoint.edge[0])),
71652             graph.parentWays(graph.entity(midpoint.edge[1])));
71653
71654         parents.forEach(function(way) {
71655             for (var i = 0; i < way.nodes.length - 1; i++) {
71656                 if (geoEdgeEqual([way.nodes[i], way.nodes[i + 1]], midpoint.edge)) {
71657                     graph = graph.replace(graph.entity(way.id).addNode(node.id, i + 1));
71658
71659                     // Add only one midpoint on doubled-back segments,
71660                     // turning them into self-intersections.
71661                     return;
71662                 }
71663             }
71664         });
71665
71666         return graph;
71667     };
71668 }
71669
71670 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/AddNodeToWayAction.as
71671 function actionAddVertex(wayId, nodeId, index) {
71672     return function(graph) {
71673         return graph.replace(graph.entity(wayId).addNode(nodeId, index));
71674     };
71675 }
71676
71677 function actionChangeMember(relationId, member, memberIndex) {
71678     return function(graph) {
71679         return graph.replace(graph.entity(relationId).updateMember(member, memberIndex));
71680     };
71681 }
71682
71683 function actionChangePreset(entityId, oldPreset, newPreset) {
71684     return function(graph) {
71685         var entity = graph.entity(entityId),
71686             geometry = entity.geometry(graph),
71687             tags = entity.tags;
71688
71689         if (oldPreset) tags = oldPreset.removeTags(tags, geometry);
71690         if (newPreset) tags = newPreset.applyTags(tags, geometry);
71691
71692         return graph.replace(entity.update({tags: tags}));
71693     };
71694 }
71695
71696 function actionChangeTags(entityId, tags) {
71697     return function(graph) {
71698         var entity = graph.entity(entityId);
71699         return graph.replace(entity.update({tags: tags}));
71700     };
71701 }
71702
71703 function actionCircularize(wayId, projection, maxAngle) {
71704     maxAngle = (maxAngle || 20) * Math.PI / 180;
71705
71706
71707     var action = function(graph, t) {
71708         if (t === null || !isFinite(t)) t = 1;
71709         t = Math.min(Math.max(+t, 0), 1);
71710
71711         var way = graph.entity(wayId),
71712             origNodes = {};
71713
71714         graph.childNodes(way).forEach(function(node) {
71715             if (!origNodes[node.id]) origNodes[node.id] = node;
71716         });
71717
71718         if (!way.isConvex(graph)) {
71719             graph = action.makeConvex(graph);
71720         }
71721
71722         var nodes = uniq(graph.childNodes(way)),
71723             keyNodes = nodes.filter(function(n) { return graph.parentWays(n).length !== 1; }),
71724             points = nodes.map(function(n) { return projection(n.loc); }),
71725             keyPoints = keyNodes.map(function(n) { return projection(n.loc); }),
71726             centroid = (points.length === 2) ? geoVecInterp(points[0], points[1], 0.5) : d3_polygonCentroid(points),
71727             radius = d3_median(points, function(p) { return geoVecLength(centroid, p); }),
71728             sign = d3_polygonArea(points) > 0 ? 1 : -1,
71729             ids;
71730
71731         // we need atleast two key nodes for the algorithm to work
71732         if (!keyNodes.length) {
71733             keyNodes = [nodes[0]];
71734             keyPoints = [points[0]];
71735         }
71736
71737         if (keyNodes.length === 1) {
71738             var index = nodes.indexOf(keyNodes[0]),
71739                 oppositeIndex = Math.floor((index + nodes.length / 2) % nodes.length);
71740
71741             keyNodes.push(nodes[oppositeIndex]);
71742             keyPoints.push(points[oppositeIndex]);
71743         }
71744
71745         // key points and nodes are those connected to the ways,
71746         // they are projected onto the circle, inbetween nodes are moved
71747         // to constant intervals between key nodes, extra inbetween nodes are
71748         // added if necessary.
71749         for (var i = 0; i < keyPoints.length; i++) {
71750             var nextKeyNodeIndex = (i + 1) % keyNodes.length,
71751                 startNode = keyNodes[i],
71752                 endNode = keyNodes[nextKeyNodeIndex],
71753                 startNodeIndex = nodes.indexOf(startNode),
71754                 endNodeIndex = nodes.indexOf(endNode),
71755                 numberNewPoints = -1,
71756                 indexRange = endNodeIndex - startNodeIndex,
71757                 nearNodes = {},
71758                 inBetweenNodes = [],
71759                 startAngle, endAngle, totalAngle, eachAngle,
71760                 angle, loc, node, origNode, j;
71761
71762             if (indexRange < 0) {
71763                 indexRange += nodes.length;
71764             }
71765
71766             // position this key node
71767             var distance = geoVecLength(centroid, keyPoints[i]);
71768             if (distance === 0) { distance = 1e-4; }
71769             keyPoints[i] = [
71770                 centroid[0] + (keyPoints[i][0] - centroid[0]) / distance * radius,
71771                 centroid[1] + (keyPoints[i][1] - centroid[1]) / distance * radius
71772             ];
71773             loc = projection.invert(keyPoints[i]);
71774             node = keyNodes[i];
71775             origNode = origNodes[node.id];
71776             node = node.move(geoVecInterp(origNode.loc, loc, t));
71777             graph = graph.replace(node);
71778
71779             // figure out the between delta angle we want to match to
71780             startAngle = Math.atan2(keyPoints[i][1] - centroid[1], keyPoints[i][0] - centroid[0]);
71781             endAngle = Math.atan2(keyPoints[nextKeyNodeIndex][1] - centroid[1], keyPoints[nextKeyNodeIndex][0] - centroid[0]);
71782             totalAngle = endAngle - startAngle;
71783
71784             // detects looping around -pi/pi
71785             if (totalAngle * sign > 0) {
71786                 totalAngle = -sign * (2 * Math.PI - Math.abs(totalAngle));
71787             }
71788
71789             do {
71790                 numberNewPoints++;
71791                 eachAngle = totalAngle / (indexRange + numberNewPoints);
71792             } while (Math.abs(eachAngle) > maxAngle);
71793
71794
71795             // move existing nodes
71796             for (j = 1; j < indexRange; j++) {
71797                 angle = startAngle + j * eachAngle;
71798                 loc = projection.invert([
71799                     centroid[0] + Math.cos(angle) * radius,
71800                     centroid[1] + Math.sin(angle) * radius
71801                 ]);
71802
71803                 node = nodes[(j + startNodeIndex) % nodes.length];
71804                 origNode = origNodes[node.id];
71805                 nearNodes[node.id] = angle;
71806
71807                 node = node.move(geoVecInterp(origNode.loc, loc, t));
71808                 graph = graph.replace(node);
71809             }
71810
71811             // add new inbetween nodes if necessary
71812             for (j = 0; j < numberNewPoints; j++) {
71813                 angle = startAngle + (indexRange + j) * eachAngle;
71814                 loc = projection.invert([
71815                     centroid[0] + Math.cos(angle) * radius,
71816                     centroid[1] + Math.sin(angle) * radius
71817                 ]);
71818
71819                 // choose a nearnode to use as the original
71820                 var min = Infinity;
71821                 for (var nodeId in nearNodes) {
71822                     var nearAngle = nearNodes[nodeId],
71823                         dist = Math.abs(nearAngle - angle);
71824                     if (dist < min) {
71825                         dist = min;
71826                         origNode = origNodes[nodeId];
71827                     }
71828                 }
71829
71830                 node = osmNode({ loc: geoVecInterp(origNode.loc, loc, t) });
71831                 graph = graph.replace(node);
71832
71833                 nodes.splice(endNodeIndex + j, 0, node);
71834                 inBetweenNodes.push(node.id);
71835             }
71836
71837             // Check for other ways that share these keyNodes..
71838             // If keyNodes are adjacent in both ways,
71839             // we can add inBetween nodes to that shared way too..
71840             if (indexRange === 1 && inBetweenNodes.length) {
71841                 var startIndex1 = way.nodes.lastIndexOf(startNode.id),
71842                     endIndex1 = way.nodes.lastIndexOf(endNode.id),
71843                     wayDirection1 = (endIndex1 - startIndex1);
71844                 if (wayDirection1 < -1) { wayDirection1 = 1; }
71845
71846                 /* eslint-disable no-loop-func */
71847                 forEach(without(graph.parentWays(keyNodes[i]), way), function(sharedWay) {
71848                     if (sharedWay.areAdjacent(startNode.id, endNode.id)) {
71849                         var startIndex2 = sharedWay.nodes.lastIndexOf(startNode.id),
71850                             endIndex2 = sharedWay.nodes.lastIndexOf(endNode.id),
71851                             wayDirection2 = (endIndex2 - startIndex2),
71852                             insertAt = endIndex2;
71853                         if (wayDirection2 < -1) { wayDirection2 = 1; }
71854
71855                         if (wayDirection1 !== wayDirection2) {
71856                             inBetweenNodes.reverse();
71857                             insertAt = startIndex2;
71858                         }
71859                         for (j = 0; j < inBetweenNodes.length; j++) {
71860                             sharedWay = sharedWay.addNode(inBetweenNodes[j], insertAt + j);
71861                         }
71862                         graph = graph.replace(sharedWay);
71863                     }
71864                 });
71865                 /* eslint-enable no-loop-func */
71866             }
71867
71868         }
71869
71870         // update the way to have all the new nodes
71871         ids = nodes.map(function(n) { return n.id; });
71872         ids.push(ids[0]);
71873
71874         way = way.update({nodes: ids});
71875         graph = graph.replace(way);
71876
71877         return graph;
71878     };
71879
71880
71881     action.makeConvex = function(graph) {
71882         var way = graph.entity(wayId),
71883             nodes = uniq(graph.childNodes(way)),
71884             points = nodes.map(function(n) { return projection(n.loc); }),
71885             sign = d3_polygonArea(points) > 0 ? 1 : -1,
71886             hull = d3_polygonHull(points);
71887
71888         // D3 convex hulls go counterclockwise..
71889         if (sign === -1) {
71890             nodes.reverse();
71891             points.reverse();
71892         }
71893
71894         for (var i = 0; i < hull.length - 1; i++) {
71895             var startIndex = points.indexOf(hull[i]),
71896                 endIndex = points.indexOf(hull[i+1]),
71897                 indexRange = (endIndex - startIndex);
71898
71899             if (indexRange < 0) {
71900                 indexRange += nodes.length;
71901             }
71902
71903             // move interior nodes to the surface of the convex hull..
71904             for (var j = 1; j < indexRange; j++) {
71905                 var point = geoVecInterp(hull[i], hull[i+1], j / indexRange),
71906                     node = nodes[(j + startIndex) % nodes.length].move(projection.invert(point));
71907                 graph = graph.replace(node);
71908             }
71909         }
71910         return graph;
71911     };
71912
71913
71914     action.disabled = function(graph) {
71915         if (!graph.entity(wayId).isClosed())
71916             return 'not_closed';
71917     };
71918
71919
71920     action.transitionable = true;
71921
71922
71923     return action;
71924 }
71925
71926 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteWayAction.as
71927 function actionDeleteWay(wayId) {
71928
71929
71930     function canDeleteNode(node, graph) {
71931         return !graph.parentWays(node).length &&
71932             !graph.parentRelations(node).length &&
71933             !node.hasInterestingTags();
71934     }
71935
71936
71937     var action = function(graph) {
71938         var way = graph.entity(wayId);
71939
71940         graph.parentRelations(way)
71941             .forEach(function(parent) {
71942                 parent = parent.removeMembersWithID(wayId);
71943                 graph = graph.replace(parent);
71944
71945                 if (parent.isDegenerate()) {
71946                     graph = actionDeleteRelation(parent.id)(graph);
71947                 }
71948             });
71949
71950         uniq(way.nodes).forEach(function(nodeId) {
71951             graph = graph.replace(way.removeNode(nodeId));
71952
71953             var node = graph.entity(nodeId);
71954             if (canDeleteNode(node, graph)) {
71955                 graph = graph.remove(node);
71956             }
71957         });
71958
71959         return graph.remove(way);
71960     };
71961
71962
71963     return action;
71964 }
71965
71966 function actionDeleteMultiple(ids) {
71967     var actions = {
71968         way: actionDeleteWay,
71969         node: actionDeleteNode,
71970         relation: actionDeleteRelation
71971     };
71972
71973
71974     var action = function(graph) {
71975         ids.forEach(function(id) {
71976             if (graph.hasEntity(id)) { // It may have been deleted aready.
71977                 graph = actions[graph.entity(id).type](id)(graph);
71978             }
71979         });
71980
71981         return graph;
71982     };
71983
71984
71985     return action;
71986 }
71987
71988 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteRelationAction.as
71989 function actionDeleteRelation(relationId) {
71990
71991
71992     function canDeleteEntity(entity, graph) {
71993         return !graph.parentWays(entity).length &&
71994             !graph.parentRelations(entity).length &&
71995             !entity.hasInterestingTags();
71996     }
71997
71998
71999     var action = function(graph) {
72000         var relation = graph.entity(relationId);
72001
72002         graph.parentRelations(relation)
72003             .forEach(function(parent) {
72004                 parent = parent.removeMembersWithID(relationId);
72005                 graph = graph.replace(parent);
72006
72007                 if (parent.isDegenerate()) {
72008                     graph = actionDeleteRelation(parent.id)(graph);
72009                 }
72010             });
72011
72012         uniq(map$4(relation.members, 'id')).forEach(function(memberId) {
72013             graph = graph.replace(relation.removeMembersWithID(memberId));
72014
72015             var entity = graph.entity(memberId);
72016             if (canDeleteEntity(entity, graph)) {
72017                 graph = actionDeleteMultiple([memberId])(graph);
72018             }
72019         });
72020
72021         return graph.remove(relation);
72022     };
72023
72024
72025     return action;
72026 }
72027
72028 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteNodeAction.as
72029 function actionDeleteNode(nodeId) {
72030     var action = function(graph) {
72031         var node = graph.entity(nodeId);
72032
72033         graph.parentWays(node)
72034             .forEach(function(parent) {
72035                 parent = parent.removeNode(nodeId);
72036                 graph = graph.replace(parent);
72037
72038                 if (parent.isDegenerate()) {
72039                     graph = actionDeleteWay(parent.id)(graph);
72040                 }
72041             });
72042
72043         graph.parentRelations(node)
72044             .forEach(function(parent) {
72045                 parent = parent.removeMembersWithID(nodeId);
72046                 graph = graph.replace(parent);
72047
72048                 if (parent.isDegenerate()) {
72049                     graph = actionDeleteRelation(parent.id)(graph);
72050                 }
72051             });
72052
72053         return graph.remove(node);
72054     };
72055
72056
72057     return action;
72058 }
72059
72060 // Connect the ways at the given nodes.
72061 //
72062 // The last node will survive. All other nodes will be replaced with
72063 // the surviving node in parent ways, and then removed.
72064 //
72065 // Tags and relation memberships of of non-surviving nodes are merged
72066 // to the survivor.
72067 //
72068 // This is the inverse of `iD.actionDisconnect`.
72069 //
72070 // Reference:
72071 //   https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MergeNodesAction.as
72072 //   https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/MergeNodesAction.java
72073 //
72074 function actionConnect(nodeIds) {
72075     return function(graph) {
72076         var last = nodeIds[nodeIds.length - 1];
72077         var survivor = graph.entity(last);
72078
72079         for (var i = 0; i < nodeIds.length - 1; i++) {
72080             var node = graph.entity(nodeIds[i]);
72081
72082             /* eslint-disable no-loop-func */
72083             graph.parentWays(node).forEach(function(parent) {
72084                 if (!parent.areAdjacent(node.id, survivor.id)) {
72085                     graph = graph.replace(parent.replaceNode(node.id, survivor.id));
72086                 }
72087             });
72088
72089             graph.parentRelations(node).forEach(function(parent) {
72090                 graph = graph.replace(parent.replaceMember(node, survivor));
72091             });
72092             /* eslint-enable no-loop-func */
72093
72094             survivor = survivor.mergeTags(node.tags);
72095             graph = actionDeleteNode(node.id)(graph);
72096         }
72097
72098         graph = graph.replace(survivor);
72099
72100         return graph;
72101     };
72102 }
72103
72104 function actionCopyEntities(ids, fromGraph) {
72105     var copies = {};
72106
72107
72108     var action = function(graph) {
72109         ids.forEach(function(id) {
72110             fromGraph.entity(id).copy(fromGraph, copies);
72111         });
72112
72113         for (var id in copies) {
72114             graph = graph.replace(copies[id]);
72115         }
72116
72117         return graph;
72118     };
72119
72120
72121     action.copies = function() {
72122         return copies;
72123     };
72124
72125
72126     return action;
72127 }
72128
72129 function actionDeleteMember(relationId, memberIndex) {
72130     return function(graph) {
72131         var relation = graph.entity(relationId)
72132             .removeMember(memberIndex);
72133
72134         graph = graph.replace(relation);
72135
72136         if (relation.isDegenerate())
72137             graph = actionDeleteRelation(relation.id)(graph);
72138
72139         return graph;
72140     };
72141 }
72142
72143 function actionDeprecateTags(entityId) {
72144
72145     return function(graph) {
72146         var entity = graph.entity(entityId),
72147             newtags = clone(entity.tags),
72148             change = false,
72149             rule;
72150
72151         // This handles dataDeprecated tags with a single condition
72152         for (var i = 0; i < dataDeprecated.length; i++) {
72153
72154             rule = dataDeprecated[i];
72155             var match = toPairs(rule.old)[0],
72156                 replacements = rule.replace ? toPairs(rule.replace) : null;
72157
72158             if (entity.tags[match[0]] && match[1] === '*') {
72159
72160                 var value = entity.tags[match[0]];
72161                 if (replacements && !newtags[replacements[0][0]]) {
72162                     newtags[replacements[0][0]] = value;
72163                 }
72164                 delete newtags[match[0]];
72165                 change = true;
72166
72167             } else if (entity.tags[match[0]] === match[1]) {
72168                 newtags = assign({}, rule.replace || {}, omit(newtags, match[0]));
72169                 change = true;
72170             }
72171         }
72172
72173         if (change) {
72174             return graph.replace(entity.update({tags: newtags}));
72175         } else {
72176             return graph;
72177         }
72178     };
72179 }
72180
72181 function actionDiscardTags(difference) {
72182
72183     return function(graph) {
72184         function discardTags(entity) {
72185             if (!isEmpty(entity.tags)) {
72186                 var tags = {};
72187                 forEach(entity.tags, function(v, k) {
72188                     if (v) tags[k] = v;
72189                 });
72190
72191                 graph = graph.replace(entity.update({
72192                     tags: omit(tags, dataDiscarded)
72193                 }));
72194             }
72195         }
72196
72197         difference.modified().forEach(discardTags);
72198         difference.created().forEach(discardTags);
72199
72200         return graph;
72201     };
72202 }
72203
72204 // Disconect the ways at the given node.
72205 //
72206 // Optionally, disconnect only the given ways.
72207 //
72208 // For testing convenience, accepts an ID to assign to the (first) new node.
72209 // Normally, this will be undefined and the way will automatically
72210 // be assigned a new ID.
72211 //
72212 // This is the inverse of `iD.actionConnect`.
72213 //
72214 // Reference:
72215 //   https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/UnjoinNodeAction.as
72216 //   https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/UnGlueAction.java
72217 //
72218 function actionDisconnect(nodeId, newNodeId) {
72219     var wayIds;
72220
72221
72222     var action = function(graph) {
72223         var node = graph.entity(nodeId),
72224             connections = action.connections(graph);
72225
72226         connections.forEach(function(connection) {
72227             var way = graph.entity(connection.wayID),
72228                 newNode = osmNode({id: newNodeId, loc: node.loc, tags: node.tags});
72229
72230             graph = graph.replace(newNode);
72231             if (connection.index === 0 && way.isArea()) {
72232                 // replace shared node with shared node..
72233                 graph = graph.replace(way.replaceNode(way.nodes[0], newNode.id));
72234             } else if (way.isClosed() && connection.index === way.nodes.length - 1) {
72235                 // replace closing node with new new node..
72236                 graph = graph.replace(way.unclose().addNode(newNode.id));
72237             } else {
72238                 // replace shared node with multiple new nodes..
72239                 graph = graph.replace(way.updateNode(newNode.id, connection.index));
72240             }
72241         });
72242
72243         return graph;
72244     };
72245
72246
72247     action.connections = function(graph) {
72248         var candidates = [],
72249             keeping = false,
72250             parentWays = graph.parentWays(graph.entity(nodeId));
72251
72252         parentWays.forEach(function(way) {
72253             if (wayIds && wayIds.indexOf(way.id) === -1) {
72254                 keeping = true;
72255                 return;
72256             }
72257             if (way.isArea() && (way.nodes[0] === nodeId)) {
72258                 candidates.push({ wayID: way.id, index: 0 });
72259             } else {
72260                 way.nodes.forEach(function(waynode, index) {
72261                     if (waynode === nodeId) {
72262                         candidates.push({ wayID: way.id, index: index });
72263                     }
72264                 });
72265             }
72266         });
72267
72268         return keeping ? candidates : candidates.slice(1);
72269     };
72270
72271
72272     action.disabled = function(graph) {
72273         var connections = action.connections(graph);
72274         if (connections.length === 0 || (wayIds && wayIds.length !== connections.length))
72275             return 'not_connected';
72276
72277         var parentWays = graph.parentWays(graph.entity(nodeId)),
72278             seenRelationIds = {},
72279             sharedRelation;
72280
72281         parentWays.forEach(function(way) {
72282             if (wayIds && wayIds.indexOf(way.id) === -1)
72283                 return;
72284
72285             var relations = graph.parentRelations(way);
72286             relations.forEach(function(relation) {
72287                 if (relation.id in seenRelationIds) {
72288                     sharedRelation = relation;
72289                 } else {
72290                     seenRelationIds[relation.id] = true;
72291                 }
72292             });
72293         });
72294
72295         if (sharedRelation)
72296             return 'relation';
72297     };
72298
72299
72300     action.limitWays = function(_) {
72301         if (!arguments.length) return wayIds;
72302         wayIds = _;
72303         return action;
72304     };
72305
72306
72307     return action;
72308 }
72309
72310 // Join ways at the end node they share.
72311 //
72312 // This is the inverse of `iD.actionSplit`.
72313 //
72314 // Reference:
72315 //   https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MergeWaysAction.as
72316 //   https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/CombineWayAction.java
72317 //
72318 function actionJoin(ids) {
72319
72320     function groupEntitiesByGeometry(graph) {
72321         var entities = ids.map(function(id) { return graph.entity(id); });
72322         return assignIn({line: []}, groupBy(entities, function(entity) { return entity.geometry(graph); }));
72323     }
72324
72325
72326     var action = function(graph) {
72327         var ways = ids.map(graph.entity, graph);
72328         var survivorID = ways[0].id;
72329
72330         // Prefer to keep an existing way.
72331         for (var i = 0; i < ways.length; i++) {
72332             if (!ways[i].isNew()) {
72333                 survivorID = ways[i].id;
72334                 break;
72335             }
72336         }
72337
72338         var sequences = osmJoinWays(ways, graph);
72339         var joined = sequences[0];
72340
72341         // We might need to reverse some of these ways before joining them.  #4688
72342         // `joined.actions` property will contain any actions we need to apply.
72343         graph = sequences.actions.reduce(function(g, action) { return action(g); }, graph);
72344
72345         var survivor = graph.entity(survivorID);
72346         survivor = survivor.update({ nodes: joined.nodes.map(function(n) { return n.id; }) });
72347         graph = graph.replace(survivor);
72348
72349         joined.forEach(function(way) {
72350             if (way.id === survivorID) return;
72351
72352             graph.parentRelations(way).forEach(function(parent) {
72353                 graph = graph.replace(parent.replaceMember(way, survivor));
72354             });
72355
72356             survivor = survivor.mergeTags(way.tags);
72357
72358             graph = graph.replace(survivor);
72359             graph = actionDeleteWay(way.id)(graph);
72360         });
72361
72362         return graph;
72363     };
72364
72365
72366     action.disabled = function(graph) {
72367         var geometries = groupEntitiesByGeometry(graph);
72368         if (ids.length < 2 || ids.length !== geometries.line.length)
72369             return 'not_eligible';
72370
72371         var joined = osmJoinWays(ids.map(graph.entity, graph), graph);
72372         if (joined.length > 1)
72373             return 'not_adjacent';
72374
72375         var nodeIds = joined[0].nodes.map(function(n) { return n.id; }).slice(1, -1);
72376         var relation;
72377         var tags = {};
72378         var conflicting = false;
72379
72380         joined[0].forEach(function(way) {
72381             var parents = graph.parentRelations(way);
72382             parents.forEach(function(parent) {
72383                 if (parent.isRestriction() && parent.members.some(function(m) { return nodeIds.indexOf(m.id) >= 0; }))
72384                     relation = parent;
72385             });
72386
72387             for (var k in way.tags) {
72388                 if (!(k in tags)) {
72389                     tags[k] = way.tags[k];
72390                 } else if (tags[k] && osmIsInterestingTag(k) && tags[k] !== way.tags[k]) {
72391                     conflicting = true;
72392                 }
72393             }
72394         });
72395
72396         if (relation)
72397             return 'restriction';
72398
72399         if (conflicting)
72400             return 'conflicting_tags';
72401     };
72402
72403
72404     return action;
72405 }
72406
72407 function actionMerge(ids) {
72408
72409     function groupEntitiesByGeometry(graph) {
72410         var entities = ids.map(function(id) { return graph.entity(id); });
72411         return assignIn({point: [], area: [], line: [], relation: []},
72412             groupBy(entities, function(entity) { return entity.geometry(graph); }));
72413     }
72414
72415
72416     var action = function(graph) {
72417         var geometries = groupEntitiesByGeometry(graph),
72418             target = geometries.area[0] || geometries.line[0],
72419             points = geometries.point;
72420
72421         points.forEach(function(point) {
72422             target = target.mergeTags(point.tags);
72423             graph = graph.replace(target);
72424
72425             graph.parentRelations(point).forEach(function(parent) {
72426                 graph = graph.replace(parent.replaceMember(point, target));
72427             });
72428
72429             var nodes = uniq(graph.childNodes(target)),
72430                 removeNode = point;
72431
72432             for (var i = 0; i < nodes.length; i++) {
72433                 var node = nodes[i];
72434                 if (graph.parentWays(node).length > 1 ||
72435                     graph.parentRelations(node).length ||
72436                     node.hasInterestingTags()) {
72437                     continue;
72438                 }
72439
72440                 // Found an uninteresting child node on the target way.
72441                 // Move orig point into its place to preserve point's history. #3683
72442                 graph = graph.replace(point.update({ tags: {}, loc: node.loc }));
72443                 target = target.replaceNode(node.id, point.id);
72444                 graph = graph.replace(target);
72445                 removeNode = node;
72446                 break;
72447             }
72448
72449             graph = graph.remove(removeNode);
72450         });
72451
72452         return graph;
72453     };
72454
72455
72456     action.disabled = function(graph) {
72457         var geometries = groupEntitiesByGeometry(graph);
72458         if (geometries.point.length === 0 ||
72459             (geometries.area.length + geometries.line.length) !== 1 ||
72460             geometries.relation.length !== 0)
72461             return 'not_eligible';
72462     };
72463
72464
72465     return action;
72466 }
72467
72468 function actionMergePolygon(ids, newRelationId) {
72469
72470     function groupEntities(graph) {
72471         var entities = ids.map(function (id) { return graph.entity(id); });
72472         return assignIn({
72473                 closedWay: [],
72474                 multipolygon: [],
72475                 other: []
72476             }, groupBy(entities, function(entity) {
72477                 if (entity.type === 'way' && entity.isClosed()) {
72478                     return 'closedWay';
72479                 } else if (entity.type === 'relation' && entity.isMultipolygon()) {
72480                     return 'multipolygon';
72481                 } else {
72482                     return 'other';
72483                 }
72484             }));
72485     }
72486
72487
72488     var action = function(graph) {
72489         var entities = groupEntities(graph);
72490
72491         // An array representing all the polygons that are part of the multipolygon.
72492         //
72493         // Each element is itself an array of objects with an id property, and has a
72494         // locs property which is an array of the locations forming the polygon.
72495         var polygons = entities.multipolygon.reduce(function(polygons, m) {
72496             return polygons.concat(osmJoinWays(m.members, graph));
72497         }, []).concat(entities.closedWay.map(function(d) {
72498             var member = [{id: d.id}];
72499             member.nodes = graph.childNodes(d);
72500             return member;
72501         }));
72502
72503         // contained is an array of arrays of boolean values,
72504         // where contained[j][k] is true iff the jth way is
72505         // contained by the kth way.
72506         var contained = polygons.map(function(w, i) {
72507             return polygons.map(function(d, n) {
72508                 if (i === n) return null;
72509                 return geoPolygonContainsPolygon(
72510                     map$4(d.nodes, 'loc'),
72511                     map$4(w.nodes, 'loc'));
72512             });
72513         });
72514
72515         // Sort all polygons as either outer or inner ways
72516         var members = [],
72517             outer = true;
72518
72519         while (polygons.length) {
72520             extractUncontained(polygons);
72521             polygons = polygons.filter(isContained);
72522             contained = contained.filter(isContained).map(filterContained);
72523         }
72524
72525         function isContained(d, i) {
72526             return some(contained[i]);
72527         }
72528
72529         function filterContained(d) {
72530             return d.filter(isContained);
72531         }
72532
72533         function extractUncontained(polygons) {
72534             polygons.forEach(function(d, i) {
72535                 if (!isContained(d, i)) {
72536                     d.forEach(function(member) {
72537                         members.push({
72538                             type: 'way',
72539                             id: member.id,
72540                             role: outer ? 'outer' : 'inner'
72541                         });
72542                     });
72543                 }
72544             });
72545             outer = !outer;
72546         }
72547
72548         // Move all tags to one relation
72549         var relation = entities.multipolygon[0] ||
72550             osmRelation({ id: newRelationId, tags: { type: 'multipolygon' }});
72551
72552         entities.multipolygon.slice(1).forEach(function(m) {
72553             relation = relation.mergeTags(m.tags);
72554             graph = graph.remove(m);
72555         });
72556
72557         entities.closedWay.forEach(function(way) {
72558             function isThisOuter(m) {
72559                 return m.id === way.id && m.role !== 'inner';
72560             }
72561             if (members.some(isThisOuter)) {
72562                 relation = relation.mergeTags(way.tags);
72563                 graph = graph.replace(way.update({ tags: {} }));
72564             }
72565         });
72566
72567         return graph.replace(relation.update({
72568             members: members,
72569             tags: omit(relation.tags, 'area')
72570         }));
72571     };
72572
72573
72574     action.disabled = function(graph) {
72575         var entities = groupEntities(graph);
72576         if (entities.other.length > 0 ||
72577             entities.closedWay.length + entities.multipolygon.length < 2)
72578             return 'not_eligible';
72579         if (!entities.multipolygon.every(function(r) { return r.isComplete(graph); }))
72580             return 'incomplete_relation';
72581     };
72582
72583
72584     return action;
72585 }
72586
72587 // Text diff algorithm following Hunt and McIlroy 1976.
72588 // J. W. Hunt and M. D. McIlroy, An algorithm for differential file
72589 // comparison, Bell Telephone Laboratories CSTR #41 (1976)
72590 // http://www.cs.dartmouth.edu/~doug/
72591 //
72592 // Expects two arrays of strings.
72593 function LCS(file1, file2) {
72594   var equivalenceClasses;
72595   var file2indices;
72596   var newCandidate;
72597   var candidates;
72598   var line;
72599   var c, i, j, jX, r, s;
72600
72601   equivalenceClasses = {};
72602   for (j = 0; j < file2.length; j++) {
72603     line = file2[j];
72604     if (equivalenceClasses[line]) {
72605       equivalenceClasses[line].push(j);
72606     } else {
72607       equivalenceClasses[line] = [j];
72608     }
72609   }
72610
72611   candidates = [
72612     { file1index: -1, file2index: -1, chain: null }
72613   ];
72614
72615   for (i = 0; i < file1.length; i++) {
72616     line = file1[i];
72617     file2indices = equivalenceClasses[line] || [];
72618
72619     r = 0;
72620     c = candidates[0];
72621
72622     for (jX = 0; jX < file2indices.length; jX++) {
72623       j = file2indices[jX];
72624
72625       for (s = r; s < candidates.length; s++) {
72626         if ((candidates[s].file2index < j) && ((s === candidates.length - 1) || (candidates[s + 1].file2index > j))) {
72627           break;
72628         }
72629       }
72630
72631       if (s < candidates.length) {
72632         newCandidate = { file1index: i, file2index: j, chain: candidates[s] };
72633         if (r === candidates.length) {
72634           candidates.push(c);
72635         } else {
72636           candidates[r] = c;
72637         }
72638         r = s + 1;
72639         c = newCandidate;
72640         if (r === candidates.length) {
72641           break; // no point in examining further (j)s
72642         }
72643       }
72644     }
72645
72646     candidates[r] = c;
72647   }
72648
72649   // At this point, we know the LCS: it's in the reverse of the
72650   // linked-list through .chain of candidates[candidates.length - 1].
72651
72652   return candidates[candidates.length - 1];
72653 }
72654
72655
72656 // We apply the LCS to give a simple representation of the
72657 // offsets and lengths of mismatched chunks in the input
72658 // files. This is used by diff3MergeIndices below.
72659 function diffIndices(file1, file2) {
72660   var result = [];
72661   var tail1 = file1.length;
72662   var tail2 = file2.length;
72663
72664   for (var candidate = LCS(file1, file2);
72665      candidate !== null;
72666      candidate = candidate.chain)
72667   {
72668     var mismatchLength1 = tail1 - candidate.file1index - 1;
72669     var mismatchLength2 = tail2 - candidate.file2index - 1;
72670     tail1 = candidate.file1index;
72671     tail2 = candidate.file2index;
72672
72673     if (mismatchLength1 || mismatchLength2) {
72674       result.push({
72675         file1: [tail1 + 1, mismatchLength1],
72676         file2: [tail2 + 1, mismatchLength2]
72677       });
72678     }
72679   }
72680
72681   result.reverse();
72682   return result;
72683 }
72684
72685
72686 // Given three files, A, O, and B, where both A and B are
72687 // independently derived from O, returns a fairly complicated
72688 // internal representation of merge decisions it's taken. The
72689 // interested reader may wish to consult
72690 //
72691 // Sanjeev Khanna, Keshav Kunal, and Benjamin C. Pierce.
72692 // 'A Formal Investigation of ' In Arvind and Prasad,
72693 // editors, Foundations of Software Technology and Theoretical
72694 // Computer Science (FSTTCS), December 2007.
72695 //
72696 // (http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf)
72697 function diff3MergeIndices(a, o, b) {
72698   var i;
72699   var m1 = diffIndices(o, a);
72700   var m2 = diffIndices(o, b);
72701
72702   var hunks = [];
72703   function addHunk(h, side) {
72704     hunks.push([h.file1[0], side, h.file1[1], h.file2[0], h.file2[1]]);
72705   }
72706   for (i = 0; i < m1.length; i++) { addHunk(m1[i], 0); }
72707   for (i = 0; i < m2.length; i++) { addHunk(m2[i], 2); }
72708   hunks.sort(function (x, y) { return x[0] - y[0]; });
72709
72710   var result = [];
72711   var commonOffset = 0;
72712   function copyCommon(targetOffset) {
72713     if (targetOffset > commonOffset) {
72714       result.push([1, commonOffset, targetOffset - commonOffset]);
72715       commonOffset = targetOffset;
72716     }
72717   }
72718
72719   for (var hunkIndex = 0; hunkIndex < hunks.length; hunkIndex++) {
72720     var firstHunkIndex = hunkIndex;
72721     var hunk = hunks[hunkIndex];
72722     var regionLhs = hunk[0];
72723     var regionRhs = regionLhs + hunk[2];
72724     while (hunkIndex < hunks.length - 1) {
72725       var maybeOverlapping = hunks[hunkIndex + 1];
72726       var maybeLhs = maybeOverlapping[0];
72727       if (maybeLhs > regionRhs) {
72728         break;
72729       }
72730       regionRhs = Math.max(regionRhs, maybeLhs + maybeOverlapping[2]);
72731       hunkIndex++;
72732     }
72733
72734     copyCommon(regionLhs);
72735     if (firstHunkIndex === hunkIndex) {
72736       // The 'overlap' was only one hunk long, meaning that
72737       // there's no conflict here. Either a and o were the
72738       // same, or b and o were the same.
72739       if (hunk[4] > 0) {
72740         result.push([hunk[1], hunk[3], hunk[4]]);
72741       }
72742     } else {
72743       // A proper conflict. Determine the extents of the
72744       // regions involved from a, o and b. Effectively merge
72745       // all the hunks on the left into one giant hunk, and
72746       // do the same for the right; then, correct for skew
72747       // in the regions of o that each side changed, and
72748       // report appropriate spans for the three sides.
72749       var regions = {
72750         0: [a.length, -1, o.length, -1],
72751         2: [b.length, -1, o.length, -1]
72752       };
72753       for (i = firstHunkIndex; i <= hunkIndex; i++) {
72754         hunk = hunks[i];
72755         var side = hunk[1];
72756         var r = regions[side];
72757         var oLhs = hunk[0];
72758         var oRhs = oLhs + hunk[2];
72759         var abLhs = hunk[3];
72760         var abRhs = abLhs + hunk[4];
72761         r[0] = Math.min(abLhs, r[0]);
72762         r[1] = Math.max(abRhs, r[1]);
72763         r[2] = Math.min(oLhs, r[2]);
72764         r[3] = Math.max(oRhs, r[3]);
72765       }
72766       var aLhs = regions[0][0] + (regionLhs - regions[0][2]);
72767       var aRhs = regions[0][1] + (regionRhs - regions[0][3]);
72768       var bLhs = regions[2][0] + (regionLhs - regions[2][2]);
72769       var bRhs = regions[2][1] + (regionRhs - regions[2][3]);
72770       result.push([-1,
72771                    aLhs,      aRhs      - aLhs,
72772                    regionLhs, regionRhs - regionLhs,
72773                    bLhs,      bRhs      - bLhs]);
72774     }
72775     commonOffset = regionRhs;
72776   }
72777
72778   copyCommon(o.length);
72779   return result;
72780 }
72781
72782
72783 // Applies the output of diff3MergeIndices to actually
72784 // construct the merged file; the returned result alternates
72785 // between 'ok' and 'conflict' blocks.
72786 function diff3Merge(a, o, b, excludeFalseConflicts) {
72787   var result = [];
72788   var files = [a, o, b];
72789   var indices = diff3MergeIndices(a, o, b);
72790
72791   var okLines = [];
72792   function flushOk() {
72793     if (okLines.length) {
72794       result.push({ok: okLines});
72795     }
72796     okLines = [];
72797   }
72798   function pushOk(xs) {
72799     for (var j = 0; j < xs.length; j++) {
72800       okLines.push(xs[j]);
72801     }
72802   }
72803
72804   function isTrueConflict(rec) {
72805     if (rec[2] !== rec[6]) return true;
72806     var aoff = rec[1];
72807     var boff = rec[5];
72808     for (var j = 0; j < rec[2]; j++) {
72809       if (a[j + aoff] !== b[j + boff]) {
72810         return true;
72811       }
72812     }
72813     return false;
72814   }
72815
72816   for (var i = 0; i < indices.length; i++) {
72817     var x = indices[i];
72818     var side = x[0];
72819     if (side === -1) {
72820       if (excludeFalseConflicts && !isTrueConflict(x)) {
72821         pushOk(files[0].slice(x[1], x[1] + x[2]));
72822       } else {
72823         flushOk();
72824         result.push({
72825           conflict: {
72826             a: a.slice(x[1], x[1] + x[2]),
72827             aIndex: x[1],
72828             o: o.slice(x[3], x[3] + x[4]),
72829             oIndex: x[3],
72830             b: b.slice(x[5], x[5] + x[6]),
72831             bIndex: x[5]
72832           }
72833         });
72834       }
72835     } else {
72836       pushOk(files[side].slice(x[1], x[1] + x[2]));
72837     }
72838   }
72839
72840   flushOk();
72841   return result;
72842 }
72843
72844 function actionMergeRemoteChanges(id, localGraph, remoteGraph, formatUser) {
72845     var option = 'safe',  // 'safe', 'force_local', 'force_remote'
72846         conflicts = [];
72847
72848
72849     function user(d) {
72850         return isFunction(formatUser) ? formatUser(d) : d;
72851     }
72852
72853
72854     function mergeLocation(remote, target) {
72855         function pointEqual(a, b) {
72856             var epsilon = 1e-6;
72857             return (Math.abs(a[0] - b[0]) < epsilon) && (Math.abs(a[1] - b[1]) < epsilon);
72858         }
72859
72860         if (option === 'force_local' || pointEqual(target.loc, remote.loc)) {
72861             return target;
72862         }
72863         if (option === 'force_remote') {
72864             return target.update({loc: remote.loc});
72865         }
72866
72867         conflicts.push(t('merge_remote_changes.conflict.location', { user: user(remote.user) }));
72868         return target;
72869     }
72870
72871
72872     function mergeNodes(base, remote, target) {
72873         if (option === 'force_local' || isEqual(target.nodes, remote.nodes)) {
72874             return target;
72875         }
72876         if (option === 'force_remote') {
72877             return target.update({nodes: remote.nodes});
72878         }
72879
72880         var ccount = conflicts.length,
72881             o = base.nodes || [],
72882             a = target.nodes || [],
72883             b = remote.nodes || [],
72884             nodes = [],
72885             hunks = diff3Merge(a, o, b, true);
72886
72887         for (var i = 0; i < hunks.length; i++) {
72888             var hunk = hunks[i];
72889             if (hunk.ok) {
72890                 nodes.push.apply(nodes, hunk.ok);
72891             } else {
72892                 // for all conflicts, we can assume c.a !== c.b
72893                 // because `diff3Merge` called with `true` option to exclude false conflicts..
72894                 var c = hunk.conflict;
72895                 if (isEqual(c.o, c.a)) {  // only changed remotely
72896                     nodes.push.apply(nodes, c.b);
72897                 } else if (isEqual(c.o, c.b)) {  // only changed locally
72898                     nodes.push.apply(nodes, c.a);
72899                 } else {       // changed both locally and remotely
72900                     conflicts.push(t('merge_remote_changes.conflict.nodelist', { user: user(remote.user) }));
72901                     break;
72902                 }
72903             }
72904         }
72905
72906         return (conflicts.length === ccount) ? target.update({nodes: nodes}) : target;
72907     }
72908
72909
72910     function mergeChildren(targetWay, children, updates, graph) {
72911         function isUsed(node, targetWay) {
72912             var parentWays = map$4(graph.parentWays(node), 'id');
72913             return node.hasInterestingTags() ||
72914                 without(parentWays, targetWay.id).length > 0 ||
72915                 graph.parentRelations(node).length > 0;
72916         }
72917
72918         var ccount = conflicts.length;
72919
72920         for (var i = 0; i < children.length; i++) {
72921             var id = children[i],
72922                 node = graph.hasEntity(id);
72923
72924             // remove unused childNodes..
72925             if (targetWay.nodes.indexOf(id) === -1) {
72926                 if (node && !isUsed(node, targetWay)) {
72927                     updates.removeIds.push(id);
72928                 }
72929                 continue;
72930             }
72931
72932             // restore used childNodes..
72933             var local = localGraph.hasEntity(id),
72934                 remote = remoteGraph.hasEntity(id),
72935                 target;
72936
72937             if (option === 'force_remote' && remote && remote.visible) {
72938                 updates.replacements.push(remote);
72939
72940             } else if (option === 'force_local' && local) {
72941                 target = osmEntity(local);
72942                 if (remote) {
72943                     target = target.update({ version: remote.version });
72944                 }
72945                 updates.replacements.push(target);
72946
72947             } else if (option === 'safe' && local && remote && local.version !== remote.version) {
72948                 target = osmEntity(local, { version: remote.version });
72949                 if (remote.visible) {
72950                     target = mergeLocation(remote, target);
72951                 } else {
72952                     conflicts.push(t('merge_remote_changes.conflict.deleted', { user: user(remote.user) }));
72953                 }
72954
72955                 if (conflicts.length !== ccount) break;
72956                 updates.replacements.push(target);
72957             }
72958         }
72959
72960         return targetWay;
72961     }
72962
72963
72964     function updateChildren(updates, graph) {
72965         for (var i = 0; i < updates.replacements.length; i++) {
72966             graph = graph.replace(updates.replacements[i]);
72967         }
72968         if (updates.removeIds.length) {
72969             graph = actionDeleteMultiple(updates.removeIds)(graph);
72970         }
72971         return graph;
72972     }
72973
72974
72975     function mergeMembers(remote, target) {
72976         if (option === 'force_local' || isEqual(target.members, remote.members)) {
72977             return target;
72978         }
72979         if (option === 'force_remote') {
72980             return target.update({members: remote.members});
72981         }
72982
72983         conflicts.push(t('merge_remote_changes.conflict.memberlist', { user: user(remote.user) }));
72984         return target;
72985     }
72986
72987
72988     function mergeTags(base, remote, target) {
72989         function ignoreKey(k) {
72990             return includes(dataDiscarded, k);
72991         }
72992
72993         if (option === 'force_local' || isEqual(target.tags, remote.tags)) {
72994             return target;
72995         }
72996         if (option === 'force_remote') {
72997             return target.update({tags: remote.tags});
72998         }
72999
73000         var ccount = conflicts.length,
73001             o = base.tags || {},
73002             a = target.tags || {},
73003             b = remote.tags || {},
73004             keys = reject(union(keys$1(o), keys$1(a), keys$1(b)), ignoreKey),
73005             tags = clone(a),
73006             changed = false;
73007
73008         for (var i = 0; i < keys.length; i++) {
73009             var k = keys[i];
73010
73011             if (o[k] !== b[k] && a[k] !== b[k]) {    // changed remotely..
73012                 if (o[k] !== a[k]) {      // changed locally..
73013                     conflicts.push(t('merge_remote_changes.conflict.tags',
73014                         { tag: k, local: a[k], remote: b[k], user: user(remote.user) }));
73015
73016                 } else {                  // unchanged locally, accept remote change..
73017                     if (b.hasOwnProperty(k)) {
73018                         tags[k] = b[k];
73019                     } else {
73020                         delete tags[k];
73021                     }
73022                     changed = true;
73023                 }
73024             }
73025         }
73026
73027         return (changed && conflicts.length === ccount) ? target.update({tags: tags}) : target;
73028     }
73029
73030
73031     //  `graph.base()` is the common ancestor of the two graphs.
73032     //  `localGraph` contains user's edits up to saving
73033     //  `remoteGraph` contains remote edits to modified nodes
73034     //  `graph` must be a descendent of `localGraph` and may include
73035     //      some conflict resolution actions performed on it.
73036     //
73037     //                  --- ... --- `localGraph` -- ... -- `graph`
73038     //                 /
73039     //  `graph.base()` --- ... --- `remoteGraph`
73040     //
73041     var action = function(graph) {
73042         var updates = { replacements: [], removeIds: [] },
73043             base = graph.base().entities[id],
73044             local = localGraph.entity(id),
73045             remote = remoteGraph.entity(id),
73046             target = osmEntity(local, { version: remote.version });
73047
73048         // delete/undelete
73049         if (!remote.visible) {
73050             if (option === 'force_remote') {
73051                 return actionDeleteMultiple([id])(graph);
73052
73053             } else if (option === 'force_local') {
73054                 if (target.type === 'way') {
73055                     target = mergeChildren(target, uniq(local.nodes), updates, graph);
73056                     graph = updateChildren(updates, graph);
73057                 }
73058                 return graph.replace(target);
73059
73060             } else {
73061                 conflicts.push(t('merge_remote_changes.conflict.deleted', { user: user(remote.user) }));
73062                 return graph;  // do nothing
73063             }
73064         }
73065
73066         // merge
73067         if (target.type === 'node') {
73068             target = mergeLocation(remote, target);
73069
73070         } else if (target.type === 'way') {
73071             // pull in any child nodes that may not be present locally..
73072             graph.rebase(remoteGraph.childNodes(remote), [graph], false);
73073             target = mergeNodes(base, remote, target);
73074             target = mergeChildren(target, union(local.nodes, remote.nodes), updates, graph);
73075
73076         } else if (target.type === 'relation') {
73077             target = mergeMembers(remote, target);
73078         }
73079
73080         target = mergeTags(base, remote, target);
73081
73082         if (!conflicts.length) {
73083             graph = updateChildren(updates, graph).replace(target);
73084         }
73085
73086         return graph;
73087     };
73088
73089
73090     action.withOption = function(opt) {
73091         option = opt;
73092         return action;
73093     };
73094
73095
73096     action.conflicts = function() {
73097         return conflicts;
73098     };
73099
73100
73101     return action;
73102 }
73103
73104 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/command/MoveCommand.java
73105 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MoveNodeAction.as
73106 function actionMove(moveIds, tryDelta, projection, cache) {
73107     var _delta = tryDelta;
73108
73109     function setupCache(graph) {
73110         function canMove(nodeId) {
73111             // Allow movement of any node that is in the selectedIDs list..
73112             if (moveIds.indexOf(nodeId) !== -1) return true;
73113
73114             // Allow movement of a vertex where 2 ways meet..
73115             var parents = map$4(graph.parentWays(graph.entity(nodeId)), 'id');
73116             if (parents.length < 3) return true;
73117
73118             // Restrict movement of a vertex where >2 ways meet, unless all parentWays are moving too..
73119             var parentsMoving = every(parents, function(id) { return cache.moving[id]; });
73120             if (!parentsMoving) delete cache.moving[nodeId];
73121
73122             return parentsMoving;
73123         }
73124
73125         function cacheEntities(ids) {
73126             ids.forEach(function(id) {
73127                 if (cache.moving[id]) return;
73128                 cache.moving[id] = true;
73129
73130                 var entity = graph.hasEntity(id);
73131                 if (!entity) return;
73132
73133                 if (entity.type === 'node') {
73134                     cache.nodes.push(id);
73135                     cache.startLoc[id] = entity.loc;
73136                 } else if (entity.type === 'way') {
73137                     cache.ways.push(id);
73138                     cacheEntities(entity.nodes);
73139                 } else {
73140                     cacheEntities(entity.members.map(function(member) {
73141                         return member.id;
73142                     }));
73143                 }
73144             });
73145         }
73146
73147         function cacheIntersections(ids) {
73148             function isEndpoint(way, id) { return !way.isClosed() && !!way.affix(id); }
73149
73150             ids.forEach(function(id) {
73151                 // consider only intersections with 1 moved and 1 unmoved way.
73152                 var childNodes = graph.childNodes(graph.entity(id));
73153                 childNodes.forEach(function(node) {
73154                     var parents = graph.parentWays(node);
73155                     if (parents.length !== 2) return;
73156
73157                     var moved = graph.entity(id),
73158                         unmoved = find$1(parents, function(way) { return !cache.moving[way.id]; });
73159                     if (!unmoved) return;
73160
73161                     // exclude ways that are overly connected..
73162                     if (intersection(moved.nodes, unmoved.nodes).length > 2) return;
73163
73164                     if (moved.isArea() || unmoved.isArea()) return;
73165
73166                     cache.intersection[node.id] = {
73167                         nodeId: node.id,
73168                         movedId: moved.id,
73169                         unmovedId: unmoved.id,
73170                         movedIsEP: isEndpoint(moved, node.id),
73171                         unmovedIsEP: isEndpoint(unmoved, node.id)
73172                     };
73173                 });
73174             });
73175         }
73176
73177
73178         if (!cache) {
73179             cache = {};
73180         }
73181         if (!cache.ok) {
73182             cache.moving = {};
73183             cache.intersection = {};
73184             cache.replacedVertex = {};
73185             cache.startLoc = {};
73186             cache.nodes = [];
73187             cache.ways = [];
73188
73189             cacheEntities(moveIds);
73190             cacheIntersections(cache.ways);
73191             cache.nodes = filter(cache.nodes, canMove);
73192
73193             cache.ok = true;
73194         }
73195     }
73196
73197
73198     // Place a vertex where the moved vertex used to be, to preserve way shape..
73199     function replaceMovedVertex(nodeId, wayId, graph, _delta) {
73200         var way = graph.entity(wayId);
73201         var moved = graph.entity(nodeId);
73202         var movedIndex = way.nodes.indexOf(nodeId);
73203         var len, prevIndex, nextIndex;
73204
73205         if (way.isClosed()) {
73206             len = way.nodes.length - 1;
73207             prevIndex = (movedIndex + len - 1) % len;
73208             nextIndex = (movedIndex + len + 1) % len;
73209         } else {
73210             len = way.nodes.length;
73211             prevIndex = movedIndex - 1;
73212             nextIndex = movedIndex + 1;
73213         }
73214
73215         var prev = graph.hasEntity(way.nodes[prevIndex]);
73216         var next = graph.hasEntity(way.nodes[nextIndex]);
73217
73218         // Don't add orig vertex at endpoint..
73219         if (!prev || !next) return graph;
73220
73221         var key = wayId + '_' + nodeId;
73222         var orig = cache.replacedVertex[key];
73223         if (!orig) {
73224             orig = osmNode();
73225             cache.replacedVertex[key] = orig;
73226             cache.startLoc[orig.id] = cache.startLoc[nodeId];
73227         }
73228
73229         var start, end;
73230         if (_delta) {
73231             start = projection(cache.startLoc[nodeId]);
73232             end = projection.invert(geoVecAdd(start, _delta));
73233         } else {
73234             end = cache.startLoc[nodeId];
73235         }
73236         orig = orig.move(end);
73237
73238         var angle = Math.abs(geoAngle(orig, prev, projection) -
73239                 geoAngle(orig, next, projection)) * 180 / Math.PI;
73240
73241         // Don't add orig vertex if it would just make a straight line..
73242         if (angle > 175 && angle < 185) return graph;
73243
73244         // Don't add orig vertex if another point is already nearby (within 10m)
73245         if (geoSphericalDistance(prev.loc, orig.loc) < 10 ||
73246             geoSphericalDistance(orig.loc, next.loc) < 10) return graph;
73247
73248         // moving forward or backward along way?
73249         var p1 = [prev.loc, orig.loc, moved.loc, next.loc].map(projection),
73250             p2 = [prev.loc, moved.loc, orig.loc, next.loc].map(projection),
73251             d1 = geoPathLength(p1),
73252             d2 = geoPathLength(p2),
73253             insertAt = (d1 < d2) ? movedIndex : nextIndex;
73254
73255         // moving around closed loop?
73256         if (way.isClosed() && insertAt === 0) insertAt = len;
73257
73258         way = way.addNode(orig.id, insertAt);
73259         return graph.replace(orig).replace(way);
73260     }
73261
73262
73263     // Reorder nodes around intersections that have moved..
73264     function unZorroIntersection(intersection$$1, graph) {
73265         var vertex = graph.entity(intersection$$1.nodeId);
73266         var way1 = graph.entity(intersection$$1.movedId);
73267         var way2 = graph.entity(intersection$$1.unmovedId);
73268         var isEP1 = intersection$$1.movedIsEP;
73269         var isEP2 = intersection$$1.unmovedIsEP;
73270
73271         // don't move the vertex if it is the endpoint of both ways.
73272         if (isEP1 && isEP2) return graph;
73273
73274         var nodes1 = without(graph.childNodes(way1), vertex);
73275         var nodes2 = without(graph.childNodes(way2), vertex);
73276
73277         if (way1.isClosed() && way1.first() === vertex.id) nodes1.push(nodes1[0]);
73278         if (way2.isClosed() && way2.first() === vertex.id) nodes2.push(nodes2[0]);
73279
73280         var edge1 = !isEP1 && geoChooseEdge(nodes1, projection(vertex.loc), projection);
73281         var edge2 = !isEP2 && geoChooseEdge(nodes2, projection(vertex.loc), projection);
73282         var loc;
73283
73284         // snap vertex to nearest edge (or some point between them)..
73285         if (!isEP1 && !isEP2) {
73286             var epsilon = 1e-4, maxIter = 10;
73287             for (var i = 0; i < maxIter; i++) {
73288                 loc = geoVecInterp(edge1.loc, edge2.loc, 0.5);
73289                 edge1 = geoChooseEdge(nodes1, projection(loc), projection);
73290                 edge2 = geoChooseEdge(nodes2, projection(loc), projection);
73291                 if (Math.abs(edge1.distance - edge2.distance) < epsilon) break;
73292             }
73293         } else if (!isEP1) {
73294             loc = edge1.loc;
73295         } else {
73296             loc = edge2.loc;
73297         }
73298
73299         graph = graph.replace(vertex.move(loc));
73300
73301         // if zorro happened, reorder nodes..
73302         if (!isEP1 && edge1.index !== way1.nodes.indexOf(vertex.id)) {
73303             way1 = way1.removeNode(vertex.id).addNode(vertex.id, edge1.index);
73304             graph = graph.replace(way1);
73305         }
73306         if (!isEP2 && edge2.index !== way2.nodes.indexOf(vertex.id)) {
73307             way2 = way2.removeNode(vertex.id).addNode(vertex.id, edge2.index);
73308             graph = graph.replace(way2);
73309         }
73310
73311         return graph;
73312     }
73313
73314
73315     function cleanupIntersections(graph) {
73316         forEach(cache.intersection, function(obj) {
73317             graph = replaceMovedVertex(obj.nodeId, obj.movedId, graph, _delta);
73318             graph = replaceMovedVertex(obj.nodeId, obj.unmovedId, graph, null);
73319             graph = unZorroIntersection(obj, graph);
73320         });
73321
73322         return graph;
73323     }
73324
73325
73326     // check if moving way endpoint can cross an unmoved way, if so limit _delta..
73327     function limitDelta(graph) {
73328         forEach(cache.intersection, function(obj) {
73329             // Don't limit movement if this is vertex joins 2 endpoints..
73330             if (obj.movedIsEP && obj.unmovedIsEP) return;
73331             // Don't limit movement if this vertex is not an endpoint anyway..
73332             if (!obj.movedIsEP) return;
73333
73334             var node = graph.entity(obj.nodeId);
73335             var start = projection(node.loc);
73336             var end = geoVecAdd(start, _delta);
73337             var movedNodes = graph.childNodes(graph.entity(obj.movedId));
73338             var movedPath = map$4(map$4(movedNodes, 'loc'), function(loc) {
73339                 return geoVecAdd(projection(loc), _delta);
73340             });
73341             var unmovedNodes = graph.childNodes(graph.entity(obj.unmovedId));
73342             var unmovedPath = map$4(map$4(unmovedNodes, 'loc'), projection);
73343             var hits = geoPathIntersections(movedPath, unmovedPath);
73344
73345             for (var i = 0; i < hits.length; i++) {
73346                 if (isEqual(hits[i], end)) continue;
73347                 var edge = geoChooseEdge(unmovedNodes, end, projection);
73348                 _delta = geoVecSubtract(projection(edge.loc), start);
73349             }
73350         });
73351     }
73352
73353
73354     var action = function(graph) {
73355         if (_delta[0] === 0 && _delta[1] === 0) return graph;
73356
73357         setupCache(graph);
73358
73359         if (!isEmpty(cache.intersection)) {
73360             limitDelta(graph);
73361         }
73362
73363         forEach(cache.nodes, function(id) {
73364             var node = graph.entity(id);
73365             var start = projection(node.loc);
73366             var end = geoVecAdd(start, _delta);
73367             graph = graph.replace(node.move(projection.invert(end)));
73368         });
73369
73370         if (!isEmpty(cache.intersection)) {
73371             graph = cleanupIntersections(graph);
73372         }
73373
73374         return graph;
73375     };
73376
73377
73378     action.delta = function() {
73379         return _delta;
73380     };
73381
73382
73383     return action;
73384 }
73385
73386 function actionMoveNode(nodeID, toLoc) {
73387
73388     var action = function(graph, t) {
73389         if (t === null || !isFinite(t)) t = 1;
73390         t = Math.min(Math.max(+t, 0), 1);
73391
73392         var node = graph.entity(nodeID);
73393         return graph.replace(
73394             node.move(geoVecInterp(node.loc, toLoc, t))
73395         );
73396     };
73397
73398     action.transitionable = true;
73399
73400     return action;
73401 }
73402
73403 function actionNoop() {
73404     return function(graph) {
73405         return graph;
73406     };
73407 }
73408
73409 /*
73410  * Based on https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/potlatch2/tools/Quadrilateralise.as
73411  */
73412 function actionOrthogonalize(wayId, projection) {
73413     var threshold = 12, // degrees within right or straight to alter
73414         lowerThreshold = Math.cos((90 - threshold) * Math.PI / 180),
73415         upperThreshold = Math.cos(threshold * Math.PI / 180);
73416
73417
73418     var action = function(graph, t) {
73419         if (t === null || !isFinite(t)) t = 1;
73420         t = Math.min(Math.max(+t, 0), 1);
73421
73422         var way = graph.entity(wayId),
73423             nodes = graph.childNodes(way),
73424             points = uniq(nodes).map(function(n) { return projection(n.loc); }),
73425             corner = {i: 0, dotp: 1},
73426             epsilon = 1e-4,
73427             node, loc, score, motions, i, j;
73428
73429         if (points.length === 3) {   // move only one vertex for right triangle
73430             for (i = 0; i < 1000; i++) {
73431                 motions = points.map(calcMotion);
73432                 points[corner.i] = addPoints(points[corner.i], motions[corner.i]);
73433                 score = corner.dotp;
73434                 if (score < epsilon) {
73435                     break;
73436                 }
73437             }
73438
73439             node = graph.entity(nodes[corner.i].id);
73440             loc = projection.invert(points[corner.i]);
73441             graph = graph.replace(node.move(geoVecInterp(node.loc, loc, t)));
73442
73443         } else {
73444             var best,
73445                 originalPoints = clone(points);
73446             score = Infinity;
73447
73448             for (i = 0; i < 1000; i++) {
73449                 motions = points.map(calcMotion);
73450                 for (j = 0; j < motions.length; j++) {
73451                     points[j] = addPoints(points[j],motions[j]);
73452                 }
73453                 var newScore = squareness(points);
73454                 if (newScore < score) {
73455                     best = clone(points);
73456                     score = newScore;
73457                 }
73458                 if (score < epsilon) {
73459                     break;
73460                 }
73461             }
73462
73463             points = best;
73464
73465             for (i = 0; i < points.length; i++) {
73466                 // only move the points that actually moved
73467                 if (originalPoints[i][0] !== points[i][0] || originalPoints[i][1] !== points[i][1]) {
73468                     loc = projection.invert(points[i]);
73469                     node = graph.entity(nodes[i].id);
73470                     graph = graph.replace(node.move(geoVecInterp(node.loc, loc, t)));
73471                 }
73472             }
73473
73474             // remove empty nodes on straight sections
73475             for (i = 0; t === 1 && i < points.length; i++) {
73476                 node = graph.entity(nodes[i].id);
73477
73478                 if (graph.parentWays(node).length > 1 ||
73479                     graph.parentRelations(node).length ||
73480                     node.hasInterestingTags()) {
73481                     continue;
73482                 }
73483
73484                 var dotp = normalizedDotProduct(i, points);
73485                 if (dotp < -1 + epsilon) {
73486                     graph = actionDeleteNode(node.id)(graph);
73487                 }
73488             }
73489         }
73490
73491         return graph;
73492
73493
73494         function calcMotion(b, i, array) {
73495             var a = array[(i - 1 + array.length) % array.length],
73496                 c = array[(i + 1) % array.length],
73497                 p = subtractPoints(a, b),
73498                 q = subtractPoints(c, b),
73499                 scale, dotp;
73500
73501             scale = 2 * Math.min(geoVecLength(p, [0, 0]), geoVecLength(q, [0, 0]));
73502             p = normalizePoint(p, 1.0);
73503             q = normalizePoint(q, 1.0);
73504
73505             dotp = filterDotProduct(p[0] * q[0] + p[1] * q[1]);
73506
73507             // nasty hack to deal with almost-straight segments (angle is closer to 180 than to 90/270).
73508             if (array.length > 3) {
73509                 if (dotp < -0.707106781186547) {
73510                     dotp += 1.0;
73511                 }
73512             } else if (dotp && Math.abs(dotp) < corner.dotp) {
73513                 corner.i = i;
73514                 corner.dotp = Math.abs(dotp);
73515             }
73516
73517             return normalizePoint(addPoints(p, q), 0.1 * dotp * scale);
73518         }
73519     };
73520
73521
73522     function squareness(points) {
73523         return points.reduce(function(sum, val, i, array) {
73524             var dotp = normalizedDotProduct(i, array);
73525
73526             dotp = filterDotProduct(dotp);
73527             return sum + 2.0 * Math.min(Math.abs(dotp - 1.0), Math.min(Math.abs(dotp), Math.abs(dotp + 1)));
73528         }, 0);
73529     }
73530
73531
73532     function normalizedDotProduct(i, points) {
73533         var a = points[(i - 1 + points.length) % points.length],
73534             b = points[i],
73535             c = points[(i + 1) % points.length],
73536             p = subtractPoints(a, b),
73537             q = subtractPoints(c, b);
73538
73539         p = normalizePoint(p, 1.0);
73540         q = normalizePoint(q, 1.0);
73541
73542         return p[0] * q[0] + p[1] * q[1];
73543     }
73544
73545
73546     function subtractPoints(a, b) {
73547         return [a[0] - b[0], a[1] - b[1]];
73548     }
73549
73550
73551     function addPoints(a, b) {
73552         return [a[0] + b[0], a[1] + b[1]];
73553     }
73554
73555
73556     function normalizePoint(point, scale) {
73557         var vector = [0, 0];
73558         var length = Math.sqrt(point[0] * point[0] + point[1] * point[1]);
73559         if (length !== 0) {
73560             vector[0] = point[0] / length;
73561             vector[1] = point[1] / length;
73562         }
73563
73564         vector[0] *= scale;
73565         vector[1] *= scale;
73566
73567         return vector;
73568     }
73569
73570
73571     function filterDotProduct(dotp) {
73572         if (lowerThreshold > Math.abs(dotp) || Math.abs(dotp) > upperThreshold) {
73573             return dotp;
73574         }
73575
73576         return 0;
73577     }
73578
73579
73580     action.disabled = function(graph) {
73581         var way = graph.entity(wayId),
73582             nodes = graph.childNodes(way),
73583             points = uniq(nodes).map(function(n) { return projection(n.loc); });
73584
73585         if (squareness(points)) {
73586             return false;
73587         }
73588
73589         return 'not_squarish';
73590     };
73591
73592
73593     action.transitionable = true;
73594
73595
73596     return action;
73597 }
73598
73599 // Split a way at the given node.
73600 //
73601 // Optionally, split only the given ways, if multiple ways share
73602 // the given node.
73603 //
73604 // This is the inverse of `iD.actionJoin`.
73605 //
73606 // For testing convenience, accepts an ID to assign to the new way.
73607 // Normally, this will be undefined and the way will automatically
73608 // be assigned a new ID.
73609 //
73610 // Reference:
73611 //   https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/SplitWayAction.as
73612 //
73613 function actionSplit(nodeId, newWayIds) {
73614     var _wayIDs;
73615
73616     // if the way is closed, we need to search for a partner node
73617     // to split the way at.
73618     //
73619     // The following looks for a node that is both far away from
73620     // the initial node in terms of way segment length and nearby
73621     // in terms of beeline-distance. This assures that areas get
73622     // split on the most "natural" points (independent of the number
73623     // of nodes).
73624     // For example: bone-shaped areas get split across their waist
73625     // line, circles across the diameter.
73626     function splitArea(nodes, idxA, graph) {
73627         var lengths = new Array(nodes.length);
73628         var length;
73629         var i;
73630         var best = 0;
73631         var idxB;
73632
73633         function wrap(index) {
73634             return utilWrap(index, nodes.length);
73635         }
73636
73637         function dist(nA, nB) {
73638             return geoSphericalDistance(graph.entity(nA).loc, graph.entity(nB).loc);
73639         }
73640
73641         // calculate lengths
73642         length = 0;
73643         for (i = wrap(idxA+1); i !== idxA; i = wrap(i+1)) {
73644             length += dist(nodes[i], nodes[wrap(i-1)]);
73645             lengths[i] = length;
73646         }
73647
73648         length = 0;
73649         for (i = wrap(idxA-1); i !== idxA; i = wrap(i-1)) {
73650             length += dist(nodes[i], nodes[wrap(i+1)]);
73651             if (length < lengths[i])
73652                 lengths[i] = length;
73653         }
73654
73655         // determine best opposite node to split
73656         for (i = 0; i < nodes.length; i++) {
73657             var cost = lengths[i] / dist(nodes[idxA], nodes[i]);
73658             if (cost > best) {
73659                 idxB = i;
73660                 best = cost;
73661             }
73662         }
73663
73664         return idxB;
73665     }
73666
73667
73668     function split(graph, wayA, newWayId) {
73669         var wayB = osmWay({id: newWayId, tags: wayA.tags});
73670         var origNodes = wayA.nodes.slice();
73671         var nodesA;
73672         var nodesB;
73673         var isArea = wayA.isArea();
73674         var isOuter = osmIsSimpleMultipolygonOuterMember(wayA, graph);
73675
73676         if (wayA.isClosed()) {
73677             var nodes = wayA.nodes.slice(0, -1);
73678             var idxA = indexOf(nodes, nodeId);
73679             var idxB = splitArea(nodes, idxA, graph);
73680
73681             if (idxB < idxA) {
73682                 nodesA = nodes.slice(idxA).concat(nodes.slice(0, idxB + 1));
73683                 nodesB = nodes.slice(idxB, idxA + 1);
73684             } else {
73685                 nodesA = nodes.slice(idxA, idxB + 1);
73686                 nodesB = nodes.slice(idxB).concat(nodes.slice(0, idxA + 1));
73687             }
73688         } else {
73689             var idx = indexOf(wayA.nodes, nodeId, 1);
73690             nodesA = wayA.nodes.slice(0, idx + 1);
73691             nodesB = wayA.nodes.slice(idx);
73692         }
73693
73694         wayA = wayA.update({nodes: nodesA});
73695         wayB = wayB.update({nodes: nodesB});
73696
73697         graph = graph.replace(wayA);
73698         graph = graph.replace(wayB);
73699
73700         graph.parentRelations(wayA).forEach(function(relation) {
73701             if (relation.isRestriction()) {
73702                 var via = relation.memberByRole('via');
73703                 if (via && wayB.contains(via.id)) {
73704                     relation = relation.replaceMember(wayA, wayB);
73705                     graph = graph.replace(relation);
73706                 }
73707             } else {
73708                 if (relation === isOuter) {
73709                     graph = graph.replace(relation.mergeTags(wayA.tags));
73710                     graph = graph.replace(wayA.update({tags: {}}));
73711                     graph = graph.replace(wayB.update({tags: {}}));
73712                 }
73713
73714                 var member = {
73715                     id: wayB.id,
73716                     type: 'way',
73717                     role: relation.memberById(wayA.id).role
73718                 };
73719
73720                 var insertPair = {
73721                     originalID: wayA.id,
73722                     insertedID: wayB.id,
73723                     nodes: origNodes
73724                 };
73725
73726                 graph = actionAddMember(relation.id, member, undefined, insertPair)(graph);
73727             }
73728         });
73729
73730         if (!isOuter && isArea) {
73731             var multipolygon = osmRelation({
73732                 tags: assignIn({}, wayA.tags, {type: 'multipolygon'}),
73733                 members: [
73734                     {id: wayA.id, role: 'outer', type: 'way'},
73735                     {id: wayB.id, role: 'outer', type: 'way'}
73736                 ]
73737             });
73738
73739             graph = graph.replace(multipolygon);
73740             graph = graph.replace(wayA.update({tags: {}}));
73741             graph = graph.replace(wayB.update({tags: {}}));
73742         }
73743
73744         return graph;
73745     }
73746
73747
73748     var action = function(graph) {
73749         var candidates = action.ways(graph);
73750         for (var i = 0; i < candidates.length; i++) {
73751             graph = split(graph, candidates[i], newWayIds && newWayIds[i]);
73752         }
73753         return graph;
73754     };
73755
73756
73757     action.ways = function(graph) {
73758         var node = graph.entity(nodeId);
73759         var parents = graph.parentWays(node);
73760         var hasLines = some(parents, function(parent) { return parent.geometry(graph) === 'line'; });
73761
73762         return parents.filter(function(parent) {
73763             if (_wayIDs && _wayIDs.indexOf(parent.id) === -1)
73764                 return false;
73765
73766             if (!_wayIDs && hasLines && parent.geometry(graph) !== 'line')
73767                 return false;
73768
73769             if (parent.isClosed()) {
73770                 return true;
73771             }
73772
73773             for (var i = 1; i < parent.nodes.length - 1; i++) {
73774                 if (parent.nodes[i] === nodeId) {
73775                     return true;
73776                 }
73777             }
73778
73779             return false;
73780         });
73781     };
73782
73783
73784     action.disabled = function(graph) {
73785         var candidates = action.ways(graph);
73786         if (candidates.length === 0 || (_wayIDs && _wayIDs.length !== candidates.length))
73787             return 'not_eligible';
73788     };
73789
73790
73791     action.limitWays = function(_) {
73792         if (!arguments.length) return _wayIDs;
73793         _wayIDs = _;
73794         return action;
73795     };
73796
73797
73798     return action;
73799 }
73800
73801 // Create a restriction relation for `turn`, which must have the following structure:
73802 //
73803 //     {
73804 //         from: { node: <node ID>, way: <way ID> },
73805 //         via:  { node: <node ID> },
73806 //         to:   { node: <node ID>, way: <way ID> },
73807 //         restriction: <'no_right_turn', 'no_left_turn', etc.>
73808 //     }
73809 //
73810 // This specifies a restriction of type `restriction` when traveling from
73811 // `from.node` in `from.way` toward `to.node` in `to.way` via `via.node`.
73812 // (The action does not check that these entities form a valid intersection.)
73813 //
73814 // If `restriction` is not provided, it is automatically determined by
73815 // osmInferRestriction.
73816 //
73817 // If necessary, the `from` and `to` ways are split. In these cases, `from.node`
73818 // and `to.node` are used to determine which portion of the split ways become
73819 // members of the restriction.
73820 //
73821 // For testing convenience, accepts an ID to assign to the new relation.
73822 // Normally, this will be undefined and the relation will automatically
73823 // be assigned a new ID.
73824 //
73825 function actionRestrictTurn(turn, projection, restrictionId) {
73826
73827     return function(graph) {
73828         var from = graph.entity(turn.from.way),
73829             via  = graph.entity(turn.via.node),
73830             to   = graph.entity(turn.to.way);
73831
73832         function isClosingNode(way, nodeId) {
73833             return nodeId === way.first() && nodeId === way.last();
73834         }
73835
73836         function split(toOrFrom) {
73837             var newID = toOrFrom.newID || osmWay().id;
73838             graph = actionSplit(via.id, [newID])
73839                 .limitWays([toOrFrom.way])(graph);
73840
73841             var a = graph.entity(newID),
73842                 b = graph.entity(toOrFrom.way);
73843
73844             if (a.nodes.indexOf(toOrFrom.node) !== -1) {
73845                 return [a, b];
73846             } else {
73847                 return [b, a];
73848             }
73849         }
73850
73851         if (!from.affix(via.id) || isClosingNode(from, via.id)) {
73852             if (turn.from.node === turn.to.node) {
73853                 // U-turn
73854                 from = to = split(turn.from)[0];
73855             } else if (turn.from.way === turn.to.way) {
73856                 // Straight-on or circular
73857                 var s = split(turn.from);
73858                 from = s[0];
73859                 to   = s[1];
73860             } else {
73861                 // Other
73862                 from = split(turn.from)[0];
73863             }
73864         }
73865
73866         if (!to.affix(via.id) || isClosingNode(to, via.id)) {
73867             to = split(turn.to)[0];
73868         }
73869
73870         return graph.replace(osmRelation({
73871             id: restrictionId,
73872             tags: {
73873                 type: 'restriction',
73874                 restriction: turn.restriction ||
73875                     osmInferRestriction(
73876                         graph,
73877                         turn.from,
73878                         turn.via,
73879                         turn.to,
73880                         projection)
73881             },
73882             members: [
73883                 {id: from.id, type: 'way',  role: 'from'},
73884                 {id: via.id,  type: 'node', role: 'via'},
73885                 {id: to.id,   type: 'way',  role: 'to'}
73886             ]
73887         }));
73888     };
73889 }
73890
73891 function actionRevert(id) {
73892     var action = function(graph) {
73893         var entity = graph.hasEntity(id),
73894             base = graph.base().entities[id];
73895
73896         if (entity && !base) {    // entity will be removed..
73897             if (entity.type === 'node') {
73898                 graph.parentWays(entity)
73899                     .forEach(function(parent) {
73900                         parent = parent.removeNode(id);
73901                         graph = graph.replace(parent);
73902
73903                         if (parent.isDegenerate()) {
73904                             graph = actionDeleteWay(parent.id)(graph);
73905                         }
73906                     });
73907             }
73908
73909             graph.parentRelations(entity)
73910                 .forEach(function(parent) {
73911                     parent = parent.removeMembersWithID(id);
73912                     graph = graph.replace(parent);
73913
73914                     if (parent.isDegenerate()) {
73915                         graph = actionDeleteRelation(parent.id)(graph);
73916                     }
73917                 });
73918         }
73919
73920         return graph.revert(id);
73921     };
73922
73923     return action;
73924 }
73925
73926 function actionRotate(rotateIds, pivot, angle, projection) {
73927
73928     var action = function(graph) {
73929         return graph.update(function(graph) {
73930             utilGetAllNodes(rotateIds, graph).forEach(function(node) {
73931                 var point = geoRotate([projection(node.loc)], angle, pivot)[0];
73932                 graph = graph.replace(node.move(projection.invert(point)));
73933             });
73934         });
73935     };
73936
73937     return action;
73938 }
73939
73940 /*
73941  * Based on https://github.com/openstreetmap/potlatch2/net/systemeD/potlatch2/tools/Straighten.as
73942  */
73943 function actionStraighten(wayId, projection) {
73944
73945     function positionAlongWay(n, s, e) {
73946         return ((n[0] - s[0]) * (e[0] - s[0]) + (n[1] - s[1]) * (e[1] - s[1])) /
73947                 (Math.pow(e[0] - s[0], 2) + Math.pow(e[1] - s[1], 2));
73948     }
73949
73950
73951     var action = function(graph, t) {
73952         if (t === null || !isFinite(t)) t = 1;
73953         t = Math.min(Math.max(+t, 0), 1);
73954
73955         var way = graph.entity(wayId),
73956             nodes = graph.childNodes(way),
73957             points = nodes.map(function(n) { return projection(n.loc); }),
73958             startPoint = points[0],
73959             endPoint = points[points.length-1],
73960             toDelete = [],
73961             i;
73962
73963         for (i = 1; i < points.length-1; i++) {
73964             var node = nodes[i],
73965                 point = points[i];
73966
73967             if (t < 1 || graph.parentWays(node).length > 1 ||
73968                 graph.parentRelations(node).length ||
73969                 node.hasInterestingTags()) {
73970
73971                 var u = positionAlongWay(point, startPoint, endPoint),
73972                     p = [
73973                         startPoint[0] + u * (endPoint[0] - startPoint[0]),
73974                         startPoint[1] + u * (endPoint[1] - startPoint[1])
73975                     ],
73976                     loc2 = projection.invert(p);
73977
73978                 graph = graph.replace(node.move(geoVecInterp(node.loc, loc2, t)));
73979
73980             } else {
73981                 // safe to delete
73982                 if (toDelete.indexOf(node) === -1) {
73983                     toDelete.push(node);
73984                 }
73985             }
73986         }
73987
73988         for (i = 0; i < toDelete.length; i++) {
73989             graph = actionDeleteNode(toDelete[i].id)(graph);
73990         }
73991
73992         return graph;
73993     };
73994
73995
73996     action.disabled = function(graph) {
73997         // check way isn't too bendy
73998         var way = graph.entity(wayId),
73999             nodes = graph.childNodes(way),
74000             points = nodes.map(function(n) { return projection(n.loc); }),
74001             startPoint = points[0],
74002             endPoint = points[points.length-1],
74003             threshold = 0.2 * geoVecLength(startPoint, endPoint),
74004             i;
74005
74006         if (threshold === 0) {
74007             return 'too_bendy';
74008         }
74009
74010         for (i = 1; i < points.length-1; i++) {
74011             var point = points[i],
74012                 u = positionAlongWay(point, startPoint, endPoint),
74013                 p0 = startPoint[0] + u * (endPoint[0] - startPoint[0]),
74014                 p1 = startPoint[1] + u * (endPoint[1] - startPoint[1]),
74015                 dist = Math.sqrt(Math.pow(p0 - point[0], 2) + Math.pow(p1 - point[1], 2));
74016
74017             // to bendy if point is off by 20% of total start/end distance in projected space
74018             if (isNaN(dist) || dist > threshold) {
74019                 return 'too_bendy';
74020             }
74021         }
74022     };
74023
74024
74025     action.transitionable = true;
74026
74027
74028     return action;
74029 }
74030
74031 // Remove the effects of `turn.restriction` on `turn`, which must have the
74032 // following structure:
74033 //
74034 //     {
74035 //         from: { node: <node ID>, way: <way ID> },
74036 //         via:  { node: <node ID> },
74037 //         to:   { node: <node ID>, way: <way ID> },
74038 //         restriction: <relation ID>
74039 //     }
74040 //
74041 // In the simple case, `restriction` is a reference to a `no_*` restriction
74042 // on the turn itself. In this case, it is simply deleted.
74043 //
74044 // The more complex case is where `restriction` references an `only_*`
74045 // restriction on a different turn in the same intersection. In that case,
74046 // that restriction is also deleted, but at the same time restrictions on
74047 // the turns other than the first two are created.
74048 //
74049 function actionUnrestrictTurn(turn) {
74050     return function(graph) {
74051         return actionDeleteRelation(turn.restriction)(graph);
74052     };
74053 }
74054
74055 /* Reflect the given area around its axis of symmetry */
74056 function actionReflect(reflectIds, projection) {
74057     var useLongAxis = true;
74058
74059
74060     // http://gis.stackexchange.com/questions/22895/finding-minimum-area-rectangle-for-given-points
74061     // http://gis.stackexchange.com/questions/3739/generalisation-strategies-for-building-outlines/3756#3756
74062     function getSmallestSurroundingRectangle(graph, nodes) {
74063         var points = nodes.map(function(n) { return projection(n.loc); }),
74064             hull = d3_polygonHull(points),
74065             centroid = d3_polygonCentroid(hull),
74066             minArea = Infinity,
74067             ssrExtent = [],
74068             ssrAngle = 0,
74069             c1 = hull[0];
74070
74071         for (var i = 0; i <= hull.length - 1; i++) {
74072             var c2 = (i === hull.length - 1) ? hull[0] : hull[i + 1],
74073                 angle = Math.atan2(c2[1] - c1[1], c2[0] - c1[0]),
74074                 poly = geoRotate(hull, -angle, centroid),
74075                 extent = poly.reduce(function(extent, point) {
74076                         return extent.extend(geoExtent(point));
74077                     }, geoExtent()),
74078                 area = extent.area();
74079
74080             if (area < minArea) {
74081                 minArea = area;
74082                 ssrExtent = extent;
74083                 ssrAngle = angle;
74084             }
74085             c1 = c2;
74086         }
74087
74088         return {
74089             poly: geoRotate(ssrExtent.polygon(), ssrAngle, centroid),
74090             angle: ssrAngle
74091         };
74092     }
74093
74094
74095     var action = function(graph, t) {
74096         if (t === null || !isFinite(t)) t = 1;
74097         t = Math.min(Math.max(+t, 0), 1);
74098
74099         var nodes = utilGetAllNodes(reflectIds, graph),
74100             ssr = getSmallestSurroundingRectangle(graph, nodes);
74101
74102         // Choose line pq = axis of symmetry.
74103         // The shape's surrounding rectangle has 2 axes of symmetry.
74104         // Reflect across the longer axis by default.
74105         var p1 = [(ssr.poly[0][0] + ssr.poly[1][0]) / 2, (ssr.poly[0][1] + ssr.poly[1][1]) / 2 ],
74106             q1 = [(ssr.poly[2][0] + ssr.poly[3][0]) / 2, (ssr.poly[2][1] + ssr.poly[3][1]) / 2 ],
74107             p2 = [(ssr.poly[3][0] + ssr.poly[4][0]) / 2, (ssr.poly[3][1] + ssr.poly[4][1]) / 2 ],
74108             q2 = [(ssr.poly[1][0] + ssr.poly[2][0]) / 2, (ssr.poly[1][1] + ssr.poly[2][1]) / 2 ],
74109             p, q;
74110
74111         var isLong = (geoVecLength(p1, q1) > geoVecLength(p2, q2));
74112         if ((useLongAxis && isLong) || (!useLongAxis && !isLong)) {
74113             p = p1;
74114             q = q1;
74115         } else {
74116             p = p2;
74117             q = q2;
74118         }
74119
74120         // reflect c across pq
74121         // http://math.stackexchange.com/questions/65503/point-reflection-over-a-line
74122         var dx = q[0] - p[0];
74123         var dy = q[1] - p[1];
74124         var a = (dx * dx - dy * dy) / (dx * dx + dy * dy);
74125         var b = 2 * dx * dy / (dx * dx + dy * dy);
74126         for (var i = 0; i < nodes.length; i++) {
74127             var node = nodes[i];
74128             var c = projection(node.loc);
74129             var c2 = [
74130                 a * (c[0] - p[0]) + b * (c[1] - p[1]) + p[0],
74131                 b * (c[0] - p[0]) - a * (c[1] - p[1]) + p[1]
74132             ];
74133             var loc2 = projection.invert(c2);
74134             node = node.move(geoVecInterp(node.loc, loc2, t));
74135             graph = graph.replace(node);
74136         }
74137
74138         return graph;
74139     };
74140
74141
74142     action.useLongAxis = function(_) {
74143         if (!arguments.length) return useLongAxis;
74144         useLongAxis = _;
74145         return action;
74146     };
74147
74148
74149     action.transitionable = true;
74150
74151
74152     return action;
74153 }
74154
74155
74156
74157 var index$4 = Object.freeze({
74158         d3combobox: d3combobox,
74159         d3geoTile: d3geoTile,
74160         d3keybinding: d3keybinding
74161 });
74162
74163 /* export some legacy symbols: */
74164 var Connection = services.osm;
74165 var debug = false;
74166
74167
74168
74169
74170 var iD = Object.freeze({
74171         Connection: Connection,
74172         debug: debug,
74173         lib: index$4,
74174         d3: index$3,
74175         Context: coreContext,
74176         setAreaKeys: setAreaKeys,
74177         Difference: coreDifference,
74178         Graph: coreGraph,
74179         History: coreHistory,
74180         Tree: coreTree,
74181         geoCross: geoVecCross,
74182         geoInterp: geoVecInterp,
74183         geoRoundCoordinates: geoVecFloor,
74184         geoEuclideanDistance: geoVecLength,
74185         Entity: osmEntity,
74186         Node: osmNode,
74187         Relation: osmRelation,
74188         Way: osmWay,
74189         BackgroundSource: rendererBackgroundSource,
74190         Background: rendererBackground,
74191         Features: rendererFeatures,
74192         Map: rendererMap,
74193         TileLayer: rendererTileLayer,
74194         Detect: utilDetect,
74195         uiPreset: uiPresetEditor,
74196         actionAddEntity: actionAddEntity,
74197         actionAddMember: actionAddMember,
74198         actionAddMidpoint: actionAddMidpoint,
74199         actionAddVertex: actionAddVertex,
74200         actionChangeMember: actionChangeMember,
74201         actionChangePreset: actionChangePreset,
74202         actionChangeTags: actionChangeTags,
74203         actionCircularize: actionCircularize,
74204         actionConnect: actionConnect,
74205         actionCopyEntities: actionCopyEntities,
74206         actionDeleteMember: actionDeleteMember,
74207         actionDeleteMultiple: actionDeleteMultiple,
74208         actionDeleteNode: actionDeleteNode,
74209         actionDeleteRelation: actionDeleteRelation,
74210         actionDeleteWay: actionDeleteWay,
74211         actionDeprecateTags: actionDeprecateTags,
74212         actionDiscardTags: actionDiscardTags,
74213         actionDisconnect: actionDisconnect,
74214         actionJoin: actionJoin,
74215         actionMerge: actionMerge,
74216         actionMergePolygon: actionMergePolygon,
74217         actionMergeRemoteChanges: actionMergeRemoteChanges,
74218         actionMove: actionMove,
74219         actionMoveNode: actionMoveNode,
74220         actionNoop: actionNoop,
74221         actionOrthogonalize: actionOrthogonalize,
74222         actionRestrictTurn: actionRestrictTurn,
74223         actionReverse: actionReverse,
74224         actionRevert: actionRevert,
74225         actionRotate: actionRotate,
74226         actionSplit: actionSplit,
74227         actionStraighten: actionStraighten,
74228         actionUnrestrictTurn: actionUnrestrictTurn,
74229         actionReflect: actionReflect,
74230         behaviorAddWay: behaviorAddWay,
74231         behaviorBreathe: behaviorBreathe,
74232         behaviorCopy: behaviorCopy,
74233         behaviorDrag: behaviorDrag,
74234         behaviorDrawWay: behaviorDrawWay,
74235         behaviorDraw: behaviorDraw,
74236         behaviorEdit: behaviorEdit,
74237         behaviorHash: behaviorHash,
74238         behaviorHover: behaviorHover,
74239         behaviorLasso: behaviorLasso,
74240         behaviorOperation: behaviorOperation,
74241         behaviorPaste: behaviorPaste,
74242         behaviorSelect: behaviorSelect,
74243         behaviorTail: behaviorTail,
74244         coreContext: coreContext,
74245         coreDifference: coreDifference,
74246         coreGraph: coreGraph,
74247         coreHistory: coreHistory,
74248         coreTree: coreTree,
74249         dataFeatureIcons: dataFeatureIcons,
74250         data: data,
74251         dataWikipedia: wikipedia$2,
74252         dataSuggestions: dataSuggestions,
74253         dataAddressFormats: dataAddressFormats,
74254         dataDeprecated: dataDeprecated,
74255         dataDiscarded: dataDiscarded,
74256         dataLocales: dataLocales,
74257         dataPhoneFormats: dataPhoneFormats,
74258         dataShortcuts: dataShortcuts,
74259         dataImperial: dataImperial,
74260         dataDriveLeft: dataDriveLeft,
74261         dataEn: en,
74262         geoExtent: geoExtent,
74263         geoLatToMeters: geoLatToMeters,
74264         geoLonToMeters: geoLonToMeters,
74265         geoMetersToLat: geoMetersToLat,
74266         geoMetersToLon: geoMetersToLon,
74267         geoMetersToOffset: geoMetersToOffset,
74268         geoOffsetToMeters: geoOffsetToMeters,
74269         geoScaleToZoom: geoScaleToZoom,
74270         geoSphericalDistance: geoSphericalDistance,
74271         geoZoomToScale: geoZoomToScale,
74272         geoAngle: geoAngle,
74273         geoChooseEdge: geoChooseEdge,
74274         geoEdgeEqual: geoEdgeEqual,
74275         geoHasSelfIntersections: geoHasSelfIntersections,
74276         geoRotate: geoRotate,
74277         geoLineIntersection: geoLineIntersection,
74278         geoPathHasIntersections: geoPathHasIntersections,
74279         geoPathIntersections: geoPathIntersections,
74280         geoPathLength: geoPathLength,
74281         geoPointInPolygon: geoPointInPolygon,
74282         geoPolygonContainsPolygon: geoPolygonContainsPolygon,
74283         geoPolygonIntersectsPolygon: geoPolygonIntersectsPolygon,
74284         geoViewportEdge: geoViewportEdge,
74285         geoRawMercator: geoRawMercator,
74286         geoVecAdd: geoVecAdd,
74287         geoVecAngle: geoVecAngle,
74288         geoVecCross: geoVecCross,
74289         geoVecDot: geoVecDot,
74290         geoVecEqual: geoVecEqual,
74291         geoVecFloor: geoVecFloor,
74292         geoVecInterp: geoVecInterp,
74293         geoVecLength: geoVecLength,
74294         geoVecSubtract: geoVecSubtract,
74295         geoVecScale: geoVecScale,
74296         modeAddArea: modeAddArea,
74297         modeAddLine: modeAddLine,
74298         modeAddPoint: modeAddPoint,
74299         modeBrowse: modeBrowse,
74300         modeDragNode: modeDragNode,
74301         modeDrawArea: modeDrawArea,
74302         modeDrawLine: modeDrawLine,
74303         modeMove: modeMove,
74304         modeRotate: modeRotate,
74305         modeSave: modeSave,
74306         modeSelect: modeSelect,
74307         operationCircularize: operationCircularize,
74308         operationContinue: operationContinue,
74309         operationDelete: operationDelete,
74310         operationDisconnect: operationDisconnect,
74311         operationMerge: operationMerge,
74312         operationMove: operationMove,
74313         operationOrthogonalize: operationOrthogonalize,
74314         operationReflectShort: operationReflectShort,
74315         operationReflectLong: operationReflectLong,
74316         operationReverse: operationReverse,
74317         operationRotate: operationRotate,
74318         operationSplit: operationSplit,
74319         operationStraighten: operationStraighten,
74320         osmChangeset: osmChangeset,
74321         osmEntity: osmEntity,
74322         osmNode: osmNode,
74323         osmRelation: osmRelation,
74324         osmWay: osmWay,
74325         osmIntersection: osmIntersection,
74326         osmTurn: osmTurn,
74327         osmInferRestriction: osmInferRestriction,
74328         osmLanes: osmLanes,
74329         osmIsSimpleMultipolygonOuterMember: osmIsSimpleMultipolygonOuterMember,
74330         osmSimpleMultipolygonOuterMember: osmSimpleMultipolygonOuterMember,
74331         osmJoinWays: osmJoinWays,
74332         osmOneWayTags: osmOneWayTags,
74333         osmPavedTags: osmPavedTags,
74334         osmIsInterestingTag: osmIsInterestingTag,
74335         presetCategory: presetCategory,
74336         presetCollection: presetCollection,
74337         presetField: presetField,
74338         presetPreset: presetPreset,
74339         presetIndex: presetIndex,
74340         rendererBackgroundSource: rendererBackgroundSource,
74341         rendererBackground: rendererBackground,
74342         rendererFeatures: rendererFeatures,
74343         rendererMap: rendererMap,
74344         rendererTileLayer: rendererTileLayer,
74345         services: services,
74346         serviceMapillary: serviceMapillary,
74347         serviceNominatim: serviceNominatim,
74348         serviceOpenstreetcam: serviceOpenstreetcam,
74349         serviceOsm: serviceOsm,
74350         serviceTaginfo: serviceTaginfo,
74351         serviceWikidata: serviceWikidata,
74352         serviceWikipedia: serviceWikipedia,
74353         svgAreas: svgAreas,
74354         svgDebug: svgDebug,
74355         svgDefs: svgDefs,
74356         svgGpx: svgGpx,
74357         svgIcon: svgIcon,
74358         svgLabels: svgLabels,
74359         svgLayers: svgLayers,
74360         svgLines: svgLines,
74361         svgMapillaryImages: svgMapillaryImages,
74362         svgMapillarySigns: svgMapillarySigns,
74363         svgMidpoints: svgMidpoints,
74364         svgOneWaySegments: svgOneWaySegments,
74365         svgOpenstreetcamImages: svgOpenstreetcamImages,
74366         svgOsm: svgOsm,
74367         svgPassiveVertex: svgPassiveVertex,
74368         svgPath: svgPath,
74369         svgPointTransform: svgPointTransform,
74370         svgPoints: svgPoints,
74371         svgRelationMemberTags: svgRelationMemberTags,
74372         svgSegmentWay: svgSegmentWay,
74373         svgTagClasses: svgTagClasses,
74374         svgTurns: svgTurns,
74375         svgVertices: svgVertices,
74376         uiFields: uiFields,
74377         uiFieldDefaultCheck: uiFieldCheck,
74378         uiFieldOnewayCheck: uiFieldCheck,
74379         uiFieldCheck: uiFieldCheck,
74380         uiFieldMultiCombo: uiFieldCombo,
74381         uiFieldNetworkCombo: uiFieldCombo,
74382         uiFieldSemiCombo: uiFieldCombo,
74383         uiFieldTypeCombo: uiFieldCombo,
74384         uiFieldCombo: uiFieldCombo,
74385         uiFieldUrl: uiFieldText,
74386         uiFieldNumber: uiFieldText,
74387         uiFieldTel: uiFieldText,
74388         uiFieldEmail: uiFieldText,
74389         uiFieldText: uiFieldText,
74390         uiFieldAccess: uiFieldAccess,
74391         uiFieldAddress: uiFieldAddress,
74392         uiFieldCycleway: uiFieldCycleway,
74393         uiFieldLanes: uiFieldLanes,
74394         uiFieldLocalized: uiFieldLocalized,
74395         uiFieldMaxspeed: uiFieldMaxspeed,
74396         uiFieldStructureRadio: uiFieldRadio,
74397         uiFieldRadio: uiFieldRadio,
74398         uiFieldRestrictions: uiFieldRestrictions,
74399         uiFieldTextarea: uiFieldTextarea,
74400         uiFieldWikipedia: uiFieldWikipedia,
74401         uiIntro: uiIntro,
74402         uiInfoPanels: uiInfoPanels,
74403         uiPanelBackground: uiPanelBackground,
74404         uiPanelHistory: uiPanelHistory,
74405         uiPanelLocation: uiPanelLocation,
74406         uiPanelMeasurement: uiPanelMeasurement,
74407         uiInit: uiInit,
74408         uiAccount: uiAccount,
74409         uiAttribution: uiAttribution,
74410         uiBackground: uiBackground,
74411         uiBackgroundDisplayOptions: uiBackgroundDisplayOptions,
74412         uiBackgroundOffset: uiBackgroundOffset,
74413         uiChangesetEditor: uiChangesetEditor,
74414         uiCmd: uiCmd,
74415         uiCommit: uiCommit,
74416         uiCommitChanges: uiCommitChanges,
74417         uiCommitWarnings: uiCommitWarnings,
74418         uiConfirm: uiConfirm,
74419         uiConflicts: uiConflicts,
74420         uiContributors: uiContributors,
74421         uiCurtain: uiCurtain,
74422         uiDisclosure: uiDisclosure,
74423         uiEditMenu: uiEditMenu,
74424         uiEntityEditor: uiEntityEditor,
74425         uiFeatureInfo: uiFeatureInfo,
74426         uiFeatureList: uiFeatureList,
74427         uiField: uiField,
74428         uiFlash: uiFlash,
74429         uiFormFields: uiFormFields,
74430         uiFullScreen: uiFullScreen,
74431         uiGeolocate: uiGeolocate,
74432         uiHelp: uiHelp,
74433         uiInfo: uiInfo,
74434         uiInspector: uiInspector,
74435         uiLasso: uiLasso,
74436         uiLoading: uiLoading,
74437         uiMapData: uiMapData,
74438         uiMapInMap: uiMapInMap,
74439         uiModal: uiModal,
74440         uiModes: uiModes,
74441         uiNotice: uiNotice,
74442         uiPresetEditor: uiPresetEditor,
74443         uiPresetIcon: uiPresetIcon,
74444         uiPresetList: uiPresetList,
74445         uiRadialMenu: uiRadialMenu,
74446         uiRawMemberEditor: uiRawMemberEditor,
74447         uiRawMembershipEditor: uiRawMembershipEditor,
74448         uiRawTagEditor: uiRawTagEditor,
74449         uiRestore: uiRestore,
74450         uiSave: uiSave,
74451         uiScale: uiScale,
74452         uiSelectionList: uiSelectionList,
74453         uiSidebar: uiSidebar,
74454         uiSourceSwitch: uiSourceSwitch,
74455         uiSpinner: uiSpinner,
74456         uiSplash: uiSplash,
74457         uiStatus: uiStatus,
74458         uiSuccess: uiSuccess,
74459         uiTagReference: uiTagReference,
74460         uiToggle: uiToggle,
74461         uiTooltipHtml: uiTooltipHtml,
74462         uiUndoRedo: uiUndoRedo,
74463         uiVersion: uiVersion,
74464         uiViewOnOSM: uiViewOnOSM,
74465         uiZoom: uiZoom,
74466         utilAsyncMap: utilAsyncMap,
74467         utilCallWhenIdle: utilCallWhenIdle,
74468         utilDisplayName: utilDisplayName,
74469         utilDisplayNameForPath: utilDisplayNameForPath,
74470         utilDisplayType: utilDisplayType,
74471         utilEditDistance: utilEditDistance,
74472         utilEntitySelector: utilEntitySelector,
74473         utilEntityOrMemberSelector: utilEntityOrMemberSelector,
74474         utilFastMouse: utilFastMouse,
74475         utilFunctor: utilFunctor,
74476         utilGetAllNodes: utilGetAllNodes,
74477         utilGetPrototypeOf: utilGetPrototypeOf,
74478         utilGetSetValue: utilGetSetValue,
74479         utilIdleWorker: utilIdleWorker,
74480         utilNoAuto: utilNoAuto,
74481         utilPrefixCSSProperty: utilPrefixCSSProperty,
74482         utilPrefixDOMProperty: utilPrefixDOMProperty,
74483         utilQsString: utilQsString,
74484         utilRebind: utilRebind,
74485         utilSetTransform: utilSetTransform,
74486         utilSessionMutex: utilSessionMutex,
74487         utilStringQs: utilStringQs,
74488         utilSuggestNames: utilSuggestNames,
74489         utilTagText: utilTagText,
74490         utilTriggerEvent: utilTriggerEvent,
74491         utilWrap: utilWrap,
74492         d3combobox: d3combobox,
74493         d3geoTile: d3geoTile,
74494         d3keybinding: d3keybinding,
74495         validationDeprecatedTag: validationDeprecatedTag,
74496         validationDisconnectedHighway: validationDisconnectedHighway,
74497         validationManyDeletions: validationManyDeletions,
74498         validationMissingTag: validationMissingTag,
74499         validationOldMultipolygon: validationOldMultipolygon,
74500         validationTagSuggestsArea: validationTagSuggestsArea
74501 });
74502
74503 window.iD = iD;
74504
74505 }());
74506 //# sourceMappingURL=iD.js.map