unimap
Version:
Unified mapping library for multiple map service providers - Google Maps, Mapbox, Bing Maps, OpenStreetMap, and more
57 lines • 124 kB
JavaScript
// UniMap Bundle
var UniMap=(()=>{var I=Object.defineProperty;var F=Object.getOwnPropertyDescriptor;var $=Object.getOwnPropertyNames;var z=Object.prototype.hasOwnProperty;var S=(m,e)=>{for(var t in e)I(m,t,{get:e[t],enumerable:!0})},A=(m,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of $(e))!z.call(m,a)&&a!==t&&I(m,a,{get:()=>e[a],enumerable:!(r=F(e,a))||r.enumerable});return m};var _=m=>A(I({},"__esModule",{value:!0}),m);var O={};S(O,{UniMap:()=>E});var P=["google","mapbox","osm","here","tomtom","bing","yandex","carto","azure","mapmyindia"];function T(m){throw new Error(`Missing required parameter: ${m}`)}var h=class{constructor(e,t,r={}){this.apiKey=e,this.containerId=t,this.options=r,this.map=null,this.markers=new Map,this.polylines=new Map,this.polygons=new Map,this.heatmaps=new Map,this.layers=new Map}async init(){throw new Error("init() method must be implemented by the adapter")}addMarker(e){throw new Error("addMarker() method must be implemented by the adapter")}addCustomMarker(e){throw new Error("addCustomMarker() method must be implemented by the adapter")}addCustomMarkers(e){throw new Error("addCustomMarkers() method must be implemented by the adapter")}onMarkerClick(e,t,r={}){throw new Error("onMarkerClick() method must be implemented by the adapter")}removeMarker(e){throw new Error("removeMarker() method must be implemented by the adapter")}updateMarker(e,t){throw new Error("updateMarker() method must be implemented by the adapter")}setCenter(e){throw new Error("setCenter() method must be implemented by the adapter")}getCenter(){throw new Error("getCenter() method must be implemented by the adapter")}setZoom(e){throw new Error("setZoom() method must be implemented by the adapter")}getZoom(){throw new Error("getZoom() method must be implemented by the adapter")}zoomIn(){throw new Error("zoomIn() method must be implemented by the adapter")}zoomOut(){throw new Error("zoomOut() method must be implemented by the adapter")}panTo(e){throw new Error("panTo() method must be implemented by the adapter")}fitBounds(e){throw new Error("fitBounds() method must be implemented by the adapter")}geocode(e){throw new Error("geocode() method must be implemented by the adapter")}reverseGeocode(e,t){throw new Error("reverseGeocode() method must be implemented by the adapter")}drawRoute(e,t={}){throw new Error("drawRoute() method must be implemented by the adapter")}getDirections(e,t,r={}){throw new Error("getDirections() method must be implemented by the adapter")}drawPolygon(e,t={}){throw new Error("drawPolygon() method must be implemented by the adapter")}drawPolyline(e,t={}){throw new Error("drawPolyline() method must be implemented by the adapter")}drawCircle(e,t,r={}){throw new Error("drawCircle() method must be implemented by the adapter")}drawRectangle(e,t={}){throw new Error("drawRectangle() method must be implemented by the adapter")}enableTrafficLayer(){throw new Error("enableTrafficLayer() method must be implemented by the adapter")}disableTrafficLayer(){throw new Error("disableTrafficLayer() method must be implemented by the adapter")}addHeatMap(e,t={}){throw new Error("addHeatMap() method must be implemented by the adapter")}addTileLayer(e,t={}){throw new Error("addTileLayer() method must be implemented by the adapter")}removeLayer(e){throw new Error("removeLayer() method must be implemented by the adapter")}trackUserLocation(e,t={}){throw new Error("trackUserLocation() method must be implemented by the adapter")}getUserLocation(){throw new Error("getUserLocation() method must be implemented by the adapter")}indoorMaps(e){throw new Error("indoorMaps() method must be implemented by the adapter")}applyMapStyle(e){throw new Error("applyMapStyle() method must be implemented by the adapter")}enable3D(e){throw new Error("enable3D() method must be implemented by the adapter")}on(e,t){throw new Error("on() method must be implemented by the adapter")}off(e,t){throw new Error("off() method must be implemented by the adapter")}getBounds(){throw new Error("getBounds() method must be implemented by the adapter")}getContainer(){return document.getElementById(this.containerId)}destroy(){throw new Error("destroy() method must be implemented by the adapter")}_validateCoordinates(e,t){return typeof e=="number"&&typeof t=="number"&&e>=-90&&e<=90&&t>=-180&&t<=180}_generateId(){return`id_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}};var g=class extends h{constructor(e,t,r={}){super(e,t,r),this.trafficLayer=null,this.eventListeners=new Map}async init(){try{await this.loadGoogleMapsScript(),await this.validateApiKey();let e=this.getContainer();if(!e)throw new Error(`Container element with ID '${this.containerId}' not found.`);let t=this.options.mapId||"unimap-default",r={center:this.options.center||{lat:0,lng:0},zoom:this.options.zoom||10,mapTypeId:this.options.mapTypeId||"roadmap",disableDefaultUI:this.options.disableDefaultUI||!1,zoomControl:this.options.zoomControl!==!1,mapTypeControl:this.options.mapTypeControl!==!1,scaleControl:this.options.scaleControl!==!1,streetViewControl:this.options.streetViewControl!==!1,rotateControl:this.options.rotateControl!==!1,fullscreenControl:this.options.fullscreenControl!==!1};t?r.mapId=t:this.options.styles&&Array.isArray(this.options.styles)&&this.options.styles.length>0&&(r.styles=this.options.styles),this.map=new google.maps.Map(e,r),await new Promise(a=>{google.maps.event.addListenerOnce(this.map,"idle",a)})}catch(e){throw console.error("Google Maps initialization error:",e),new Error(`Failed to initialize Google Maps: ${e.message}`)}}loadGoogleMapsScript(){return new Promise((e,t)=>{if(window.google&&window.google.maps)return e();let r=document.createElement("script");r.src=`https://maps.googleapis.com/maps/api/js?key=${this.apiKey}&libraries=places,visualization,geometry,marker&loading=async&callback=initGoogleMaps`,r.async=!0,r.defer=!0,window.initGoogleMaps=()=>{e()},r.onerror=a=>{t(new Error("Failed to load Google Maps script"))},setTimeout(()=>{(!window.google||!window.google.maps)&&t(new Error("Google Maps script loading timeout"))},1e4),document.head.appendChild(r)})}async validateApiKey(){if(!this.apiKey||this.apiKey.trim()==="")throw new Error("Google Maps API key is required");try{let e=new google.maps.Geocoder;await new Promise((t,r)=>{e.geocode({address:"New York"},(a,o)=>{o==="OK"?t():r(o==="REQUEST_DENIED"?new Error("API key is invalid or restricted"):o==="OVER_QUERY_LIMIT"?new Error("API key has exceeded quota"):new Error(`API key validation failed: ${o}`))})})}catch(e){throw new Error(`API key validation failed: ${e.message}`)}}addMarker(e){if(!this.map)throw new Error("Map not initialized");let t=this._generateId(),r=new google.maps.Marker({position:{lat:e.lat,lng:e.lng},map:this.map,title:e.title||"",label:e.label||"",icon:e.icon||null,draggable:e.draggable||!1,clickable:e.clickable!==!1});return this.markers.set(t,r),t}addCustomMarker(e){if(!this.map)throw new Error("Map not initialized");if(!e||typeof e.lat!="number"||typeof e.lng!="number")throw new Error("addCustomMarker requires options with numeric lat and lng properties");let t=this._generateId();if(e.html){let o=google.maps.marker&&google.maps.marker.AdvancedMarkerElement;if(o)try{let n=new o({map:this.map,position:{lat:e.lat,lng:e.lng},content:this._createMarkerElement(e.html,e.className)});return this.markers.set(t,n),t}catch(n){console.warn("AdvancedMarkerElement failed, falling back to standard Marker:",n.message);let i=new google.maps.Marker({position:{lat:e.lat,lng:e.lng},map:this.map,title:e.title||"Custom marker"});return this.markers.set(t,i),t}console.warn("google.maps.marker.AdvancedMarkerElement unavailable. Falling back to standard Marker.");let s=new google.maps.Marker({position:{lat:e.lat,lng:e.lng},map:this.map,title:e.title||"Custom marker"});return this.markers.set(t,s),t}let r={position:{lat:e.lat,lng:e.lng},map:this.map,title:e.title||"",label:e.label||"",draggable:e.draggable||!1,clickable:e.clickable!==!1};(e.iconUrl||e.icon)&&(r.icon=e.icon||{url:e.iconUrl,scaledSize:e.iconSize?new google.maps.Size(e.iconSize.width||32,e.iconSize.height||32):null,anchor:e.iconAnchor?new google.maps.Point(e.iconAnchor.x||16,e.iconAnchor.y||16):null});let a=new google.maps.Marker(r);return this.markers.set(t,a),t}addCustomMarkers(e){if(!Array.isArray(e))throw new Error("addCustomMarkers requires an array of marker options");return e.map(t=>this.addCustomMarker(t))}onMarkerClick(e,t,r={}){let a=this.markers.get(e);if(!a)throw new Error(`Marker with id ${e} not found`);let o=google.maps.marker&&google.maps.marker.AdvancedMarkerElement&&a instanceof google.maps.marker.AdvancedMarkerElement,s=n=>{let i,l;if(o)n.latLng?(i=n.latLng.lat(),l=n.latLng.lng()):a.position&&(i=typeof a.position.lat=="function"?a.position.lat():a.position.lat,l=typeof a.position.lng=="function"?a.position.lng():a.position.lng);else if(n.latLng)i=n.latLng.lat(),l=n.latLng.lng();else if(a.position&&typeof a.getPosition=="function"){let c=a.getPosition();i=c.lat(),l=c.lng()}if(t&&i!==void 0&&l!==void 0&&t({lat:i,lng:l,markerId:e,event:n}),r.popupHtml){let c=new google.maps.InfoWindow({content:r.popupHtml});if(o&&a.position){let d=typeof a.position.lat=="function"?{lat:a.position.lat(),lng:a.position.lng()}:a.position;c.setPosition(d),c.open(this.map)}else c.open(this.map,a)}(r.toast||r.toastMessage)&&this._showToast(r.toastMessage||"Marker clicked",r.toastDuration||3e3)};this.markerClickHandlers||(this.markerClickHandlers=new Map),this.markerClickHandlers.set(e,s);try{o&&a.addListener?a.addListener("gmp-click",s):a.addListener("click",s)}catch{a.addListener("click",s)}return e}_createMarkerElement(e,t){let r=document.createElement("div");return r.innerHTML=e,t&&(r.className=t),r.style.cursor="pointer",r}_showToast(e,t=3e3){this.toastContainer||(this.toastContainer=document.createElement("div"),this.toastContainer.style.cssText=`
position: fixed;
top: 20px;
right: 20px;
z-index: 10000;
pointer-events: none;
`,document.body.appendChild(this.toastContainer));let r=document.createElement("div");return r.style.cssText=`
background: #333;
color: white;
padding: 12px 24px;
border-radius: 4px;
margin-bottom: 10px;
box-shadow: 0 2px 8px rgba(0,0,0,0.2);
opacity: 0;
transition: opacity 0.3s;
pointer-events: auto;
`,r.textContent=e,this.toastContainer.appendChild(r),setTimeout(()=>{r.style.opacity="1"},10),setTimeout(()=>{r.style.opacity="0",setTimeout(()=>{r.parentNode&&r.parentNode.removeChild(r)},300)},t),r}removeMarker(e){let t=this.markers.get(e);return t?(t.setMap(null),this.markers.delete(e),!0):!1}updateMarker(e,t){let r=this.markers.get(e);if(!r)return!1;if(google.maps.marker&&google.maps.marker.AdvancedMarkerElement&&r instanceof google.maps.marker.AdvancedMarkerElement){if(t.position){let o=typeof t.position.lat=="number"?t.position.lat:parseFloat(t.position.lat),s=typeof t.position.lng=="number"?t.position.lng:parseFloat(t.position.lng);if(typeof o=="number"&&typeof s=="number"&&isFinite(o)&&isFinite(s))try{r.position=new google.maps.LatLng(o,s)}catch{r.position={lat:o,lng:s}}else return console.error("Invalid position for AdvancedMarkerElement:",t.position),!1}return(t.title!==void 0||t.label!==void 0||t.icon!==void 0)&&console.warn("AdvancedMarkerElement: title, label, and icon updates require recreating the marker with new HTML content."),!0}else{if(t.position){let o=typeof t.position.lat=="number"?t.position.lat:parseFloat(t.position.lat),s=typeof t.position.lng=="number"?t.position.lng:parseFloat(t.position.lng);if(typeof o=="number"&&typeof s=="number"&&isFinite(o)&&isFinite(s))if(typeof r.setPosition=="function")r.setPosition({lat:o,lng:s});else if(r.position!==void 0)try{r.position=new google.maps.LatLng(o,s)}catch{r.position={lat:o,lng:s}}else return console.warn("Marker does not support setPosition method and has no position property"),!1;else return console.error("Invalid position for marker update:",t.position),!1}return t.title!==void 0&&typeof r.setTitle=="function"&&r.setTitle(t.title),t.label!==void 0&&typeof r.setLabel=="function"&&r.setLabel(t.label),t.icon!==void 0&&typeof r.setIcon=="function"&&r.setIcon(t.icon),t.draggable!==void 0&&typeof r.setDraggable=="function"&&r.setDraggable(t.draggable),!0}}setCenter(e){if(!this.map)throw new Error("Map not initialized");this._validateCoordinates(e.lat,e.lng)&&this.map.setCenter({lat:e.lat,lng:e.lng})}getCenter(){if(!this.map)throw new Error("Map not initialized");let e=this.map.getCenter();return{lat:e.lat(),lng:e.lng()}}setZoom(e){if(!this.map)throw new Error("Map not initialized");this.map.setZoom(e)}getZoom(){if(!this.map)throw new Error("Map not initialized");return this.map.getZoom()}zoomIn(){if(!this.map)throw new Error("Map not initialized");this.map.setZoom(this.map.getZoom()+1)}zoomOut(){if(!this.map)throw new Error("Map not initialized");this.map.setZoom(this.map.getZoom()-1)}panTo(e){if(!this.map)throw new Error("Map not initialized");this._validateCoordinates(e.lat,e.lng)&&this.map.panTo({lat:e.lat,lng:e.lng})}fitBounds(e){if(!this.map)throw new Error("Map not initialized");let t=new google.maps.LatLngBounds({lat:e.southwest.lat,lng:e.southwest.lng},{lat:e.northeast.lat,lng:e.northeast.lng});this.map.fitBounds(t)}geocode(e){if(!this.map)throw new Error("Map not initialized");let t=new google.maps.Geocoder;return new Promise((r,a)=>{t.geocode({address:e},(o,s)=>{if(s==="OK"){let n=o[0].geometry.location;r({lat:n.lat(),lng:n.lng(),formattedAddress:o[0].formatted_address})}else a(`Geocode failed: ${s}`)})})}reverseGeocode(e,t){if(!this.map)throw new Error("Map not initialized");if(!this._validateCoordinates(e,t))return Promise.reject(new Error("Invalid coordinates"));let r=new google.maps.Geocoder;return new Promise((a,o)=>{r.geocode({location:{lat:e,lng:t}},(s,n)=>{n==="OK"?a({formattedAddress:s[0].formatted_address,components:s[0].address_components}):o(`Reverse geocode failed: ${n}`)})})}drawRoute(e,t={}){if(!this.map)throw new Error("Map not initialized");let r=e.map(s=>({lat:s.lat,lng:s.lng})),a=new google.maps.Polyline({path:r,geodesic:!0,strokeColor:t.strokeColor||"#FF0000",strokeOpacity:t.strokeOpacity||1,strokeWeight:t.strokeWeight||2}),o=this._generateId();return a.setMap(this.map),this.polylines.set(o,a),o}getDirections(e,t,r={}){if(!this.map)throw new Error("Map not initialized");let a=new google.maps.DirectionsService,o=new google.maps.DirectionsRenderer({map:this.map,suppressMarkers:r.suppressMarkers||!1});return new Promise((s,n)=>{a.route({origin:e,destination:t,travelMode:r.travelMode||google.maps.TravelMode.DRIVING,waypoints:r.waypoints||[],optimizeWaypoints:r.optimizeWaypoints||!1},(i,l)=>{l==="OK"?(o.setDirections(i),s(i)):n(`Directions failed: ${l}`)})})}drawPolygon(e,t={}){if(!this.map)throw new Error("Map not initialized");let r=new google.maps.Polygon({paths:e.map(o=>({lat:o.lat,lng:o.lng})),strokeColor:t.strokeColor||"#FF0000",strokeOpacity:t.strokeOpacity||.8,strokeWeight:t.strokeWeight||2,fillColor:t.fillColor||"#FF0000",fillOpacity:t.fillOpacity||.35}),a=this._generateId();return r.setMap(this.map),this.polygons.set(a,r),a}drawPolyline(e,t={}){return this.drawRoute(e,t)}drawCircle(e,t,r={}){if(!this.map)throw new Error("Map not initialized");let a=new google.maps.Circle({center:{lat:e.lat,lng:e.lng},radius:t,strokeColor:r.strokeColor||"#FF0000",strokeOpacity:r.strokeOpacity||.8,strokeWeight:r.strokeWeight||2,fillColor:r.fillColor||"#FF0000",fillOpacity:r.fillOpacity||.35}),o=this._generateId();return a.setMap(this.map),this.polygons.set(o,a),o}drawRectangle(e,t={}){if(!this.map)throw new Error("Map not initialized");let r=new google.maps.Rectangle({bounds:{south:e.southwest.lat,west:e.southwest.lng,north:e.northeast.lat,east:e.northeast.lng},strokeColor:t.strokeColor||"#FF0000",strokeOpacity:t.strokeOpacity||.8,strokeWeight:t.strokeWeight||2,fillColor:t.fillColor||"#FF0000",fillOpacity:t.fillOpacity||.35}),a=this._generateId();return r.setMap(this.map),this.polygons.set(a,r),a}enableTrafficLayer(){if(!this.map)throw new Error("Map not initialized");this.trafficLayer||(this.trafficLayer=new google.maps.TrafficLayer),this.trafficLayer.setMap(this.map)}disableTrafficLayer(){this.trafficLayer&&this.trafficLayer.setMap(null)}addHeatMap(e,t={}){if(!this.map)throw new Error("Map not initialized");let r=e.map(o=>new google.maps.LatLng(o.lat,o.lng));this.heatmap=new google.maps.visualization.HeatmapLayer({data:r,radius:t.radius||20,opacity:t.opacity||.6});let a=this._generateId();return this.heatmap.setMap(this.map),this.heatmaps.set(a,this.heatmap),a}addTileLayer(e,t={}){if(!this.map)throw new Error("Map not initialized");let r=new google.maps.ImageMapType({getTileUrl:function(o,s){return e.replace("{x}",o.x).replace("{y}",o.y).replace("{z}",s)},tileSize:new google.maps.Size(256,256),opacity:t.opacity||1}),a=this._generateId();return this.layers.set(a,r),a}removeLayer(e){let t=this.layers.get(e);return t?(t.setMap&&t.setMap(null),this.layers.delete(e),!0):!1}trackUserLocation(e,t={}){return navigator.geolocation?navigator.geolocation.watchPosition(a=>{let o={lat:a.coords.latitude,lng:a.coords.longitude,accuracy:a.coords.accuracy};e(o)},a=>console.error("Geolocation error:",a),{enableHighAccuracy:t.enableHighAccuracy||!1,timeout:t.timeout||5e3,maximumAge:t.maximumAge||0}):(console.error("Geolocation is not supported by this browser."),null)}getUserLocation(){return new Promise((e,t)=>{navigator.geolocation?navigator.geolocation.getCurrentPosition(r=>{e({lat:r.coords.latitude,lng:r.coords.longitude,accuracy:r.coords.accuracy})},r=>t(r),{enableHighAccuracy:!0,timeout:1e4,maximumAge:6e4}):t(new Error("Geolocation is not supported by this browser."))})}indoorMaps(e){console.info("Indoor maps are enabled by default in Google Maps.")}applyMapStyle(e){if(!this.map)throw new Error("Map not initialized");this.map.setOptions({styles:e})}enable3D(e){if(!this.map)throw new Error("Map not initialized");e?this.map.setTilt(45):this.map.setTilt(0)}on(e,t){if(!this.map)throw new Error("Map not initialized");this.eventListeners.has(e)||this.eventListeners.set(e,[]);let r=this.map.addListener(e,t);this.eventListeners.get(e).push({callback:t,listener:r})}off(e,t){let r=this.eventListeners.get(e);if(r){let a=r.findIndex(o=>o.callback===t);if(a>-1){let{listener:o}=r[a];google.maps.event.removeListener(o),r.splice(a,1)}}}getBounds(){if(!this.map)throw new Error("Map not initialized");let e=this.map.getBounds();return e?{southwest:{lat:e.getSouthWest().lat(),lng:e.getSouthWest().lng()},northeast:{lat:e.getNorthEast().lat(),lng:e.getNorthEast().lng()}}:null}destroy(){this.eventListeners.forEach((t,r)=>{t.forEach(({listener:a})=>{google.maps.event.removeListener(a)})}),this.eventListeners.clear(),this.markers.forEach(t=>t.setMap(null)),this.polylines.forEach(t=>t.setMap(null)),this.polygons.forEach(t=>t.setMap(null)),this.heatmaps.forEach(t=>t.setMap(null)),this.layers.forEach(t=>{t.setMap&&t.setMap(null)}),this.markers.clear(),this.polylines.clear(),this.polygons.clear(),this.heatmaps.clear(),this.layers.clear();let e=this.getContainer();if(e)for(;e.firstChild;)e.removeChild(e.firstChild);this.map=null,this.trafficLayer=null}};var f=class extends h{constructor(e,t,r={}){super(e,t,r),this.eventListeners=new Map,this.sources=new Map,this.layers=new Map,this._isLoaded=!1}async init(){if(await this.loadMapboxScript(),!this.getContainer())throw new Error(`Container element with ID '${this.containerId}' not found.`);if(!this.apiKey||typeof this.apiKey!="string")throw new Error("Mapbox access token is required");mapboxgl.accessToken=this.apiKey;let t=typeof this.options.center?.lat=="number"?this.options.center.lat:0,r=typeof this.options.center?.lng=="number"?this.options.center.lng:0;this.map=new mapboxgl.Map({container:this.containerId,style:this.options.style||"mapbox://styles/mapbox/streets-v11",center:[r,t],zoom:this.options.zoom||10}),await new Promise(a=>{this.map.on("load",()=>{this._isLoaded=!0,a()})})}isReady(){return this.map?typeof this.map.isStyleLoaded=="function"?this.map.isStyleLoaded():this._isLoaded:!1}executeWhenReady(e){this.isReady()?e():this.map.once("load",e)}loadMapboxScript(){return new Promise((e,t)=>{if(window.mapboxgl)return e();let r=document.createElement("link");r.href="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.css",r.rel="stylesheet",document.head.appendChild(r);let a=document.createElement("script");a.src="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.js",a.async=!0,a.onload=e,a.onerror=t,document.head.appendChild(a)})}addMarker(e){if(!e||typeof e.lat!="number"||typeof e.lng!="number")throw new Error("addMarker requires options with numeric lat and lng properties");if(!isFinite(e.lat)||!isFinite(e.lng))throw new Error("addMarker requires valid numeric coordinates (lat and lng must be finite numbers)");let t=this._generateId(),r=document.createElement("div");r.className="mapbox-marker",r.style.width="20px",r.style.height="20px",r.style.backgroundColor=e.color||"#FF0000",r.style.borderRadius="50%",r.style.border="2px solid white",r.style.cursor="pointer",e.label&&r.setAttribute("title",e.label);try{let a=new mapboxgl.Marker(r).setLngLat([e.lng,e.lat]).addTo(this.map);return this.markers.set(t,a),t}catch(a){throw new Error(`Failed to add marker: ${a.message||"Invalid coordinates format. Mapbox expects [lng, lat] array."}`)}}addCustomMarker(e){if(!e||typeof e.lat!="number"||typeof e.lng!="number")throw new Error("addCustomMarker requires options with numeric lat and lng properties");let t=this._generateId(),r=document.createElement("div");e.html?r.innerHTML=e.html:(r.className=e.className||"mapbox-marker",e.iconUrl?(r.style.backgroundImage=`url(${e.iconUrl})`,r.style.backgroundSize="cover",r.style.width=(e.iconSize?.width||32)+"px",r.style.height=(e.iconSize?.height||32)+"px"):(r.style.width=(e.iconSize?.width||20)+"px",r.style.height=(e.iconSize?.height||20)+"px",r.style.backgroundColor=e.color||"#FF0000",r.style.borderRadius="50%",r.style.border="2px solid white")),r.style.cursor="pointer",e.title&&r.setAttribute("title",e.title);try{let a=new mapboxgl.Marker(r).setLngLat([e.lng,e.lat]).addTo(this.map);return this.markers.set(t,a),t}catch(a){throw new Error(`Failed to add custom marker: ${a.message}`)}}addCustomMarkers(e){if(!Array.isArray(e))throw new Error("addCustomMarkers requires an array of marker options");return e.map(t=>this.addCustomMarker(t))}onMarkerClick(e,t,r={}){let a=this.markers.get(e);if(!a)throw new Error(`Marker with id ${e} not found`);let o=()=>{let s=a.getLngLat(),n={lat:s.lat,lng:s.lng,markerId:e};t&&t(n),r.popupHtml&&new mapboxgl.Popup({offset:25}).setLngLat([s.lng,s.lat]).setHTML(r.popupHtml).addTo(this.map),(r.toast||r.toastMessage)&&this._showToast(r.toastMessage||"Marker clicked",r.toastDuration||3e3)};return this.markerClickHandlers||(this.markerClickHandlers=new Map),this.markerClickHandlers.set(e,o),a.getElement().addEventListener("click",o),e}_showToast(e,t=3e3){this.toastContainer||(this.toastContainer=document.createElement("div"),this.toastContainer.style.cssText=`
position: fixed;
top: 20px;
right: 20px;
z-index: 10000;
pointer-events: none;
`,document.body.appendChild(this.toastContainer));let r=document.createElement("div");return r.style.cssText=`
background: #333;
color: white;
padding: 12px 24px;
border-radius: 4px;
margin-bottom: 10px;
box-shadow: 0 2px 8px rgba(0,0,0,0.2);
opacity: 0;
transition: opacity 0.3s;
pointer-events: auto;
`,r.textContent=e,this.toastContainer.appendChild(r),setTimeout(()=>{r.style.opacity="1"},10),setTimeout(()=>{r.style.opacity="0",setTimeout(()=>{r.parentNode&&r.parentNode.removeChild(r)},300)},t),r}removeMarker(e){let t=this.markers.get(e);return t?(t.remove(),this.markers.delete(e),this.markerClickHandlers&&this.markerClickHandlers.delete(e),!0):!1}updateMarker(e,t){let r=this.markers.get(e);if(!r)return!1;if(t.position){let a=typeof t.position.lat=="number"?t.position.lat:parseFloat(t.position.lat),o=typeof t.position.lng=="number"?t.position.lng:parseFloat(t.position.lng);if(typeof a!="number"||typeof o!="number"||!isFinite(a)||!isFinite(o))return console.error("Invalid position for Mapbox marker update:",t.position),!1;try{r.setLngLat([o,a])}catch(s){return console.error("Failed to update marker position:",s.message),!1}}return(t.title!==void 0||t.label!==void 0)&&console.warn("Mapbox custom markers: title and label updates require recreating the marker with new HTML content."),!0}setCenter(e){this._validateCoordinates(e.lat,e.lng)&&this.map.setCenter([e.lng,e.lat])}getCenter(){let e=this.map.getCenter();return{lat:e.lat,lng:e.lng}}setZoom(e){this.map.setZoom(e)}getZoom(){return this.map.getZoom()}zoomIn(){this.map.zoomIn()}zoomOut(){this.map.zoomOut()}panTo(e){if(!e||typeof e.lat!="number"||typeof e.lng!="number")throw new Error("panTo requires coords with numeric lat and lng properties");this._validateCoordinates(e.lat,e.lng)&&this.map.panTo([e.lng,e.lat])}fitBounds(e){let t=[[e.southwest.lng,e.southwest.lat],[e.northeast.lng,e.northeast.lat]];this.map.fitBounds(t)}async geocode(e){let t=encodeURIComponent(e),r=await fetch(`https://api.mapbox.com/geocoding/v5/mapbox.places/${t}.json?access_token=${this.apiKey}&limit=1`);if(!r.ok){let o=await r.text().catch(()=>"");throw new Error(`Geocoding failed: ${r.status} ${r.statusText}${o?` - ${o}`:""}`)}let a=await r.json();if(a.features&&a.features.length>0){let[o,s]=a.features[0].center;return{lat:s,lng:o,formattedAddress:a.features[0].place_name}}else throw new Error("No results found")}async reverseGeocode(e,t){if(!this._validateCoordinates(e,t))return Promise.reject(new Error("Invalid coordinates"));let r=await fetch(`https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(t)},${encodeURIComponent(e)}.json?access_token=${this.apiKey}&limit=1`);if(!r.ok){let o=await r.text().catch(()=>"");throw new Error(`Reverse geocoding failed: ${r.status} ${r.statusText}${o?` - ${o}`:""}`)}let a=await r.json();if(a.features&&a.features.length>0)return{formattedAddress:a.features[0].place_name,components:a.features[0].context||[]};throw new Error("No results found")}drawRoute(e,t={}){let r=this._generateId(),a=`route-source-${r}`,o=`route-layer-${r}`,s=e.map(n=>[n.lng,n.lat]);return this.executeWhenReady(()=>{this.map.getSource(a)||this.map.addSource(a,{type:"geojson",data:{type:"Feature",properties:{},geometry:{type:"LineString",coordinates:s}}}),this.map.getLayer(o)||this.map.addLayer({id:o,type:"line",source:a,layout:{"line-join":"round","line-cap":"round"},paint:{"line-color":t.strokeColor||"#FF0000","line-width":t.strokeWeight||3,"line-opacity":t.strokeOpacity||1}})}),this.sources.set(a,a),this.polylines.set(r,{sourceId:a,layerId:o}),r}async getDirections(e,t,r={}){let a=r.travelMode||"driving",o=`${e.lng},${e.lat};${t.lng},${t.lat}`,s=await fetch(`https://api.mapbox.com/directions/v5/mapbox/${a}/${o}?access_token=${this.apiKey}&geometries=geojson`);if(!s.ok){let i=await s.text().catch(()=>"");throw new Error(`Directions failed: ${s.status} ${s.statusText}${i?` - ${i}`:""}`)}let n=await s.json();if(n.routes&&n.routes.length>0){let i=n.routes[0];return{routeId:this.drawRoute(i.geometry.coordinates.map(c=>({lng:c[0],lat:c[1]})),r),duration:i.duration,distance:i.distance}}else throw new Error("No route found")}drawPolygon(e,t={}){let r=this._generateId(),a=`polygon-source-${r}`,o=`polygon-layer-${r}`,s=e.map(n=>[n.lng,n.lat]);return this.executeWhenReady(()=>{this.map.getSource(a)||this.map.addSource(a,{type:"geojson",data:{type:"Feature",properties:{},geometry:{type:"Polygon",coordinates:[s]}}}),this.map.getLayer(o)||this.map.addLayer({id:o,type:"fill",source:a,paint:{"fill-color":t.fillColor||"#FF0000","fill-opacity":t.fillOpacity||.35}});let n=`${o}-outline`;this.map.getLayer(n)||this.map.addLayer({id:n,type:"line",source:a,paint:{"line-color":t.strokeColor||"#FF0000","line-width":t.strokeWeight||2,"line-opacity":t.strokeOpacity||.8}})}),this.sources.set(a,a),this.polygons.set(r,{sourceId:a,layerId:o}),r}drawPolyline(e,t={}){return this.drawRoute(e,t)}drawCircle(e,t,r={}){let o=[];for(let s=0;s<64;s++){let n=s/64*2*Math.PI,i=e.lat+t/111320*Math.cos(n),l=e.lng+t/(111320*Math.cos(e.lat*Math.PI/180))*Math.sin(n);o.push({lat:i,lng:l})}return this.drawPolygon(o,r)}drawRectangle(e,t={}){let r=[{lat:e.southwest.lat,lng:e.southwest.lng},{lat:e.southwest.lat,lng:e.northeast.lng},{lat:e.northeast.lat,lng:e.northeast.lng},{lat:e.northeast.lat,lng:e.southwest.lng}];return this.drawPolygon(r,t)}enableTrafficLayer(){console.info("Traffic layer not available in Mapbox. Consider using Mapbox Traffic API.")}disableTrafficLayer(){}addHeatMap(e,t={}){let r=this._generateId(),a=`heatmap-source-${r}`,o=`heatmap-layer-${r}`,s=e.map(n=>({type:"Feature",properties:{weight:n.weight||1},geometry:{type:"Point",coordinates:[n.lng,n.lat]}}));return this.executeWhenReady(()=>{this.map.getSource(a)||this.map.addSource(a,{type:"geojson",data:{type:"FeatureCollection",features:s}}),this.map.getLayer(o)||this.map.addLayer({id:o,type:"heatmap",source:a,paint:{"heatmap-weight":["get","weight"],"heatmap-intensity":t.intensity||1,"heatmap-color":["interpolate",["linear"],["heatmap-density"],0,"rgba(0, 0, 255, 0)",.5,"rgba(0, 0, 255, 1)",1,"rgba(255, 0, 0, 1)"],"heatmap-radius":t.radius||20,"heatmap-opacity":t.opacity||.6}})}),this.sources.set(a,a),this.heatmaps.set(r,{sourceId:a,layerId:o}),r}addTileLayer(e,t={}){let r=this._generateId();return this.executeWhenReady(()=>{this.map.getSource(r)||this.map.addSource(r,{type:"raster",tiles:[e],tileSize:t.tileSize||256}),this.map.getLayer(r)||this.map.addLayer({id:r,type:"raster",source:r,paint:{"raster-opacity":t.opacity||1}})}),this.sources.set(r,r),this.layers.set(r,r),r}removeLayer(e){let t=this.layers.get(e);return t?(this.map.getLayer(t)&&this.map.removeLayer(t),this.map.getSource(t)&&this.map.removeSource(t),this.layers.delete(e),!0):!1}trackUserLocation(e,t={}){return navigator.geolocation?navigator.geolocation.watchPosition(a=>{let o={lat:a.coords.latitude,lng:a.coords.longitude,accuracy:a.coords.accuracy};e(o)},a=>console.error("Geolocation error:",a),{enableHighAccuracy:t.enableHighAccuracy||!1,timeout:t.timeout||5e3,maximumAge:t.maximumAge||0}):(console.error("Geolocation is not supported by this browser."),null)}getUserLocation(){return new Promise((e,t)=>{navigator.geolocation?navigator.geolocation.getCurrentPosition(r=>{e({lat:r.coords.latitude,lng:r.coords.longitude,accuracy:r.coords.accuracy})},r=>t(r),{enableHighAccuracy:!0,timeout:1e4,maximumAge:6e4}):t(new Error("Geolocation is not supported by this browser."))})}indoorMaps(e){console.info("Indoor maps not available in Mapbox.")}applyMapStyle(e){typeof e=="string"?this.map.setStyle(e):typeof e=="object"&&Object.keys(e).forEach(t=>{this.map.setPaintProperty(t,e[t])})}enable3D(e){e?this.map.addLayer({id:"3d-buildings",source:"composite","source-layer":"building",filter:["==","extrude","true"],type:"fill-extrusion",minzoom:15,paint:{"fill-extrusion-color":"#aaa","fill-extrusion-height":["get","height"],"fill-extrusion-base":["get","min_height"],"fill-extrusion-opacity":.6}}):this.map.getLayer("3d-buildings")&&this.map.removeLayer("3d-buildings")}on(e,t){this.eventListeners.has(e)||this.eventListeners.set(e,[]),this.eventListeners.get(e).push(t),this.map.on(e,t)}off(e,t){let r=this.eventListeners.get(e);if(r){let a=r.indexOf(t);a>-1&&(r.splice(a,1),this.map.off(e,t))}}getBounds(){let e=this.map.getBounds();return{southwest:{lat:e.getSouthWest().lat,lng:e.getSouthWest().lng},northeast:{lat:e.getNorthEast().lat,lng:e.getNorthEast().lng}}}destroy(){this.eventListeners.forEach((e,t)=>{e.forEach(r=>{this.map.off(t,r)})}),this.eventListeners.clear(),this.sources.forEach((e,t)=>{this.map.getSource(e)&&this.map.removeSource(e)}),this.markers.clear(),this.polylines.clear(),this.polygons.clear(),this.heatmaps.clear(),this.layers.clear(),this.sources.clear(),this.map&&(this.map.remove(),this.map=null)}};var y=class extends h{constructor(e,t,r={}){super(e,t,r),this.eventListeners=new Map,this.entities=new Map}async init(){await this.loadBingMapsScript();let e=this.getContainer();if(!e)throw new Error(`Container element with ID '${this.containerId}' not found.`);let t=typeof this.options.center?.lat=="number"?this.options.center.lat:0,r=typeof this.options.center?.lng=="number"?this.options.center.lng:0;this.map=new Microsoft.Maps.Map(e,{credentials:this.apiKey,center:new Microsoft.Maps.Location(t,r),zoom:this.options.zoom||10,mapTypeId:this.options.mapTypeId||Microsoft.Maps.MapTypeId.road,showMapTypeSelector:this.options.showMapTypeSelector!==!1,showZoomButton:this.options.showZoomButton!==!1,showScalebar:this.options.showScalebar!==!1,showBreadcrumb:this.options.showBreadcrumb!==!1,enableCORS:this.options.enableCORS!==!1,enableHighDpi:this.options.enableHighDpi!==!1,enableInertia:this.options.enableInertia!==!1})}loadBingMapsScript(){return new Promise((e,t)=>{if(window.Microsoft&&window.Microsoft.Maps&&window.Microsoft.Maps.Location)return e();let r="bingMapsLoadCallback";window[r]=()=>{window.Microsoft&&window.Microsoft.Maps&&window.Microsoft.Maps.Location?e():t(new Error("Bing Maps failed to load properly")),delete window[r]};let a=document.createElement("script");a.src=`https://www.bing.com/api/maps/mapcontrol?key=${this.apiKey}&callback=${r}`,a.async=!0,a.onerror=()=>{delete window[r],t(new Error("Failed to load Bing Maps script"))},document.head.appendChild(a)})}addMarker(e){let t=this._generateId(),r=new Microsoft.Maps.Location(e.lat,e.lng),a={title:e.title||"",text:e.label||"",draggable:e.draggable||!1};e.icon&&(a.icon=e.icon),e.color!==void 0?a.color=e.color:Microsoft.Maps.PushpinColor&&Microsoft.Maps.PushpinColor.red&&(a.color=Microsoft.Maps.PushpinColor.red);let o=new Microsoft.Maps.Pushpin(r,a);return this.map.entities.push(o),this.markers.set(t,o),t}addCustomMarker(e){if(!e||typeof e.lat!="number"||typeof e.lng!="number")throw new Error("addCustomMarker requires options with numeric lat and lng properties");let t=this._generateId(),r=new Microsoft.Maps.Location(e.lat,e.lng);if(e.html){let s=new Microsoft.Maps.CustomOverlay({htmlContent:e.html,position:r});return this.map.layers.insert(s),this.markers.set(t,s),t}let a={title:e.title||"",text:e.label||"",draggable:e.draggable||!1};e.iconUrl?a.icon=e.iconUrl:e.color&&(a.color=e.color);let o=new Microsoft.Maps.Pushpin(r,a);return this.map.entities.push(o),this.markers.set(t,o),t}addCustomMarkers(e){if(!Array.isArray(e))throw new Error("addCustomMarkers requires an array of marker options");return e.map(t=>this.addCustomMarker(t))}onMarkerClick(e,t,r={}){let a=this.markers.get(e);if(!a)throw new Error(`Marker with id ${e} not found`);return Microsoft.Maps.Events.addHandler(a,"click",o=>{let s=a.getLocation?a.getLocation():a.position,n={lat:s.latitude,lng:s.longitude,markerId:e,event:o};if(t&&t(n),r.popupHtml){let i=new Microsoft.Maps.Infobox(s,{description:r.popupHtml,visible:!0});this.map.entities.push(i)}(r.toast||r.toastMessage)&&this._showToast(r.toastMessage||"Marker clicked",r.toastDuration||3e3)}),e}_showToast(e,t=3e3){this.toastContainer||(this.toastContainer=document.createElement("div"),this.toastContainer.style.cssText=`
position: fixed;
top: 20px;
right: 20px;
z-index: 10000;
pointer-events: none;
`,document.body.appendChild(this.toastContainer));let r=document.createElement("div");return r.style.cssText=`
background: #333;
color: white;
padding: 12px 24px;
border-radius: 4px;
margin-bottom: 10px;
box-shadow: 0 2px 8px rgba(0,0,0,0.2);
opacity: 0;
transition: opacity 0.3s;
pointer-events: auto;
`,r.textContent=e,this.toastContainer.appendChild(r),setTimeout(()=>{r.style.opacity="1"},10),setTimeout(()=>{r.style.opacity="0",setTimeout(()=>{r.parentNode&&r.parentNode.removeChild(r)},300)},t),r}removeMarker(e){let t=this.markers.get(e);return t?(t instanceof Microsoft.Maps.CustomOverlay?this.map.layers.remove(t):this.map.entities.remove(t),this.markers.delete(e),!0):!1}updateMarker(e,t){let r=this.markers.get(e);if(!r)return!1;if(t.position){let a=typeof t.position.lat=="number"?t.position.lat:parseFloat(t.position.lat),o=typeof t.position.lng=="number"?t.position.lng:parseFloat(t.position.lng);if(typeof a!="number"||typeof o!="number"||!isFinite(a)||!isFinite(o))return console.error("Invalid position for Bing Maps marker update:",t.position),!1;try{r.setLocation(new Microsoft.Maps.Location(a,o))}catch(s){return console.error("Failed to update marker position:",s.message),!1}}return t.title!==void 0&&typeof r.setTitle=="function"&&r.setTitle(t.title),t.text!==void 0&&typeof r.setText=="function"&&r.setText(t.text),t.color!==void 0&&typeof r.setColor=="function"&&r.setColor(t.color),!0}setCenter(e){this._validateCoordinates(e.lat,e.lng)&&this.map.setView({center:new Microsoft.Maps.Location(e.lat,e.lng)})}getCenter(){let e=this.map.getCenter();return{lat:e.latitude,lng:e.longitude}}setZoom(e){this.map.setView({zoom:e})}getZoom(){return this.map.getZoom()}zoomIn(){this.map.setView({zoom:this.map.getZoom()+1})}zoomOut(){this.map.setView({zoom:this.map.getZoom()-1})}panTo(e){this._validateCoordinates(e.lat,e.lng)&&this.map.panTo(new Microsoft.Maps.Location(e.lat,e.lng))}fitBounds(e){let t=[new Microsoft.Maps.Location(e.southwest.lat,e.southwest.lng),new Microsoft.Maps.Location(e.northeast.lat,e.northeast.lng)],r=Microsoft.Maps.LocationRect.fromLocations(t);this.map.setView({bounds:r})}async geocode(e){return!e||typeof e!="string"?Promise.reject(new Error("Address must be a non-empty string")):new Promise((t,r)=>{let a=setTimeout(()=>{r(new Error("Geocoding request timeout"))},3e4);try{Microsoft.Maps.loadModule("Microsoft.Maps.Search",()=>{try{let o=new Microsoft.Maps.Search.SearchManager(this.map),s={where:e.trim(),callback:n=>{if(clearTimeout(a),n&&n.results&&n.results.length>0){let i=n.results[0];t({lat:i.location.latitude,lng:i.location.longitude,formattedAddress:i.address?.formattedAddress||i.name||e})}else r(new Error("No results found"))},errorCallback:async n=>{clearTimeout(a);let i=n&&n.message?n.message:n?JSON.stringify(n):"Unknown geocoding error";try{let l=await this._bingRestGeocode(e);if(l){t(l);return}}catch{}r(new Error(`Geocoding failed: ${i}`))}};o.geocode(s)}catch(o){clearTimeout(a),r(new Error(`Geocoding setup error: ${o.message}`))}})}catch(o){clearTimeout(a),r(new Error(`Geocoding initialization error: ${o.message}`))}})}async reverseGeocode(e,t){return this._validateCoordinates(e,t)?new Promise((r,a)=>{let o=setTimeout(()=>{a(new Error("Reverse geocoding request timeout"))},3e4);try{Microsoft.Maps.loadModule("Microsoft.Maps.Search",()=>{try{let s=new Microsoft.Maps.Search.SearchManager(this.map),i={location:new Microsoft.Maps.Location(e,t),callback:l=>{clearTimeout(o),l&&l.address?r({formattedAddress:l.address.formattedAddress,components:l.address}):a(new Error("No results found"))},errorCallback:async l=>{clearTimeout(o);let c=l&&l.message?l.message:l?JSON.stringify(l):"Unknown reverse geocoding error";try{let d=await this._bingRestReverseGeocode(e,t);if(d){r(d);return}}catch{}a(new Error(`Reverse geocoding failed: ${c}`))}};s.reverseGeocode(i)}catch(s){clearTimeout(o),a(new Error(`Reverse geocoding setup error: ${s.message}`))}})}catch(s){clearTimeout(o),a(new Error(`Reverse geocoding initialization error: ${s.message}`))}}):Promise.reject(new Error("Invalid coordinates"))}async _bingRestGeocode(e){try{let t=`https://dev.virtualearth.net/REST/v1/Locations?q=${encodeURIComponent(e)}&maxResults=1&key=${this.apiKey}`,r=await fetch(t);if(!r.ok)return null;let a=await r.json(),o=a&&a.resourceSets;if(o&&o.length>0&&o[0].resources&&o[0].resources.length>0){let s=o[0].resources[0],n=s.point&&s.point.coordinates;if(n&&n.length>=2)return{lat:n[0],lng:n[1],formattedAddress:s.address&&(s.address.formattedAddress||s.name)||e}}return null}catch{return null}}async _bingRestReverseGeocode(e,t){try{let r=`https://dev.virtualearth.net/REST/v1/Locations/${e},${t}?key=${this.apiKey}`,a=await fetch(r);if(!a.ok)return null;let o=await a.json(),s=o&&o.resourceSets;if(s&&s.length>0&&s[0].resources&&s[0].resources.length>0){let n=s[0].resources[0];return{formattedAddress:n.address&&n.address.formattedAddress||n.name||`${e},${t}`,components:n.address||{}}}return null}catch{return null}}drawRoute(e,t={}){let r=this._generateId(),a=e.map(s=>new Microsoft.Maps.Location(s.lat,s.lng)),o=new Microsoft.Maps.Polyline(a,{strokeColor:t.strokeColor||"#FF0000",strokeThickness:t.strokeWeight||3,strokeDashArray:t.strokeDashArray||"1"});return this.map.entities.push(o),this.polylines.set(r,o),r}async getDirections(e,t,r={}){return!e||typeof e.lat!="number"||typeof e.lng!="number"?Promise.reject(new Error("Origin must be an object with numeric lat and lng properties")):!t||typeof t.lat!="number"||typeof t.lng!="number"?Promise.reject(new Error("Destination must be an object with numeric lat and lng properties")):new Promise((a,o)=>{let s=setTimeout(()=>{o(new Error("Directions request timeout"))},3e4);try{Microsoft.Maps.loadModule("Microsoft.Maps.Directions",()=>{try{let n=new Microsoft.Maps.Directions.DirectionsManager(this.map);if(!n){clearTimeout(s),o(new Error("Failed to create DirectionsManager instance"));return}n.setRequestOptions({routeMode:r.travelMode||Microsoft.Maps.Directions.RouteMode.driving,routeOptimization:r.optimizeWaypoints?Microsoft.Maps.Directions.RouteOptimization.shortestTime:Microsoft.Maps.Directions.RouteOptimization.shortestDistance});let i=new Microsoft.Maps.Directions.Waypoint({location:new Microsoft.Maps.Location(e.lat,e.lng),address:e.address||""}),l=new Microsoft.Maps.Directions.Waypoint({location:new Microsoft.Maps.Location(t.lat,t.lng),address:t.address||""});n.addWaypoint(i),n.addWaypoint(l),Microsoft.Maps.Events.addHandler(n,"directionsUpdated",c=>{clearTimeout(s);try{if(c&&c.route&&c.route.length>0){let d=c.route[0];if(d&&d.routePath&&d.routePath.length>0){let p=this.drawRoute(d.routePath.map(u=>({lat:u.latitude,lng:u.longitude})),r);a({routeId:p,duration:d.duration,distance:d.distance})}else o(new Error("No route found: route path is empty"))}else o(new Error("No route found"))}catch(d){o(new Error(`Directions callback error: ${d.message}`))}}),Microsoft.Maps.Events.addHandler(n,"directionsError",c=>{clearTimeout(s);let d=c&&c.message?c.message:"Unknown error";o(new Error(`Directions failed: ${d}`))}),n.calculateDirections()}catch(n){clearTimeout(s),o(new Error(`Directions setup failed: ${n.message||n}`))}},n=>{clearTimeout(s),o(new Error(`Failed to load Bing Maps Directions module: ${n}`))})}catch(n){clearTimeout(s),o(new Error(`Directions failed: ${n.message||n}`))}})}drawPolygon(e,t={}){let r=this._generateId(),a=e.map(s=>new Microsoft.Maps.Location(s.lat,s.lng)),o=new Microsoft.Maps.Polygon(a,{fillColor:t.fillColor||"#FF0000",fillOpacity:t.fillOpacity||.35,strokeColor:t.strokeColor||"#FF0000",strokeThickness:t.strokeWeight||2});return this.map.entities.push(o),this.polygons.set(r,o),r}drawPolyline(e,t={}){return this.drawRoute(e,t)}drawCircle(e,t,r={}){let a=this._generateId(),o=64,s=[];for(let i=0;i<o;i++){let l=i/o*2*Math.PI,c=e.lat+t/111320*Math.cos(l),d=e.lng+t/(111320*Math.cos(e.lat*Math.PI/180))*Math.sin(l);s.push(new Microsoft.Maps.Location(c,d))}let n=new Microsoft.Maps.Polygon(s,{fillColor:r.fillColor||"#FF0000",fillOpacity:r.fillOpacity||.35,strokeColor:r.strokeColor||"#FF0000",strokeThickness:r.strokeWeight||2});return this.map.entities.push(n),this.polygons.set(a,n),a}drawRectangle(e,t={}){let r=this._generateId(),a=[new Microsoft.Maps.Location(e.southwest.lat,e.southwest.lng),new Microsoft.Maps.Location(e.northeast.lat,e.northeast.lng)],o=new Microsoft.Maps.Rectangle(Microsoft.Maps.LocationRect.fromLocations(a),{fillColor:t.fillColor||"#FF0000",fillOpacity:t.fillOpacity||.35,strokeColor:t.strokeColor||"#FF0000",strokeThickness:t.strokeWeight||2});return this.map.entities.push(o),this.polygons.set(r,o),r}enableTrafficLayer(){this.trafficLayer||(this.trafficLayer=new Microsoft.Maps.Traffic.TrafficManager(this.map)),this.trafficLayer.show()}disableTrafficLayer(){this.trafficLayer&&this.trafficLayer.hide()}addHeatMap(e,t={}){let r=this._generateId(),a=[];return e.forEach(o=>{let s=new Microsoft.Maps.Location(o.lat,o.lng),n=new Microsoft.Maps.Pushpin(s,{color:o.color||"#FF0000",opacity:t.opacity||.6});this.map.entities.push(n),a.push(n)}),this.heatmaps.set(r,a),r}addTileLayer(e,t={}){let r=this._generateId(),a=new Microsoft.Maps.TileLayer({uriConstructor:e,opacity:t.opacity||1});return this.map.layers.insert(a),this.layers.set(r,a),r}removeLayer(e){let t=this.layers.get(e);return t?(this.map.layers.remove(t),this.layers.delete(e),!0):!1}trackUserLocation(e,t={}){return navigator.geolocation?navigator.geolocation.watchPosition(a=>{let o={lat:a.coords.latitude,lng:a.coords.longitude,accuracy:a.coords.accuracy};e(o)},a=>console.error("Geolocation error:",a),{enableHighAccuracy:t.enableHighAccuracy||!1,timeout:t.timeout||5e3,maximumAge:t.maximumAge||0}):(console.error("Geolocation is not supported by this browser."),null)}getUserLocation(){return new Promise((e,t)=>{navigator.geolocation?navigator.geolocation.getCurrentPosition(r=>{e({lat:r.coords.latitude,lng:r.coords.longitude,accuracy:r.coords.accuracy})},r=>t(r),{enableHighAccuracy:!0,timeout:1e4,maximumAge:6e4}):t(new Error("Geolocation is not supported by this browser."))})}indoorMaps(e){console.info("Indoor maps support is limited in Bing Maps.")}applyMapStyle(e){typeof e=="string"?this.map.setMapStyle(e):typeof e=="object"&&this.map.setOptions(e)}enable3D(e){e?this.map.setView({pitch:45}):this.map.setView({pitch:0})}on(e,t){this.eventListeners.has(e)||this.eventListeners.set(e,[]);let r=Microsoft.Maps.Events.addHandler(this.map,e,t);this.eventListeners.get(e).push({callback:t,listener:r})}off(e,t){let r=this.eventListeners.get(e);if(r){let a=r.findIndex(o=>o.callback===t);if(a>-1){let{listener:o}=r[a];Microsoft.Maps.Events.removeHandler(o),r.splice(a,1)}}}getBounds(){let e=this.map.getBounds();return e?{southwest:{lat:e.getSouthwest().latitude,lng:e.getSouthwest().longitude},northeast:{lat:e.getNortheast().latitude,lng:e.getNortheast().longitude}}:null}destroy(){this.eventListeners.forEach((t,r)=>{t.forEach(({listener:a})=>{Microsoft.Maps.Events.removeHandler(a)})}),this.eventListeners.clear(),this.map.entities.clear(),this.markers.clear(),this.polylines.clear(),this.polygons.clear(),this.heatmaps.clear(),this.layers.clear();let e=this.getContainer();if(e)for(;e.firstChild;)e.removeChild(e.firstChild);this.map=null,this.trafficLayer=null}};var w=class extends h{constructor(e,t,r={}){super(e,t,r),this.eventListeners=new Map,this.tileLayers=new Map,this.currentBaseLayer=null}async init(){if(await this.loadLeafletScript(),!this.getContainer())throw new Error(`Container element with ID '${this.containerId}' not found.`);this.map=L.map(this.containerId,{center:[this.options.center?.lat||0,this.options.center?.lng||0],zoom:this.options.zoom||10,zoomControl:this.options.zoomControl!==!1,attributionControl:this.options.attributionControl!==!1,...this.options}),this.currentBaseLayer=L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",{attribution:"\xA9 OpenStreetMap contributors",maxZoom:19}),this.currentBaseLayer.addTo(this.map)}loadLeafletScript(){return new Promise((e,t)=>{if(window.L)return e();let r=document.createElement("link");r.href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css",r.rel="stylesheet",document.head.appendChild(r);let a=document.createElement("script");a.src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js",a.async=!0,a.onload=e,a.onerror=t,document.head.appendChild(a)})}addMarker(e){let t=this._generateId(),r=L.marker([e.lat,e.lng],{title:e.title||"",draggable:e.draggable||!1,clickable:e.clickable!==!1});return e.label&&r.bindTooltip(e.label),e.icon&&r.setIcon(L.icon(e.icon)),r.addTo(this.map),this.markers.set(t,r),t}addCustomMarker(e){if(!e||typeof e.lat!="number"||typeof e.lng!="number")throw new Error("addCustomMarker requires options with numeric lat and lng properties");let t=this._generateId(),r;if(e.html){let a=document.createElement("div");a.innerHTML=e.html,a.style.cursor="pointer";let o=L.divIcon({html:e.html,className:e.className||"custom-marker",iconSize:e.iconSize?[e.iconSize.width||32,e.iconSize.height||32]:[32,32]});r=L.marker([e.lat,e.lng],{icon:o})}else if(e.iconUrl){let a=L.icon({iconUrl:e.iconUrl,iconSize:e.iconSize?[e.iconSize.width||32,e.iconSize.height||32]:[32,32],iconAnchor:e.iconAnchor?[e.iconAnchor.x||16,e.iconAnchor.y||16]:[16,16]});r=L.marker([e.lat,e.lng],{icon:a,title:e.title||""})}else r=L.marker([e.lat,e.lng],{title:e.title||"",draggable:e.draggable||!1});return e.title&&!e.html&&r.bindPopup(e.title),r.addTo(this.map),this.markers.set(t,r),t}addCustomMarkers(e){if(!Array.isArray(e))throw new Error("addCustomMarkers requires an array of marker options");return e.map(t=>this.addCustomMarker(t))}onMarkerClick(e,t,r={}){let a=this.markers.get(e);if(!a)throw new Error(`Marker with id ${e} not found`);let o=s=>{let n={lat:s.latlng.lat,lng:s.latlng.lng,markerId:e,event:s};t&&t(n),r.popupHtml&&a.bindPopup(r.popupHtml).openPopup(),(r.toast||r.toastMessage)&&this._showToast(r.toastMessage||"Marker clicked",r.toastDuration||3e3)};return this.markerClickHandlers||(this.markerClickHandlers=new Map),this.markerClickHandlers.set(e,o),a.on("click",o),e}_showToast(e,t=3e3){this.toastContainer||(this.toastContainer=document.createElement("div"),this.toastContainer.style.cssText=`
position: fixed;
top: 20px;
right: 20px;
z-index: 10000;
pointer-events: none;
`,document.body.appendChild(this.toastContainer));let r=document.createElement("div");return r.style.cssText=`
backgro