diff --git a/geolet.js b/geolet.js
new file mode 100644
index 0000000..a668815
--- /dev/null
+++ b/geolet.js
@@ -0,0 +1,318 @@
+/*
+GEOLET version 20.12.31
+Copyright (c) 2020 Ruben Holthuijsen; available under the MIT license
+https://github.com/rhlt/leaflet-geolet/
+*/
+
+(function () {
+
+ var _consolePrefix = '[GEOLET] ';
+ var L = window.L;
+
+ if (!L || !L.map) {
+ //Was Leaflet loaded correctly?
+ console.error(_consolePrefix + 'Missing Leaflet');
+ return;
+ }
+
+ var _merge = function (object1, object2) {
+ //Merge all properties from object 2 into object 1, recursively for plain objects
+
+ if (typeof object2 != 'object' || object2 === null)
+ return object1;
+ if (typeof object1 != 'object' || object1 === null)
+ object1 = {};
+
+ for (key in object2) if (({}).hasOwnProperty.call(object2, key)) {
+ if (typeof object2[key] == 'object' && object2[key] !== null && Object.getPrototypeOf(object2[key]) == Object.getPrototypeOf({})) {
+ //Plain object: merge the next level
+ object1[key] = _merge(object1[key], object2[key]);
+ } else {
+ //Anything else (including typed objects): just assign it
+ object1[key] = object2[key];
+ }
+ }
+
+ return object1;
+ };
+
+ var _defaultMarker = function (controlOptions) {
+ //Generate a default marker
+ return L.marker(null, {
+ icon: L.divIcon({
+ html: '',
+ iconAnchor: [10, 10],
+ className: ''
+ }),
+ attribution: 'Geolet',
+ zIndexOffset: 1000
+ });
+ };
+
+
+ L.Geolet = L.Control.extend({
+
+ options: {
+ title: 'Find current location',
+ className: null,
+ activeClassName: null,
+ style: { display: 'flex', color: '' },
+ activeStyle: { display: 'flex', color: '#E00' },
+ html: '',
+ geoOptions: { enableHighAccuracy: true, maximumAge: 30000, timeout: 27000 },
+ marker: null,
+ popup: null,
+ popupContent: null,
+ updatePopupWhenOpen: true,
+ autoPan: true,
+ minZoom: 9
+ },
+
+ _a: null,
+ _map: null,
+ _watchId: null,
+ _latLng: null,
+ _popupContent: null,
+ _first: false,
+
+ marker: null,
+ popup: null,
+
+ initialize: function (options) {
+ //Set control options
+ if (typeof options == 'object' && options !== null)
+ L.setOptions(this, options);
+ },
+
+ isActive: function () {
+ //Is the control active (are we displaying the current location, or trying to obtain it)?
+ return this._watchId ? true : false;
+ },
+
+ getLatLng: function () {
+ //Returns the coordinates of the location currently displayed on the map (if any) -- might still be null if isActive()
+ return this.isActive() ? this._latLng : null;
+ },
+
+ updatePopup: function () {
+ //Update the popup with new content
+ var popupContent;
+ if (!this._popup)
+ return;
+ if (typeof this.options.popupContent == 'undefined' || this.options.popupContent === null) {
+ popupContent = '' + L.Geolet.formatLatLng(this.getLatLng()) + '';
+ } else if (typeof this.options.popupContent == 'function') {
+ popupContent = this.options.popupContent.call(this, this.getLatLng());
+ } else if (this.options.popupContent) {
+ popupContent = this.options.popupContent;
+ }
+ if (popupContent !== null)
+ this._popup.setContent(popupContent);
+ },
+
+ activate: function () {
+ //Activate the current location display
+
+ if (!L.Geolet.browserSupport)
+ return;
+
+ this.styleAnchor(true);
+
+ var control = this;
+
+ var geoSuccessCallback = function (data) {
+ var first = !!control._first;
+ control._latLng = L.latLng(data.coords.latitude, data.coords.longitude, data.coords.altitude);
+ control._popupContent = control.options.popupContent;
+ if (control._popup) {
+ if (control._popup.isOpen() && control.options.updatePopupWhenOpen)
+ control.updatePopup();
+ }
+ if (control._marker) {
+ control._marker.setLatLng(control._latLng);
+ control._marker.addTo(control._map);
+ }
+ if (control._first) {
+ control._first = false;
+ if (control.options.autoPan)
+ control._map.setView(control._latLng, control.options.minZoom ? Math.max(control._map.getZoom(), control.options.minZoom) : control._map.getZoom());
+ }
+ control._map.fire('geolet_success', {
+ control: control,
+ first: first,
+ marker: control._marker,
+ latlng: control._latLng, //"latlng" all-lowercase for consistency with Leaflet's MouseEvent
+ raw: data
+ });
+ };
+
+ var geoErrorCallback = function (data) {
+ control.deactivate();
+ console.warn(_consolePrefix + data.message);
+ control._map.fire('geolet_error', {
+ control: control,
+ raw: data
+ });
+ };
+
+ this._first = true;
+ this._watchId = navigator.geolocation.watchPosition(geoSuccessCallback, geoErrorCallback, this.options.geoOptions);
+ },
+
+ deactivate: function () {
+ //Deactivate current location display
+
+ this.styleAnchor(false);
+
+ if (this.isActive()) {
+ navigator.geolocation.clearWatch(this._watchId);
+ this._watchId = null;
+ }
+
+ this._latLng = null;
+
+ if (this._marker)
+ this._marker.remove();
+ if (this._popup)
+ this._popup.remove();
+ },
+
+ styleAnchor: function (active) {
+ //Apply CSS classes and styles to the button's element
+
+ var className = [];
+ if (!this._a)
+ return;
+ if (this.options.className)
+ className.push(this.options.className);
+ if (active && this.options.activeClassName)
+ className.push(this.options.activeClassName);
+ if (className.length) {
+ this._a.className = className.join(' ');
+ } else {
+ this._a.className = '';
+ }
+ if (active && this.options.activeStyle)
+ _merge(this._a.style, this.options.activeStyle);
+ if (!active && this.options.style)
+ _merge(this._a.style, this.options.style);
+ },
+
+ onAdd: function (map) {
+ //Initialize everything when the control is added
+
+ var control = this;
+ var el = L.DomUtil.create('div');
+ this._map = map;
+
+ if (!L.Geolet.browserSupport) {
+ console.warn(_consolePrefix + 'Browser does not support Geolocation');
+ el.style.display = 'none';
+ return el;
+ }
+
+ if (this._marker)
+ this._marker.remove();
+ if (typeof this.options.marker == 'function') {
+ this._marker = this.options.marker.call(this, map);
+ } else if (this.options.marker) {
+ this._marker = this.options.marker;
+ } else if (typeof this.options.marker == 'undefined' || this.options.marker === null) {
+ this._marker = _defaultMarker();
+ } else {
+ this._marker = null;
+ }
+
+ if (this._popup)
+ this._popup.remove();
+ if (typeof this.options.popup == 'function') {
+ this._popup = this.options.popup.call(this, map);
+ } else if (this.options.popup) {
+ this._popup = this.options.popup;
+ } else if (typeof this.options.popup == 'undefined' || this.options.popup === null) {
+ this._popup = L.popup({ autoPan: this.options.autoPan });
+ } else {
+ this._popup = null;
+ }
+
+ if (this._marker && this._popup) {
+ this._marker.bindPopup(this._popup);
+ this._marker.on('popupopen', function () { control.updatePopup(); });
+ }
+
+ el.className = 'leaflet-bar leaflet-control';
+
+ this._a = document.createElement('a');
+ this._a.setAttribute('href', '#');
+ if (this.options.title)
+ this._a.setAttribute('title', this.options.title);
+
+ this.styleAnchor();
+
+ this._a.addEventListener('click', function (event) {
+ if (!control.isActive()) {
+ //Currently inactive
+ control.activate();
+ } else {
+ //Currently active
+ control.deactivate();
+ }
+ event.preventDefault();
+ event.stopPropagation();
+ });
+
+ this._a.addEventListener('dblclick', function (event) {
+ //Ignore double clicks
+ event.stopPropagation();
+ });
+
+ if (this.options.html)
+ this._a.innerHTML = this.options.html;
+ el.appendChild(this._a);
+
+ return el;
+ },
+
+ onRemove: function (map) {
+ //Deinitialize everything when the control is removed
+ this.deactivate();
+ this._a = null;
+ this._map = null;
+ this._popup = null;
+ this._marker = null;
+ }
+ });
+
+
+ //Browser support test
+ L.Geolet.browserSupport = !!(navigator && navigator.geolocation && navigator.geolocation.watchPosition);
+
+ //Format coordinates (for use in the default pop up)
+ L.Geolet.formatSymbols = {};
+ L.Geolet.formatLatLng = function (latLng, l, a) {
+
+ latLng = L.latLng(latLng, l, a);
+ if (!latLng)
+ return;
+
+ var result = [];
+ var symbols = _merge({ deg: '°', min: '’', sec: '”', N: 'N', E: 'E', S: 'S', W: 'W', space: ' ', comma: ', ' }, L.Geolet.formatSymbols);
+
+ ['lat', 'lng'].forEach(function (key) {
+ var dir = (key == 'lat' ? (latLng[key] < 0 ? symbols.S : symbols.N) : (latLng[key] < 0 ? symbols.W : symbols.E));
+ var val = Math.round(Math.abs(latLng[key]) * 3600) / 3600;
+ var deg = Math.floor(val) + symbols.deg;
+ var min = Math.floor(val * 60) % 60 + symbols.min;
+ var sec = Math.floor(val * 3600) % 60 + symbols.sec;
+ result.push([deg, min, sec, dir].join(symbols.space));
+ });
+
+ return result.join(symbols.comma);
+ };
+
+ //Factory function
+ L.geolet = function (options) {
+ return new L.Geolet(options);
+ };
+
+})()
diff --git a/index.html b/index.html
index 1d92e39..496e11e 100644
--- a/index.html
+++ b/index.html
@@ -6,11 +6,40 @@
Dashboard
+
+
-
+