PageSourceSearch

https://ggflu.com/leaflet-binding-2.2.3/leaflet.js

js ggflu.com collected 2026-09-25 22:32:13 UTC 95,313 bytes, 2,787 lines download raw bytes

1(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2"use strict";
3
4Object.defineProperty(exports, "__esModule", {
5  value: true
6});
7exports["default"] = undefined;
8
9var _util = require("./util");
10
11function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12
13function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
14
15function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
16
17var ClusterLayerStore = /*#__PURE__*/function () {
18  function ClusterLayerStore(group) {
19    _classCallCheck(this, ClusterLayerStore);
20
21    this._layers = {};
22    this._group = group;
23  }
24
25  _createClass(ClusterLayerStore, [{
26    key: "add",
27    value: function add(layer, id) {
28      if (typeof id !== "undefined" && id !== null) {
29        if (this._layers[id]) {
30          this._group.removeLayer(this._layers[id]);
31        }
32
33        this._layers[id] = layer;
34      }
35
36      this._group.addLayer(layer);
37    }
38  }, {
39    key: "remove",
40    value: function remove(id) {
41      if (typeof id === "undefined" || id === null) {
42        return;
43      }
44
45      id = (0, _util.asArray)(id);
46
47      for (var i = 0; i < id.length; i++) {
48        if (this._layers[id[i]]) {
49          this._group.removeLayer(this._layers[id[i]]);
50
51          delete this._layers[id[i]];
52        }
53      }
54    }
55  }, {
56    key: "clear",
57    value: function clear() {
58      this._layers = {};
59
60      this._group.clearLayers();
61    }
62  }]);
63
64  return ClusterLayerStore;
65}();
66
67exports["default"] = ClusterLayerStore;
68
69
70},{"./util":17}],2:[function(require,module,exports){
71"use strict";
72
73Object.defineProperty(exports, "__esModule", {
74  value: true
75});
76
77function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
78
79function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
80
81function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
82
83var ControlStore = /*#__PURE__*/function () {
84  function ControlStore(map) {
85    _classCallCheck(this, ControlStore);
86
87    this._controlsNoId = [];
88    this._controlsById = {};
89    this._map = map;
90  }
91
92  _createClass(ControlStore, [{
93    key: "add",
94    value: function add(control, id, html) {
95      if (typeof id !== "undefined" && id !== null) {
96        if (this._controlsById[id]) {
97          this._map.removeControl(this._controlsById[id]);
98        }
99
100        this._controlsById[id] = control;
101      } else {
102        this._controlsNoId.push(control);
103      }
104
105      this._map.addControl(control);
106    }
107  }, {
108    key: "get",
109    value: function get(id) {
110      var control = null;
111
112      if (this._controlsById[id]) {
113        control = this._controlsById[id];
114      }
115
116      return control;
117    }
118  }, {
119    key: "remove",
120    value: function remove(id) {
121      if (this._controlsById[id]) {
122        var control = this._controlsById[id];
123
124        this._map.removeControl(control);
125
126        delete this._controlsById[id];
127      }
128    }
129  }, {
130    key: "clear",
131    value: function clear() {
132      for (var i = 0; i < this._controlsNoId.length; i++) {
133        var control = this._controlsNoId[i];
134
135        this._map.removeControl(control);
136      }
137
138      this._controlsNoId = [];
139
140      for (var key in this._controlsById) {
141        var _control = this._controlsById[key];
142
143        this._map.removeControl(_control);
144      }
145
146      this._controlsById = {};
147    }
148  }]);
149
150  return ControlStore;
151}();
152
153exports["default"] = ControlStore;
154
155
156},{}],3:[function(require,module,exports){
157"use strict";
158
159Object.defineProperty(exports, "__esModule", {
160  value: true
161});
162exports.getCRS = getCRS;
163
164var _leaflet = require("./global/leaflet");
165
166var _leaflet2 = _interopRequireDefault(_leaflet);
167
168var _proj4leaflet = require("./global/proj4leaflet");
169
170var _proj4leaflet2 = _interopRequireDefault(_proj4leaflet);
171
172function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
173
174// Helper function to instanciate a ICRS instance.
175function getCRS(crsOptions) {
176  var crs = _leaflet2["default"].CRS.EPSG3857; // Default Spherical Mercator
177
178  switch (crsOptions.crsClass) {
179    case "L.CRS.EPSG3857":
180      crs = _leaflet2["default"].CRS.EPSG3857;
181      break;
182
183    case "L.CRS.EPSG4326":
184      crs = _leaflet2["default"].CRS.EPSG4326;
185      break;
186
187    case "L.CRS.EPSG3395":
188      crs = _leaflet2["default"].CRS.EPSG3395;
189      break;
190
191    case "L.CRS.Simple":
192      crs = _leaflet2["default"].CRS.Simple;
193      break;
194
195    case "L.Proj.CRS":
196      if (crsOptions.options && crsOptions.options.bounds) {
197        crsOptions.options.bounds = _leaflet2["default"].bounds(crsOptions.options.bounds);
198      }
199
200      if (crsOptions.options && crsOptions.options.transformation) {
201        crsOptions.options.transformation = new _leaflet2["default"].Transformation(crsOptions.options.transformation[0], crsOptions.options.transformation[1], crsOptions.options.transformation[2], crsOptions.options.transformation[3]);
202      }
203
204      crs = new _proj4leaflet2["default"].CRS(crsOptions.code, crsOptions.proj4def, crsOptions.options);
205      break;
206
207    case "L.Proj.CRS.TMS":
208      if (crsOptions.options && crsOptions.options.bounds) {
209        crsOptions.options.bounds = _leaflet2["default"].bounds(crsOptions.options.bounds);
210      }
211
212      if (crsOptions.options && crsOptions.options.transformation) {
213        crsOptions.options.transformation = _leaflet2["default"].Transformation(crsOptions.options.transformation[0], crsOptions.options.transformation[1], crsOptions.options.transformation[2], crsOptions.options.transformation[3]);
214      } // L.Proj.CRS.TMS is deprecated as of Leaflet 1.x, fall back to L.Proj.CRS
215      //crs = new Proj4Leaflet.CRS.TMS(crsOptions.code, crsOptions.proj4def, crsOptions.projectedBounds, crsOptions.options);
216
217
218      crs = new _proj4leaflet2["default"].CRS(crsOptions.code, crsOptions.proj4def, crsOptions.options);
219      break;
220  }
221
222  return crs;
223}
224
225
226},{"./global/leaflet":10,"./global/proj4leaflet":11}],4:[function(require,module,exports){
227"use strict";
228
229Object.defineProperty(exports, "__esModule", {
230  value: true
231});
232exports["default"] = undefined;
233
234var _util = require("./util");
235
236function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
237
238function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
239
240function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
241
242var DataFrame = /*#__PURE__*/function () {
243  function DataFrame() {
244    _classCallCheck(this, DataFrame);
245
246    this.columns = [];
247    this.colnames = [];
248    this.colstrict = [];
249    this.effectiveLength = 0;
250    this.colindices = {};
251  }
252
253  _createClass(DataFrame, [{
254    key: "_updateCachedProperties",
255    value: function _updateCachedProperties() {
256      var _this = this;
257
258      this.effectiveLength = 0;
259      this.colindices = {};
260      this.columns.forEach(function (column, i) {
261        _this.effectiveLength = Math.max(_this.effectiveLength, column.length);
262        _this.colindices[_this.colnames[i]] = i;
263      });
264    }
265  }, {
266    key: "_colIndex",
267    value: function _colIndex(colname) {
268      var index = this.colindices[colname];
269      if (typeof index === "undefined") return -1;
270      return index;
271    }
272  }, {
273    key: "col",
274    value: function col(name, values, strict) {
275      if (typeof name !== "string") throw new Error("Invalid column name \"" + name + "\"");
276
277      var index = this._colIndex(name);
278
279      if (arguments.length === 1) {
280        if (index < 0) return null;else return (0, _util.recycle)(this.columns[index], this.effectiveLength);
281      }
282
283      if (index < 0) {
284        index = this.colnames.length;
285        this.colnames.push(name);
286      }
287
288      this.columns[index] = (0, _util.asArray)(values);
289      this.colstrict[index] = !!strict; // TODO: Validate strictness (ensure lengths match up with other stricts)
290
291      this._updateCachedProperties();
292
293      return this;
294    }
295  }, {
296    key: "cbind",
297    value: function cbind(obj, strict) {
298      var _this2 = this;
299
300      Object.keys(obj).forEach(function (name) {
301        var coldata = obj[name];
302
303        _this2.col(name, coldata);
304      });
305      return this;
306    }
307  }, {
308    key: "get",
309    value: function get(row, col, missingOK) {
310      var _this3 = this;
311
312      if (row > this.effectiveLength) throw new Error("Row argument was out of bounds: " + row + " > " + this.effectiveLength);
313      var colIndex = -1;
314
315      if (typeof col === "undefined") {
316        var rowData = {};
317        this.colnames.forEach(function (name, i) {
318          rowData[name] = _this3.columns[i][row % _this3.columns[i].length];
319        });
320        return rowData;
321      } else if (typeof col === "string") {
322        colIndex = this._colIndex(col);
323      } else if (typeof col === "number") {
324        colIndex = col;
325      }
326
327      if (colIndex < 0 || colIndex > this.columns.length) {
328        if (missingOK) return void 0;else throw new Error("Unknown column index: " + col);
329      }
330
331      return this.columns[colIndex][row % this.columns[colIndex].length];
332    }
333  }, {
334    key: "nrow",
335    value: function nrow() {
336      return this.effectiveLength;
337    }
338  }]);
339
340  return DataFrame;
341}();
342
343exports["default"] = DataFrame;
344
345
346},{"./util":17}],5:[function(require,module,exports){
347"use strict";
348
349var _leaflet = require("./global/leaflet");
350
351var _leaflet2 = _interopRequireDefault(_leaflet);
352
353function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
354
355// In RMarkdown's self-contained mode, we don't have a way to carry around the
356// images that Leaflet needs but doesn't load into the page. Instead, we'll use
357// the unpkg CDN.
358if (typeof _leaflet2["default"].Icon.Default.imagePath === "undefined") {
359  _leaflet2["default"].Icon.Default.imagePath = "https://unpkg.com/[email protected]/dist/images/";
360}
361
362
363},{"./global/leaflet":10}],6:[function(require,module,exports){
364"use strict";
365
366var _leaflet = require("./global/leaflet");
367
368var _leaflet2 = _interopRequireDefault(_leaflet);
369
370function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
371
372// add texxtsize, textOnly, and style
373_leaflet2["default"].Tooltip.prototype.options.textsize = "10px";
374_leaflet2["default"].Tooltip.prototype.options.textOnly = false;
375_leaflet2["default"].Tooltip.prototype.options.style = null; // copy original layout to not completely stomp it.
376
377var initLayoutOriginal = _leaflet2["default"].Tooltip.prototype._initLayout;
378
379_leaflet2["default"].Tooltip.prototype._initLayout = function () {
380  initLayoutOriginal.call(this);
381  this._container.style.fontSize = this.options.textsize;
382
383  if (this.options.textOnly) {
384    _leaflet2["default"].DomUtil.addClass(this._container, "leaflet-tooltip-text-only");
385  }
386
387  if (this.options.style) {
388    for (var property in this.options.style) {
389      this._container.style[property] = this.options.style[property];
390    }
391  }
392};
393
394
395},{"./global/leaflet":10}],7:[function(require,module,exports){
396"use strict";
397
398var _leaflet = require("./global/leaflet");
399
400var _leaflet2 = _interopRequireDefault(_leaflet);
401
402function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
403
404var protocolRegex = /^\/\//;
405
406var upgrade_protocol = function upgrade_protocol(urlTemplate) {
407  if (protocolRegex.test(urlTemplate)) {
408    if (window.location.protocol === "file:") {
409      // if in a local file, support http
410      // http should auto upgrade if necessary
411      urlTemplate = "http:" + urlTemplate;
412    }
413  }
414
415  return urlTemplate;
416};
417
418var originalLTileLayerInitialize = _leaflet2["default"].TileLayer.prototype.initialize;
419
420_leaflet2["default"].TileLayer.prototype.initialize = function (urlTemplate, options) {
421  urlTemplate = upgrade_protocol(urlTemplate);
422  originalLTileLayerInitialize.call(this, urlTemplate, options);
423};
424
425var originalLTileLayerWMSInitialize = _leaflet2["default"].TileLayer.WMS.prototype.initialize;
426
427_leaflet2["default"].TileLayer.WMS.prototype.initialize = function (urlTemplate, options) {
428  urlTemplate = upgrade_protocol(urlTemplate);
429  originalLTileLayerWMSInitialize.call(this, urlTemplate, options);
430};
431
432
433},{"./global/leaflet":10}],8:[function(require,module,exports){
434(function (global){(function (){
435"use strict";
436
437Object.defineProperty(exports, "__esModule", {
438  value: true
439});
440exports["default"] = global.HTMLWidgets;
441
442
443}
443).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
444},{}],9:[function(require,module,exports){
445(function (global){(function (){
446"use strict";
447
448Object.defineProperty(exports, "__esModule", {
449  value: true
450});
451exports["default"] = global.jQuery;
452
453
454}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
455},{}],10:[function(require,module,exports){
456(function (global){(function (){
457"use strict";
458
459Object.defineProperty(exports, "__esModule", {
460  value: true
461});
462exports["default"] = global.L;
463
464
465}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
466},{}],11:[function(require,module,exports){
467(function (global){(function (){
468"use strict";
469
470Object.defineProperty(exports, "__esModule", {
471  value: true
472});
473exports["default"] = global.L.Proj;
474
475
476}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
477},{}],12:[function(require,module,exports){
478(function (global){(function (){
479"use strict";
480
481Object.defineProperty(exports, "__esModule", {
482  value: true
483});
484exports["default"] = global.Shiny;
485
486
487}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
488},{}],13:[function(require,module,exports){
489"use strict";
490
491var _jquery = require("./global/jquery");
492
493var _jquery2 = _interopRequireDefault(_jquery);
494
495var _leaflet = require("./global/leaflet");
496
497var _leaflet2 = _interopRequireDefault(_leaflet);
498
499var _shiny = require("./global/shiny");
500
501var _shiny2 = _interopRequireDefault(_shiny);
502
503var _htmlwidgets = require("./global/htmlwidgets");
504
505var _htmlwidgets2 = _interopRequireDefault(_htmlwidgets);
506
507var _util = require("./util");
508
509var _crs_utils = require("./crs_utils");
510
511var _controlStore = require("./control-store");
512
513var _controlStore2 = _interopRequireDefault(_controlStore);
514
515var _layerManager = require("./layer-manager");
516
517var _layerManager2 = _interopRequireDefault(_layerManager);
518
519var _methods = require("./methods");
520
521var _methods2 = _interopRequireDefault(_methods);
522
523require("./fixup-default-icon");
524
525require("./fixup-default-tooltip");
526
527require("./fixup-url-protocol");
528
529var _dataframe = require("./dataframe");
530
531var _dataframe2 = _interopRequireDefault(_dataframe);
532
533var _clusterLayerStore = require("./cluster-layer-store");
534
535var _clusterLayerStore2 = _interopRequireDefault(_clusterLayerStore);
536
537function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
538
539window.LeafletWidget = {};
540window.LeafletWidget.utils = {};
541
542var methods = window.LeafletWidget.methods = _jquery2["default"].extend({}, _methods2["default"]);
543
544window.LeafletWidget.DataFrame = _dataframe2["default"];
545window.LeafletWidget.ClusterLayerStore = _clusterLayerStore2["default"];
546window.LeafletWidget.utils.getCRS = _crs_utils.getCRS; // Send updated bounds back to app. Takes a leaflet event object as input.
547
548function updateBounds(map) {
549  var id = map.getContainer().id;
550  var bounds = map.getBounds();
551
552  _shiny2["default"].onInputChange(id + "_bounds", {
553    north: bounds.getNorthEast().lat,
554    east: bounds.getNorthEast().lng,
555    south: bounds.getSouthWest().lat,
556    west: bounds.getSouthWest().lng
557  });
558
559  _shiny2["default"].onInputChange(id + "_center", {
560    lng: map.getCenter().lng,
561    lat: map.getCenter().lat
562  });
563
564  _shiny2["default"].onInputChange(id + "_zoom", map.getZoom());
565}
566
567function preventUnintendedZoomOnScroll(map) {
568  // Prevent unwanted scroll capturing. Similar in purpose to
569  // https://github.com/CliffCloud/Leaflet.Sleep but with a
570  // different set of heuristics.
571  // The basic idea is that when a mousewheel/DOMMouseScroll
572  // event is seen, we disable scroll wheel zooming until the
573  // user moves their mouse cursor or clicks on the map. This
574  // is slightly trickier than just listening for mousemove,
575  // because mousemove is fired when the page is scrolled,
576  // even if the user did not physically move the mouse. We
577  // handle this by examining the mousemove event's screenX
578  // and screenY properties; if they change, we know it's a
579  // "true" move.
580  // lastScreen can never be null, but its x and y can.
581  var lastScreen = {
582    x: null,
583    y: null
584  };
585  (0, _jquery2["default"])(document).on("mousewheel DOMMouseScroll", "*", function (e) {
586    // Disable zooming (until the mouse moves or click)
587    map.scrollWheelZoom.disable(); // Any mousemove events at this screen position will be ignored.
588
589    lastScreen = {
590      x: e.originalEvent.screenX,
591      y: e.originalEvent.screenY
592    };
593  });
594  (0, _jquery2["default"])(document).on("mousemove", "*", function (e) {
595    // Did the mouse really move?
596    if (map.options.scrollWheelZoom) {
597      if (lastScreen.x !== null && e.screenX !== lastScreen.x || e.screenY !== lastScreen.y) {
598        // It really moved. Enable zooming.
599        map.scrollWheelZoom.enable();
600        lastScreen = {
601          x: null,
602          y: null
603        };
604      }
605    }
606  });
607  (0, _jquery2["default"])(document).on("mousedown", ".leaflet", function (e) {
608    // Clicking always enables zooming.
609    if (map.options.scrollWheelZoom) {
610      map.scrollWheelZoom.enable();
611      lastScreen = {
612        x: null,
613        y: null
614      };
615    }
616  });
617}
618
619_htmlwidgets2["default"].widget({
620  name: "leaflet",
621  type: "output",
622  factory: function factory(el, width, height) {
623    var map = null;
624    return {
625      // we need to store our map in our returned object.
626      getMap: function getMap() {
627        return map;
628      },
629      renderValue: function renderValue(data) {
630        // Create an appropriate CRS Object if specified
631        if (data && data.options && data.options.crs) {
632          data.options.crs = (0, _crs_utils.getCRS)(data.options.crs);
633        } // As per https://github.com/rstudio/leaflet/pull/294#discussion_r79584810
634
635
636        if (map) {
637          map.remove();
638
639          map = function () {
640            return;
641          }(); // undefine map
642
643        }
644
645        if (data.options.mapFactory && typeof data.options.mapFactory === "function") {
646          map = data.options.mapFactory(el, data.options);
647        } else {
648          map = _leaflet2["default"].map(el, data.options);
649        }
650
651        preventUnintendedZoomOnScroll(map); // Store some state in the map object
652
653        map.leafletr = {
654          // Has the map ever rendered successfully?
655          hasRendered: false,
656          // Data to be rendered when resize is called with area != 0
657          pendingRenderData: null
658        }; // Check if the map is rendered statically (no output binding)
659
660        if (_htmlwidgets2["default"].shinyMode && /\bshiny-bound-output\b/.test(el.className)) {
661          map.id = el.id; // Store the map on the element so we can find it later by ID
662
663          (0, _jquery2["default"])(el).data("leaflet-map", map); // When the map is clicked, send the coordinates back to the app
664
665          map.on("click", function (e) {
666            _shiny2["default"].onInputChange(map.id + "_click", {
667              lat: e.latlng.lat,
668              lng: e.latlng.lng,
669              ".nonce": Math.random() // Force reactivity if lat/lng hasn't changed
670
671            });
672          });
673          var groupTimerId = null;
674          map.on("moveend", function (e) {
675            updateBounds(e.target);
676          }).on("layeradd layerremove", function (e) {
677            // If the layer that's coming or going is a group we created, tell
678            // the server.
679            if (map.layerManager.getGroupNameFromLayerGroup(e.layer)) {
680              // But to avoid chattiness, coalesce events
681              if (groupTimerId) {
682                clearTimeout(groupTimerId);
683                groupTimerId = null;
684              }
685
686              groupTimerId = setTimeout(function () {
687                groupTimerId = null;
688
689                _shiny2["default"].onInputChange(map.id + "_groups", map.layerManager.getVisibleGroups());
690              }, 100);
691            }
692          });
693        }
694
695        this.doRenderValue(data, map);
696      },
697      doRenderValue: function doRenderValue(data, map) {
698        // Leaflet does not behave well when you set up a bunch of layers when
699        // the map is not visible (width/height == 0). Popups get misaligned
700        // relative to their owning markers, and the fitBounds calculations
701        // are off. Therefore we wait until the map is actually showing to
702        // render the value (we rely on the resize() callback being invoked
703        // at the appropriate time).
704        if (el.offsetWidth === 0 || el.offsetHeight === 0) {
705          map.leafletr.pendingRenderData = data;
706          return;
707        }
708
709        map.leafletr.pendingRenderData = null; // Merge data options into defaults
710
711        var options = _jquery2["default"].extend({
712          zoomToLimits: "always"
713        }, data.options);
714
715        if (!map.layerManager) {
716          map.controls = new _controlStore2["default"](map);
717          map.layerManager = new _layerManager2["default"](map);
718        } else {
719          map.controls.clear();
720          map.layerManager.clear();
721        }
722
723        var explicitView = false;
724
725        if (data.setView) {
726          explicitView = true;
727          map.setView.apply(map, data.setView);
728        }
729
730        if (data.fitBounds) {
731          explicitView = true;
732          methods.fitBounds.apply(map, data.fitBounds);
733        }
734
735        if (data.flyTo) {
736          if (!explicitView && !map.leafletr.hasRendered) {
737            // must be done to give a initial starting point
738            map.fitWorld();
739          }
740
741          explicitView = true;
742          map.flyTo.apply(map, data.flyTo);
743        }
744
745        if (data.flyToBounds) {
746          if (!explicitView && !map.leafletr.hasRendered) {
747            // must be done to give a initial starting point
748            map.fitWorld();
749          }
750
751          explicitView = true;
752          methods.flyToBounds.apply(map, data.flyToBounds);
753        }
754
755        if (data.options.center) {
756          explicitView = true;
757        } // Returns true if the zoomToLimits option says that the map should be
758        // zoomed to map elements.
759
760
761        function needsZoom() {
762          return options.zoomToLimits === "always" || options.zoomToLimits === "first" && !map.leafletr.hasRendered;
763        }
764
765        if (!explicitView && needsZoom() && !map.getZoom()) {
766          if (data.limits && !_jquery2["default"].isEmptyObject(data.limits)) {
767            // Use the natural limits of what's being drawn on the map
768            // If the size of the bounding box is 0, leaflet gets all weird
769            var pad = 0.006;
770
771            if (data.limits.lat[0] === data.limits.lat[1]) {
772              data.limits.lat[0] = data.limits.lat[0] - pad;
773              data.limits.lat[1] = data.limits.lat[1] + pad;
774            }
775
776            if (data.limits.lng[0] === data.limits.lng[1]) {
777              data.limits.lng[0] = data.limits.lng[0] - pad;
778              data.limits.lng[1] = data.limits.lng[1] + pad;
779            }
780
781            map.fitBounds([[data.limits.lat[0], data.limits.lng[0]], [data.limits.lat[1], data.limits.lng[1]]]);
782          } else {
783            map.fitWorld();
784          }
785        }
786
787        for (var i = 0; data.calls && i < data.calls.length; i++) {
788          var call = data.calls[i];
789          if (methods[call.method]) methods[call.method].apply(map, call.args);else (0, _util.log)("Unknown method " + call.method);
790        }
791
792        map.leafletr.hasRendered = true;
793
794        if (_htmlwidgets2["default"].shinyMode) {
795          setTimeout(function () {
796            updateBounds(map);
797          }, 1);
798        }
799      },
800      resize: function resize(width, height) {
801        if (map) {
802          map.invalidateSize();
803
804          if (map.leafletr.pendingRenderData) {
805            this.doRenderValue(map.leafletr.pendingRenderData, map);
806          }
807        }
808      }
809    };
810  }
811});
812
813if (_htmlwidgets2["default"].shinyMode) {
814  _shiny2["default"].addCustomMessageHandler("leaflet-calls", function (data) {
815    var id = data.id;
816    var el = document.getElementById(id);
817    var map = el ? (0, _jquery2["default"])(el).data("leaflet-map") : null;
818
819    if (!map) {
820      (0, _util.log)("Couldn't find map with id " + id);
821      return;
822    } // If the map has not rendered, stash the proposed `leafletProxy()` calls
823    // in `pendingRenderData.calls` to be run on display via `doRenderValue()`.
824    // This is necessary if the map has not been rendered.
825    // If new pendingRenderData is set via a new `leaflet()`, the previous calls will be discarded.
826
827
828    if (!map.leafletr.hasRendered) {
829      map.leafletr.pendingRenderData.calls = map.leafletr.pendingRenderData.calls.concat(data.calls);
830      return;
831    }
832
833    for (var i = 0; i < data.calls.length; i++) {
834      var call = data.calls[i];
835      var args = call.args;
836
837      for (var _i = 0; _i < call.evals.length; _i++) {
838        window.HTMLWidgets.evaluateStringMember(args, call.evals[_i]);
839      }
840
841      if (call.dependencies) {
842        _shiny2["default"].renderDependencies(call.dependencies);
843      }
844
845      if (methods[call.method]) methods[call.method].apply(map, args);else (0, _util.log)("Unknown method " + call.method);
846    }
847  });
848}
849
850
851},{"./cluster-layer-store":1,"./control-store":2,"./crs_utils":3,"./dataframe":4,"./fixup-default-icon":5,"./fixup-default-tooltip":6,"./fixup-url-protocol":7,"./global/htmlwidgets":8,"./global/jquery":9,"./global/leaflet":10,"./global/shiny":12,"./layer-manager"
851:14,"./methods":15,"./util":17}],14:[function(require,module,exports){
852(function (global){(function (){
853"use strict";
854
855Object.defineProperty(exports, "__esModule", {
856  value: true
857});
858exports["default"] = undefined;
859
860var _jquery = require("./global/jquery");
861
862var _jquery2 = _interopRequireDefault(_jquery);
863
864var _leaflet = require("./global/leaflet");
865
866var _leaflet2 = _interopRequireDefault(_leaflet);
867
868var _util = require("./util");
869
870function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
871
872function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
873
874function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
875
876function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
877
878var LayerManager = /*#__PURE__*/function () {
879  function LayerManager(map) {
880    _classCallCheck(this, LayerManager);
881
882    this._map = map; // BEGIN layer indices
883    // {<groupname>: {<stamp>: layer}}
884
885    this._byGroup = {}; // {<categoryName>: {<stamp>: layer}}
886
887    this._byCategory = {}; // {<categoryName_layerId>: layer}
888
889    this._byLayerId = {}; // {<stamp>: {
890    //             "group": <groupname>,
891    //             "layerId": <layerId>,
892    //             "category": <category>,
893    //             "container": <container>
894    //           }
895    // }
896
897    this._byStamp = {}; // {<crosstalkGroupName>: {<key>: [<stamp>, <stamp>, ...], ...}}
898
899    this._byCrosstalkGroup = {}; // END layer indices
900    // {<categoryName>: L.layerGroup}
901
902    this._categoryContainers = {}; // {<groupName>: L.layerGroup}
903
904    this._groupContainers = {};
905  }
906
907  _createClass(LayerManager, [{
908    key: "addLayer",
909    value: function addLayer(layer, category, layerId, group, ctGroup, ctKey) {
910      var _this = this;
911
912      // Was a group provided?
913      var hasId = typeof layerId === "string";
914      var grouped = typeof group === "string";
915      var stamp = _leaflet2["default"].Util.stamp(layer) + ""; // This will be the default layer group to add the layer to.
916      // We may overwrite this let before using it (i.e. if a group is assigned).
917      // This one liner creates the _categoryContainers[category] entry if it
918      // doesn't already exist.
919
920      var container = this._categoryContainers[category] = this._categoryContainers[category] || _leaflet2["default"].layerGroup().addTo(this._map);
921
922      var oldLayer = null;
923
924      if (hasId) {
925        // First, remove any layer with the same category and layerId
926        var prefixedLayerId = this._layerIdKey(category, layerId);
927
928        oldLayer = this._byLayerId[prefixedLayerId];
929
930        if (oldLayer) {
931          this._removeLayer(oldLayer);
932        } // Update layerId index
933
934
935        this._byLayerId[prefixedLayerId] = layer;
936      } // Update group index
937
938
939      if (grouped) {
940        this._byGroup[group] = this._byGroup[group] || {};
941        this._byGroup[group][stamp] = layer; // Since a group is assigned, don't add the layer to the category's layer
942        // group; instead, use the group's layer group.
943        // This one liner creates the _groupContainers[group] entry if it doesn't
944        // already exist.
945
946        container = this.getLayerGroup(group, true);
947      } // Update category index
948
949
950      this._byCategory[category] = this._byCategory[category] || {};
951      this._byCategory[category][stamp] = layer; // Update stamp index
952
953      var layerInfo = this._byStamp[stamp] = {
954        layer: layer,
955        group: group,
956        ctGroup: ctGroup,
957        ctKey: ctKey,
958        layerId: layerId,
959        category: category,
960        container: container,
961        hidden: false
962      }; // Update crosstalk group index
963
964      if (ctGroup) {
965        if (layer.setStyle) {
966          // Need to save this info so we know what to set opacity to later
967          layer.options.origOpacity = typeof layer.options.opacity !== "undefined" ? layer.options.opacity : 0.5;
968          layer.options.origFillOpacity = typeof layer.options.fillOpacity !== "undefined" ? layer.options.fillOpacity : 0.2;
969        }
970
971        var ctg = this._byCrosstalkGroup[ctGroup];
972
973        if (!ctg) {
974          ctg = this._byCrosstalkGroup[ctGroup] = {};
975          var crosstalk = global.crosstalk;
976
977          var handleFilter = function handleFilter(e) {
978            if (!e.value) {
979              var groupKeys = Object.keys(ctg);
980
981              for (var i = 0; i < groupKeys.length; i++) {
982                var key = groupKeys[i];
983                var _layerInfo = _this._byStamp[ctg[key]];
984
985                _this._setVisibility(_layerInfo, true);
986              }
987            } else {
988              var selectedKeys = {};
989
990              for (var _i = 0; _i < e.value.length; _i++) {
991                selectedKeys[e.value[_i]] = true;
992              }
993
994              var _groupKeys = Object.keys(ctg);
995
996              for (var _i2 = 0; _i2 < _groupKeys.length; _i2++) {
997                var _key = _groupKeys[_i2];
998                var _layerInfo2 = _this._byStamp[ctg[_key]];
999
1000                _this._setVisibility(_layerInfo2, selectedKeys[_groupKeys[_i2]]);
1001              }
1002            }
1003          };
1004
1005          var filterHandle = new crosstalk.FilterHandle(ctGroup);
1006          filterHandle.on("change", handleFilter);
1007
1008          var handleSelection = function handleSelection(e) {
1009            if (!e.value || !e.value.length) {
1010              var groupKeys = Object.keys(ctg);
1011
1012              for (var i = 0; i < groupKeys.length; i++) {
1013                var key = groupKeys[i];
1014                var _layerInfo3 = _this._byStamp[ctg[key]];
1015
1016                _this._setOpacity(_layerInfo3, 1.0);
1017              }
1018            } else {
1019              var selectedKeys = {};
1020
1021              for (var _i3 = 0; _i3 < e.value.length; _i3++) {
1022                selectedKeys[e.value[_i3]] = true;
1023              }
1024
1025              var _groupKeys2 = Object.keys(ctg);
1026
1027              for (var _i4 = 0; _i4 < _groupKeys2.length; _i4++) {
1028                var _key2 = _groupKeys2[_i4];
1029                var _layerInfo4 = _this._byStamp[ctg[_key2]];
1030
1031                _this._setOpacity(_layerInfo4, selectedKeys[_groupKeys2[_i4]] ? 1.0 : 0.2);
1032              }
1033            }
1034          };
1035
1036          var selHandle = new crosstalk.SelectionHandle(ctGroup);
1037          selHandle.on("change", handleSelection);
1038          setTimeout(function () {
1039            handleFilter({
1040              value: filterHandle.filteredKeys
1041            });
1042            handleSelection({
1043              value: selHandle.value
1044            });
1045          }, 100);
1046        }
1047
1048        if (!ctg[ctKey]) ctg[ctKey] = [];
1049        ctg[ctKey].push(stamp);
1050      } // Add to container
1051
1052
1053      if (!layerInfo.hidden) container.addLayer(layer);
1054      return oldLayer;
1055    }
1056  }, {
1057    key: "brush",
1058    value: function brush(bounds, extraInfo) {
1059      var _this2 = this;
1060
1061      /* eslint-disable no-console */
1062      // For each Crosstalk group...
1063      Object.keys(this._byCrosstalkGroup).forEach(function (ctGroupName) {
1064        var ctg = _this2._byCrosstalkGroup[ctGroupName];
1065        var selection = []; // ...iterate over each Crosstalk key (each of which may have multiple
1066        // layers)...
1067
1068        Object.keys(ctg).forEach(function (ctKey) {
1069          // ...and for each layer...
1070          ctg[ctKey].forEach(function (stamp) {
1071            var layerInfo = _this2._byStamp[stamp]; // ...if it's something with a point...
1072
1073            if (layerInfo.layer.getLatLng) {
1074              // ... and it's inside the selection bounds...
1075              // TODO: Use pixel containment, not lat/lng containment
1076              if (bounds.contains(layerInfo.layer.getLatLng())) {
1077                // ...add the key to the selection.
1078                selection.push(ctKey);
1079              }
1080            }
1081          });
1082        });
1083        new global.crosstalk.SelectionHandle(ctGroupName).set(selection, extraInfo);
1084      });
1085    }
1086  }, {
1087    key: "unbrush",
1088    value: function unbrush(extraInfo) {
1089      Object.keys(this._byCrosstalkGroup).forEach(function (ctGroupName) {
1090        new global.crosstalk.SelectionHandle(ctGroupName).clear(extraInfo);
1091      });
1092    }
1093  }, {
1094    key: "_setVisibility",
1095    value: function _setVisibility(layerInfo, visible) {
1096      if (layerInfo.hidden ^ visible) {
1097        return;
1098      } else if (visible) {
1099        layerInfo.container.addLayer(layerInfo.layer);
1100        layerInfo.hidden = false;
1101      } else {
1102        layerInfo.container.removeLayer(layerInfo.layer);
1103        layerInfo.hidden = true;
1104      }
1105    }
1106  }, {
1107    key: "_setOpacity",
1108    value: function _setOpacity(layerInfo, opacity) {
1109      if (layerInfo.layer.setOpacity) {
1110        layerInfo.layer.setOpacity(opacity);
1111      } else if (layerInfo.layer.setStyle) {
1112        layerInfo.layer.setStyle({
1113          opacity: opacity * layerInfo.layer.options.origOpacity,
1114          fillOpacity: opacity * layerInfo.layer.options.origFillOpacity
1115        });
1116      }
1117    }
1118  }, {
1119    key: "getLayer",
1120    value: function getLayer(category, layerId) {
1121      return this._byLayerId[this._layerIdKey(category, layerId)];
1122    }
1123  }, {
1124    key: "removeLayer",
1125    value: function removeLayer(category, layerIds) {
1126      var _this3 = this;
1127
1128      // Find layer info
1129      _jquery2["default"].each((0, _util.asArray)(layerIds), function (i, layerId) {
1130        var layer = _this3._byLayerId[_this3._layerIdKey(category, layerId)];
1131
1132        if (layer) {
1133          _this3._removeLayer(layer);
1134        }
1135      });
1136    }
1137  }, {
1138    key: "clearLayers",
1139    value: function clearLayers(category) {
1140      var _this4 = this;
1141
1142      // Find all layers in _byCategory[category]
1143      var catTable = this._byCategory[category];
1144
1145      if (!catTable) {
1146        return false;
1147      } // Remove all layers. Make copy of keys to avoid mutating the collection
1148      // behind the iterator you're accessing.
1149
1150
1151      var stamps = [];
1152
1153      _jquery2["default"].each(catTable, function (k, v) {
1154        stamps.push(k);
1155      });
1156
1157      _jquery2["default"].each(stamps, function (i, stamp) {
1158        _this4._removeLayer(stamp);
1159      });
1160    }
1161  }, {
1162    key: "getLayerGroup",
1163    value: function getLayerGroup(group, ensureExists) {
1164      var g = this._groupContainers[group];
1165
1166      if (ensureExists && !g) {
1167        this._byGroup[group] = this._byGroup[group] || {};
1168        g = this._groupContainers[group] = _leaflet2["default"].featureGroup();
1169        g.groupname = group;
1170        g.addTo(this._map);
1171      }
1172
1173      return g;
1174    }
1175  }, {
1176    key: "getGroupNameFromLayerGroup",
1177    value: function getGroupNameFromLayerGroup(layerGroup) {
1178      return layerGroup.groupname;
1179    }
1180  }, {
1181    key: "getVisibleGroups",
1182    value: function getVisibleGroups() {
1183      var _this5 = this;
1184
1185      var result = [];
1186
1187      _jquery2["default"].each(this._groupContainers, function (k, v) {
1188        if (_this5._map.hasLayer(v)) {
1189          result.push(k);
1190        }
1191      });
1192
1193      return result;
1194    }
1195  }, {
1196    key: "getAllGroupNames",
1197    value: function getAllGroupNames() {
1198      var result = [];
1199
1200      _jquery2["default"].each(this._groupContainers, function (k, v) {
1201        result.push(k);
1202      });
1203
1204      return result;
1205    }
1206  }, {
1207    key: "clearGroup",
1208    value: function clearGroup(group) {
1209      var _this6 = this;
1210
1211      // Find all layers in _byGroup[group]
1212      var groupTable = this._byGroup[group];
1213
1214      if (!groupTable) {
1215        return false;
1216      } // Remove all layers. Make copy of keys to avoid mutating the collection
1217      // behind the iterator you're accessing.
1218
1219
1220      var stamps = [];
1221
1222      _jquery2["default"].each(groupTable, function (k, v) {
1223        stamps.push(k);
1224      });
1225
1226      _jquery2["default"].each(stamps, function (i, stamp) {
1227        _this6._removeLayer(stamp);
1228      });
1229    }
1230  }, {
1231    key: "clear",
1232    value: function clear() {
1233      function clearLayerGroup(key, layerGroup) {
1234        layerGroup.clearLayers();
1235      } // Clear all indices and layerGroups
1236
1237
1238      this._byGroup = {};
1239      this._byCategory = {};
1240      this._byLayerId = {};
1241      this._byStamp = {};
1242      this._byCrosstalkGroup = {};
1243
1244      _jquery2["default"].each(this._categoryContainers, clearLayerGroup);
1245
1246      this._categoryContainers = {};
1247
1248      _jquery2["default"].each(this._groupContainers, clearLayerGroup);
1249
1250      this._groupContainers = {};
1251    }
1252  }, {
1253    key: "_removeLayer",
1254    value: function _removeLayer(layer) {
1255      var stamp;
1256
1257      if (typeof layer === "string") {
1258        stamp = layer;
1259      } else {
1260        stamp = _leaflet2["default"].Util.stamp(layer);
1261      }
1262
1263      var layerInfo = this._byStamp[stamp];
1264
1265      if (!layerInfo) {
1266        return false;
1267      }
1268
1269      layerInfo.container.removeLayer(stamp);
1270
1271      if (typeof layerInfo.group === "string") {
1272        delete this._byGroup[layerInfo.group][stamp];
1273      }
1274
1275      if (typeof layerInfo.layerId === "string") {
1276        delete this._byLayerId[this._layerIdKey(layerInfo.category, layerInfo.layerId)];
1277      }
1278
1279      delete this._byCategory[layerInfo.category][stamp];
1280      delete this._byStamp[stamp];
1281
1282      if (layerInfo.ctGroup) {
1283        var ctGroup = this._byCrosstalkGroup[layerInfo.ctGroup];
1284        var layersForKey = ctGroup[layerInfo.ctKey];
1285        var idx = layersForKey ? layersForKey.indexOf(stamp) : -1;
1286
1287        if (idx >= 0) {
1288          if (layersForKey.length === 1) {
1289            delete ctGroup[layerInfo.ctKey];
1290          } else {
1291            layersForKey.splice(idx, 1);
1292          }
1293        }
1294      }
1295    }
1296  }, {
1297    key: "_layerIdKey",
1298    value: function _layerIdKey(category, layerId) {
1299      return category + "\n" + layerId;
1300    }
1301  }]);
1302
1303  return LayerManager;
1304}();
1305
1306exports["default"] = LayerManager;
1307
1308
1309}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1310},{"./global/jquery":9,"./global/leaflet":10,"./util":17}],15:[function(require,module,exports){
1311(function (global){(function (){
1312"use strict";
1313
1314Object.defineProperty(exports, "__esModule", {
1315  value: true
1316});
1317
1318var _jquery = require("./global/jquery");
1319
1320var _jquery2 = _interopRequireDefault(_jquery);
1321
1322var _leaflet = require("./global/leaflet");
1323
1324var _leaflet2 = _interopRequireDefault(_leaflet);
1325
1326var _shiny = require("./global/shiny");
1327
1328var _shiny2 = _interopRequireDefault(_shiny);
1329
1330var _htmlwidgets = require("./global/htmlwidgets");
1331
1332var _htmlwidgets2 = _interopRequireDefault(_htmlwidgets);
1333
1334var _util = require("./util");
1335
1336var _crs_utils = require("./crs_utils");
1337
1338var _dataframe = require("./dataframe");
1339
1340var _dataframe2 = _interopRequireDefault(_dataframe);
1341
1342var _clusterLayerStore = require("./cluster-layer-store");
1343
1344var _clusterLayerStore2 = _interopRequireDefault(_clusterLayerStore);
1345
1346var _mipmapper = require("./mipmapper");
1347
1348var _mipmapper2 = _interopRequireDefault(_mipmapper);
1349
1350function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
1351
1352var methods = {};
1353exports["default"] = methods;
1354
1355function mouseHandler(mapId, layerId, group, eventName, extraInfo) {
1356  return function (e) {
1357    if (!_htmlwidgets2["default"].shinyMode) return;
1358    var latLng = e.target.getLatLng ? e.target.getLatLng() : e.latlng;
1359
1360    if (latLng) {
1361      // retrieve only lat, lon values to remove prototype
1362      //   and extra parameters added by 3rd party modules
1363      // these objects are for json serialization, not javascript
1364      var latLngVal = _leaflet2["default"].latLng(latLng); // make sure it has consistent shape
1365
1366
1367      latLng = {
1368        lat: latLngVal.lat,
1369        lng: latLngVal.lng
1370      };
1371    }
1372
1373    var eventInfo = _jquery2["default"].extend({
1374      id: layerId,
1375      ".nonce": Math.random() // force reactivity
1376
1377    }, group !== null ? {
1378      group: group
1379    } : null, latLng, extraInfo);
1380
1381    _shiny2["default"].onInputChange(mapId + "_" + eventName, eventInfo);
1382  };
1383}
1384
1385methods.mouseHandler = mouseHandler;
1386
1387methods.clearGroup = function (group) {
1388  var _this = this;
1389
1390  _jquery2["default"].each((0, _util.asArray)(group), function (i, v) {
1391    _this.layerManager.clearGroup(v);
1392  });
1393};
1394
1395methods.setView = function (center, zoom, options) {
1396  this.setView(center, zoom, options);
1397};
1398
1399methods.fitBounds = function (lat1, lng1, lat2, lng2, options) {
1400  this.fitBounds([[lat1, lng1], [lat2, lng2]], options);
1401};
1402
1403methods.flyTo = function (center, zoom, options) {
1404  this.flyTo(center, zoom, options);
1405};
1406
1407methods.flyToBounds = function (lat1, lng1, lat2, lng2, options) {
1408  this.flyToBounds([[lat1, lng1], [lat2, lng2]], options);
1409};
1410
1411methods.setMaxBounds = function (lat1, lng1, lat2, lng2) {
1412  this.setMaxBounds([[lat1, lng1], [lat2, lng2]]);
1413};
1414
1415methods.addPopups = function (lat, lng, popup, layerId, group, options) {
1416  var _this2 = this;
1417
1418  var df = new _dataframe2["default"]().col("lat", lat).col("lng", lng).col("popup", popup).col("layerId", layerId).col("group", group).cbind(options);
1419
1420  var _loop = function _loop(i) {
1421    if (_jquery2["default"].isNumeric(df.get(i, "lat")) && _jquery2["default"].isNumeric(df.get(i, "lng"))) {
1422      (function () {
1423        var popup = _leaflet2["default"].popup(df.get(i)).setLatLng([df.get(i, "lat"), df.get(i, "lng")]).setContent(df.get(i, "popup"));
1424
1425        var thisId = df.get(i, "layerId");
1426        var thisGroup = df.get(i, "group");
1427        this.layerManager.addLayer(popup, "popup", thisId, thisGroup);
1428      }).call(_this2);
1429    }
1430  };
1431
1432  for (var i = 0; i < df.nrow(); i++) {
1433    _loop(i);
1434  }
1435};
1436
1437methods.removePopup = function (layerId) {
1438  this.layerManager.removeLayer("popup", layerId);
1439};
1440
1441methods.clearPopups = function () {
1442  this.layerManager.clearLayers("popup");
1443};
1444
1445methods.addTiles = function (urlTemplate, layerId, group, options) {
1446  this.layerManager.addLayer(_leaflet2["default"].tileLayer(urlTemplate, options), "tile", layerId, group);
1447};
1448
1449methods.removeTiles = function (layerId) {
1450  this.layerManager.removeLayer("tile", layerId);
1451};
1452
1453methods.clearTiles = function () {
1454  this.layerManager.clearLayers("tile");
1455};
1456
1457methods.addWMSTiles = function (baseUrl, layerId, group, options) {
1458  if (options && options.crs) {
1459    options.crs = (0, _crs_utils.getCRS)(options.crs);
1460  }
1461
1462  this.layerManager.addLayer(_leaflet2["default"].tileLayer.wms(baseUrl, options), "tile", layerId, group);
1463}; // Given:
1464//   {data: ["a", "b", "c"], index: [0, 1, 0, 2]}
1465// returns:
1466//   ["a", "b", "a", "c"]
1467
1468
1469function unpackStrings(iconset) {
1470  if (!iconset) {
1471    return iconset;
1472  }
1473
1474  if (typeof iconset.index === "undefined") {
1475    return iconset;
1476  }
1477
1478  iconset.data = (0, _util.asArray)(iconset.data);
1479  iconset.index = (0, _util.asArray)(iconset.index);
1480  return _jquery2["default"].map(iconset.index, function (e, i) {
1481    return iconset.data[e];
1482  });
1483}
1484
1485function addMarkers(map, df, group, clusterOptions, clusterId, markerFunc) {
1486  (function () {
1487    var _this3 = this;
1488
1489    var clusterGroup = this.layerManager.getLayer("cluster", clusterId),
1490        cluster = clusterOptions !== null;
1491
1492    if (cluster && !clusterGroup) {
1493      clusterGroup = _leaflet2["default"].markerClusterGroup.layerSupport(clusterOptions);
1494
1495      if (clusterOptions.freezeAtZoom) {
1496        var freezeAtZoom = clusterOptions.freezeAtZoom;
1497        delete clusterOptions.freezeAtZoom;
1498        clusterGroup.freezeAtZoom(freezeAtZoom);
1499      }
1500
1501      clusterGroup.clusterLayerStore = new _clusterLayerStore2["default"](clusterGroup);
1502    }
1503
1504    var extraInfo = cluster ? {
1505      clusterId: clusterId
1506    } : {};
1507
1508    var _loop2 = function _loop2(i) {
1509      if (_jquery2["default"].isNumeric(df.get(i, "lat")) && _jquery2["default"].isNumeric(df.get(i, "lng"))) {
1510        (function () {
1511          var marker = markerFunc(df, i);
1512          var thisId = df.get(i, "layerId");
1513          var thisGroup = cluster ? null : df.get(i, "group");
1514
1515          if (cluster) {
1516            clusterGroup.clusterLayerStore.add(marker, thisId);
1517          } else {
1518            this.layerManager.addLayer(marker, "marker", thisId, thisGroup, df.get(i, "ctGroup", true), df.get(i, "ctKey", true));
1519          }
1520
1521          var popup = df.get(i, "popup");
1522          var popupOptions = df.get(i, "popupOptions");
1523
1524          if (popup !== null) {
1525            if (popupOptions !== null) {
1526              marker.bindPopup(popup, popupOptions);
1527            } else {
1528              marker.bindPopup(popup);
1529            }
1530          }
1531
1532          var label = df.get(i, "label");
1533          var labelOptions = df.get(i, "labelOptions");
1534
1535          if (label !== null) {
1536            if (labelOptions !== null) {
1537              if (labelOptions.permanent) {
1538                marker.bindTooltip(label, labelOptions).openTooltip();
1539              } else {
1540                marker.bindTooltip(label, labelOptions);
1541              }
1542            } else {
1543              marker.bindTooltip(label);
1544            }
1545          }
1546
1547          marker.on("click", mouseHandler(this.id, thisId, thisGroup, "marker_click", extraInfo), this);
1548          marker.on("mouseover", mouseHandler(this.id, thisId, thisGroup, "marker_mouseover", extraInfo), this);
1549          marker.on("mouseout", mouseHandler(this.id, thisId, thisGroup, "marker_mouseout", extraInfo), this);
1550          marker.on("dragend", mouseHandler(this.id, thisId, thisGroup, "marker_dragend", extraInfo), this);
1551        }).call(_this3);
1552      }
1553    };
1554
1555    for (var i = 0; i < df.nrow(); i++) {
1556      _loop2(i);
1557    }
1558
1559    if (cluster) {
1560      this.layerManager.addLayer(clusterGroup, "cluster", clusterId, group);
1561    }
1562  }).call(map);
1563}
1564
1565methods.addGenericMarkers = addMarkers;
1566
1567methods.addMarkers = function (lat, lng, icon, layerId, group, options, popup, popupOptions, clusterOptions, clusterId, label, labelOptions, crosstalkOptions) {
1568  var icondf;
1569  var getIcon;
1570
1571  if (icon) {
1572    // Unpack icons
1573    icon.iconUrl = unpackStrings(icon.iconUrl);
1574    icon.iconRetinaUrl = unpackStrings(icon.iconRetinaUrl);
1575    icon.shadowUrl = unpackStrings(icon.shadowUrl);
1576    icon.shadowRetinaUrl = unpackStrings(icon.shadowRetinaUrl); // This cbinds the icon URLs and any other icon options; they're all
1577    // present on the icon object.
1578
1579    icondf = new _dataframe2["default"]().cbind(icon); // Constructs an icon from a specified row of the icon dataframe.
1580
1581    getIcon = function getIcon(i) {
1582      var opts = icondf.get(i);
1583
1584      if (!opts.iconUrl) {
1585        return new _leaflet2["default"].Icon.Default();
1586      } // Composite options (like points or sizes) are passed from R with each
1587      // individual component as its own option. We need to combine them now
1588      // into their composite form.
1589
1590
1591      if (opts.iconWidth) {
1592        opts.iconSize = [opts.iconWidth, opts.iconHeight];
1593      }
1594
1595      if (opts.shadowWidth) {
1596        opts.shadowSize = [opts.shadowWidth, opts.shadowHeight];
1597      }
1598
1599      if (opts.iconAnchorX) {
1600        opts.iconAnchor = [opts.iconAnchorX, opts.iconAnchorY];
1601      }
1602
1603      if (opts.shadowAnchorX) {
1604        opts.shadowAnchor = [opts.shadowAnchorX, opts.shadowAnchorY];
1605      }
1606
1607      if (opts.popupAnchorX) {
1608        opts.popupAnchor = [opts.popupAnchorX, opts.popupAnchorY];
1609      }
1610
1611      return new _leaflet2["default"].Icon(opts);
1612    };
1613  }
1614
1615  if (!(_jquery2["default"].isEmptyObject(lat) || _jquery2["default"].isEmptyObject(lng)) || _jquery2["default"].isNumeric(lat) && _jquery2["default"].isNumeric(lng)) {
1616    var df = new _dataframe2["default"]().col("lat", lat).col("lng", lng).col("layerId", layerId).col("group", group).col("popup", popup).col("popupOptions", popupOptions).col("label", label).col("labelOptions", labelOptions).cbind(options).cbind(crosstalkOptions || {});
1617    if (icon) icondf.effectiveLength = df.nrow();
1618    addMarkers(this, df, group, clusterOptions, clusterId, function (df, i) {
1619      var options = df.get(i);
1620      if (icon) options.icon = getIcon(i);
1621      return _leaflet2["default"].marker([df.get(i, "lat"), df.get(i, "lng")], options);
1622    });
1623  }
1624};
1625
1626methods.addAwesomeMarkers = function (lat, lng, icon, layerId, group, options, popup, popupOptions, clusterOptions, clusterId, label, labelOptions, crosstalkOptions) {
1627  var icondf;
1628  var getIcon;
1629
1630  if (icon) {
1631    // This cbinds the icon URLs and any other icon options; they're all
1632    // present on the icon object.
1633    icondf = new _dataframe2["default"]().cbind(icon); // Constructs an icon from a specified row of the icon dataframe.
1634
1635    getIcon = function getIcon(i) {
1636      var opts = icondf.get(i);
1637
1638      if (!opts) {
1639        return new _leaflet2["default"].AwesomeMarkers.icon();
1640      }
1641
1642      if (opts.squareMarker) {
1643        opts.className = "awesome-marker awesome-marker-square";
1644      }
1645
1646      return new _leaflet2["default"].AwesomeMarkers.icon(opts);
1647    };
1648  }
1649
1650  if (!(_jquery2["default"].isEmptyObject(lat) || _jquery2["default"].isEmptyObject(lng)) || _jquery2["default"].isNumeric(lat) && _jquery2["default"].isNumeric(lng)) {
1651    var df = new _dataframe2["default"]().col("lat", lat).col("lng", lng).col("layerId", layerId).col("group", group).col("popup", popup).col("popupOptions", popupOptions).col("label", label).col("labelOptions", labelOptions).cbind(options).cbind(crosstalkOptions || {});
1652    if (icon) icondf.effectiveLength = df.nrow();
1653    addMarkers(this, df, group, clusterOptions, clusterId, function (df, i) {
1654      var options = df.get(i);
1655      if (icon) options.icon = getIcon(i);
1656      return _leaflet2["default"].marker([df.get(i, "lat"), df.get(i, "lng")], options);
1657    });
1658  }
1659};
1660
1661function addLayers(map, category, df, layerFunc) {
1662  var _loop3 = function _loop3(i) {
1663    (function () {
1664      var layer = layerFunc(df, i);
1665
1666      if (!_jquery2["default"].isEmptyObject(layer)) {
1667        var thisId = df.get(i, "layerId");
1668        var thisGroup = df.get(i, "group");
1669        this.layerManager.addLayer(layer, category, thisId, thisGroup, df.get(i, "ctGroup", true), df.get(i, "ctKey", true));
1670
1671        if (layer.bindPopup) {
1672          var popup = df.get(i, "popup");
1673          var popupOptions = df.get(i, "popupOptions");
1674
1675          if (popup !== null) {
1676            if (popupOptions !== null) {
1677              layer.bindPopup(popup, popupOptions);
1678            } else {
1679              layer.bindPopup(popup);
1680            }
1681          }
1682        }
1683
1684        if (layer.bindTooltip) {
1685          var label = df.get(i, "label");
1686          var labelOptions = df.get(i, "labelOptions");
1687
1688          if (label !== null) {
1689            if (labelOptions !== null) {
1690              layer.bindTooltip(label, labelOptions);
1691            } else {
1692              layer.bindTooltip(label);
1693            }
1694          }
1695        }
1696
1697        layer.on("click", mouseHandler(this.id, thisId, thisGroup, category + "_click"), this);
1698        layer.on("mouseover", mouseHandler(this.id, thisId, thisGroup, category + "_mouseover"), this);
1699        layer.on("mouseout", mouseHandler(this.id, thisId, thisGroup, category + "_mouseout"), this);
1700        var highlightStyle = df.get(i, "highlightOptions");
1701
1702        if (!_jquery2["default"].isEmptyObject(highlightStyle)) {
1703          var defaultStyle = {};
1704
1705          _jquery2["default"].each(highlightStyle, function (k, v) {
1706            if (k != "bringToFront" && k != "sendToBack") {
1707              if (df.get(i, k)) {
1708                defaultStyle[k] = df.get(i, k);
1709              }
1710            }
1711          });
1712
1713          layer.on("mouseover", function (e) {
1714            this.setStyle(highlightStyle);
1715
1716            if (highlightStyle.bringToFront) {
1717              this.bringToFront();
1718            }
1719          });
1720          layer.on("mouseout", function (e) {
1721            this.setStyle(defaultStyle);
1722
1723            if (highlightStyle.sendToBack) {
1724              this.bringToBack();
1725            }
1726          });
1727        }
1728      }
1729    }).call(map);
1730  };
1731
1732  for (var i = 0; i < df.nrow(); i++) {
1733    _loop3(i);
1734  }
1735}
1736
1737methods.addGenericLayers = addLayers;
1738
1739methods.addCircles = function (lat, lng, radius, layerId, group, options, popup, popupOptions, label, labelOptions, highlightOptions, crosstalkOptions) {
1740  if (!(_jquery2["default"].isEmptyObject(lat) || _jquery2["default"].isEmptyObject(lng)) || _jquery2["default"].isNumeric(lat) && _jquery2["default"].isNumeric(lng)) {
1741    var df = new _dataframe2["default"]().col("lat", lat).col("lng", lng).col("radius", radius).col("layerId", layerId).col("group", group).col("popup", popup).col("popupOptions", popupOptions).col("label", label).col("labelOptions", labelOptions).col("highlightOptions", highlightOptions).cbind(options).cbind(crosstalkOptions || {});
1742    addLayers(this, "shape", df, function (df, i) {
1743      if (_jquery2["default"].isNumeric(df.get(i, "lat")) && _jquery2["default"].isNumeric(df.get(i, "lng")) && _jquery2["default"].isNumeric(df.get(i, "radius"))) {
1744        return _leaflet2["default"].circle([df.get(i, "lat"), df.get(i, "lng")], df.get(i, "radius"), df.get(i));
1745      } else {
1746        return null;
1747      }
1748    });
1749  }
1750};
1751
1752methods.addCircleMarkers = function (lat, lng, radius, layerId, group, options, clusterOptions, clusterId, popup, popupOptions, label, labelOptions, crosstalkOptions) {
1753  if (!(_jquery2["default"].isEmptyObject(lat) || _jquery2["default"].isEmptyObject(lng)) || _jquery2["default"].isNumeric(lat) && _jquery2["default"].isNumeric(lng)) {
1754    var df = new _dataframe2["default"]().col("lat", lat).col("lng", lng).col("radius", radius).col("layerId", layerId).col("group", group).col("popup", popup).col("popupOptions", popupOptions).col("label", label).col("labelOptions", labelOptions).cbind(crosstalkOptions || {}).cbind(options);
1755    addMarkers(this, df, group, clusterOptions, clusterId, function (df, i) {
1756      return _leaflet2["default"].circleMarker([df.get(i, "lat"), df.get(i, "lng")], df.get(i));
1757    });
1758  }
1759};
1760/*
1761 * @param lat Array of arrays of latitude coordinates for polylines
1762 * @param lng Array of arrays of longitude coordinates for polylines
1763 */
1764
1765
1766methods.addPolylines = function (polygons, layerId, group, options, popup, popupOptions, label, labelOptions, highlightOptions) {
1767  if (polygons.length > 0) {
1768    var df = new _dataframe2["default"]().col("shapes", polygons).col("layerId", layerId).col("group", group).col("popup", popup).col("popupOptions", popupOptions).col("label", label).col("labelOptions", labelOptions).col("highlightOptions", highlightOptions).cbind(options);
1769    addLayers(this, "shape", df, function (df, i) {
1770      var shapes = df.get(i, "shapes");
1771      shapes = shapes.map(function (shape) {
1772        return _htmlwidgets2["default"].dataframeToD3(shape[0]);
1773      });
1774
1775      if (shapes.length > 1) {
1776        return _leaflet2["default"].polyline(shapes, df.get(i));
1777      } else {
1778        return _leaflet2["default"].polyline(shapes[0], df.get(i));
1779      }
1780    });
1781  }
1782};
1783
1784methods.removeMarker = function (layerId) {
1785  this.layerManager.removeLayer("marker", layerId);
1786};
1787
1788methods.clearMarkers = function () {
1789  this.layerManager.clearLayers("marker");
1790};
1791
1792methods.removeMarkerCluster = function (layerId) {
1793  this.layerManager.removeLayer("cluster", layerId);
1794};
1795
1796methods.removeMarkerFromCluster = function (layerId, clusterId) {
1797  var cluster = this.layerManager.getLayer("cluster", clusterId);
1798  if (!cluster) return;
1799  cluster.clusterLayerStore.remove(layerId);
1800};
1801
1802methods.clearMarkerClusters = function () {
1803  this.layerManager.clearLayers("cluster");
1804};
1805
1806methods.removeShape = function (layerId) {
1807  this.layerManager.removeLayer("shape", layerId);
1808};
1809
1810methods.clearShapes = function () {
1811  this.layerManager.clearLayers("shape");
1812};
1813
1814methods.addRectangles = function (lat1, lng1, lat2, lng2, layerId, group, options, popup, popupOptions, label, labelOptions, highlightOptions) {
1815  var df = new _dataframe2["default"]().col("lat1", lat1).col("lng1", lng1).col("lat2", lat2).col("lng2", lng2).col("layerId", layerId).col("group", group).col("popup", popup).col("popupOptions", popupOptions).col("label", label).col("labelOptions", labelOptions).col("highlightOptions", highlightOptions).cbind(options);
1816  addLayers(this, "shape", df, function (df, i) {
1817    if (_jquery2["default"].isNumeric(df.get(i, "lat1")) && _jquery2["default"].isNumeric(df.get(i, "lng1")) && _jquery2["default"].isNumeric(df.get(i, "lat2")) && _jquery2["default"].isNumeric(df.get(i, "lng2"))) {
1818      return _leaflet2["default"].rectangle([[df.get(i, "lat1"), df.get(i, "lng1")], [df.get(i, "lat2"), df.get(i, "lng2")]], df.get(i));
1819    } else {
1820      return null;
1821    }
1822  });
1823};
1824/*
1825 * @param lat Array of arrays of latitude coordinates for polygons
1826 * @param lng Array of arrays of longitude coordinates for polygons
1827 */
1828
1829
1830methods.addPolygons = function (polygons, layerId, group, options, popup, popupOptions, label, labelOptions, highlightOptions) {
1831  if (polygons.length > 0) {
1832    var df = new _dataframe2["default"]().col("shapes", polygons).col("layerId", layerId).col("group", group).col("popup", popup).col("popupOptions", popupOptions).col("label", label).col("labelOptions", labelOptions).col("highlightOptions", highlightOptions).cbind(options);
1833    addLayers(this, "shape", df, function (df, i) {
1834      // This code used to use L.multiPolygon, but that caused
1835      // double-click on a multipolygon to fail to zoom in on the
1836      // map. Surprisingly, putting all the rings in a single
1837      // polygon seems to still work; complicated multipolygons
1838      // are still rendered correctly.
1839      var shapes = df.get(i, "shapes").map(function (polygon) {
1840        return polygon.map(_htmlwidgets2["default"].dataframeToD3);
1841      }).reduce(function (acc, val) {
1842        return acc.concat(val);
1843      }, []);
1844      return _leaflet2["default"].polygon(shapes, df.get(i));
1845    });
1846  }
1847};
1848
1849methods.addGeoJSON = function (data, layerId, group, style) {
1850  // This time, self is actually needed because the callbacks below need
1851  // to access both the inner and outer senses of "this"
1852  var self = this;
1853
1854  if (typeof data === "string") {
1855    data = JSON.parse(data);
1856  }
1857
1858  var globalStyle = _jquery2["default"].extend({}, style, data.style || {});
1859
1860  var gjlayer = _leaflet2["default"].geoJson(data, {
1861    style: function style(feature) {
1862      if (feature.style || feature.properties.style) {
1863        return _jquery2["default"].extend({}, globalStyle, feature.style, feature.properties.style);
1864      } else {
1865        return globalStyle;
1866      }
1867    },
1868    onEachFeature: function onEachFeature(feature, layer) {
1869      var extraInfo = {
1870        featureId: feature.id,
1871        properties: feature.properties
1872      };
1873      var popup = feature.properties ? feature.properties.popup : null;
1874      if (typeof popup !== "undefined" && popup !== null) layer.bindPopup(popup);
1875      layer.on("click", mouseHandler(self.id, layerId, group, "geojson_click", extraInfo), this);
1876      layer.on("mouseover", mouseHandler(self.id, layerId, group, "geojson_mouseover", extraInfo), this);
1877      layer.on("mouseout", mouseHandler(self.id, layerId, group, "geojson_mouseout", extraInfo), this);
1878    }
1879  });
1880
1881  this.layerManager.addLayer(gjlayer, "geojson", layerId, group);
1882};
1883
1884methods.removeGeoJSON = function (layerId) {
1885  this.layerManager.removeLayer("geojson", layerId);
1886};
1887
1888methods.clearGeoJSON = function () {
1889  this.layerManager.clearLayers("geojson");
1890};
1891
1892methods.addTopoJSON = function (data, layerId, group, style) {
1893  // This time, self is actually needed because the callbacks below need
1894  // to access both the inner and outer senses of "this"
1895  var self = this;
1896
1897  if (typeof data === "string") {
1898    data = JSON.parse(data);
1899  }
1900
1901  var globalStyle = _jquery2["default"].extend({}, style, data.style || {});
1902
1903  var gjlayer = _leaflet2["default"].geoJson(null, {
1904    style: function style(feature) {
1905      if (feature.style || feature.properties.style) {
1906        return _jquery2["default"].extend({}, globalStyle, feature.style, feature.properties.style);
1907      } else {
1908        return globalStyle;
1909      }
1910    },
1911    onEachFeature: function onEachFeature(feature, layer) {
1912      var extraInfo = {
1913        featureId: feature.id,
1914        properties: feature.properties
1915      };
1916      var popup = feature.properties.popup;
1917      if (typeof popup !== "undefined" && popup !== null) layer.bindPopup(popup);
1918      layer.on("click", mouseHandler(self.id, layerId, group, "topojson_click", extraInfo), this);
1919      layer.on("mouseover", mouseHandler(self.id, layerId, group, "topojson_mouseover", extraInfo), this);
1920      layer.on("mouseout", mouseHandler(self.id, layerId, group, "topojson_mouseout", extraInfo), this);
1921    }
1922  });
1923
1924  global.omnivore.topojson.parse(data, null, gjlayer);
1925  this.layerManager.addLayer(gjlayer, "topojson", layerId, group);
1926};
1927
1928methods.removeTopoJSON = function (layerId) {
1929  this.layerManager.removeLayer("topojson", layerId);
1930};
1931
1932methods.clearTopoJSON = function () {
1933  this.layerManager.clearLayers("topojson");
1934};
1935
1936methods.addControl = function (html, position, layerId, classes) {
1937  function onAdd(map) {
1938    var div = _leaflet2["default"].DomUtil.create("div", classes);
1939
1940    if (typeof layerId !== "undefined" && layerId !== null) {
1941      div.setAttribute("id", layerId);
1942    }
1943
1944    this._div = div; // It's possible for window.Shiny to be true but Shiny.initializeInputs to
1945    // not be, when a static leaflet widget is included as part of the shiny
1946    // UI directly (not through leafletOutput or uiOutput). In this case we
1947    // don't do the normal Shiny stuff as that will all happen when Shiny
1948    // itself loads and binds the entire doc.
1949
1950    if (window.Shiny && _shiny2["default"].initializeInputs) {
1951      _shiny2["default"].renderHtml(html, this._div);
1952
1953      _shiny2["default"].initializeInputs(this._div);
1954
1955      _shiny2["default"].bindAll(this._div);
1956    } else {
1957      this._div.innerHTML = html;
1958    }
1959
1960    return this._div;
1961  }
1962
1963  function onRemove(map) {
1964    if (window.Shiny && _shiny2["default"].unbindAll) {
1965      _shiny2["default"].unbindAll(this._div);
1966    }
1967  }
1968
1969  var Control = _leaflet2["default"].Control.extend({
1970    options: {
1971      position: position
1972    },
1973    onAdd: onAdd,
1974    onRemove: onRemove
1975  });
1976
1977  this.controls.add(new Control(), layerId, html);
1978};
1979
1980methods.addCustomControl = function (control, layerId) {
1981  this.controls.add(control, layerId);
1982};
1983
1984methods.removeControl = function (layerId) {
1985  this.controls.remove(layerId);
1986};
1987
1988methods.getControl = function (layerId) {
1989  this.controls.get(layerId);
1990};
1991
1992methods.clearControls = function () {
1993  this.controls.clear();
1994};
1995
1996methods.addLegend = function (options) {
1997  var legend = _leaflet2["default"].control({
1998    position: options.position
1999  });
2000
2001  var gradSpan;
2002
2003  legend.onAdd = function (map) {
2004    var div = _leaflet2["default"].DomUtil.create("div", options.className),
2005        colors = options.colors,
2006        labels = options.labels,
2007        legendHTML = "";
2008
2009    if (options.type === "numeric") {
2010      // # Formatting constants.
2011      var singleBinHeight = 20; // The distance between tick marks, in px
2012
2013      var vMargin = 8; // If 1st tick mark starts at top of gradient, how
2014      // many extra px are needed for the top half of the
2015      // 1st label? (ditto for last tick mark/label)
2016
2017      var tickWidth = 4; // How wide should tick marks be, in px?
2018
2019      var labelPadding = 6; // How much distance to reserve for tick mark?
2020      // (Must be >= tickWidth)
2021      // # Derived formatting parameters.
2022      // What's the height of a single bin, in percentage (of gradient height)?
2023      // It might not just be 1/(n-1), if the gradient extends past the tick
2024      // marks (which can be the case for pretty cut points).
2025
2026      var singleBinPct = (options.extra.p_n - options.extra.p_1) / (labels.length - 1); // Each bin is `singleBinHeight` high. How tall is the gradient?
2027
2028      var totalHeight = 1 / singleBinPct * singleBinHeight + 1; // How far should the first tick be shifted down, relative to the top
2029      // of the gradient?
2030
2031      var tickOffset = singleBinHeight / singleBinPct * options.extra.p_1;
2032      gradSpan = (0, _jquery2["default"])("<span/>").css({
2033        "background": "linear-gradient(" + colors + ")",
2034        "opacity": options.opacity,
2035        "height": totalHeight + "px",
2036        "width": "18px",
2037        "display": "block",
2038        "margin-top": vMargin + "px"
2039      });
2040      var leftDiv = (0, _jquery2["default"])("<div/>").css("float", "left"),
2041          rightDiv = (0, _jquery2["default"])("<div/>").css("float", "left");
2042      leftDiv.append(gradSpan);
2043      (0, _jquery2["default"])(div).append(leftDiv).append(rightDiv).append((0, _jquery2["default"])("<br>")); // Have to attach the div to the body at this early point, so that the
2044      // svg text getComputedTextLength() actually works, below.
2045
2046      document.body.appendChild(div);
2047      var ns = "http://www.w3.org/2000/svg";
2048      var svg = document.createElementNS(ns, "svg");
2049      rightDiv.append(svg);
2050      var g = document.createElementNS(ns, "g");
2051      (0, _jquery2["default"])(g).attr("transform", "translate(0, " + vMargin + ")");
2052      svg.appendChild(g); // max label width needed to set width of svg, and right-justify text
2053
2054      var maxLblWidth = 0; // Create tick marks and labels
2055
2056      _jquery2["default"].each(labels, function (i, label) {
2057        var y = tickOffset + i * singleBinHeight + 0.5;
2058        var thisLabel = document.createElementNS(ns, "text");
2059        (0, _jquery2["default"])(thisLabel).text(labels[i]).attr("y", y).attr("dx", labelPadding).attr("dy", "0.5ex");
2060        g.appendChild(thisLabel);
2061        maxLblWidth = Math.max(maxLblWidth, thisLabel.getComputedTextLength());
2062        var thisTick = document.createElementNS(ns, "line");
2063        (0, _jquery2["default"])(thisTick).attr("x1", 0).attr("x2", tickWidth).attr("y1", y).attr("y2", y).attr("stroke-width", 1);
2064        g.appendChild(thisTick);
2065      }); // Now that we know the max label width, we can right-justify
2066
2067
2068      (0, _jquery2["default"])(svg).find("text").attr("dx", labelPadding + maxLblWidth).attr("text-anchor", "end"); // Final size for <svg>
2069
2070      (0, _jquery2["default"])(svg).css({
2071        width: maxLblWidth + labelPadding + "px",
2072        height: totalHeight + vMargin * 2 + "px"
2073      });
2074
2075      if (options.na_color && _jquery2["default"].inArray(options.na_label, labels) < 0) {
2076        (0, _jquery2["default"])(div).append("<div><i style=\"" + "background:" + options.na_color + ";opacity:" + options.opacity + ";margin-right:" + labelPadding + "px" + ";\"></i>" + options.na_label + "</div>");
2077      }
2078    } else {
2079      if (options.na_color && _jquery2["default"].inArray(options.na_label, labels) < 0) {
2080        colors.push(options.na_color);
2081        labels.push(options.na_label);
2082      }
2083
2084      for (var i = 0; i < colors.length; i++) {
2085        legendHTML += "<i style=\"background:" + colors[i] + ";opacity:" + options.opacity + "\"></i> " + labels[i] + "<br>";
2086      }
2087
2088      div.innerHTML = legendHTML;
2089    }
2090
2091    if (options.title) (0, _jquery2["default"])(div).prepend("<div style=\"margin-bottom:3px\"><strong>" + options.title + "</strong></div>");
2092    return div;
2093  };
2094
2095  if (options.group) {
2096    // Auto generate a layerID if not provided
2097    if (!options.layerId) {
2098      options.layerId = _leaflet2["default"].Util.stamp(legend);
2099    }
2100
2101    var map = this;
2102    map.on("overlayadd", function (e) {
2103      if (e.name === options.group) {
2104        map.controls.add(legend, options.layerId);
2105      }
2106    });
2107    map.on("overlayremove", function (e) {
2108      if (e.name === options.group) {
2109        map.controls.remove(options.layerId);
2110      }
2111    });
2112    map.on("groupadd", function (e) {
2113      if (e.name === options.group) {
2114        map.controls.add(legend, options.layerId);
2115      }
2116    });
2117    map.on("groupremove", function (e) {
2118      if (e.name === options.group) {
2119        map.controls.remove(options.layerId);
2120      }
2121    });
2122  }
2123
2124  this.controls.add(legend, options.layerId);
2125};
2126
2127methods.addLayersControl = function (baseGroups, overlayGroups, options) {
2128  var _this4 = this;
2129
2130  // Only allow one layers control at a time
2131  methods.removeLayersControl.call(this);
2132  var firstLayer = true;
2133  var base = {};
2134
2135  _jquery2["default"].each((0, _util.asArray)(baseGroups), function (i, g) {
2136    var layer = _this4.layerManager.getLayerGroup(g, true);
2137
2138    if (layer) {
2139      base[g] = layer; // Check if >1 base layers are visible; if so, hide all but the first one
2140
2141      if (_this4.hasLayer(layer)) {
2142        if (firstLayer) {
2143          firstLayer = false;
2144        } else {
2145          _this4.removeLayer(layer);
2146        }
2147      }
2148    }
2149  });
2150
2151  var overlay = {};
2152
2153  _jquery2["default"].each((0, _util.asArray)(overlayGroups), function (i, g) {
2154    var layer = _this4.layerManager.getLayerGroup(g, true);
2155
2156    if (layer) {
2157      overlay[g] = layer;
2158    }
2159  });
2160
2161  this.currentLayersControl = _leaflet2["default"].control.layers(base, overlay, options);
2162  this.addControl(this.currentLayersControl);
2163};
2164
2165methods.removeLayersControl = function () {
2166  if (this.currentLayersControl) {
2167    this.removeControl(this.currentLayersControl);
2168    this.currentLayersControl = null;
2169  }
2170};
2171
2172methods.addScaleBar = function (options) {
2173  // Only allow one scale bar at a time
2174  methods.removeScaleBar.call(this);
2175
2176  var scaleBar = _leaflet2["default"].control.scale(options).addTo(this);
2177
2178  this.currentScaleBar = scaleBar;
2179};
2180
2181methods.removeScaleBar = function () {
2182  if (this.currentScaleBar) {
2183    this.currentScaleBar.remove();
2184    this.currentScaleBar = null;
2185  }
2186};
2187
2188methods.hideGroup = function (group) {
2189  var _this5 = this;
2190
2191  _jquery2["default"].each((0, _util.asArray)(group), function (i, g) {
2192    var layer = _this5.layerManager.getLayerGroup(g, true);
2193
2194    if (layer) {
2195      _this5.removeLayer(layer);
2196    }
2197  });
2198};
2199
2200methods.showGroup = function (group) {
2201  var _this6 = this;
2202
2203  _jquery2["default"].each((0, _util.asArray)(group), function (i, g) {
2204    var layer = _this6.layerManager.getLayerGroup(g, true);
2205
2206    if (layer) {
2207      _this6.addLayer(layer);
2208    }
2209  });
2210};
2211
2212function setupShowHideGroupsOnZoom(map) {
2213  if (map.leafletr._hasInitializedShowHideGroups) {
2214    return;
2215  }
2216
2217  map.leafletr._hasInitializedShowHideGroups = true;
2218
2219  function setVisibility(layer, visible, group) {
2220    if (visible !== map.hasLayer(layer)) {
2221      if (visible) {
2222        map.addLayer(layer);
2223        map.fire("groupadd", {
2224          "name": group,
2225          "layer": layer
2226        });
2227      } else {
2228        map.removeLayer(layer);
2229        map.fire("groupremove", {
2230          "name": group,
2231          "layer": layer
2232        });
2233      }
2234    }
2235  }
2236
2237  function showHideGroupsOnZoom() {
2238    if (!map.layerManager) return;
2239    var zoom = map.getZoom();
2240    map.layerManager.getAllGroupNames().forEach(function (group) {
2241      var layer = map.layerManager.getLayerGroup(group, false);
2242
2243      if (layer && typeof layer.zoomLevels !== "undefined") {
2244        setVisibility(layer, layer.zoomLevels === true || layer.zoomLevels.indexOf(zoom) >= 0, group);
2245      }
2246    });
2247  }
2248
2249  map.showHideGroupsOnZoom = showHideGroupsOnZoom;
2250  map.on("zoomend", showHideGroupsOnZoom);
2251}
2252
2253methods.setGroupOptions = function (group, options) {
2254  var _this7 = this;
2255
2256  _jquery2["default"].each((0, _util.asArray)(group), function (i, g) {
2257    var layer = _this7.layerManager.getLayerGroup(g, true); // This slightly tortured check is because 0 is a valid value for zoomLevels
2258
2259
2260    if (typeof options.zoomLevels !== "undefined" && options.zoomLevels !== null) {
2261      layer.zoomLevels = (0, _util.asArray)(options.zoomLevels);
2262    }
2263  });
2264
2265  setupShowHideGroupsOnZoom(this);
2266  this.showHideGroupsOnZoom();
2267};
2268
2269methods.addRasterImage = function (uri, bounds, layerId, group, options) {
2270  // uri is a data URI containing an image. We want to paint this image as a
2271  // layer at (top-left) bounds[0] to (bottom-right) bounds[1].
2272  // We can't simply use ImageOverlay, as it uses bilinear scaling which looks
2273  // awful as you zoom in (and sometimes shifts positions or disappears).
2274  // Instead, we'll use a TileLayer.Canvas to draw pieces of the image.
2275  // First, some helper functions.
2276  // degree2tile converts latitude, longitude, and zoom to x and y tile
2277  // numbers. The tile numbers returned can be non-integral, as there's no
2278  // reason to expect that the lat/lng inputs are exactly on the border of two
2279  // tiles.
2280  //
2281  // We'll use this to convert the bounds we got from the server, into coords
2282  // in tile-space at a given zoom level. Note that once we do the conversion,
2283  // we don't to do any more trigonometry to convert between pixel coordinates
2284  // and tile coordinates; the source image pixel coords, destination canvas
2285  // pixel coords, and tile coords all can be scaled linearly.
2286  function degree2tile(lat, lng, zoom) {
2287    // See http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
2288    var latRad = lat * Math.PI / 180;
2289    var n = Math.pow(2, zoom);
2290    var x = (lng + 180) / 360 * n;
2291    var y = (1 - Math.log(Math.tan(latRad) + 1 / Math.cos(latRad)) / Math.PI) / 2 * n;
2292    return {
2293      x: x,
2294      y: y
2295    };
2296  }
2296 // Given a range [from,to) and either one or two numbers, returns true if
2297  // there is any overlap between [x,x1) and the range--or if x1 is omitted,
2298  // then returns true if x is within [from,to).
2299
2300
2301  function overlap(from, to, x,
2302  /* optional */
2303  x1) {
2304    if (arguments.length == 3) x1 = x;
2305    return x < to && x1 >= from;
2306  }
2307
2308  function getCanvasSmoothingProperty(ctx) {
2309    var candidates = ["imageSmoothingEnabled", "mozImageSmoothingEnabled", "webkitImageSmoothingEnabled", "msImageSmoothingEnabled"];
2310
2311    for (var i = 0; i < candidates.length; i++) {
2312      if (typeof ctx[candidates[i]] !== "undefined") {
2313        return candidates[i];
2314      }
2315    }
2316
2317    return null;
2318  } // Our general strategy is to:
2319  // 1. Load the data URI in an Image() object, so we can get its pixel
2320  //    dimensions and the underlying image data. (We could have done this
2321  //    by not encoding as PNG at all but just send an array of RGBA values
2322  //    from the server, but that would inflate the JSON too much.)
2323  // 2. Create a hidden canvas that we use just to extract the image data
2324  //    from the Image (using Context2D.getImageData()).
2325  // 3. Create a TileLayer.Canvas and add it to the map.
2326  // We want to synchronously create and attach the TileLayer.Canvas (so an
2327  // immediate call to clearRasters() will be respected, for example), but
2328  // Image loads its data asynchronously. Fortunately we can resolve this
2329  // by putting TileLayer.Canvas into async mode, which will let us create
2330  // and attach the layer but have it wait until the image is loaded before
2331  // it actually draws anything.
2332  // These are the variables that we will populate once the image is loaded.
2333
2334
2335  var imgData = null; // 1d row-major array, four [0-255] integers per pixel
2336
2337  var imgDataMipMapper = null;
2338  var w = null; // image width in pixels
2339
2340  var h = null; // image height in pixels
2341  // We'll use this array to store callbacks that need to be invoked once
2342  // imgData, w, and h have been resolved.
2343
2344  var imgDataCallbacks = []; // Consumers of imgData, w, and h can call this to be notified when data
2345  // is available.
2346
2347  function getImageData(callback) {
2348    if (imgData != null) {
2349      // Must not invoke the callback immediately; it's too confusing and
2350      // fragile to have a function invoke the callback *either* immediately
2351      // or in the future. Better to be consistent here.
2352      setTimeout(function () {
2353        callback(imgData, w, h, imgDataMipMapper);
2354      }, 0);
2355    } else {
2356      imgDataCallbacks.push(callback);
2357    }
2358  }
2359
2360  var img = new Image();
2361
2362  img.onload = function () {
2363    // Save size
2364    w = img.width;
2365    h = img.height; // Create a dummy canvas to extract the image data
2366
2367    var imgDataCanvas = document.createElement("canvas");
2368    imgDataCanvas.width = w;
2369    imgDataCanvas.height = h;
2370    imgDataCanvas.style.display = "none";
2371    document.body.appendChild(imgDataCanvas);
2372    var imgDataCtx = imgDataCanvas.getContext("2d");
2373    imgDataCtx.drawImage(img, 0, 0); // Save the image data.
2374
2375    imgData = imgDataCtx.getImageData(0, 0, w, h).data;
2376    imgDataMipMapper = new _mipmapper2["default"](img); // Done with the canvas, remove it from the page so it can be gc'd.
2377
2378    document.body.removeChild(imgDataCanvas); // Alert any getImageData callers who are waiting.
2379
2380    for (var i = 0; i < imgDataCallbacks.length; i++) {
2381      imgDataCallbacks[i](imgData, w, h, imgDataMipMapper);
2382    }
2383
2384    imgDataCallbacks = [];
2385  };
2386
2387  img.src = uri;
2388
2389  var canvasTiles = _leaflet2["default"].gridLayer(Object.assign({}, options, {
2390    detectRetina: true,
2391    async: true
2392  })); // NOTE: The done() function MUST NOT be invoked until after the current
2393  // tick; done() looks in Leaflet's tile cache for the current tile, and
2394  // since it's still being constructed, it won't be found.
2395
2396
2397  canvasTiles.createTile = function (tilePoint, done) {
2398    var zoom = tilePoint.z;
2399
2400    var canvas = _leaflet2["default"].DomUtil.create("canvas");
2401
2402    var error; // setup tile width and height according to the options
2403
2404    var size = this.getTileSize();
2405    canvas.width = size.x;
2406    canvas.height = size.y;
2407    getImageData(function (imgData, w, h, mipmapper) {
2408      try {
2409        // The Context2D we'll being drawing onto. It's always 256x256.
2410        var ctx = canvas.getContext("2d"); // Convert our image data's top-left and bottom-right locations into
2411        // x/y tile coordinates. This is essentially doing a spherical mercator
2412        // projection, then multiplying by 2^zoom.
2413
2414        var topLeft = degree2tile(bounds[0][0], bounds[0][1], zoom);
2415        var bottomRight = degree2tile(bounds[1][0], bounds[1][1], zoom); // The size of the image in x/y tile coordinates.
2416
2417        var extent = {
2418          x: bottomRight.x - topLeft.x,
2419          y: bottomRight.y - topLeft.y
2420        }; // Short circuit if tile is totally disjoint from image.
2421
2422        if (!overlap(tilePoint.x, tilePoint.x + 1, topLeft.x, bottomRight.x)) return;
2423        if (!overlap(tilePoint.y, tilePoint.y + 1, topLeft.y, bottomRight.y)) return; // The linear resolution of the tile we're drawing is always 256px per tile unit.
2424        // If the linear resolution (in either direction) of the image is less than 256px
2425        // per tile unit, then use nearest neighbor; otherwise, use the canvas's built-in
2426        // scaling.
2427
2428        var imgRes = {
2429          x: w / extent.x,
2430          y: h / extent.y
2431        }; // We can do the actual drawing in one of three ways:
2432        // - Call drawImage(). This is easy and fast, and results in smooth
2433        //   interpolation (bilinear?). This is what we want when we are
2434        //   reducing the image from its native size.
2435        // - Call drawImage() with imageSmoothingEnabled=false. This is easy
2436        //   and fast and gives us nearest-neighbor interpolation, which is what
2437        //   we want when enlarging the image. However, it's unsupported on many
2438        //   browsers (including QtWebkit).
2439        // - Do a manual nearest-neighbor interpolation. This is what we'll fall
2440        //   back to when enlarging, and imageSmoothingEnabled isn't supported.
2441        //   In theory it's slower, but still pretty fast on my machine, and the
2442        //   results look the same AFAICT.
2443        // Is imageSmoothingEnabled supported? If so, we can let canvas do
2444        // nearest-neighbor interpolation for us.
2445
2446        var smoothingProperty = getCanvasSmoothingProperty(ctx);
2447
2448        if (smoothingProperty || imgRes.x >= 256 && imgRes.y >= 256) {
2449          // Use built-in scaling
2450          // Turn off anti-aliasing if necessary
2451          if (smoothingProperty) {
2452            ctx[smoothingProperty] = imgRes.x >= 256 && imgRes.y >= 256;
2453          } // Don't necessarily draw with the full-size image; if we're
2454          // downscaling, use the mipmapper to get a pre-downscaled image
2455          // (see comments on Mipmapper class for why this matters).
2456
2457
2458          mipmapper.getBySize(extent.x * 256, extent.y * 256, function (mip) {
2459            // It's possible that the image will go off the edge of the canvas--
2460            // that's OK, the canvas should clip appropriately.
2461            ctx.drawImage(mip, // Convert abs tile coords to rel tile coords, then *256 to convert
2462            // to rel pixel coords
2463            (topLeft.x - tilePoint.x) * 256, (topLeft.y - tilePoint.y) * 256, // Always draw the whole thing and let canvas clip; so we can just
2464            // convert from size in tile coords straight to pixels
2465            extent.x * 256, extent.y * 256);
2466          });
2467        } else {
2468          // Use manual nearest-neighbor interpolation
2469          // Calculate the source image pixel coordinates that correspond with
2470          // the top-left and bottom-right of this tile. (If the source image
2471          // only partially overlaps the tile, we use max/min to limit the
2472          // sourceStart/End to only reflect the overlapping portion.)
2473          var sourceStart = {
2474            x: Math.max(0, Math.floor((tilePoint.x - topLeft.x) * imgRes.x)),
2475            y: Math.max(0, Math.floor((tilePoint.y - topLeft.y) * imgRes.y))
2476          };
2477          var sourceEnd = {
2478            x: Math.min(w, Math.ceil((tilePoint.x + 1 - topLeft.x) * imgRes.x)),
2479            y: Math.min(h, Math.ceil((tilePoint.y + 1 - topLeft.y) * imgRes.y))
2480          }; // The size, in dest pixels, that each source pixel should occupy.
2481          // This might be greater or less than 1 (e.g. if x and y resolution
2482          // are very different).
2483
2484          var pixelSize = {
2485            x: 256 / imgRes.x,
2486            y: 256 / imgRes.y
2487          }; // For each pixel in the source image that overlaps the tile...
2488
2489          for (var row = sourceStart.y; row < sourceEnd.y; row++) {
2490            for (var col = sourceStart.x; col < sourceEnd.x; col++) {
2491              // ...extract the pixel data...
2492              var i = (row * w + col) * 4;
2493              var r = imgData[i];
2494              var g = imgData[i + 1];
2495              var b = imgData[i + 2];
2496              var a = imgData[i + 3];
2497              ctx.fillStyle = "rgba(" + [r, g, b, a / 255].join(",") + ")"; // ...calculate the corresponding pixel coord in the dest image
2498              // where it should be drawn...
2499
2500              var pixelPos = {
2501                x: (col / imgRes.x + topLeft.x - tilePoint.x) * 256,
2502                y: (row / imgRes.y + topLeft.y - tilePoint.y) * 256
2503              }; // ...and draw a rectangle there.
2504
2505              ctx.fillRect(Math.round(pixelPos.x), Math.round(pixelPos.y), // Looks crazy, but this is necessary to prevent roun
2505ding from
2506              // causing overlap between this rect and its neighbors. The
2507              // minuend is the location of the next pixel, while the
2508              // subtrahend is the position of the current pixel (to turn an
2509              // absolute coordinate to a width/height). Yes, I had to look
2510              // up minuend and subtrahend.
2511              Math.round(pixelPos.x + pixelSize.x) - Math.round(pixelPos.x), Math.round(pixelPos.y + pixelSize.y) - Math.round(pixelPos.y));
2512            }
2513          }
2514        }
2515      } catch (e) {
2516        error = e;
2517      } finally {
2518        done(error, canvas);
2519      }
2520    });
2521    return canvas;
2522  };
2523
2524  this.layerManager.addLayer(canvasTiles, "image", layerId, group);
2525};
2526
2527methods.removeImage = function (layerId) {
2528  this.layerManager.removeLayer("image", layerId);
2529};
2530
2531methods.clearImages = function () {
2532  this.layerManager.clearLayers("image");
2533};
2534
2535methods.addMeasure = function (options) {
2536  // if a measureControl already exists, then remove it and
2537  //   replace with a new one
2538  methods.removeMeasure.call(this);
2539  this.measureControl = _leaflet2["default"].control.measure(options);
2540  this.addControl(this.measureControl);
2541};
2542
2543methods.removeMeasure = function () {
2544  if (this.measureControl) {
2545    this.removeControl(this.measureControl);
2546    this.measureControl = null;
2547  }
2548};
2549
2550methods.addSelect = function (ctGroup) {
2551  var _this8 = this;
2552
2553  methods.removeSelect.call(this);
2554  this._selectButton = _leaflet2["default"].easyButton({
2555    states: [{
2556      stateName: "select-inactive",
2557      icon: "ion-qr-scanner",
2558      title: "Make a selection",
2559      onClick: function onClick(btn, map) {
2560        btn.state("select-active");
2561        _this8._locationFilter = new _leaflet2["default"].LocationFilter2();
2562
2563        if (ctGroup) {
2564          var selectionHandle = new global.crosstalk.SelectionHandle(ctGroup);
2565          selectionHandle.on("change", function (e) {
2566            if (e.sender !== selectionHandle) {
2567              if (_this8._locationFilter) {
2568                _this8._locationFilter.disable();
2569
2570                btn.state("select-inactive");
2571              }
2572            }
2573          });
2574
2575          var handler = function handler(e) {
2576            _this8.layerManager.brush(_this8._locationFilter.getBounds(), {
2577              sender: selectionHandle
2578            });
2579          };
2580
2581          _this8._locationFilter.on("enabled", handler);
2582
2583          _this8._locationFilter.on("change", handler);
2584
2585          _this8._locationFilter.on("disabled", function () {
2586            selectionHandle.close();
2587            _this8._locationFilter = null;
2588          });
2589        }
2590
2591        _this8._locationFilter.addTo(map);
2592      }
2593    }, {
2594      stateName: "select-active",
2595      icon: "ion-close-round",
2596      title: "Dismiss selection",
2597      onClick: function onClick(btn, map) {
2598        btn.state("select-inactive");
2599
2600        _this8._locationFilter.disable(); // If explicitly dismissed, clear the crosstalk selections
2601
2602
2603        _this8.layerManager.unbrush();
2604      }
2605    }]
2606  });
2607
2608  this._selectButton.addTo(this);
2609};
2610
2611methods.removeSelect = function () {
2612  if (this._locationFilter) {
2613    this._locationFilter.disable();
2614  }
2615
2616  if (this._selectButton) {
2617    this.removeControl(this._selectButton);
2618    this._selectButton = null;
2619  }
2620};
2621
2622methods.createMapPane = function (name, zIndex) {
2623  this.createPane(name);
2624  this.getPane(name).style.zIndex = zIndex;
2625};
2626
2627
2628}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2629},{"./cluster-layer-store":1,"./crs_utils":3,"./dataframe":4,"./global/htmlwidgets":8,"./global/jquery":9,"./global/leaflet":10,"./global/shiny":12,"./mipmapper":16,"./util":17}],16:[function(require,module,exports){
2630"use strict";
2631
2632Object.defineProperty(exports, "__esModule", {
2633  value: true
2634});
2635
2636function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2637
2638function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
2639
2640function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
2641
2642// This class simulates a mipmap, which shrinks images by powers of two. This
2643// stepwise reduction results in "pixel-perfect downscaling" (where every
2644// pixel of the original image has some contribution to the downscaled image)
2645// as opposed to a single-step downscaling which will discard a lot of data
2646// (and with sparse images at small scales can give very surprising results).
2647var Mipmapper = /*#__PURE__*/function () {
2648  function Mipmapper(img) {
2649    _classCallCheck(this, Mipmapper);
2650
2651    this._layers = [img];
2652  } // The various functions on this class take a callback function BUT MAY OR MAY
2653  // NOT actually behave asynchronously.
2654
2655
2656  _createClass(Mipmapper, [{
2657    key: "getBySize",
2658    value: function getBySize(desiredWidth, desiredHeight, callback) {
2659      var _this = this;
2660
2661      var i = 0;
2662      var lastImg = this._layers[0];
2663
2664      var testNext = function testNext() {
2665        _this.getByIndex(i, function (img) {
2666          // If current image is invalid (i.e. too small to be rendered) or
2667          // it's smaller than what we wanted, return the last known good image.
2668          if (!img || img.width < desiredWidth || img.height < desiredHeight) {
2669            callback(lastImg);
2670            return;
2671          } else {
2672            lastImg = img;
2673            i++;
2674            testNext();
2675            return;
2676          }
2677        });
2678      };
2679
2680      testNext();
2681    }
2682  }, {
2683    key: "getByIndex",
2684    value: function getByIndex(i, callback) {
2685      var _this2 = this;
2686
2687      if (this._layers[i]) {
2688        callback(this._layers[i]);
2689        return;
2690      }
2691
2692      this.getByIndex(i - 1, function (prevImg) {
2693        if (!prevImg) {
2694          // prevImg could not be calculated (too small, possibly)
2695          callback(null);
2696          return;
2697        }
2698
2699        if (prevImg.width < 2 || prevImg.height < 2) {
2700          // Can't reduce this image any further
2701          callback(null);
2702          return;
2703        } // If reduce ever becomes truly asynchronous, we should stuff a promise or
2704        // something into this._layers[i] before calling this.reduce(), to prevent
2705        // redundant reduce operations from happening.
2706
2707
2708        _this2.reduce(prevImg, function (reducedImg) {
2709          _this2._layers[i] = reducedImg;
2710          callback(reducedImg);
2711          return;
2712        });
2713      });
2714    }
2715  }, {
2716    key: "reduce",
2717    value: function reduce(img, callback) {
2718      var imgDataCanvas = document.createElement("canvas");
2719      imgDataCanvas.width = Math.ceil(img.width / 2);
2720      imgDataCanvas.height = Math.ceil(img.height / 2);
2721      imgDataCanvas.style.display = "none";
2722      document.body.appendChild(imgDataCanvas);
2723
2724      try {
2725        var imgDataCtx = imgDataCanvas.getContext("2d");
2726        imgDataCtx.drawImage(img, 0, 0, img.width / 2, img.height / 2);
2727        callback(imgDataCanvas);
2728      } finally {
2729        document.body.removeChild(imgDataCanvas);
2730      }
2731    }
2732  }]);
2733
2734  return Mipmapper;
2735}();
2736
2737exports["default"] = Mipmapper;
2738
2739
2740},{}],17:[function(require,module,exports){
2741"use strict";
2742
2743Object.defineProperty(exports, "__esModule", {
2744  value: true
2745});
2746exports.log = log;
2747exports.recycle = recycle;
2748exports.asArray = asArray;
2749
2750function log(message) {
2751  /* eslint-disable no-console */
2752  if (console && console.log) console.log(message);
2753  /* eslint-enable no-console */
2754}
2755
2756function recycle(values, length, inPlace) {
2757  if (length === 0 && !inPlace) return [];
2758
2759  if (!(values instanceof Array)) {
2760    if (inPlace) {
2761      throw new Error("Can't do in-place recycling of a non-Array value");
2762    }
2763
2764    values = [values];
2765  }
2766
2767  if (typeof length === "undefined") length = values.length;
2768  var dest = inPlace ? values : [];
2769  var origLength = values.length;
2770
2771  while (dest.length < length) {
2772    dest.push(values[dest.length % origLength]);
2773  }
2774
2775  if (dest.length > length) {
2776    dest.splice(length, dest.length - length);
2777  }
2778
2779  return dest;
2780}
2781
2782function asArray(value) {
2783  if (value instanceof Array) return value;else return [value];
2784}
2785
2786
2787},{}]},{},[13]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.