PageSourceSearch

https://www.veloloisirprovence.com/vendors/leaflet/leaflet-control-geocoder/Control.Geocoder.js

js veloloisirprovence.com collected 2026-10-02 11:24:25 UTC 53,770 bytes, 1,764 lines download raw bytes

1/* @preserve
2 * Leaflet Control Geocoder 1.13.0
3 * https://github.com/perliedman/leaflet-control-geocoder
4 *
5 * Copyright (c) 2012 sa3m (https://github.com/sa3m)
6 * Copyright (c) 2018 Per Liedman
7 * All rights reserved.
8 */
9
10this.L = this.L || {};
11this.L.Control = this.L.Control || {};
12this.L.Control.Geocoder = (function (L) {
13  'use strict';
14
15  L = L && L.hasOwnProperty('default') ? L['default'] : L;
16
17  var lastCallbackId = 0;
18
19  // Adapted from handlebars.js
20  // https://github.com/wycats/handlebars.js/
21  var badChars = /[&<>"'`]/g;
22  var possible = /[&<>"'`]/;
23  var escape = {
24    '&': '&amp;',
25    '<': '&lt;',
26    '>': '&gt;',
27    '"': '&quot;',
28    "'": '&#x27;',
29    '`': '&#x60;'
30  };
31
32  function escapeChar(chr) {
33    return escape[chr];
34  }
35
36  function htmlEscape(string) {
37    if (string == null) {
38      return '';
39    } else if (!string) {
40      return string + '';
41    }
42
43    // Force a string conversion as this will be done by the append regardless and
44    // the regex test will do this transparently behind the scenes, causing issues if
45    // an object's to string has escaped characters in it.
46    string = '' + string;
47
48    if (!possible.test(string)) {
49      return string;
50    }
51    return string.replace(badChars, escapeChar);
52  }
53
54  function jsonp(url, params, callback, context, jsonpParam) {
55    var callbackId = '_l_geocoder_' + lastCallbackId++;
56    params[jsonpParam || 'callback'] = callbackId;
57    window[callbackId] = L.Util.bind(callback, context);
58    var script = document.createElement('script');
59    script.type = 'text/javascript';
60    script.src = url + getParamString(params);
61    script.id = callbackId;
62    document.getElementsByTagName('head')[0].appendChild(script);
63  }
64
65  function getJSON(url, params, callback) {
66    var xmlHttp = new XMLHttpRequest();
67    xmlHttp.onreadystatechange = function() {
68      if (xmlHttp.readyState !== 4) {
69        return;
70      }
71      var message;
72      if (xmlHttp.status !== 200 && xmlHttp.status !== 304) {
73        message = '';
74      } else if (typeof xmlHttp.response === 'string') {
75        // IE doesn't parse JSON responses even with responseType: 'json'.
76        try {
77          message = JSON.parse(xmlHttp.response);
78        } catch (e) {
79          // Not a JSON response
80          message = xmlHttp.response;
81        }
82      } else {
83        message = xmlHttp.response;
84      }
85      callback(message);
86    };
87    xmlHttp.open('GET', url + getParamString(params), true);
88    xmlHttp.responseType = 'json';
89    xmlHttp.setRequestHeader('Accept', 'application/json');
90    xmlHttp.send(null);
91  }
92
93  function template(str, data) {
94    return str.replace(/\{ *([\w_]+) *\}/g, function(str, key) {
95      var value = data[key];
96      if (value === undefined) {
97        value = '';
98      } else if (typeof value === 'function') {
99        value = value(data);
100      }
101      return htmlEscape(value);
102    });
103  }
104
105  function getParamString(obj, existingUrl, uppercase) {
106    var params = [];
107    for (var i in obj) {
108      var key = encodeURIComponent(uppercase ? i.toUpperCase() : i);
109      var value = obj[i];
110      if (!L.Util.isArray(value)) {
111        params.push(key + '=' + encodeURIComponent(value));
112      } else {
113        for (var j = 0; j < value.length; j++) {
114          params.push(key + '=' + encodeURIComponent(value[j]));
115        }
116      }
117    }
118    return (!existingUrl || existingUrl.indexOf('?') === -1 ? '?' : '&') + params.join('&');
119  }
120
121  var ArcGis = L.Class.extend({
122    options: {
123      service_url: 'https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer'
124    },
125
126    initialize: function(accessToken, options) {
127      L.setOptions(this, options);
128      this._accessToken = accessToken;
129    },
130
131    geocode: function(query, cb, context) {
132      var params = {
133        SingleLine: query,
134        outFields: 'Addr_Type',
135        forStorage: false,
136        maxLocations: 10,
137        f: 'json'
138      };
139
140      if (this._key && this._key.length) {
141        params.token = this._key;
142      }
143
144      getJSON(
145        this.options.service_url + '/findAddressCandidates',
146        L.extend(params, this.options.geocodingQueryParams),
147        function(data) {
148          var results = [],
149            loc,
150            latLng,
151            latLngBounds;
152
153          if (data.candidates && data.candidates.length) {
154            for (var i = 0; i <= data.candidates.length - 1; i++) {
155              loc = data.candidates[i];
156              latLng = L.latLng(loc.location.y, loc.location.x);
157              latLngBounds = L.latLngBounds(
158                L.latLng(loc.extent.ymax, loc.extent.xmax),
159                L.latLng(loc.extent.ymin, loc.extent.xmin)
160              );
161              results[i] = {
162                name: loc.address,
163                bbox: latLngBounds,
164                center: latLng
165              };
166            }
167          }
168
169          cb.call(context, results);
170        }
171      );
172    },
173
174    suggest: function(query, cb, context) {
175      return this.geocode(query, cb, context);
176    },
177
178    reverse: function(location, scale, cb, context) {
179      var params = {
180        location: encodeURIComponent(location.lng) + ',' + encodeURIComponent(location.lat),
181        distance: 100,
182        f: 'json'
183      };
184
185      getJSON(this.options.service_url + '/reverseGeocode', params, function(data) {
186        var result = [],
187          loc;
188
189        if (data && !data.error) {
190          loc = L.latLng(data.location.y, data.location.x);
191          result.push({
192            name: data.address.Match_addr,
193            center: loc,
194            bounds: L.latLngBounds(loc, loc)
195          });
196        }
197
198        cb.call(context, result);
199      });
200    }
201  });
202
203  function arcgis(accessToken, options) {
204    return new ArcGis(accessToken, options);
205  }
206
207  var Bing = L.Class.extend({
208    initialize: function(key) {
209      this.key = key;
210    },
211
212    geocode: function(query, cb, context) {
213      jsonp(
214        'https://dev.virtualearth.net/REST/v1/Locations',
215        {
216          query: query,
217          key: this.key
218        },
219        function(data) {
220          var results = [];
221          if (data.resourceSets.length > 0) {
222            for (var i = data.resourceSets[0].resources.length - 1; i >= 0; i--) {
223              var resource = data.resourceSets[0].resources[i],
224                bbox = resource.bbox;
225              results[i] = {
226                name: resource.name,
227                bbox: L.latLngBounds([bbox[0], bbox[1]], [bbox[2], bbox[3]]),
228                center: L.latLng(resource.point.coordinates)
229              };
230            }
231          }
232          cb.call(context, results);
233        },
234        this,
235        'jsonp'
236      );
237    },
238
239    reverse: function(location, scale, cb, context) {
240      jsonp(
241        '//dev.virtualearth.net/REST/v1/Locations/' + location.lat + ',' + location.lng,
242        {
243          key: this.key
244        },
245        function(data) {
246          var results = [];
247          for (var i = data.resourceSets[0].resources.length - 1; i >= 0; i--) {
248            var resource = data.resourceSets[0].resources[i],
249              bbox = resource.bbox;
250            results[i] = {
251              name: resource.name,
252              bbox: L.latLngBounds([bbox[0], bbox[1]], [bbox[2], bbox[3]]),
253              center: L.latLng(resource.point.coordinates)
254            };
255          }
256          cb.call(context, results);
257        },
258        this,
259        'jsonp'
260      );
261    }
262  });
263
264  function bing(key) {
265    return new Bing(key);
266  }
267
268  var Google = L.Class.extend({
269    options: {
270      serviceUrl: 'https://maps.googleapis.com/maps/api/geocode/json',
271      geocodingQueryParams: {},
272      reverseQueryParams: {}
273    },
274
275    initialize: function(key, options) {
276      this._key = key;
277      L.setOptions(this, options);
278      // Backwards compatibility
279      this.options.serviceUrl = this.options.service_url || this.options.serviceUrl;
280    },
281
282    geocode: function(query, cb, context) {
283      var params = {
284        address: query
285      };
286
287      if (this._key && this._key.length) {
288        params.key = this._key;
289      }
290
291      params = L.Util.extend(params, this.options.geocodingQueryParams);
292
293      getJSON(this.options.serviceUrl, params, function(data) {
294        var results = [],
295          loc,
296          latLng,
297          latLngBounds;
298        if (data.results && data.results.length) {
299          for (var i = 0; i <= data.results.length - 1; i++) {
300            loc = data.results[i];
301            latLng = L.latLng(loc.geometry.location);
302            latLngBounds = L.latLngBounds(
303              L.latLng(loc.geometry.viewport.northeast),
304              L.latLng(loc.geometry.viewport.southwest)
305            );
306            results[i] = {
307              name: loc.formatted_address,
308              bbox: latLngBounds,
309              center: latLng,
310              properties: loc.address_components
311            };
312          }
313        }
314
315        cb.call(context, results);
316      });
317    },
318
319    reverse: function(location, scale, cb, context) {
320      var params = {
321        latlng: encodeURIComponent(location.lat) + ',' + encodeURIComponent(location.lng)
322      };
323      params = L.Util.extend(params, this.options.reverseQueryParams);
324      if (this._key && this._key.length) {
325        params.key = this._key;
326      }
327
328      getJSON(this.options.serviceUrl, params, function(data) {
329        var results = [],
330          loc,
331          latLng,
332          latLngBounds;
333        if (data.results && data.results.length) {
334          for (var i = 0; i <= data.results.length - 1; i++) {
335            loc = data.results[i];
336            latLng = L.latLng(loc.geometry.location);
337            latLngBounds = L.latLngBounds(
338              L.latLng(loc.geometry.viewport.northeast),
339              L.latLng(loc.geometry.viewport.southwest)
340            );
341            results[i] = {
342              name: loc.formatted_address,
343              bbox: latLngBounds,
344              center: latLng,
345              properties: loc.address_components
346            };
347          }
348        }
349
350        cb.call(context, results);
351      });
352    }
353  });
354
355  function google(key, options) {
356    return new Google(key, options);
357  }
358
359  var HERE = L.Class.extend({
360    options: {
361      geocodeUrl: 'https://geocoder.api.here.com/6.2/geocode.json',
362      reverseGeocodeUrl: 'https://reverse.geocoder.api.here.com/6.2/reversegeocode.json',
363      app_id: '<insert your app_id here>',
364      app_code: '<insert your app_code here>',
365      geocodingQueryParams: {},
366      reverseQueryParams: {},
367      reverseGeocodeProxRadius: null
368    },
369    initialize: function(options) {
370      L.setOptions(this, options);
371    },
372    geocode: function(query, cb, context) {
373      var params = {
374        searchtext: query,
375        gen: 9,
376        app_id: this.options.app_id,
377        app_code: this.options.app_code,
378        jsonattributes: 1
379      };
380      params = L.Util.extend(params, this.options.geocodingQueryParams);
381      this.getJSON(this.options.geocodeUrl, params, cb, context);
382    },
383    reverse: function(location, scale, cb, context) {
384      var _proxRadius = this.options.reverseGeocodeProxRadius
385        ? this.options.reverseGeocodeProxRadius
386        : null;
387      var proxRadius = _proxRadius ? ',' + encodeURIComponent(_proxRadius) : '';
388      var params = {
389        prox: encodeURIComponent(location.lat) + ',' + encodeURIComponent(location.lng) + proxRadius,
390        mode: 'retrieveAddresses',
391        app_id: this.options.app_id,
392        app_code: this.options.app_code,
393        gen: 9,
394        jsonattributes: 1
395      };
396      params = L.Util.extend(params, this.options.reverseQueryParams);
397      this.getJSON(this.options.reverseGeocodeUrl, params, cb, context);
398    },
399    getJSON: function(url, params, cb, context) {
400      getJSON(url, params, function(data) {
401        var results = [],
402          loc,
403          latLng,
404          latLngBounds;
405        if (data.response.view && data.response.view.length) {
406          for (var i = 0; i <= data.response.view[0].result.length - 1; i++) {
407            loc = data.response.view[0].result[i].location;
408            latLng = L.latLng(loc.displayPosition.latitude, loc.displayPosition.longitude);
409            latLngBounds = L.latLngBounds(
410              L.latLng(loc.mapView.topLeft.latitude, loc.mapView.topLeft.longitude),
411              L.latLng(loc.mapView.bottomRight.latitude, loc.mapView.bottomRight.longitude)
412            );
413            results[i] = {
414              name: loc.address.label,
415              properties: loc.address,
416              bbox: latLngBounds,
417              center: latLng
418            };
419          }
420        }
421        cb.call(context, results);
422      });
423    }
424  });
425  function here(options) {
426    return new HERE(options);
427  }
428
429  var LatLng = L.Class.extend({
430    options: {
431      // the next geocoder to use
432      next: undefined,
433      sizeInMeters: 10000
434    },
435
436    initialize: function(options) {
437      L.Util.setOptions(this, options);
438    },
439
440    geocode: function(query, cb, context) {
441      var match;
442      var center;
443      // regex from https://github.com/openstreetmap/openstreetmap-website/blob/master/app/controllers/geocoder_controller.rb
444      if ((match = query.match(/^([NS])\s*(\d{1,3}(?:\.\d*)?)\W*([EW])\s*(\d{1,3}(?:\.\d*)?)$/))) {
445        // [NSEW] decimal degrees
446        center = L.latLng(
447          (/N/i.test(match[1]) ? 1 : -1) * parseFloat(match[2]),
448          (/E/i.test(match[3]) ? 1 : -1) * parseFloat(match[4])
449        );
450      } else if (
451        (match = query.match(/^(\d{1,3}(?:\.\d*)?)\s*([NS])\W*(\d{1,3}(?:\.\d*)?)\s*([EW])$/))
452      ) {
453        // decimal degrees [NSEW]
454        center = L.latLng(
455          (/N/i.test(match[2]) ? 1 : -1) * parseFloat(match[1]),
456          (/E/i.test(match[4]) ? 1 : -1) * parseFloat(match[3])
457        );
458      } else if (
459        (match = query.match(
460          /^([NS])\s*(\d{1,3})°?\s*(\d{1,3}(?:\.\d*)?)?['′]?\W*([EW])\s*(\d{1,3})°?\s*(\d{1,3}(?:\.\d*)?)?['′]?$/
461        ))
462      ) {
463        // [NSEW] degrees, decimal minutes
464        center = L.latLng(
465          (/N/i.test(match[1]) ? 1 : -1) * (parseFloat(match[2]) + parseFloat(match[3] / 60)),
466          (/E/i.test(match[4]) ? 1 : -1) * (parseFloat(match[5]) + parseFloat(match[6] / 60))
467        );
468      } else if (
469        (match = query.match(
470          /^(\d{1,3})°?\s*(\d{1,3}(?:\.\d*)?)?['′]?\s*([NS])\W*(\d{1,3})°?\s*(\d{1,3}(?:\.\d*)?)?['′]?\s*([EW])$/
471        ))
472      ) {
473        // degrees, decimal minutes [NSEW]
474        center = L.latLng(
475          (/N/i.test(match[3]) ? 1 : -1) * (parseFloat(match[1]) + parseFloat(match[2] / 60)),
476          (/E/i.test(match[6]) ? 1 : -1) * (parseFloat(match[4]) + parseFloat(match[5] / 60))
477        );
478      } else if (
479        (match = query.match(
480          /^([NS])\s*(\d{1,3})°?\s*(\d{1,2})['′]?\s*(\d{1,3}(?:\.\d*)?)?["″]?\W*([EW])\s*(\d{1,3})°?\s*(\d{1,2})['′]?\s*(\d{1,3}(?:\.\d*)?)?["″]?$/
481        ))
482      ) {
483        // [NSEW] degrees, minutes, decimal seconds
484        center = L.latLng(
485          (/N/i.test(match[1]) ? 1 : -1) *
486            (parseFloat(match[2]) + parseFloat(match[3] / 60 + parseFloat(match[4] / 3600))),
487          (/E/i.test(match[5]) ? 1 : -1) *
488            (parseFloat(match[6]) + parseFloat(match[7] / 60) + parseFloat(match[8] / 3600))
489        );
490      } else if (
491        (match = query.match(
492          /^(\d{1,3})°?\s*(\d{1,2})['′]?\s*(\d{1,3}(?:\.\d*)?)?["″]\s*([NS])\W*(\d{1,3})°?\s*(\d{1,2})['′]?\s*(\d{1,3}(?:\.\d*)?)?["″]?\s*([EW])$/
493        ))
494      ) {
495        // degrees, minutes, decimal seconds [NSEW]
496        center = L.latLng(
497          (/N/i.test(match[4]) ? 1 : -1) *
498            (parseFloat(match[1]) + parseFloat(match[2] / 60 + parseFloat(match[3] / 3600))),
499          (/E/i.test(match[8]) ? 1 : -1) *
500            (parseFloat(match[5]) + parseFloat(match[6] / 60) + parseFloat(match[7] / 3600))
501        );
502      } else if (
503        (match = query.match(/^\s*([+-]?\d+(?:\.\d*)?)\s*[\s,]\s*([+-]?\d+(?:\.\d*)?)\s*$/))
504      ) {
505        center = L.latLng(parseFloat(match[1]), parseFloat(match[2]));
506      }
507      if (center) {
508        var results = [
509          {
510            name: query,
511            center: center,
512            bbox: center.toBounds(this.options.sizeInMeters)
513          }
514        ];
515        cb.call(context, results);
516      } else if (this.options.next) {
517        this.options.next.geocode(query, cb, context);
518      }
519    }
520  });
521
522  function latLng(options) {
523    return new LatLng(options);
524  }
525
526  var Mapbox = L.Class.extend({
527    options: {
528      serviceUrl: 'https://api.mapbox.com/geocoding/v5/mapbox.places/',
529      geocodingQueryParams: {},
530      reverseQueryParams: {}
531    },
532
533    initialize: function(accessToken, options) {
534      L.setOptions(this, options);
535      this.options.geocodingQueryParams.access_token = accessToken;
536      this.options.reverseQueryParams.access_token = accessToken;
537    },
538
539    geocode: function(query, cb, context) {
540      var params = this.options.geocodingQueryParams;
541      if (
542        params.proximity !== undefined &&
543        params.proximity.lat !== undefined &&
544        params.proximity.lng !== undefined
545      ) {
546        params.proximity = params.proximity.lng + ',' + params.proximity.lat;
547      }
548      getJSON(this.options.serviceUrl + encodeURIComponent(query) + '.json', params, function(data) {
549        var results = [],
550          loc,
551          latLng,
552          latLngBounds;
553        if (data.features && data.features.length) {
554          for (var i = 0; i <= data.features.length - 1; i++) {
555            loc = data.features[i];
556            latLng = L.latLng(loc.center.reverse());
557            if (loc.bbox) {
558              latLngBounds = L.latLngBounds(
559                L.latLng(loc.bbox.slice(0, 2).reverse()),
560                L.latLng(loc.bbox.slice(2, 4).reverse())
561              );
562            } else {
563              latLngBounds = L.latLngBounds(latLng, latLng);
564            }
565
566            var properties = {
567              text: loc.text,
568              address: loc.address
569            };
570
571            for (var j = 0; j < (loc.context || []).length; j++) {
572              var id = loc.context[j].id.split('.')[0];
573              properties[id] = loc.context[j].text;
574
575              // Get country code when available
576              if (loc.context[j].short_code) {
577                properties['countryShortCode'] = loc.context[j].short_code;
578              }
579            }
580
581            results[i] = {
582              name: loc.place_name,
583              bbox: latLngBounds,
584              center: latLng,
585              properties: properties
586            };
587          }
588        }
589
590        cb.call(context, results);
591      });
592    },
593
594    suggest: function(query, cb, context) {
595      return this.geocode(query, cb, context);
596    },
597
598    reverse: function(location, scale, cb, context) {
599      getJSON(
600        this.options.serviceUrl +
601          encodeURIComponent(location.lng) +
602          ',' +
603          encodeURIComponent(location.lat) +
604          '.json',
605        this.options.reverseQueryParams,
606        function(data) {
607          var results = [],
608            loc,
609            latLng,
610            latLngBounds;
611          if (data.features && data.features.length) {
612            for (var i = 0; i <= data.features.length - 1; i++) {
613              loc = data.features[i];
614              latLng = L.latLng(loc.center.reverse());
615              if (loc.bbox) {
616                latLngBounds = L.latLngBounds(
617                  L.latLng(loc.bbox.slice(0, 2).reverse()),
618                  L.latLng(loc.bbox.slice(2, 4).reverse())
619                );
620              } else {
621                latLngBounds = L.latLngBounds(latLng, latLng);
622              }
623              results[i] = {
624                name: loc.place_name,
625                bbox: latLngBounds,
626                center: latLng
627              };
628            }
629          }
630
631          cb.call(context, results);
632        }
633      );
634    }
635  });
636
637  function mapbox(accessToken, options) {
638    return new Mapbox(accessToken, options);
639  }
640
641  var MapQuest = L.Class.extend({
642    options: {
643      serviceUrl: 'https://www.mapquestapi.com/geocoding/v1'
644    },
645
646    initialize: function(key, options) {
647      // MapQuest seems to provide URI encoded API keys,
648      // so to avoid encoding them twice, we decode them here
649      this._key = decodeURIComponent(key);
650
651      L.Util.setOptions(this, options);
652    },
653
654    _formatName: function() {
655      var r = [],
656        i;
657      for (i = 0; i < arguments.length; i++) {
658        if (arguments[i]) {
659          r.push(arguments[i]);
660        }
661      }
662
663      return r.join(', ');
664    },
665
666    geocode: function(query, cb, context) {
667      getJSON(
668        this.options.serviceUrl + '/address',
669        {
670          key: this._key,
671          location: query,
672          limit: 5,
673          outFormat: 'json'
674        },
675        L.bind(function(data) {
676          var results = [],
677            loc,
678            latLng;
679          if (data.results && data.results[0].locations) {
680            for (var i = data.results[0].locations.length - 1; i >= 0; i--) {
681              loc = data.results[0].locations[i];
682              latLng = L.latLng(loc.latLng);
683              results[i] = {
684                name: this._formatName(loc.street, loc.adminArea4, loc.adminArea3, loc.adminArea1),
685                bbox: L.latLngBounds(latLng, latLng),
686                center: latLng
687              };
688            }
689          }
690
691          cb.call(context, results);
692        }, this)
693      );
694    },
695
696    reverse: function(location, scale, cb, context) {
697      getJSON(
698        this.options.serviceUrl + '/reverse',
699        {
700          key: this._key,
701          location: location.lat + ',' + location.lng,
702          outputFormat: 'json'
703        },
704        L.bind(function(data) {
705          var results = [],
706            loc,
707            latLng;
708          if (data.results && data.results[0].locations) {
709            for (var i = data.results[0].locations.length - 1; i >= 0; i--) {
710              loc = data.results[0].locations[i];
711              latLng = L.latLng(loc.latLng);
712              results[i] = {
713                name: this._formatName(loc.street, loc.adminArea4, loc.adminArea3, loc.adminArea1),
714                bbox: L.latLngBounds(latLng, latLng),
715                center: latLng
716              };
717            }
718          }
719
720          cb.call(context, results);
721        }, this)
722      );
723    }
724  });
725
726  function mapQuest(key, options) {
727    return new MapQuest(key, options);
728  }
729
730  var Neutrino = L.Class.extend({
731    options: {
732      userId: '<insert your userId here>',
733      apiKey: '<insert your apiKey here>',
734      serviceUrl: 'https://neutrinoapi.com/'
735    },
736
737    initialize: function(options) {
738      L.Util.setOptions(this, options);
739    },
740
741    // https://www.neutrinoapi.com/api/geocode-address/
742    geocode: function(query, cb, context) {
743      getJSON(
744        this.options.serviceUrl + 'geocode-address',
745        {
746          apiKey: this.options.apiKey,
747          userId: this.options.userId,
748          //get three words and make a dot based string
749          address: query.split(/\s+/).join('.')
750        },
751        function(data) {
752          var results = [],
753            latLng,
754            latLngBounds;
755          if (data.locations) {
756            data.geometry = data.locations[0];
757            latLng = L.latLng(data.geometry['latitude'], data.geometry['longitude']);
758            latLngBounds = L.latLngBounds(latLng, latLng);
759            results[0] = {
760              name: data.geometry.address,
761              bbox: latLngBounds,
762              center: latLng
763            };
764          }
765
766          cb.call(context, results);
767        }
768      );
769    },
770
771    suggest: function(query, cb, context) {
772      return this.geocode(query, cb, context);
773    },
774
775    // https://www.neutrinoapi.com/api/geocode-reverse/
776    reverse: function(location, scale, cb, context) {
777      getJSON(
778        this.options.serviceUrl + 'geocode-reverse',
779        {
780          apiKey: this.options.apiKey,
781          userId: this.options.userId,
782          latitude: location.lat,
783          longitude: location.lng
784        },
785        function(data) {
786          var results = [],
787            latLng,
788            latLngBounds;
789          if (data.status.status == 200 && data.found) {
790            latLng = L.latLng(location.lat, location.lng);
791            latLngBounds = L.latLngBounds(latLng, latLng);
792            results[0] = {
793              name: data.address,
794              bbox: latLngBounds,
795              center: latLng
796            };
797          }
798          cb.call(context, results);
799        }
800      );
801    }
802  });
803
804  function neutrino(accessToken) {
805    return new Neutrino(accessToken);
806  }
807
808  var Nominatim = L.Class.extend({
809    options: {
810      serviceUrl: 'https://nominatim.openstreetmap.org/',
811      geocodingQueryParams: {},
812      reverseQueryParams: {},
813      htmlTemplate: function(r) {
814        var a = r.address,
815          className,
816          parts = [];
817        if (a.road || a.building) {
818          parts.push('{building} {road} {house_number}');
819        }
820
821        if (a.city || a.town || a.village || a.hamlet) {
822          className = parts.length > 0 ? 'leaflet-control-geocoder-address-detail' : '';
823          parts.push(
824            '<span class="' + className + '">{postcode} {city} {town} {village} {hamlet}</span>'
825          );
826        }
827
828        if (a.state || a.country) {
829          className = parts.length > 0 ? 'leaflet-control-geocoder-address-context' : '';
830          parts.push('<span class="' + className + '">{state} {country}</span>');
831        }
832
833        return template(parts.join('<br/>'), a, true);
834      }
835    },
836
837    initialize: function(options) {
838      L.Util.setOptions(this, options);
839    },
840
841    geocode: function(query, cb, context) {
842      getJSON(
843        this.options.serviceUrl + 'search',
844        L.extend(
845          {
846            q: query,
847            limit: 5,
848            format: 'json',
849            addressdetails: 1
850          },
851          this.options.geocodingQueryParams
852        ),
853        L.bind(function(data) {
854          var results = [];
855          for (var i = data.length - 1; i >= 0; i--) {
856            var bbox = data[i].boundingbox;
857            for (var j = 0; j < 4; j++) bbox[j] = parseFloat(bbox[j]);
858            results[i] = {
859              icon: data[i].icon,
860              name: data[i].display_name,
861              html: this.options.htmlTemplate ? this.options.htmlTemplate(data[i]) : undefined,
862              bbox: L.latLngBounds([bbox[0], bbox[2]], [bbox[1], bbox[3]]),
863              center: L.latLng(data[i].lat, data[i].lon),
864              properties: data[i]
865            };
866          }
867          cb.call(context, results);
868        }, this)
869      );
870    },
871
872    reverse: function(location, scale, cb, context) {
873      getJSON(
874        this.options.serviceUrl + 'reverse',
875        L.extend(
876          {
877            lat: location.lat,
878            lon: location.lng,
879            zoom: Math.round(Math.log(scale / 256) / Math.log(2)),
880            addressdetails: 1,
881            format: 'json'
882          },
883          this.options.reverseQueryParams
884        ),
885        L.bind(function(data) {
886          var result = [],
887            loc;
888
889          if (data && data.lat && data.lon) {
890            loc = L.latLng(data.lat, data.lon);
891            result.push({
892              name: data.display_name,
893              html: this.options.htmlTemplate ? this.options.htmlTemplate(data) : undefined,
894              center: loc,
895              bounds: L.latLngBounds(loc, loc),
896              properties: data
897            });
898          }
899
900          cb.call(context, result);
901        }, this)
902      );
903    }
904  });
905
906  function nominatim(options) {
907    return new Nominatim(options);
908  }
909
910  var OpenLocationCode = L.Class.extend({
911    options: {
912      OpenLocationCode: undefined,
913      codeLength: undefined
914    },
915
916    initialize: function(options) {
917      L.setOptions(this, options);
918    },
919
920    geocode: function(query, cb, context) {
921      try {
922        var decoded = this.options.OpenLocationCode.decode(query);
923        var result = {
924          name: query,
925          center: L.latLng(decoded.latitudeCenter, decoded.longitudeCenter),
926          bbox: L.latLngBounds(
927            L.latLng(decoded.latitudeLo, decoded.longitudeLo),
928            L.latLng(decoded.latitudeHi, decoded.longitudeHi)
929          )
930        };
931        cb.call(context, [result]);
932      } catch (e) {
933        console.warn(e); // eslint-disable-line no-console
934        cb.call(context, []);
935      }
936    },
937    reverse: function(location, scale, cb, context) {
938      try {
939        var code = this.options.OpenLocationCode.encode(
940          location.lat,
941          location.lng,
942          this.options.codeLength
943        );
944        var result = {
945          name: code,
946          center: L.latLng(location.lat, location.lng),
947          bbox: L.latLngBounds(
948            L.latLng(location.lat, location.lng),
949            L.latLng(location.lat, location.lng)
950          )
951        };
952        cb.call(context, [result]);
953      } catch (e) {
954        console.warn(e); // eslint-disable-line no-console
955        cb.call(context, []);
956      }
957    }
958  });
959
960  function openLocationCode(options) {
961    return new OpenLocationCode(options);
962  }
963
964  var OpenCage = L.Class.extend({
965    options: {
966      serviceUrl: 'https://api.opencagedata.com/geocode/v1/json',
967      geocodingQueryParams: {},
968      reverseQueryParams: {}
969    },
970
971    initialize: function(apiKey, options) {
972      L.setOptions(this, options);
973      this._accessToken = apiKey;
974    },
975
976    geocode: function(query, cb, context) {
977      var params = {
978        key: this._accessToken,
979        q: query
980      };
981      params = L.extend(params, this.options.geocodingQueryParams);
982      getJSON(this.options.serviceUrl, params, function(data) {
983        var results = [],
984          latLng,
985          latLngBounds,
986          loc;
987        if (data.results && data.results.length) {
988          for (var i = 0; i < data.results.length; i++) {
989            loc = data.results[i];
990            latLng = L.latLng(loc.geometry);
991            if (loc.annotations && loc.annotations.bounds) {
992              latLngBounds = L.latLngBounds(
993                L.latLng(loc.annotations.bounds.northeast),
994                L.latLng(loc.annotations.bounds.southwest)
995              );
996            } else {
997              latLngBounds = L.latLngBounds(latLng, latLng);
998            }
999            results.push({
1000              name: loc.formatted,
1001              bbox: latLngBounds,
1002              center: latLng
1003            });
1004          }
1005        }
1006        cb.call(context, results);
1007      });
1008    },
1009
1010    suggest: function(query, cb, context) {
1011      return this.geocode(query, cb, context);
1012    },
1013
1014    reverse: function(location, scale, cb, context) {
1015      var params = {
1016        key: this._accessToken,
1017        q: [location.lat, location.lng].join(',')
1018      };
1019      params = L.extend(params, this.options.reverseQueryParams);
1020      getJSON(this.options.serviceUrl, params, function(data) {
1021        var results = [],
1022          latLng,
1023          latLngBounds,
1024          loc;
1025        if (data.results && data.results.length) {
1026          for (var i = 0; i < data.results.length; i++) {
1027            loc = data.results[i];
1028            latLng = L.latLng(loc.geometry);
1029            if (loc.annotations && loc.annotations.bounds) {
1030              latLngBounds = L.latLngBounds(
1031                L.latLng(loc.annotations.bounds.northeast),
1032                L.latLng(loc.annotations.bounds.southwest)
1033              );
1034            } else {
1035              latLngBounds = L.latLngBounds(latLng, latLng);
1036            }
1037            results.push({
1038              name: loc.formatted,
1039              bbox: latLngBounds,
1040              center: latLng
1041            });
1042          }
1043        }
1044        cb.call(context, results);
1045      });
1046    }
1047  });
1048
1049  function opencage(apiKey, options) {
1050    return new OpenCage(apiKey, options);
1051  }
1052
1053  var Pelias = L.Class.extend({
1054    options: {
1055      serviceUrl: 'https://api.geocode.earth/v1',
1056      geocodingQueryParams: {},
1057      reverseQueryParams: {}
1058    },
1059
1060    initialize: function(apiKey, options) {
1061      L.Util.setOptions(this, options);
1062      this._apiKey = apiKey;
1063      this._lastSuggest = 0;
1064    },
1065
1066    geocode: function(query, cb, context) {
1067      var _this = this;
1068      getJSON(
1069        this.options.serviceUrl + '/search',
1070        L.extend(
1071          {
1072            api_key: this._apiKey,
1073            text: query
1074          },
1075          this.options.geocodingQueryParams
1076        ),
1077        function(data) {
1078          cb.call(context, _this._parseResults(data, 'bbox'));
1079        }
1080      );
1081    },
1082
1083    suggest: function(query, cb, context) {
1084      var _this = this;
1085      getJSON(
1086        this.options.serviceUrl + '/autocomplete',
1087        L.extend(
1088          {
1089            api_key: this._apiKey,
1090            text: query
1091          },
1092          this.options.geocodingQueryParams
1093        ),
1094        L.bind(function(data) {
1095          if (data.geocoding.timestamp > this._lastSuggest) {
1096            this._lastSuggest = data.geocoding.timestamp;
1097            cb.call(context, _this._parseResults(data, 'bbox'));
1098          }
1099        }, this)
1100      );
1101    },
1102
1103    reverse: function(location, scale, cb, context) {
1104      var _this = this;
1105      getJSON(
1106        this.options.serviceUrl + '/reverse',
1107        L.extend(
1108          {
1109            api_key: this._apiKey,
1110            'point.lat': location.lat,
1111            'point.lon': location.lng
1112          },
1113          this.options.reverseQueryParams
1114        ),
1115        function(data) {
1116          cb.call(context, _this._parseResults(data, 'bounds'));
1117        }
1118      );
1119    },
1120
1121    _parseResults: function(data, bboxname) {
1122      var results = [];
1123      L.geoJson(data, {
1124        pointToLayer: function(feature, latlng) {
1125          return L.circleMarker(latlng);
1126        },
1127        onEachFeature: function(feature, layer) {
1128          var result = {},
1129            bbox,
1130            center;
1131
1132          if (layer.getBounds) {
1133            bbox = layer.getBounds();
1134            center = bbox.getCenter();
1135          } else if (layer.feature.bbox) {
1136            center = layer.getLatLng();
1137            bbox = L.latLngBounds(
1138              L.GeoJSON.coordsToLatLng(layer.feature.bbox.slice(0, 2)),
1139              L.GeoJSON.coordsToLatLng(layer.feature.bbox.slice(2, 4))
1140            );
1141          } else {
1142            center = layer.getLatLng();
1143            bbox = L.latLngBounds(center, center);
1144          }
1145
1146          result.name = layer.feature.properties.label;
1147          result.center = center;
1148          result[bboxname] = bbox;
1149          result.properties = layer.feature.properties;
1150          results.push(result);
1151        }
1152      });
1153      return results;
1154    }
1155  });
1156
1157  function pelias(apiKey, options) {
1158    return new Pelias(apiKey, options);
1159  }
1160  var GeocodeEarth = Pelias;
1161  var geocodeEarth = pelias;
1162
1163  var Mapzen = Pelias; // r.i.p.
1164  var mapzen = pelias;
1165
1166  var Openrouteservice = Mapzen.extend({
1167    options: {
1168      serviceUrl: 'https://api.openrouteservice.org/geocode'
1169    }
1170  });
1171  function openrouteservice(apiKey, options) {
1172    return new Openrouteservice(apiKey, options);
1173  }
1174
1175  var Photon = L.Class.extend({
1176    options: {
1177      serviceUrl: 'https://photon.komoot.de/api/',
1178      reverseUrl: 'https://photon.komoot.de/reverse/',
1179      nameProperties: ['name', 'street', 'suburb', 'hamlet', 'town', 'city', 'state', 'country']
1180    },
1181
1182    initialize: function(options) {
1183      L.setOptions(this, options);
1184    },
1185
1186    geocode: function(query, cb, context) {
1187      var params = L.extend(
1188        {
1189          q: query
1190        },
1191        this.options.geocodingQueryParams
1192      );
1193
1194      getJSON(
1195        this.options.serviceUrl,
1196        params,
1197        L.bind(function(data) {
1198          cb.call(context, this._decodeFeatures(data));
1199        }, this)
1200      );
1201    },
1202
1203    suggest: function(query, cb, context) {
1204      return this.geocode(query, cb, context);
1205    },
1206
1207    reverse: function(latLng, scale, cb, context) {
1208      var params = L.extend(
1209        {
1210          lat: latLng.lat,
1211          lon: latLng.lng
1212        },
1213        this.options.reverseQueryParams
1214      );
1215
1216      getJSON(
1217        this.options.reverseUrl,
1218        params,
1219        L.bind(function(data) {
1220          cb.call(context, this._decodeFeatures(data));
1221        }, this)
1222      );
1223    },
1224
1225    _decodeFeatures: function(data) {
1226      var results = [],
1227        i,
1228        f,
1229        c,
1230        latLng,
1231        extent,
1232        bbox;
1233
1234      if (data && data.features) {
1235        for (i = 0; i < data.features.length; i++) {
1236          f = data.features[i];
1237          c = f.geometry.coordinates;
1238          latLng = L.latLng(c[1], c[0]);
1239          extent = f.properties.extent;
1240
1241          if (extent) {
1242            bbox = L.latLngBounds([extent[1], extent[0]], [extent[3], extent[2]]);
1243          } else {
1244            bbox = L.latLngBounds(latLng, latLng);
1245          }
1246
1247          results.push({
1248            name: this._decodeFeatureName(f),
1249            html: this.options.htmlTemplate ? this.options.htmlTemplate(f) : undefined,
1250            center: latLng,
1251            bbox: bbox,
1252            properties: f.properties
1253          });
1254        }
1255      }
1256
1257      return results;
1258    },
1259
1260    _decodeFeatureName: function(f) {
1261      return (this.options.nameProperties || [])
1262        .map(function(p) {
1263          return f.properties[p];
1264        })
1265        .filter(function(v) {
1266          return !!v;
1267        })
1268        .join(', ');
1269    }
1270  });
1271
1272  function photon(options) {
1273    return new Photon(options);
1274  }
1275
1276  var What3Words = L.Class.extend({
1277    options: {
1278      serviceUrl: 'https://api.what3words.com/v2/'
1279    },
1280
1281    initialize: function(accessToken) {
1282      this._accessToken = accessToken;
1283    },
1284
1285    geocode: function(query, cb, context) {
1286      //get three words and make a dot based string
1287      getJSON(
1288        this.options.serviceUrl + 'forward',
1289        {
1290          key: this._accessToken,
1291          addr: query.split(/\s+/).join('.')
1292        },
1293        function(data) {
1294          var results = [],
1295            latLng,
1296            latLngBounds;
1297          if (data.geometry) {
1298            latLng = L.latLng(data.geometry['lat'], data.geometry['lng']);
1299            latLngBounds = L.latLngBounds(latLng, latLng);
1300            results[0] = {
1301              name: data.words,
1302              bbox: latLngBounds,
1303              center: latLng
1304            };
1305          }
1306
1307          cb.call(context, results);
1308        }
1309      );
1310    },
1311
1312    suggest: function(query, cb, context) {
1313      return this.geocode(query, cb, context);
1314    },
1315
1316    reverse: function(location, scale, cb, context) {
1317      getJSON(
1318        this.options.serviceUrl + 'reverse',
1319        {
1320          key: this._accessToken,
1321          coords: [location.lat, location.lng].join(',')
1322        },
1323        function(data) {
1324          var results = [],
1325            latLng,
1326            latLngBounds;
1327          if (data.status.status == 200) {
1328            latLng = L.latLng(data.geometry['lat'], data.geometry['lng']);
1329            latLngBounds = L.latLngBounds(latLng, latLng);
1330            results[0] = {
1331              name: data.words,
1332              bbox: latLngBounds,
1333              center: latLng
1334            };
1335          }
1336          cb.call(context, results);
1337        }
1338      );
1339    }
1340  });
1341
1342  function what3words(accessToken) {
1343    return new What3Words(accessToken);
1344  }
1345
1346
1347
1348  var geocoders = /*#__PURE__*/Object.freeze({
1349    ArcGis: ArcGis,
1350    arcgis: arcgis,
1351    Bing: Bing,
1352    bing: bing,
1353    Google: Google,
1354    google: google,
1355    HERE: HERE,
1356    here: here,
1357    LatLng: LatLng,
1358    latLng: latLng,
1359    Mapbox: Mapbox,
1360    mapbox: mapbox,
1361    MapQuest: MapQuest,
1362    mapQuest: mapQuest,
1363    Neutrino: Neutrino,
1364    neutrino: neutrino,
1365    Nominatim: Nominatim,
1366    nominatim: nominatim,
1367    OpenLocationCode: OpenLocationCode,
1368    openLocationCode: openLocationCode,
1369    OpenCage: OpenCage,
1370    opencage: opencage,
1371    Pelias: Pelias,
1372    pelias: pelias,
1373    GeocodeEarth: GeocodeEarth,
1374    geocodeEarth: geocodeEarth,
1375    Mapzen: Mapzen,
1376    mapzen: mapzen,
1377    Openrouteservice: Openrouteservice,
1378    openrouteservice: openrouteservice,
1379    Photon: Photon,
1380    photon: photon,
1381    What3Words: What3Words,
1382    what3words: what3words
1383  });
1384
1385  var Geocoder = L.Control.extend({
1386    options: {
1387      showUniqueResult: true,
1388      showResultIcons: false,
1389      collapsed: true,
1390      expand: 'touch', // options: touch, click, anythingelse
1391      position: 'topright',
1392      placeholder: 'Search...',
1393      errorMessage: 'Nothing found.',
1394      iconLabel: 'Initiate a new search',
1395      queryMinLength: 1,
1396      suggestMinLength: 3,
1397      suggestTimeout: 250,
1398      defaultMarkGeocode: true
1399    },
1400
1401    includes: L.Evented.prototype || L.Mixin.Events,
1402
1403    initialize: function(options) {
1404      L.Util.setOptions(this, options);
1405      if (!this.options.geocoder) {
1406        this.options.geocoder = new Nominatim();
1407      }
1408
1409      this._requestCount = 0;
1410    },
1411
1412    addThrobberClass: function() {
1413      L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-throbber');
1414    },
1415
1416    removeThrobberClass: function() {
1417      L.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-throbber');
1418    },
1419
1420    onAdd: function(map) {
1421      var className = 'leaflet-control-geocoder',
1422        container = L.DomUtil.create('div', className + ' leaflet-bar'),
1423        icon = L.DomUtil.create('button', className + '-icon', container),
1424        form = (this._form = L.DomUtil.create('div', className + '-form', container)),
1425        input;
1426
1427      this._map = map;
1428      this._container = container;
1429
1430      icon.innerHTML = '&nbsp;';
1431      icon.type = 'button';
1432      icon.setAttribute('aria-label', this.options.iconLabel);
1433
1434      input = this._input = L.DomUtil.create('input', '', form);
1435      input.type = 'text';
1436      input.value = this.options.query || '';
1437      input.placeholder = this.options.placeholder;
1438      L.DomEvent.disableClickPropagation(input);
1439
1440      this._errorElement = L.DomUtil.create('div', className + '-form-no-error', container);
1441      this._errorElement.innerHTML = this.options.errorMessage;
1442
1443      this._alts = L.DomUtil.create(
1444        'ul',
1445        className + '-alternatives leaflet-control-geocoder-alternatives-minimized',
1446        container
1447      );
1448      L.DomEvent.disableClickPropagation(this._alts);
1449
1450      L.DomEvent.addListener(input, 'keydown', this._keydown, this);
1451      if (this.options.geocoder.suggest) {
1452        L.DomEvent.addListener(input, 'input', this._change, this);
1453      }
1454      L.DomEvent.addListener(
1455        input,
1456        'blur',
1457        function() {
1458          if (this.options.collapsed && !this._preventBlurCollapse) {
1459            this._collapse();
1460          }
1461          this._preventBlurCollapse = false;
1462        },
1463        this
1464      );
1465
1466      if (this.options.collapsed) {
1467        if (this.options.expand === 'click') {
1468          L.DomEvent.addListener(
1469            container,
1470            'click',
1471            function(e) {
1472              if (e.button === 0 && e.detail !== 2) {
1473                this._toggle();
1474              }
1475            },
1476            this
1477          );
1478        } else if (this.options.expand === 'touch') {
1479          L.DomEvent.addListener(
1480            container,
1481            L.Browser.touch ? 'touchstart mousedown' : 'mousedown',
1482            function(e) {
1483              this._toggle();
1484              e.preventDefault(); // mobile: clicking focuses the icon, so UI expands and immediately collapses
1485              e.stopPropagation();
1486            },
1487            this
1488          );
1489        } else {
1490          L.DomEvent.addListener(container, 'mouseover', this._expand, this);
1491          L.DomEvent.addListener(container, 'mouseout', this._collapse, this);
1492          this._map.on('movestart', this._collapse, this);
1493        }
1494      } else {
1495        this._expand();
1496        if (L.Browser.touch) {
1497          L.DomEvent.addListener(
1498            container,
1499            'touchstart',
1500            function() {
1501              this._geocode();
1502            },
1503            this
1504          );
1505        } else {
1506          L.DomEvent.addListener(
1507            container,
1508            'click',
1509            function() {
1510              this._geocode();
1511            },
1512            this
1513          );
1514        }
1515      }
1516
1517      if (this.options.defaultMarkGeocode) {
1518        this.on('markgeocode', this.markGeocode, this);
1519      }
1520
1521      this.on('startgeocode', this.addThrobberClass, this);
1522      this.on('finishgeocode', this.removeThrobberClass, this);
1523      this.on('startsuggest', this.addThrobberClass, this);
1524      this.on('finishsuggest', this.removeThrobberClass, this);
1525
1526      L.DomEvent.disableClickPropagation(container);
1527
1528      return container;
1529    },
1530
1531    setQuery: function(string) {
1532      this._input.value = string;
1533      return this;
1534    },
1535
1536    _geocodeResult: function(results, suggest) {
1537      if (!suggest && this.options.showUniqueResult && results.length === 1) {
1538        this._geocodeResultSelected(results[0]);
1539      } else if (results.length > 0) {
1540        this._alts.innerHTML = '';
1541        this._results = results;
1542        L.DomUtil.removeClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
1543        L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-options-open');
1544        for (var i = 0; i < results.length; i++) {
1545          this._alts.appendChild(this._createAlt(results[i], i));
1546        }
1547      } else {
1548        L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-options-error');
1549        L.DomUtil.addClass(this._errorElement, 'leaflet-control-geocoder-error');
1550      }
1551    },
1552
1553    markGeocode: function(result) {
1554      result = result.geocode || result;
1555
1556      this._map.fitBounds(result.bbox);
1557
1558      if (this._geocodeMarker) {
1559        this._map.removeLayer(this._geocodeMarker);
1560      }
1561
1562      this._geocodeMarker = new L.Marker(result.center)
1563        .bindPopup(result.html || result.name)
1564        .addTo(this._map)
1565        .openPopup();
1566
1567      return this;
1568    },
1569
1570    _geocode: function(suggest) {
1571      var value = this._input.value;
1572      if (!suggest && value.length < this.options.queryMinLength) {
1573        return;
1574      }
1575
1576      var requestCount = ++this._requestCount,
1577        mode = suggest ? 'suggest' : 'geocode',
1578        eventData = { input: value };
1579
1580      this._lastGeocode = value;
1581      if (!suggest) {
1582        this._clearResults();
1583      }
1584
1585      this.fire('start' + mode, eventData);
1586      this.options.geocoder[mode](
1587        value,
1588        function(results) {
1589          if (requestCount === this._requestCount) {
1590            eventData.results = results;
1591            this.fire('finish' + mode, eventData);
1592            this._geocodeResult(results, suggest);
1593          }
1594        },
1595        this
1596      );
1597    },
1598
1599    _geocodeResultSelected: function(result) {
1600      this.fire('markgeocode', { geocode: result });
1601    },
1602
1603    _toggle: function() {
1604      if (L.DomUtil.hasClass(this._container, 'leaflet-control-geocoder-expanded')) {
1605        this._collapse();
1606      } else {
1607        this._expand();
1608      }
1609    },
1610
1611    _expand: function() {
1612      L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-expanded');
1613      this._input.select();
1614      this.fire('expand');
1615    },
1616
1617    _collapse: function() {
1618      L.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-expanded');
1619      L.DomUtil.addClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
1620      L.DomUtil.removeClass(this._errorElement, 'leaflet-control-geocoder-error');
1621      L.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-options-open');
1622      L.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-options-error');
1623      this._input.blur(); // mobile: keyboard shouldn't stay expanded
1624      this.fire('collapse');
1625    },
1626
1627    _clearResults: function() {
1628      L.DomUtil.addClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
1629      this._selection = null;
1630      L.DomUtil.removeClass(this._errorElement, 'leaflet-control-geocoder-error');
1631      L.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-options-open');
1632      L.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-options-error');
1633    },
1634
1635    _createAlt: function(result, index) {
1636      var li = L.DomUtil.create('li', ''),
1637        a = L.DomUtil.create('a', '', li),
1638        icon = this.options.showResultIcons && result.icon ? L.DomUtil.create('img', '', a) : null,
1639        text = result.html ? undefined : document.createTextNode(result.name),
1640        mouseDownHandler = function mouseDownHandler(e) {
1641          // In some browsers, a click will fire on the map if the control is
1642          // collapsed directly after mousedown. To work around this, we
1643          // wait until the click is completed, and _then_ collapse the
1644          // control. Messy, but this is the workaround I could come up with
1645          // for #142.
1646          this._preventBlurCollapse = true;
1647          L.DomEvent.stop(e);
1648          this._geocodeResultSelected(result);
1649          L.DomEvent.on(
1650            li,
1651            'click touchend',
1652            function() {
1653              if (this.options.collapsed) {
1654                this._collapse();
1655              } else {
1656                this._clearResults();
1657              }
1658            },
1659            this
1660          );
1661        };
1662
1663      if (icon) {
1664        icon.src = result.icon;
1665      }
1666
1667      li.setAttribute('data-result-index', index);
1668
1669      if (result.html) {
1670        a.innerHTML = a.innerHTML + result.html;
1671      } else {
1672        a.appendChild(text);
1673      }
1674
1675      // Use mousedown and not click, since click will fire _after_ blur,
1676      // causing the control to have collapsed and removed the items
1677      // before the click can fire.
1678      L.DomEvent.addListener(li, 'mousedown touchstart', mouseDownHandler, this);
1679
1680      return li;
1681    },
1682
1683    _keydown: function(e) {
1684      var _this = this,
1685        select = function select(dir) {
1686          if (_this._selection) {
1687            L.DomUtil.removeClass(_this._selection, 'leaflet-control-geocoder-selected');
1688            _this._selection = _this._selection[dir > 0 ? 'nextSibling' : 'previousSibling'];
1689          }
1690          if (!_this._selection) {
1691            _this._selection = _this._alts[dir > 0 ? 'firstChild' : 'lastChild'];
1692          }
1693
1694          if (_this._selection) {
1695            L.DomUtil.addClass(_this._selection, 'leaflet-control-geocoder-selected');
1696          }
1697        };
1698
1699      switch (e.keyCode) {
1700        // Escape
1701        case 27:
1702          if (this.options.collapsed) {
1703            this._collapse();
1704          } else {
1705            this._clearResults();
1706          }
1707          break;
1708        // Up
1709        case 38:
1710          select(-1);
1711          break;
1712        // Up
1713        case 40:
1714          select(1);
1715          break;
1716        // Enter
1717        case 13:
1718          if (this._selection) {
1719            var index = parseInt(this._selection.getAttribute('data-result-index'), 10);
1720            this._geocodeResultSelected(this._results[index]);
1721            this._clearResults();
1722          } else {
1723            this._geocode();
1724          }
1725          break;
1726        default:
1727          return;
1728      }
1729
1730      L.DomEvent.preventDefault(e);
1731    },
1732    _change: function() {
1733      var v = this._input.value;
1734      if (v !== this._lastGeocode) {
1735        clearTimeout(this._suggestTimeout);
1736        if (v.length >= this.options.suggestMinLength) {
1737          this._suggestTimeout = setTimeout(
1738            L.bind(function() {
1739              this._geocode(true);
1740            }, this),
1741            this.options.suggestTimeout
1742          );
1743        } else {
1744          this._clearResults();
1745        }
1746      }
1747    }
1748  });
1749
1750  function geocoder(options) {
1751    return new Geocoder(options);
1752  }
1753
1754  L.Util.extend(Geocoder, geocoders);
1755
1756  L.Util.extend(L.Control, {
1757    Geocoder: Geocoder,
1758    geocoder: geocoder
1759  });
1760
1761  return Geocoder;
1762
1763}(L));
1764//# sourceMappingURL=Control.Geocoder.js.map

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.