View Issue Details

IDProjectCategoryView StatusLast Update
0038875pas2jsrtlpublic2021-05-27 13:16
Reporterhenrique Assigned ToMichael Van Canneyt  
PrioritynormalSeverityminorReproducibilityalways
Status assignedResolutionopen 
PlatformPas2JsOSWindows 
Summary0038875: Maps implementation
DescriptionI don't know if it's this way to send the implementation I did.

But I implemented the classes to interact with google, bing, and OSM maps with Leaflet.

I haven't used all the available resources, but it's a foundation to get started and help me fully implement maps.
TagsNo tags attached.
Fixed in Revision
Attached Files

Relationships

related to 0038858 assignedMattias Gaertner Subclass construction 

Activities

henrique

2021-05-11 19:21

reporter  

0001-Implementa-o-da-base-dos-mapas.patch (186,092 bytes)   
From ac21a4395cef9864d440a1fc9af6233ca5ade688 Mon Sep 17 00:00:00 2001
From: Henrique Gottardi Werlang <henriquewerlang@hotmail.com>
Date: Tue, 11 May 2021 16:17:36 -0300
Subject: [PATCH] =?UTF-8?q?Implementa=C3=A7=C3=A3o=20da=20base=20dos=20map?=
 =?UTF-8?q?as.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 packages/maps/Bing.Maps.pas    |  873 +++++++++++++
 packages/maps/GeoJSON.pas      |  166 +++
 packages/maps/Google.Maps.pas  | 2170 ++++++++++++++++++++++++++++++++
 packages/maps/Leaflet.Maps.pas | 1856 +++++++++++++++++++++++++++
 4 files changed, 5065 insertions(+)
 create mode 100644 packages/maps/Bing.Maps.pas
 create mode 100644 packages/maps/GeoJSON.pas
 create mode 100644 packages/maps/Google.Maps.pas
 create mode 100644 packages/maps/Leaflet.Maps.pas

diff --git a/packages/maps/Bing.Maps.pas b/packages/maps/Bing.Maps.pas
new file mode 100644
index 00000000..72625916
--- /dev/null
+++ b/packages/maps/Bing.Maps.pas
@@ -0,0 +1,873 @@
+unit Bing.Maps;
+
+interface
+
+{$modeswitch externalclass}
+
+uses Web, JS, SysUtils;
+
+type
+  TAddress = class;
+  TAnimatedFrameEventArgs = class;
+  TAnimatedTileLayerOptions  = class;
+  TBorderedMapElementStyle = class;
+  TCustomMapStyle = class;
+  TCustomOverlayOptions = class;
+  TGroundOverlayOptions = class;
+  THandlerId = class;
+  TInfoboxEventArgs = class;
+  TInfoboxOptions  = class;
+  TLayer = class;
+  TMapElementStyle = class;
+  TMapElements = class;
+  TMapOptions = class;
+  TMapTypeChangeEventArgs = class;
+  TModuleOptions = class;
+  TMouseEventArgs = class;
+  TPanoramaInfo = class;
+  TPolygonOptions = class;
+  TPolylineOptions = class;
+  TPrimitiveChangedEventArgs = class;
+  TPrimitiveOptions = class;
+  TPushpinOptions = class;
+  TRange = class;
+  TSettingsStyle = class;
+  TStreetsideOptions  = class;
+  TStyleUrl = class;
+  TStylesOptions = class;
+  TTileLayerOptions = class;
+  TTileSourceOptions = class;
+  TViewOptions = class;
+
+  TMicrosoft = class external name 'Microsoft'
+  public type
+    TMaps = class external name 'Maps'
+    public type
+      TCustomOverlay = class;
+      TInfobox = class;
+      TLayer = class;
+      TLocation = class;
+      TLocationRect = class;
+      TMap = class;
+      TPoint = class;
+      TPolygon = class;
+      TPolyline = class;
+      TPushpin = class;
+      TTileSource = class;
+
+      TLabelOverlay = (loHidden, loVisible);
+      TMapTypeId = (mtAerial, mtBirdseye, mtCanvasDark, mtCanvasLight, mtGrayscale, mtMercator, mtOrdnanceSurvey, mtRoad, mtStreetside);
+      TNavigationBarMode = (nbCompact, nbDefault, nbMinified);
+      TNavigationBarOrientation = (nboHorizontal, nboVertical);
+      TOverviewMapMode = (omExpanded, omHidden, omMinimized);
+      TPixelReference = (prControl, prPage, prViewport);
+
+      TPrimitive = class external name 'Primitive' abstract
+      public
+        function getCursor: String;
+        function getVisible: Boolean;
+        procedure setOptions(options: TPrimitiveOptions);
+      end;
+
+      TAnimatedTileLayer = class external name 'AnimatedTileLayer'
+      public
+        constructor Create(options: TAnimatedTileLayerOptions); external name '';
+
+        function getFrameRate: Double;
+        function getLoadingScreen: TCustomOverlay;
+        function getMaxTotalLoadTime: Double;
+        function getTileSources: TArray<TTileSource>;
+        function getVisible: Boolean;
+
+        procedure pause;
+        procedure play;
+        procedure setOptions(options: TAnimatedTileLayerOptions);
+        procedure stop;
+      end;
+
+      TColor = class external name 'Color'
+      public
+        a: Double;
+        r: Double;
+        g: Double;
+        b: Double;
+
+        constructor Create(a: Double; r: Double; g: Double; b: Double); external name '';
+
+        class function clone(color: TColor): TColor; overload;
+        class function fromHex(hex: String): TColor;
+
+        function clone: TColor; overload;
+        function getOpacity: Double;
+        function toHex: String;
+        function toRgba: String;
+      end;
+
+      TLayer = class external name 'Layer'
+      public
+        metadata: JSValue;
+
+        constructor Create(id: String); external name '';
+
+        function getId: String;
+        function getPrimitives: TArray<TPrimitive>;
+        function getVisible: Boolean;
+        function getZIndex: Double;
+        function remove(primitive: TPrimitive): TPrimitive;
+        function removeAt(index: Double): TPrimitive;
+
+        procedure add(primitive: TArray<TPrimitive>; index: Double);
+        procedure clear;
+        procedure dispose;
+        procedure setPrimitives(primitives: TArray<TPrimitive>);
+        procedure setVisible(value: Boolean);
+        procedure setZIndex(zIndex: Double);
+      end;
+
+      TCustomOverlay = class external name 'CustomOverlay' (TLayer)
+      public
+        _map: TMap;
+
+        constructor Create(options: TCustomOverlayOptions); external name '';
+
+        function getHtmlElement: TJSHTMLElement;
+        function getMap: TMap;
+
+        procedure onAdd;
+        procedure onLoad;
+        procedure onRemove;
+        procedure setHtmlElement(htmlElement: TJSHTMLElement);
+      end;
+
+      TEvents = class external name 'Events'
+      public
+        function addHandler(target: JSValue; eventName: String; handler: TProc<JSValue>): THandlerId; overload;
+        function addHandler(target: TInfobox; eventName: String; handler: TProc<TInfoboxEventArgs>): THandlerId; overload;
+        function addHandler(target: TLayer; eventName: String; handler: TProc<TMouseEventArgs>): THandlerId; overload;
+        function addHandler(target: TMap; eventName: String; handler: TProc<TMapTypeChangeEventArgs>): THandlerId; overload;
+        function addHandler(target: TMap; eventName: String; handler: TProc<TMouseEventArgs>): THandlerId; overload;
+        function addHandler(target: TPolygon; eventName: String; handler: TProc<TMouseEventArgs>): THandlerId; overload;
+        function addHandler(target: TPolygon; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>): THandlerId; overload;
+        function addHandler(target: TPolyline; eventName: String; handler: TProc<TMouseEventArgs>): THandlerId; overload;
+        function addHandler(target: TPolyline; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>): THandlerId; overload;
+        function addHandler(target: TPushpin; eventName: String; handler: TProc<TMouseEventArgs>): THandlerId; overload;
+        function addHandler(target: TPushpin; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>): THandlerId; overload;
+        function addThrottledHandler(target: JSValue; eventName: String; handler: TProc<JSValue>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TInfobox; eventName: String; handler: TProc<TInfoboxEventArgs>): THandlerId; overload;
+        function addThrottledHandler(target: TLayer; eventName: String; handler: TProc<TMouseEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TMap; eventName: String; handler: TProc<TMapTypeChangeEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TMap; eventName: String; handler: TProc<TMouseEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPolygon; eventName: String; handler: TProc<TMouseEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPolygon; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPolyline; eventName: String; handler: TProc<TMouseEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPolyline; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPushpin; eventName: String; handler: TProc<TMouseEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPushpin; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function hasHandler(target: JSValue; eventName: String): Boolean;
+
+        procedure addOne(target: JSValue; eventName: String; handler: TProc<JSValue>); overload;
+        procedure addOne(target: TInfobox; eventName: String; handler: TProc<TInfoboxEventArgs>); overload;
+        procedure addOne(target: TLayer; eventName: String; handler: TProc<TMouseEventArgs>); overload;
+        procedure addOne(target: TMap; eventName: String; handler: TProc<TMapTypeChangeEventArgs>); overload;
+        procedure addOne(target: TMap; eventName: String; handler: TProc<TMouseEventArgs>); overload;
+        procedure addOne(target: TPolygon; eventName: String; handler: TProc<TMouseEventArgs>); overload;
+        procedure addOne(target: TPolygon; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>); overload;
+        procedure addOne(target: TPolyline; eventName: String; handler: TProc<TMouseEventArgs>); overload;
+        procedure addOne(target: TPolyline; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>); overload;
+        procedure addOne(target: TPushpin; eventName: String; handler: TProc<TMouseEventArgs>); overload;
+        procedure addOne(target: TPushpin; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>); overload;
+        procedure invoke(target: JSValue; evenName: String; args: JSValue);
+        procedure removeHandler(handlerId: THandlerId);
+      end;
+
+      TGroundOverlay = class external name 'GroundOverlay' (TCustomOverlay)
+      public
+        metadata: JSValue; external name 'metadata';
+
+        constructor Create(options: TGroundOverlayOptions); external name '';
+
+        function getBackgroundColor: TColor;
+        function getBounds: TLocationRect;
+        function getImageUrl: String;
+        function getMap: TMap;
+        function getOpacity: Double;
+        function getRotation: Double;
+        function getVisible: Boolean;
+
+        procedure setOptions(options: TGroundOverlayOptions);
+        procedure setVisible(visible: Boolean);
+      end;
+
+      THeading = class external name 'Heading'
+      public
+        class var East: Double;
+        class var North: Double;
+        class var South: Double;
+        class var West: Double;
+      end;
+
+      TInfobox = class external name 'Infobox'
+      public
+        constructor Create(location: TLocation; options: TInfoboxOptions); external name '';
+
+        function getAnchor: TPoint;
+        function getDescription: String;
+        function getHeight: Double;
+        function getHtmlContent: String;
+        function getLocation: TLocation;
+        function getMaxHeight: Double;
+        function getMaxWidth: Double;
+        function getOffset: TPoint;
+        function getOptions: TInfoboxOptions;
+        function getShowCloseButton: Boolean;
+        function getShowPointer: Boolean;
+        function getTitle: String;
+        function getVisible: Boolean;
+        function getWidth: Double;
+        function getZIndex: Double;
+
+        procedure setHtmlContent(content: String);
+        procedure setLocation(loc: TLocation);
+        procedure setMap(Map: TMap);
+        procedure setOptions(options: TInfoboxOptions; ignoreDelay: Boolean);
+      end;
+
+      TLayerCollection = class external name 'LayerCollection'
+      public
+        length: Double;
+
+        function indexOf(layer: TLayer): Double;
+
+        procedure clear;
+        procedure insert(layer: TLayer);
+        procedure insertAll(layers: TArray<TLayer>);
+        procedure remove(layer: TLayer);
+        procedure removeAt(idx: Double);
+      end;
+
+      TLocation = class external name 'Location'
+      public
+        latitude: Double;
+        longitude: Double;
+
+        constructor Create(latitude, longitude: Double); external name '';
+
+        class function areEqual(location1: TLocation; location2: TLocation): Boolean;
+        class function cloneFrom(source: TLocation): TLocation;
+        class function normalizeLongitude(longitude: Double): Double;
+        class function parseLatLong(str: String): TLocation;
+
+        function clone: TLocation;
+        function toString: String;
+      end;
+
+      TLocationRect = class external name 'LocationRect'
+      public
+        center: TLocation;
+        height: Double;
+        width: Double;
+
+        constructor Create(center: TLocation; width: Double; height: Double); external name '';
+
+        class function fromCorners(northwest: TLocation; southeast: TLocation): TLocationRect;
+        class function fromEdges(north: Double; west: Double; south: Double; east: Double): TLocationRect;
+        class function fromLocations(locations: TArray<TLocation>): TLocationRect;
+        class function fromShapes(shapes: TArray<TArray<TPrimitive>>): TLocationRect; overload;
+        class function fromShapes(shapes: TArray<TPrimitive>): TLocationRect; overload;
+        class function fromString(str: String): TLocationRect;
+        class function merge(rect1: TLocationRect; rect2: TLocationRect): TLocationRect;
+
+        function clone: TLocationRect;
+        function contains(location: TLocation): Boolean;
+        function crossesInternationalDateLine: Boolean;
+        function getEast: Double;
+        function getNorth: Double;
+        function getNorthwest: TLocation;
+        function getSouth: Double;
+        function getSoutheast: TLocation;
+        function getWest: Double;
+        function intersects(rect: TLocationRect): Boolean;
+        function splitByInternationalDateLine: TArray<TLocationRect>;
+        function toString: String;
+
+        procedure buffer(percentage: Double);
+      end;
+
+      TMap = class external name 'Map'
+      public
+        layers: TLayerCollection;
+
+        constructor Create(parentElement: String; options: TMapOptions); external name ''; overload;
+        constructor Create(parentElement: TJSHTMLElement; options: TMapOptions); external name ''; overload;
+        constructor Create(parentElement: String; options: TViewOptions); external name ''; overload;
+        constructor Create(parentElement: TJSHTMLElement; options: TViewOptions); external name ''; overload;
+
+        class function getVersion: String;
+
+        function getBounds: TLocationRect;
+        function getCenter: TLocation;
+        function getCulture: String;
+        function getHeading: Double;
+        function getHeight: Double;
+        function getImageryId: String;
+        function getMapTypeId: TMapTypeId;
+        function getMetersPerPixel: Double;
+        function getOptions: TMapOptions;
+        function getPageX: Double;
+        function getPageY: Double;
+        function getPitch: Double;
+        function getRootElement: TJSHTMLElement;
+        function getUserRegion: String;
+        function getWidth: Double;
+        function getZoom: Double;
+        function getZoomRange: TRange;
+        function isMercator: Boolean;
+        function isRotationEnabled: Boolean;
+        function tryLocationToPixel(location: TArray<TLocation>; reference: JSValue): TArray<TPoint>;
+        function tryPixelToLocation(point: TArray<TPoint>; reference: JSValue): TArray<TLocation>;
+
+        class procedure getClosestPanorama(bounds: TLocationRect; success: TProc<TPanoramaInfo>; missingCoverage: TProc);
+
+        procedure dispose;
+        procedure getCopyrights(callback: TProc<TArray<String>>);
+        procedure getCredentials(callback: TProc<String>);
+        procedure setMapType(mapTypeId: TMapTypeId);
+        procedure setOptions(options: TMapOptions);
+        procedure setView(viewOptions: TViewOptions);
+      end;
+
+      TPoint = class external name 'Point'
+      public
+        x: Double;
+        y: Double;
+
+        constructor Create(x: Double; y: Double); external name '';
+
+        function add(point: TPoint): TPoint;
+        function clone: TPoint;
+        function equals(point: TPoint; tolerance: Double): Boolean;
+        function subtract(point: TPoint): TPoint;
+        function toString: String;
+      end;
+
+      TPointCompression = class external name 'ointCompression'
+      public
+        class function decode(value: String): TArray<TLocation>;
+        class function encode(locations: TArray<TLocation>): String;
+      end;
+
+      TPolygon = class external name 'Polygon' (TPrimitive)
+      public
+        metadata: JSValue;
+
+        constructor Create(rings: TArray<TArray<TLocation>>; options: TPolygonOptions); external name ''; overload;
+        constructor Create(rings: TArray<TLocation>; options: TPolygonOptions); external name ''; overload;
+
+        function getCursor: String;
+        function getFillColor: TColor;
+        function getGeneralizable: Boolean;
+        function getLocations: TArray<TLocation>;
+        function getRings: TArray<TArray<TLocation>>;
+        function getStrokeColor: TColor;
+        function getStrokeDashArray: TArray<Double>;
+        function getStrokeDashArrayString: String; external name 'getStrokeDashArray';
+        function getStrokeThickness: Double;
+        function getVisible: Boolean;
+
+        procedure setLocations(locations: TArray<TLocation>);
+        procedure setOptions(options: TPolygonOptions);
+        procedure setRings(rings: TArray<TArray<TLocation>>); overload;
+        procedure setRings(rings: TArray<TLocation>); overload;
+      end;
+
+      TPolyline = class external name 'Polyline' (TPrimitive)
+      public
+        metadata: JSValue;
+
+        constructor Create(locations: TArray<TLocation>; options: TPolylineOptions); external name '';
+
+        function getCursor: String;
+        function getGeneralizable: Boolean;
+        function getLocations: TArray<TLocation>;
+        function getStrokeColor: TColor;
+        function getStrokeDashArray: TArray<Double>;
+        function getStrokeDashArrayString: String; external name 'getStrokeDashArray';
+        function getStrokeThickness: Double;
+        function getVisible: Boolean;
+
+        procedure setLocations(locations: TArray<TLocation>);
+        procedure setOptions(options: TPolylineOptions);
+      end;
+
+      TPushpin = class external name 'Pushpin' (TPrimitive)
+      public
+        metadata: JSValue;
+
+        constructor Create(location: TLocation; options: TPushpinOptions); external name '';
+
+        function getAnchor: TPoint;
+        function getClickedStyleEnabled: Boolean;
+        function getColor: TColor;
+        function getCursor: String;
+        function getDraggable: Boolean;
+        function getHoverStyleEnabled: Boolean;
+        function getIcon: String;
+        function getLocation: TLocation;
+        function getRoundClickableArea: Boolean;
+        function getSubTitle: String;
+        function getText: String;
+        function getTextOffset: TPoint;
+        function getTitle: String;
+        function getVisible: Boolean;
+
+        procedure setLocation(location: TLocation);
+        procedure setOptions(options: TPushpinOptions);
+      end;
+
+      TPyramidTileId = class external name 'PyramidTileId'
+      public
+        pixelHeight: Double;
+        pixelWidth: Double;
+        quadKey: String;
+        x: Double;
+        y: Double;
+        zoom: Double;
+
+        constructor Create(x: Double; y: Double; zoom: Double; width: Double; height: Double) external name '';
+
+        class function areEqual(tileId1: TPyramidTileId; tileId2: TPyramidTileId): Boolean;
+        class function fromQuadKey(quadkey: String; width: Double; height: Double): TPyramidTileId;
+      end;
+
+      TTileLayer = class external name 'TileLayer' (TLayer)
+      public
+        metadata: JSValue;
+
+        constructor Create(options: TTileLayerOptions); external name '';
+
+        function getOpacity: Double;
+        function getTileSource: TTileSource;
+        function getVisible: Boolean;
+        function getZIndex: Double;
+
+        procedure setOpacity(opacity: Double);
+        procedure setOptions(options: TTileLayerOptions);
+        procedure setVisible(show: Boolean);
+        procedure setZIndex(idx: Double);
+      end;
+
+      TTileSource = class external name 'TileSource'
+      public
+        constructor Create(options: TTileSourceOptions); external name '';
+
+        function getBounds: TLocationRect;
+        function getHeight: Double;
+        function getMaxZoom: Double;
+        function getMinZoom: Double;
+        function getUriConstructor(tile: TPyramidTileId): String; overload;
+        function getUriConstructor: String; overload;
+        function getWidth: Double;
+      end;
+    public
+      class var Credentials: String;
+
+      procedure getIsBirdseyeAvailable(loc: TLocation; heading: Double; callback: TProc<Boolean>); overload;
+      procedure getIsBirdseyeAvailable(loc: TLocation; heading: THeading; callback: TProc<Boolean>); overload;
+      procedure loadModule(moduleName: TArray<String>; options: TModuleOptions); overload;
+      procedure loadModule(moduleName: TArray<String>; options: TProc); overload;
+      procedure moduleLoaded(moduleName: String);
+      procedure registerModule(moduleName: String; url: String; styles: TStyleUrl);
+    end;
+  end;
+
+  TAddress = class
+  public
+    addressLine: String;
+    adminDistrict: String;
+    countryRegion: String;
+    countryRegionISO2: String;
+    district: String;
+    formattedAddress: String;
+    locality: String;
+    postalCode: String;
+  end;
+
+  TAnimatedFrameEventArgs = class
+  public
+    animatedTileLayer: TMicrosoft.TMaps.TAnimatedTileLayer;
+    index: Double;
+  end;
+
+  TAnimatedTileLayerOptions = class
+  public
+    autoPlay: Boolean;
+    frameRate: Double;
+    loadingScreen: TMicrosoft.TMaps.TCustomOverlay;
+    maxTotalLoadTime: Double;
+    mercator: TArray<TMicrosoft.TMaps.TTileSource>;
+    visible: Boolean;
+  end;
+
+  TCustomOverlayOptions = class
+  public
+    beneathLabels: Boolean;
+  end;
+
+  TGroundOverlayOptions = class(TCustomOverlayOptions)
+  public
+    backgroundColor: TMicrosoft.TMaps.TColor;
+    bounds: TMicrosoft.TMaps.TLocationRect;
+    imageUrl: String;
+    opacity: Double;
+    rotation: Double;
+    visible: Boolean;
+  end;
+
+  THandlerId = class
+  end;
+
+  TLayer = class
+  end;
+
+  TInfoboxOptions  = class
+  public
+    description: String;
+    closeDelayTime: Double;
+    htmlContent: String;
+    location: TMicrosoft.TMaps.TLocation;
+    maxHeight: Double;
+    maxWidth: Double;
+    offset: TMicrosoft.TMaps.TPoint;
+    showCloseButton: Boolean;
+    showPointer: Boolean;
+    title: String;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TInfoboxEventArgs = class
+  public
+    eventName: String;
+    pageX: Double;
+    pageY: Double;
+    target: TMicrosoft.TMaps.TInfobox;
+    targetType: String;
+    originalEvent: TJSMouseEvent;
+  end;
+
+  TMapOptions = class
+  public
+    allowHidingLabelsOfRoad: Boolean;
+    allowInfoboxOverflow: Boolean;
+    backgroundColor: TMicrosoft.TMaps.TColor;
+    customMapStyle: TCustomMapStyle;
+    disableBirdseye: Boolean;
+    disableKeyboardInput: Boolean;
+    disableMapTypeSelectorMouseOver: Boolean;
+    disablePanning: Boolean;
+    disableScrollWheelZoom: Boolean;
+    disableStreetside: Boolean;
+    disableStreetsideAutoCoverage: Boolean;
+    disableZooming: Boolean;
+    enableClickableLogo: Boolean;
+    enableCORS: Boolean;
+    enableHighDpi: Boolean;
+    enableInertia: Boolean;
+    liteMode: Boolean;
+    maxBounds: TMicrosoft.TMaps.TLocationRect;
+    maxZoom: Double;
+    minZoom: Double;
+    navigationBarMode: TMicrosoft.TMaps.TNavigationBarMode;
+    navigationBarOrientation: TMicrosoft.TMaps.TNavigationBarOrientation;
+    showBreadcrumb: Boolean;
+    showDashboard: Boolean;
+    showLocateMeButton: Boolean;
+    showLogo: Boolean;
+    showMapTypeSelector: Boolean;
+    showScalebar: Boolean;
+    showTrafficButton: Boolean;
+    showTermsLink: Boolean;
+    showZoomButtons: Boolean;
+    streetsideOptions: TStreetsideOptions;
+    supportedMapTypes: TArray<TMicrosoft.TMaps.TMapTypeId>;
+  end;
+
+  TMapTypeChangeEventArgs = class
+  public
+    newMapTypeId: TMicrosoft.TMaps.TMapTypeId;
+    oldMapTypeId: TMicrosoft.TMaps.TMapTypeId;
+    target: TMicrosoft.TMaps.TMap;
+    targetType: String;
+  end;
+
+  TModuleOptions = class
+  public
+    errorCallback: TProc;
+    credentials: String;
+  end;
+
+  TMouseEventArgs = class
+  public
+    eventName: String;
+    isPrimary: Boolean;
+    isSecondary: Boolean;
+    layer: TMicrosoft.TMaps.TLayer;
+    location: TMicrosoft.TMaps.TLocation;
+    pageX: Double;
+    pageY: Double;
+    point: TMicrosoft.TMaps.TPoint;
+    target: TMicrosoft.TMaps.TMap;
+    targetPrimitive: TMicrosoft.TMaps.TPrimitive; external name 'target';
+    targetType: String;
+    wheelDelta: Double;
+  end;
+
+  TPanoramaInfo = class
+  public
+    cd: String;
+  end;
+
+  TPrimitiveChangedEventArgs = class
+  public
+    sender: TMicrosoft.TMaps.TPrimitive;
+    name: String;
+  end;
+
+  TPrimitiveOptions = class
+  public
+    cursor: String;
+    visible: Boolean;
+  end;
+
+  TPolylineOptions = class(TPrimitiveOptions)
+  public
+    generalizable: Boolean;
+    strokeColor: TMicrosoft.TMaps.TColor;
+    strokeDashArray: TArray<Double>;
+    strokeDashArrayString: String; external name 'strokeDashArray';
+    strokeThickness: Double;
+  end;
+
+  TPolygonOptions = class(TPolylineOptions)
+  public
+    fillColor: TMicrosoft.TMaps.TColor;
+  end;
+
+  TPushpinOptions = class(TPrimitiveOptions)
+  public
+    anchor: TMicrosoft.TMaps.TPoint;
+    color: TMicrosoft.TMaps.TColor;
+    draggable: Boolean;
+    enableClickedStyle: Boolean;
+    enableHoverStyle: Boolean;
+    icon: String;
+    roundClickableArea: Boolean;
+    subTitle: String;
+    title: String;
+    text: String;
+    textOffset: TMicrosoft.TMaps.TPoint;
+  end;
+
+  TRange = class
+  public
+    min: Double;
+    max: Double;
+  end;
+
+  TStreetsideOptions  = class
+  public
+    disablePanoramaNavigation: Boolean;
+    locationToLookAt: TMicrosoft.TMaps.TLocation;
+    onErrorLoading: TProc;
+    onSuccessLoading: TProc;
+    overviewMapMode: TMicrosoft.TMaps.TOverviewMapMode;
+    panoramaInfo: TPanoramaInfo;
+    panoramaLookupRadius: Double;
+    showCurrentAddress: Boolean;
+    showExitButton: Boolean;
+    showHeadingCompass: Boolean;
+    showProblemReporting: Boolean;
+    showZoomButtons: Boolean;
+  end;
+
+  TStylesOptions = class
+  public
+    pushpinOptions: TPushpinOptions;
+    polylineOptions: TPolylineOptions;
+    polygonOptions: TPolygonOptions;
+  end;
+
+  TStyleUrl = class
+  public
+    styleURLs: TArray<String>;
+  end;
+
+  TTileLayerOptions = class
+  public
+    enableCORS: Boolean;
+    downloadTimeout: Double;
+    mercator: TMicrosoft.TMaps.TTileSource;
+    opacity: Double;
+    useCredentialsForCORS: Boolean;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TTileSourceOptions = class
+  public
+    bounds: TMicrosoft.TMaps.TLocationRect;
+    maxZoom: Double;
+    minZoom: Double;
+    uriConstructor: String;
+    uriConstructorFunction: TFunc<TMicrosoft.TMaps.TPyramidTileId, String>; external name 'uriConstructor';
+  end;
+
+  TViewOptions = class
+  public
+    bounds: TMicrosoft.TMaps.TLocationRect;
+    center: TMicrosoft.TMaps.TLocation;
+    centerOffset: TMicrosoft.TMaps.TPoint;
+    heading: Double;
+    labelOverlay: TMicrosoft.TMaps.TLabelOverlay;
+    mapTypeId: TMicrosoft.TMaps.TMapTypeId;
+    padding: Double;
+    pitch: Double;
+    zoom: Double;
+  end;
+
+  TMapElementStyle = class
+  public
+    fillColor: String;
+    labelColor: String;
+    labelOutlineColor: String;
+    labelVisible: boolean;
+    strokeColor: String;
+    visible: Boolean;
+  end;
+
+  TBorderedMapElementStyle = class(TMapElementStyle)
+  public
+    borderOutlineColor: String;
+    borderStrokeColor: String;
+    borderVisible: Boolean;
+  end;
+
+  TSettingsStyle = class
+  public
+    landColor: String;
+    shadedReliefVisible: Boolean;
+  end;
+
+  TMapElements = class
+  public
+    adminDistrict: TBorderedMapElementStyle;
+    adminDistrictCapital: TMapElementStyle;
+    airport: TMapElementStyle;
+    area: TMapElementStyle;
+    arterialRoad: TMapElementStyle;
+    building: TMapElementStyle;
+    business: TMapElementStyle;
+    capital: TMapElementStyle;
+    cemetery: TMapElementStyle;
+    continent: TMapElementStyle;
+    controlledAccessHighway: TMapElementStyle;
+    countryRegion: TBorderedMapElementStyle;
+    countryRegionCapital: TMapElementStyle;
+    district: TBorderedMapElementStyle;
+    education: TMapElementStyle;
+    educationBuilding: TMapElementStyle;
+    foodPoint: TMapElementStyle;
+    forest: TMapElementStyle;
+    golfCourse: TMapElementStyle;
+    highSpeedRamp: TMapElementStyle;
+    highway: TMapElementStyle;
+    indigenousPeoplesReserve: TMapElementStyle;
+    island: TMapElementStyle;
+    majorRoad: TMapElementStyle;
+    mapElement: TMapElementStyle;
+    medical: TMapElementStyle;
+    medicalBuilding: TMapElementStyle;
+    military: TMapElementStyle;
+    naturalPoint: TMapElementStyle;
+    nautical: TMapElementStyle;
+    neighborhood: TMapElementStyle;
+    park: TMapElementStyle;
+    peak: TMapElementStyle;
+    playingField: TMapElementStyle;
+    point: TMapElementStyle;
+    pointOfInterest: TMapElementStyle;
+    political: TBorderedMapElementStyle;
+    populatedPlace: TMapElementStyle;
+    railway: TMapElementStyle;
+    ramp: TMapElementStyle;
+    reserve: TMapElementStyle;
+    river: TMapElementStyle;
+    road: TMapElementStyle;
+    roadExit: TMapElementStyle;
+    runway: TMapElementStyle;
+    sand: TMapElementStyle;
+    shoppingCenter: TMapElementStyle;
+    stadium: TMapElementStyle;
+    street: TMapElementStyle;
+    structure: TMapElementStyle;
+    tollRoad: TMapElementStyle;
+    trail: TMapElementStyle;
+    transit: TMapElementStyle;
+    transitBuilding: TMapElementStyle;
+    transportation: TMapElementStyle;
+    unpavedStreet: TMapElementStyle;
+    vegetation: TMapElementStyle;
+    volcanicPeak: TMapElementStyle;
+    water: TMapElementStyle;
+    waterPoint: TMapElementStyle;
+    waterRoute: TMapElementStyle;
+  end;
+
+  TCustomMapStyle = class
+  public
+    elements: TMapElements;
+    settings: TSettingsStyle;
+    version: String;
+  end;
+
+function InitializeMap(Key: String): TJSPromise;
+
+implementation
+
+var
+  GResolvePromise: TJSPromiseResolver;
+
+procedure MapLoaded;
+begin
+  if Assigned(GResolvePromise) then
+    GResolvePromise(True);
+end;
+
+function InitializeMap(Key: String): TJSPromise;
+begin
+  GResolvePromise := nil;
+
+  MapLoaded;
+
+  Result := TJSPromise.New(
+    procedure(Resolve, Reject: TJSPromiseResolver)
+    var
+      Script: TJSHTMLScriptElement;
+
+    begin
+      GResolvePromise := Resolve;
+      Script := TJSHTMLScriptElement(document.createElement('script'));
+      Script.async := False;
+      Script.text := 'function BingMapLoaded(){pas["Bing.Maps"].$impl.MapLoaded();}';
+
+      document.head.appendChild(Script);
+
+      Script := TJSHTMLScriptElement(document.createElement('script'));
+      Script.src := Format('https://www.bing.com/maps/sdk/mapcontrol?key=%s&callback=BingMapLoaded', [Key]);
+
+      document.head.appendChild(Script);
+    end);
+end;
+
+end.
+
diff --git a/packages/maps/GeoJSON.pas b/packages/maps/GeoJSON.pas
new file mode 100644
index 00000000..ca5ad2cc
--- /dev/null
+++ b/packages/maps/GeoJSON.pas
@@ -0,0 +1,166 @@
+unit GeoJSON;
+
+interface
+
+{$modeswitch externalclass}
+
+uses JS;
+
+type
+  TBBox = TArray<Double>;
+  TPosition = TArray<Double>;
+
+  TGeoJsonObject = class
+  private
+    function GetForeignMember(name: String): JSValue; external name '[]';
+
+    procedure SetForeignMember(name: String; value: JSValue); external name '[]';
+  public
+    &type: String;
+    bbox: TBBox;
+
+    constructor Create(&type: String);
+
+    property ForeignMember[name: String]: JSValue read GetForeignMember write SetForeignMember; default;
+  end;
+
+  TGeometryObject = class(TGeoJsonObject)
+
+  end;
+
+  TPoint = class (TGeometryObject)
+  public
+    coordinates: TPosition;
+
+    constructor Create;
+  end;
+
+  TMultiPoint = class (TGeometryObject)
+  public
+    coordinates: TArray<TPosition>;
+    constructor Create;
+  end;
+
+  TLineString = class (TGeometryObject)
+  public
+    coordinates: TArray<TPosition>;
+
+    constructor Create;
+  end;
+
+  TMultiLineString = class (TGeometryObject)
+  public
+    coordinates: TArray<TArray<TPosition>>;
+
+    constructor Create;
+  end;
+
+  TPolygon = class(TGeometryObject)
+  public
+    coordinates: TArray<TArray<TPosition>>;
+
+    constructor Create;
+  end;
+
+  TMultiPolygon = class(TGeometryObject)
+  public
+    coordinates: TArray<TArray<TArray<TPosition>>>;
+
+    constructor Create;
+  end;
+
+  TGeometryCollection = class(TGeoJsonObject)
+  public
+    geometries: TArray<TGeometryObject>;
+
+    constructor Create;
+  end;
+
+  TFeature = class (TGeoJsonObject)
+    geometry: TGeometryObject;
+    id: String;
+    properties: TJSObject;
+
+    constructor Create;
+  end;
+
+  TFeatureCollection = class (TGeoJsonObject)
+  public
+    features: TArray<TGeoJsonObject>;
+
+    constructor Create;
+  end;
+
+implementation
+
+{ TGeoJsonObject }
+
+constructor TGeoJsonObject.Create(&type: String);
+begin
+  Self.&type := &type;
+end;
+
+{ TPoint }
+
+constructor TPoint.Create;
+begin
+  inherited Create('Point');
+end;
+
+{ TMultiPoint }
+
+constructor TMultiPoint.Create;
+begin
+  inherited Create('MultiPoint');
+end;
+
+{ TLineString }
+
+constructor TLineString.Create;
+begin
+  inherited Create('LineString');
+end;
+
+{ TMultiLineString }
+
+constructor TMultiLineString.Create;
+begin
+  inherited Create('MultiLineString');
+end;
+
+{ TPolygon }
+
+constructor TPolygon.Create;
+begin
+  inherited Create('Polygon');
+end;
+
+{ TMultiPolygon }
+
+constructor TMultiPolygon.Create;
+begin
+  inherited Create('MultiPolygon');
+end;
+
+{ TGeometryCollection }
+
+constructor TGeometryCollection.Create;
+begin
+  inherited Create('GeometryCollection');
+end;
+
+{ TFeature }
+
+constructor TFeature.Create;
+begin
+  inherited Create('Feature');
+end;
+
+{ TFeatureCollection }
+
+constructor TFeatureCollection.Create;
+begin
+  inherited Create('FeatureCollection');
+end;
+
+end.
diff --git a/packages/maps/Google.Maps.pas b/packages/maps/Google.Maps.pas
new file mode 100644
index 00000000..ec4e463d
--- /dev/null
+++ b/packages/maps/Google.Maps.pas
@@ -0,0 +1,2170 @@
+unit Google.Maps;
+
+interface
+
+{$modeswitch externalclass}
+
+uses JS, SysUtils, GeoJSON, Web;
+
+type
+  TAddFeatureEvent = class;
+  TAutocompleteOptions = class;
+  TAutocompletePrediction = class;
+  TAutocompleteResponse = class;
+  TAutocompleteSessionToken = class;
+  TAutocompletionRequest = class;
+  TCircleLiteral = class;
+  TCircleOptions = class;
+  TComponentRestrictions = class;
+  TDataOptions = class;
+  TDirectionsGeocodedWaypoint = class;
+  TDirectionsLeg = class;
+  TDirectionsRendererOptions = class;
+  TDirectionsRequest = class;
+  TDirectionsResult = class;
+  TDirectionsRoute = class;
+  TDirectionsStep = class;
+  TDirectionsWaypoint = class;
+  TDistance = class;
+  TDistanceMatrixRequest = class;
+  TDistanceMatrixResponse = class;
+  TDistanceMatrixResponseElement = class;
+  TDistanceMatrixResponseRow = class;
+  TDrawingControlOptions = class;
+  TDrawingManagerOptions = class;
+  TDrivingOptions = class;
+  TDuration = class;
+  TElevationResult = class;
+  TFeatureOptions = class;
+  TFindPlaceFromPhoneNumberRequest = class;
+  TFindPlaceFromQueryRequest = class;
+  TFullscreenControlOptions = class;
+  TGeoJsonOptions = class;
+  TGeocoderAddressComponent = class;
+  TGeocoderComponentRestrictions = class;
+  TGeocoderGeometry = class;
+  TGeocoderRequest = class;
+  TGeocoderResponse = class;
+  TGeocoderResult = class;
+  TGroundOverlayOptions = class;
+  THeatmapLayerOptions = class;
+  TIcon = class;
+  TIconMouseEvent = class;
+  TIconSequence = class;
+  TImageMapTypeOptions = class;
+  TInfoWindowOptions = class;
+  TKmlAuthor = class;
+  TKmlFeatureData = class;
+  TKmlLayerMetadata = class;
+  TKmlLayerOptions = class;
+  TKmlMouseEvent = class;
+  TLatLngBoundsLiteral = class;
+  TLatLngLiteral = class;
+  TLocationElevationRequest = class;
+  TLocationElevationResponse = class;
+  TMapCanvasProjection = class;
+  TMapMouseEvent = class;
+  TMapOptions = class;
+  TMapPanes = class;
+  TMapRestriction = class;
+  TMapType = class;
+  TMapTypeControlOptions = class;
+  TMapTypeStyle = class;
+  TMapsEventListener = class;
+  TMarkerLabel = class;
+  TMarkerOptions = class;
+  TMarkerShape = class;
+  TMaxZoomResult = class;
+  TMotionTrackingControlOptions = class;
+  TMouseEvent = class;
+  TOverlayCompleteEvent = class;
+  TPadding = class;
+  TPanControlOptions = class;
+  TPanoProviderOptions = class;
+  TPathElevationRequest = class;
+  TPathElevationResponse = class;
+  TPinOptions = class;
+  TPlace = class;
+  TPolyMouseEvent = class;
+  TPolygonOptions = class;
+  TPolylineOptions = class;
+  TPredictionSubstring = class;
+  TPredictionTerm = class;
+  TProjection = class;
+  TQueryAutocompletionRequest = class;
+  TRectangleOptions = class;
+  TRemoveFeatureEvent = class;
+  TRemovePropertyEvent = class;
+  TRotateControlOptions = class;
+  TScaleControlOptions = class;
+  TSearchBoxOptions = class;
+  TSetGeometryEvent = class;
+  TSetPropertyEvent = class;
+  TStreetViewAddressControlOptions = class;
+  TStreetViewControlOptions = class;
+  TStreetViewLink = class;
+  TStreetViewLocation = class;
+  TStreetViewLocationRequest = class;
+  TStreetViewPanoRequest = class;
+  TStreetViewPanoramaData = class;
+  TStreetViewPanoramaOptions = class;
+  TStreetViewPov = class;
+  TStreetViewResponse = class;
+  TStreetViewTileData = class;
+  TStructuredFormatting = class;
+  TStyleOptions = class;
+  TStyledMapTypeOptions = class;
+  TSymbol = class;
+  TTextSearchRequest = class;
+  TTime = class;
+  TTrafficLayerOptions = class;
+  TTransitAgency = class;
+  TTransitDetails = class;
+  TTransitFare = class;
+  TTransitLine = class;
+  TTransitOptions = class;
+  TTransitStop = class;
+  TTransitVehicle = class;
+  TWeightedLocation = class;
+  TZoomControlOptions = class;
+
+  TGoogle = class external name 'google'
+  public type
+    TMaps = class external name 'maps'
+    public type
+      TLatLng = class;
+      TLatLngBounds = class;
+      TMap = class;
+      TMapTypeRegistry = class;
+      TOverlayType = class;
+      TPlacesServiceStatus = class;
+      TPoint = class;
+      TSize = class;
+      TStreetViewPanorama = class;
+
+      TAnimation = (BOUNCE, DROP);
+      TControlPosition = (BOTTOM_CENTER, BOTTOM_LEFT, BOTTOM_RIGHT, LEFT_BOTTOM, LEFT_CENTER, LEFT_TOP, RIGHT_BOTTOM, RIGHT_CENTER, RIGHT_TOP, TOP_CENTER, TOP_LEFT, TOP_RIGHT);
+      TMapTypeControlStyle = (DEFAULT, DROPDOWN_MENU, HORIZONTAL_BAR);
+      TStrokePosition = (CENTER, INSIDE, OUTSIDE);
+      TSymbolPath = (BACKWARD_CLOSED_ARROW, BACKWARD_OPEN_ARROW, CIRCLE, FORWARD_CLOSED_ARROW, FORWARD_OPEN_ARROW);
+      TUnitSystem = (IMPERIAL, METRIC);
+      TRankBy = (DISTANCE, PROMINENCE);
+
+      TMVCObject = class external name 'MVCObject'
+      public
+        function addListener(eventName: String; handler: TProc): TMapsEventListener;
+        procedure bindTo(key: String; target: TMVCObject; targetKey: String; noNotify: Boolean);
+        function get(key: String): JSValue;
+        procedure notify(key: String);
+        procedure &set(key: String; value: JSValue);
+        procedure setValues(values: TJSObject);
+        procedure unbind(key: String);
+        procedure unbindAll;
+      end;
+
+      TBicyclingLayer = class external name 'BicyclingLayer' (TMVCObject)
+      public
+        function getMap: TMap;
+        procedure setMap(map: TMap);
+      end;
+
+      TCircle = class external name 'Circle' (TMVCObject)
+      public
+        constructor Create(opts: TCircleOptions); external name '';
+        function getBounds: TLatLngBounds;
+        function getCenter: TLatLng;
+        function getDraggable: Boolean;
+        function getEditable: Boolean;
+        function getMap: TMap;
+        function getRadius: Double;
+        function getVisible: Boolean;
+        procedure setCenter(center: TLatLng); overload;
+        procedure setCenter(center: TLatLngLiteral); overload;
+        procedure setDraggable(draggable: Boolean);
+        procedure setEditable(editable: Boolean);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TCircleOptions);
+        procedure setRadius(radius: Double);
+        procedure setVisible(visible: Boolean);
+      end;
+
+      TData = class external name 'Data' (TMVCObject)
+      public type
+        TGeometry = class;
+        TPolygon = class;
+
+        TFeature = class external name 'Feature'
+        public
+          constructor Create(options: TFeatureOptions); external name '';
+
+          procedure forEachProperty(callback: TProc<JSValue, String>);
+          function getGeometry: TGeometry;
+          function getId: Double;
+          function getIdString: String; external name 'getId';
+          function getProperty(name: String): JSValue;
+          procedure removeProperty(name: String);
+          procedure setGeometry(newGeometry: TGeometry); overload;
+          procedure setGeometry(newGeometry: TLatLng); overload;
+          procedure setGeometry(newGeometry: TLatLngLiteral); overload;
+          procedure setProperty(name: String; newValue: JSValue);
+          procedure toGeoJson(callback: TProc<TJSObject>);
+        end;
+
+        TGeometry = class external name 'Geometry'
+        public
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getType: String;
+        end;
+
+        TGeometryCollection = class external name 'GeometryCollection' (TGeometry)
+        public
+          constructor Create(elements: TArray<TGeometry>); external name ''; overload;
+          constructor Create(elements: TArray<TLatLng>); external name ''; overload;
+          constructor Create(elements: TArray<TLatLngLiteral>); external name ''; overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TGeometry>;
+          function getAt(n: Double): TGeometry;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TLineString = class external name 'LineString' (TGeometry)
+        public
+          constructor Create(elements: TArray<TLatLng>); external name ''; overload;
+          constructor Create(elements: TArray<TLatLngLiteral>); external name ''; overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TLatLng>;
+          function getAt(n: Double): TLatLng;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TLinearRing = class external name 'LinearRing' (TGeometry)
+        public
+          constructor Create(elements: TArray<TLatLng>); external name ''; overload;
+          constructor Create(elements: TArray<TLatLngLiteral>); external name ''; overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TLatLng>;
+          function getAt(n: Double): TLatLng;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TMultiLineString = class external name 'MultiLineString' (TGeometry)
+        public
+          constructor Create(elements: TArray<TLatLng>); external name ''; overload;
+          constructor Create(elements: TArray<TLatLngLiteral>); external name ''; overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TLineString>;
+          function getAt(n: Double): TLineString;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TMultiPoint = class external name 'MultiPoint' (TGeometry)
+        public
+          constructor Create(elements: TArray<TLatLng>); external name ''; overload;
+          constructor Create(elements: TArray<TLatLngLiteral>); external name ''; overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TLatLng>;
+          function getAt(n: Double): TLatLng;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TMultiPolygon = class external name 'MultiPolygon' (TGeometry)
+        public
+          constructor Create(elements: TArray<TLatLng>); external name ''; overload;
+          constructor Create(elements: TArray<TLatLngLiteral>); external name ''; overload;
+          constructor Create(elements: TArray<TLinearRing>); external name ''; overload;
+          constructor Create(elements: TArray<TPolygon>); external name ''; overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+
+          function getArray: TArray<TPolygon>;
+          function getAt(n: Double): TPolygon;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TPoint = class external name 'Point' (TGeometry)
+        public
+          constructor Create(elements: TArray<TLatLng>); external name ''; overload;
+          constructor Create(elements: TArray<TLatLngLiteral>); external name ''; overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function get: TLatLng;
+          function getType: String;
+        end;
+
+        TPolygon = class external name 'Polygon' (TGeometry)
+        public
+          constructor Create(elements: TArray<TArray<TLatLng>>); external name ''; overload;
+          constructor Create(elements: TArray<TLatLngLiteral>); external name ''; overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TLinearRing>;
+          function getAt(n: Double): TLinearRing;
+          function getLength: Double;
+          function getType: String;
+        end;
+      public
+        constructor Create(options: TDataOptions); external name '';
+        function add(feature: TFeature): TFeature; overload;
+        function add(feature: TFeatureOptions): TFeature; overload;
+        function addGeoJson(geoJson: TGeoJSONObject; options: TGeoJsonOptions): TArray<TFeature>;
+        function contains(feature: TFeature): Boolean;
+        procedure forEach(callback: TProc<TFeature>);
+        function getControlPosition: TControlPosition;
+        function getControls: TArray<String>;
+        function getDrawingMode: String;
+        function getFeatureById(id: Double): TFeature; overload;
+        function getFeatureById(id: String): TFeature; overload;
+        function getMap: TMap;
+        function getStyle: TStyleOptions;
+        function getStyleFunction: TFunc<TFeature, TStyleOptions>; external name 'getStyle';
+        procedure loadGeoJson(url: String; options: TGeoJsonOptions; callback: TProc<TArray<TFeature>>);
+        procedure overrideStyle(feature: TFeature; style: TStyleOptions);
+        procedure remove(feature: TFeature);
+        procedure revertStyle(feature: TFeature);
+        procedure setControlPosition(controlPosition: TControlPosition);
+        procedure setControls(controls: TArray<String>);
+        procedure setDrawingMode(drawingMode: String);
+        procedure setMap(map: TMap);
+        procedure setStyle(style: TStyleOptions); overload;
+        procedure setStyle(style: TFunc<TFeature, TStyleOptions>); overload;
+        procedure toGeoJson(callback: TProc<TGeoJSONObject>);
+      end;
+
+      TDirectionsRenderer = class external name 'DirectionsRenderer' (TMVCObject)
+      public
+        constructor Create(opts: TDirectionsRendererOptions); external name '';
+        function getDirections: TDirectionsResult;
+        function getMap: TMap;
+        function getPanel: TJSNode;
+        function getRouteIndex: Double;
+        procedure setDirections(directions: TDirectionsResult);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TDirectionsRendererOptions);
+        procedure setPanel(panel: TJSNode);
+        procedure setRouteIndex(routeIndex: Double);
+      end;
+
+      TDirectionsStatus = class
+      public const
+        INVALID_REQUEST = 'INVALID_REQUEST';
+        MAX_WAYPOINTS_EXCEEDED = 'MAX_WAYPOINTS_EXCEEDED';
+        NOT_FOUND = 'NOT_FOUND';
+        OK = 'OK';
+        OVER_QUERY_LIMIT = 'OVER_QUERY_LIMIT';
+        REQUEST_DENIED = 'REQUEST_DENIED';
+        UNKNOWN_ERROR = 'UNKNOWN_ERROR';
+        ZERO_RESULTS = 'ZERO_RESULTS';
+      end;
+
+      TDirectionsService = class external name 'DirectionsService'
+      public
+        function route(request: TDirectionsRequest; callback: TProc<TDirectionsResult, TDirectionsStatus>): TJSPromise;
+      end;
+
+      TDistanceMatrixService = class external name 'DistanceMatrixService'
+      public type
+        TDistanceMatrixStatus = (INVALID_REQUEST, MAX_DIMENSIONS_EXCEEDED, MAX_ELEMENTS_EXCEEDED, OK, OVER_QUERY_LIMIT, REQUEST_DENIED, UNKNOWN_ERROR);
+      public
+        function getDistanceMatrix(request: TDistanceMatrixRequest; callback: TProc<TDistanceMatrixResponse, TDistanceMatrixStatus>): TJSPromise;
+      end;
+
+      TElevationStatus = class
+      public const
+        INVALID_REQUEST = 'INVALID_REQUEST';
+        OK = 'OK';
+        OVER_QUERY_LIMIT = 'OVER_QUERY_LIMIT';
+        REQUEST_DENIED = 'REQUEST_DENIED';
+        UNKNOWN_ERROR = 'UNKNOWN_ERROR';
+      end;
+
+      TElevationService = class external name 'ElevationService'
+      public
+        function getElevationAlongPath(request: TPathElevationRequest; callback: TProc<TArray<TElevationResult>, TElevationStatus>): TJSPromise;
+        function getElevationForLocations(request: TLocationElevationRequest; callback: TProc<TArray<TElevationResult>, TElevationStatus>): TJSPromise;
+      end;
+
+      TGeocoderStatus = class
+      public const
+        ERROR = 'ERROR';
+        INVALID_REQUEST = 'INVALID_REQUEST';
+        OK = 'OK';
+        OVER_QUERY_LIMIT = 'OVER_QUERY_LIMIT';
+        REQUEST_DENIED = 'REQUEST_DENIED';
+        UNKNOWN_ERROR = 'UNKNOWN_ERROR';
+        ZERO_RESULTS = 'ZERO_RESULTS';
+      end;
+
+      TGeocoder = class external name 'Geocoder'
+      public
+        function geocode(request: TGeocoderRequest; callback: TProc<TArray<TGeocoderResult>, TGeocoderStatus>): TJSPromise;
+      end;
+
+      TGroundOverlay = class external name 'GroundOverlay' (TMVCObject)
+      public
+        constructor Create(url: String; bounds: TLatLngBounds; opts: TGroundOverlayOptions); external name ''; overload;
+        constructor Create(url: String; bounds: TLatLngBoundsLiteral; opts: TGroundOverlayOptions); external name ''; overload;
+        function getBounds: TLatLngBounds;
+        function getMap: TMap;
+        function getOpacity: Double;
+        function getUrl: String;
+        procedure setMap(map: TMap);
+        procedure setOpacity(opacity: Double);
+      end;
+
+      TImageMapType = class external name 'ImageMapType' (TMVCObject)
+      public
+        alt: String;
+        maxZoom: Double;
+        minZoom: Double;
+        name: String;
+        projection: TProjection;
+        radius: Double;
+        tileSize: TSize;
+
+        constructor Create(opts: TImageMapTypeOptions); external name '';
+
+        function getOpacity: Double;
+        function getTile(tileCoord: TPoint; zoom: Double; ownerDocument: TJSDocument): TJSNode;
+        procedure releaseTile(tileDiv: TJSNode);
+        procedure setOpacity(opacity: Double);
+      end;
+
+      TInfoWindow = class external name 'InfoWindow' (TMVCObject)
+      public
+        constructor Create(opts: TInfoWindowOptions); external name '';
+        procedure close;
+        function getContent: TJSNode;
+        function getContentString: String; external name 'getContent';
+        function getPosition: TLatLng;
+        function getZIndex: Double;
+        procedure open(map: TMap; anchor: TMVCObject); overload;
+        procedure open(map: TStreetViewPanorama; anchor: TMVCObject); overload;
+        procedure setContent(content: TJSNode); overload;
+        procedure setContent(content: String); overload;
+        procedure setOptions(options: TInfoWindowOptions);
+        procedure setPosition(position: TLatLng); overload;
+        procedure setPosition(position: TLatLngLiteral); overload;
+        procedure setZIndex(zIndex: Double);
+      end;
+
+      TKmlLayerStatus = class external name 'KmlLayerStatus'
+      public const
+        DOCUMENT_NOT_FOUND = 'DOCUMENT_NOT_FOUND';
+        DOCUMENT_TOO_LARGE = 'DOCUMENT_TOO_LARGE';
+        FETCH_ERROR = 'FETCH_ERROR';
+        INVALID_DOCUMENT = 'INVALID_DOCUMENT';
+        INVALID_REQUEST = 'INVALID_REQUEST';
+        LIMITS_EXCEEDED = 'LIMITS_EXCEEDED';
+        OK = 'OK';
+        TIMED_OUT = 'TIMED_OUT';
+        UNKNOWN = 'UNKNOWN';
+      end;
+
+      TKmlLayer = class external name 'KmlLayer' (TMVCObject)
+      public
+        constructor Create(opts: TKmlLayerOptions); external name '';
+        function getDefaultViewport: TLatLngBounds;
+        function getMap: TMap;
+        function getMetadata: TKmlLayerMetadata;
+        function getStatus: TKmlLayerStatus;
+        function getUrl: String;
+        function getZIndex: Double;
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TKmlLayerOptions);
+        procedure setUrl(url: String);
+        procedure setZIndex(zIndex: Double);
+      end;
+
+      TLatLng = class external name 'LatLng'
+      public
+        constructor Create(lat, lng: Double); external name ''; overload;
+        constructor Create(lat, lng: Double; lngOrNoWrap, noWrap: Boolean); external name ''; overload;
+        constructor Create(latLngLiteral: TLatLngLiteral); external name ''; overload;
+        constructor Create(latLngLiteral: TLatLngLiteral; lngOrNoWrap, noWrap: Boolean); external name ''; overload;
+        function equals(other: TLatLng): Boolean;
+        function lat: Double;
+        function lng: Double;
+        function toJSON: TLatLngLiteral;
+        function toString: String;
+        function toUrlValue(precision: Double): String;
+      end;
+
+      TLatLngBounds = class external name 'LatLngBounds'
+      public
+        constructor Create(sw, ne: TLatLng); external name ''; overload;
+        constructor Create(sw, ne: TLatLngLiteral); external name ''; overload;
+        function contains(latLng: TLatLng): Boolean; overload;
+        function contains(latLng: TLatLngLiteral): Boolean; overload;
+        function equals(other: TLatLng): Boolean; overload;
+        function equals(other: TLatLngBounds): Boolean; overload;
+        function extend(point: TLatLng): TLatLngBounds; overload;
+        function extend(point: TLatLngLiteral): TLatLngBounds; overload;
+        function getCenter: TLatLng;
+        function getNorthEast: TLatLng;
+        function getSouthWest: TLatLng;
+        function intersects(other: TLatLngBounds): Boolean; overload;
+        function intersects(other: TLatLngBoundsLiteral): Boolean; overload;
+        function isEmpty: Boolean;
+        function toJSON: TLatLngBoundsLiteral;
+        function toSpan: TLatLng;
+        function toString: String;
+        function toUrlValue(precision: Double): String;
+        function union(other: TLatLngBounds): TLatLngBounds; overload;
+        function union(other: TLatLngBoundsLiteral): TLatLngBounds; overload;
+      end;
+
+      TMVCArray<T> = class external name 'MVCArray' (TMVCObject)
+      public
+        constructor Create(&array: TArray<T>); external name '';
+        procedure clear;
+        procedure forEach(callback: TProc<T, Double>);
+        function getArray: TArray<T>;
+        function getAt(i: Double): T;
+        function getLength: Double;
+        procedure insertAt(i: Double; elem: T);
+        function pop: T;
+        function push(elem: T): Double;
+        function removeAt(i: Double): T;
+        procedure setAt(i: Double; elem: T);
+      end;
+
+      TMapTypeId = class external name 'MapTypeId'
+      public const
+        HYBRID = 'HYBRID';
+        ROADMAP = 'ROADMAP';
+        SATELLITE = 'SATELLITE';
+        TERRAIN = 'TERRAIN';
+      end;
+
+      TMap = class external name 'Map' (TMVCObject)
+      public
+        controls: TArray<TMVCArray<JSValue>>;
+        data: TData;
+        mapTypes: TMapTypeRegistry;
+        overlayMapTypes: TMVCArray<JSValue>;
+
+        constructor Create(mapDiv: TJSHTMLElement; opts: TMapOptions); external name '';
+        procedure fitBounds(bounds: TLatLngBounds; padding: Double); overload;
+        procedure fitBounds(bounds: TLatLngBounds; padding: TPadding); overload;
+        procedure fitBounds(bounds: TLatLngBoundsLiteral; padding: Double); overload;
+        procedure fitBounds(bounds: TLatLngBoundsLiteral; padding: TPadding); overload;
+        function getBounds: TLatLngBounds;
+        function getCenter: TLatLng;
+        function getClickableIcons: Boolean;
+        function getDiv: TJSHTMLElement;
+        function getHeading: Double;
+        function getMapTypeId: String;
+        function getProjection: TProjection;
+        function getStreetView: TStreetViewPanorama;
+        function getTilt: Double;
+        function getZoom: Double;
+        procedure panBy(x, y: Double);
+        procedure panTo(latLng: TLatLng); overload;
+        procedure panTo(latLng: TLatLngLiteral); overload;
+        procedure panToBounds(bounds: TLatLngBounds; padding: Double); overload;
+        procedure panToBounds(bounds: TLatLngBounds; padding: TPadding); overload;
+        procedure panToBounds(bounds: TLatLngBoundsLiteral; padding: Double); overload;
+        procedure panToBounds(bounds: TLatLngBoundsLiteral; padding: TPadding); overload;
+        procedure setCenter(latlng: TLatLng); overload;
+        procedure setCenter(latlng: TLatLngLiteral); overload;
+        procedure setClickableIcons(value: Boolean);
+        procedure setHeading(heading: Double);
+        procedure setMapTypeId(mapTypeId: String);
+        procedure setOptions(options: TMapOptions);
+        procedure setStreetView(panorama: TStreetViewPanorama);
+        procedure setTilt(tilt: Double);
+        procedure setZoom(zoom: Double);
+      end;
+
+      TMapTypeRegistry = class external name 'MapTypeRegistry' (TMVCObject)
+      public
+        procedure &set(id: String; mapType: JSValue);
+      end;
+
+      TMarker = class external name 'Marker' (TMVCObject)
+      public
+        constructor Create(opts: TMarkerOptions); external name '';
+        function getAnimation: TAnimation;
+        function getClickable: Boolean;
+        function getCursor: String;
+        function getDraggable: Boolean;
+        function getIcon: JSValue;
+        function getLabel: TMarkerLabel;
+        function getMap: TMap;
+        function getStreetViewPanorama: TStreetViewPanorama; external name 'getMap';
+        function getOpacity: Double;
+        function getPosition: TLatLng;
+        function getShape: TMarkerShape;
+        function getTitle: String;
+        function getVisible: Boolean;
+        function getZIndex: Double;
+        procedure setAnimation(animation: TAnimation);
+        procedure setClickable(flag: Boolean);
+        procedure setCursor(cursor: String);
+        procedure setDraggable(flag: Boolean);
+        procedure setIcon(icon: String); overload;
+        procedure setIcon(icon: TIcon); overload;
+        procedure setIcon(icon: TSymbol); overload;
+        procedure setLabel(&label: String); overload;
+        procedure setLabel(&label: TMarkerLabel); overload;
+        procedure setMap(map: TMap); overload;
+        procedure setMap(map: TStreetViewPanorama); overload;
+        procedure setOpacity(opacity: Double);
+        procedure setOptions(options: TMarkerOptions);
+        procedure setPosition(latlng: TLatLng); overload;
+        procedure setPosition(latlng: TLatLngLiteral); overload;
+        procedure setShape(shape: TMarkerShape);
+        procedure setTitle(title: String);
+        procedure setVisible(visible: Boolean);
+        procedure setZIndex(zIndex: Double);
+
+        class var MAX_ZINDEX: Double;
+      end;
+
+      TMaxZoomService = class external name 'MaxZoomService'
+      public
+        function getMaxZoomAtLatLng(latlng: TLatLng; callback: TProc<TMaxZoomResult>): TJSPromise; overload;
+        function getMaxZoomAtLatLng(latlng: TLatLngLiteral; callback: TProc<TMaxZoomResult>): TJSPromise; overload;
+      end;
+
+      TOverlayView = class external name 'OverlayView' (TMVCObject)
+      public
+        procedure draw;
+        function getMap: TMap;
+        function getMapStreetViewPanorama: TStreetViewPanorama; external name 'getMap';
+        function getPanes: TMapPanes;
+        function getProjection: TMapCanvasProjection;
+        procedure onAdd;
+        procedure onRemove;
+        procedure setMap(map: TMap); overload;
+        procedure setMap(map: TStreetViewPanorama); overload;
+        class procedure preventMapHitsAndGesturesFrom(this: JSValue; element: TJSHTMLElement);
+        class procedure preventMapHitsFrom(this: JSValue; element: TJSHTMLElement);
+      end;
+
+      TPoint = class external name 'Point'
+      public
+        x: Double;
+        y: Double;
+
+        constructor Create(x, y: Double); external name '';
+        function equals(other: TPoint): Boolean;
+        function toString: String;
+      end;
+
+      TPolygon = class external name 'Polygon' (TMVCObject)
+      public
+        constructor Create(opts: TPolygonOptions); external name '';
+        function getDraggable: Boolean;
+        function getEditable: Boolean;
+        function getMap: TMap;
+        function getPath: TMVCArray<JSValue>;
+        function getPaths: TMVCArray<JSValue>;
+        function getVisible: Boolean;
+        procedure setDraggable(draggable: Boolean);
+        procedure setEditable(editable: Boolean);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TPolygonOptions);
+        procedure setPath(path: TMVCArray<JSValue>); overload;
+        procedure setPath(path: TArray<TLatLng>); overload;
+        procedure setPath(path: TArray<TLatLngLiteral>); overload;
+        procedure setPaths(paths: TMVCArray<JSValue>); overload;
+        procedure setPaths(paths: TArray<JSValue>); overload;
+        procedure setVisible(visible: Boolean);
+      end;
+
+      TPolyline = class external name 'Polyline' (TMVCObject)
+      public
+        constructor Create(opts: TPolylineOptions); external name '';
+        function getDraggable: Boolean;
+        function getEditable: Boolean;
+        function getMap: TMap;
+        function getPath: TMVCArray<JSValue>;
+        function getVisible: Boolean;
+        procedure setDraggable(draggable: Boolean);
+        procedure setEditable(editable: Boolean);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TPolylineOptions);
+        procedure setPath(path: TMVCArray<JSValue>); overload;
+        procedure setPath(path: TArray<TLatLng>); overload;
+        procedure setPath(path: TArray<TLatLngLiteral>); overload;
+        procedure setVisible(visible: Boolean);
+      end;
+
+      TRectangle = class external name 'Rectangle' (TMVCObject)
+      public
+        constructor Create(opts: TRectangleOptions); external name '';
+        function getBounds: TLatLngBounds;
+        function getDraggable: Boolean;
+        function getEditable: Boolean;
+        function getMap: TMap;
+        function getVisible: Boolean;
+        procedure setBounds(bounds: TLatLngBounds); overload;
+        procedure setBounds(bounds: TLatLngBoundsLiteral); overload;
+        procedure setDraggable(draggable: Boolean);
+        procedure setEditable(editable: Boolean);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TRectangleOptions);
+        procedure setVisible(visible: Boolean);
+      end;
+
+      TSize = class external name 'Size'
+      public
+        height: Double;
+        width: Double;
+
+        constructor Create(width, height: Double; widthUnit, heightUnit: String); external name '';
+        function equals(other: TSize): Boolean;
+        function toString: String;
+      end;
+
+      TStreetViewCoverageLayer = class external name 'StreetViewCoverageLayer' (TMVCObject)
+      public
+        function getMap: TMap;
+        procedure setMap(map: TMap);
+      end;
+
+      TStreetViewStatus = class external name 'StreetViewStatus'
+      public const
+        OK = 'OK';
+        UNKNOWN_ERROR = 'UNKNOWN_ERROR';
+        ZERO_RESULTS = 'ZERO_RESULTS';
+      end;
+
+      TStreetViewPanorama = class external name 'StreetViewPanorama' (TMVCObject)
+      public
+        controls: TArray<TMVCArray<JSValue>>;
+
+        constructor Create(container: TJSHTMLElement; opts: TStreetViewPanoramaOptions); external name '';
+        function getLinks: TArray<TStreetViewLink>;
+        function getLocation: TStreetViewLocation;
+        function getMotionTracking: Boolean;
+        function getPano: String;
+        function getPhotographerPov: TStreetViewPov;
+        function getPosition: TLatLng;
+        function getPov: TStreetViewPov;
+        function getStatus: TStreetViewStatus;
+        function getVisible: Boolean;
+        function getZoom: Double;
+        procedure registerPanoProvider(provider: TFunc<String, TStreetViewPanoramaData>; opt_options: TPanoProviderOptions);
+        procedure setLinks(links: TArray<TStreetViewLink>);
+        procedure setMotionTracking(motionTracking: Boolean);
+        procedure setOptions(options: TStreetViewPanoramaOptions);
+        procedure setPano(pano: String);
+        procedure setPosition(latLng: TLatLng); overload;
+        procedure setPosition(latLng: TLatLngLiteral); overload;
+        procedure setPov(pov: TStreetViewPov);
+        procedure setVisible(flag: Boolean);
+        procedure setZoom(zoom: Double);
+      end;
+
+      TStreetViewService = class external name 'StreetViewService'
+      public
+        function getPanorama(request: TStreetViewLocationRequest; callback: TProc<TStreetViewPanoramaData, TStreetViewStatus>): TJSPromise; overload;
+        function getPanorama(request: TStreetViewPanoRequest; callback: TProc<TStreetViewPanoramaData, TStreetViewStatus>): TJSPromise; overload;
+      end;
+
+      TStyledMapType = class external name 'StyledMapType' (TMVCObject)
+      public
+        alt: String;
+        maxZoom: Double;
+        minZoom: Double;
+        name: String;
+        projection: TProjection;
+        radius: Double;
+        tileSize: TSize;
+        constructor Create(styles: TArray<TMapTypeStyle>; options: TStyledMapTypeOptions); external name '';
+        function getTile(tileCoord: TPoint; zoom: Double; ownerDocument: TJSDocument): TJSNode;
+        procedure releaseTile(tile: TJSNode);
+      end;
+
+      TTrafficLayer = class external name 'TrafficLayer' (TMVCObject)
+      public
+        constructor Create(opts: TTrafficLayerOptions); external name '';
+        function getMap: TMap;
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TTrafficLayerOptions);
+      end;
+
+      TTransitLayer = class external name 'TransitLayer' (TMVCObject)
+      public
+        function getMap: TMap;
+        procedure setMap(map: TMap);
+      end;
+
+      TDrawingManager = class external name 'DrawingManager' (TMVCObject)
+      public
+        constructor Create(options: TDrawingManagerOptions); external name '';
+        function getDrawingMode: TOverlayType;
+        function getMap: TMap;
+        procedure setDrawingMode(drawingMode: TOverlayType);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TDrawingManagerOptions);
+      end;
+
+      TEvent = class external name 'event'
+      public
+        function addDomListener(instance: TJSObject; eventName: String; handler: TProc; capture: Boolean): TMapsEventListener;
+        function addDomListenerOnce(instance: TJSObject; eventName: String; handler: TProc; capture: Boolean): TMapsEventListener;
+        function addListener(instance: TJSObject; eventName: String; handler: TProc): TMapsEventListener;
+        function addListenerOnce(instance: TJSObject; eventName: String; handler: TProc): TMapsEventListener;
+        procedure clearInstanceListeners(instance: TJSObject);
+        procedure clearListeners(instance: TJSObject; eventName: String);
+        procedure removeListener(listener: TMapsEventListener);
+        procedure trigger(instance: TJSObject; eventName: String); varargs;
+      end;
+
+      TGeometry = class external name 'geometry'
+      public type
+        TEncoding = class external name 'encoding'
+        public
+          function decodePath(encodedPath: String): TArray<TLatLng>;
+          function encodePath(path: TArray<TLatLng>): String; overload;
+          function encodePath(path: TMVCArray<JSValue>): String; overload;
+        end;
+
+        TPoly = class external name 'poly'
+        public
+          function containsLocation(point: TLatLng; polygon: TGoogle.TMaps.TPolygon): Boolean;
+          function isLocationOnEdge(point: TLatLng; poly: TGoogle.TMaps.TPolygon; tolerance: Double): Boolean; overload;
+          function isLocationOnEdge(point: TLatLng; poly: TGoogle.TMaps.TPolyline; tolerance: Double): Boolean; overload;
+        end;
+
+        TSpherical = class external name 'spherical'
+        public
+          function computeArea(path: TArray<TLatLng>; radius: Double): Double; overload;
+          function computeArea(path: TMVCArray<JSValue>; radius: Double): Double; overload;
+          function computeDistanceBetween(from: TLatLng; &to: TLatLng; radius: Double): Double;
+          function computeHeading(from: TLatLng; &to: TLatLng): Double;
+          function computeLength(path: TArray<TLatLng>; radius: Double): Double; overload;
+          function computeLength(path: TMVCArray<JSValue>; radius: Double): Double; overload;
+          function computeOffset(from: TLatLng; distance, heading, radius: Double): TLatLng;
+          function computeOffsetOrigin(&to: TLatLng; distance, heading, radius: Double): TLatLng;
+          function computeSignedArea(loop: TArray<TLatLng>; radius: Double): Double; overload;
+          function computeSignedArea(loop: TMVCArray<JSValue>; radius: Double): Double; overload;
+          function interpolate(from, &to: TLatLng; fraction: Double): TLatLng;
+        end;
+      end;
+
+      TVisualization = class external name 'visualization'
+      public type
+        THeatmapLayer = class external name 'HeatmapLayer' (TMVCObject)
+        public
+          constructor Create(opts: THeatmapLayerOptions); external name '';
+          function getData: TMVCArray<JSValue>;
+          function getMap: TMaps;
+          procedure setData(data: TMVCArray<JSValue>); overload;
+          procedure setData(data: TArray<TLatLng>); overload;
+          procedure setData(data: TArray<TWeightedLocation>); overload;
+          procedure setMap(map: TMap);
+          procedure setOptions(options: THeatmapLayerOptions);
+        end;
+      end;
+
+      TStreetViewPreference = class external name 'StreetViewPreference'
+      public const
+        BEST = 'BEST';
+        NEAREST = 'NEAREST';
+      end;
+
+      TMaxZoomStatus = class external name 'MaxZoomStatus'
+      public const
+        ERROR = 'ERROR';
+        OK = 'OK';
+      end;
+
+      TGeocoderLocationType = class external name 'GeocoderLocationType'
+      public const
+        APPROXIMATE = 'APPROXIMATE';
+        GEOMETRIC_CENTER = 'GEOMETRIC_CENTER';
+        RANGE_INTERPOLATED = 'RANGE_INTERPOLATED';
+        ROOFTOP = 'ROOFTOP';
+      end;
+
+      TTrafficModel = class external name 'TrafficModel'
+      public const
+        BEST_GUESS = 'BEST_GUESS';
+        OPTIMISTIC = 'OPTIMISTIC';
+        PESSIMISTIC = 'PESSIMISTIC';
+      end;
+
+      TTransitMode = class external name 'TransitMode'
+      public const
+        BUS = 'BUS';
+        RAIL = 'RAIL';
+        SUBWAY = 'SUBWAY';
+        TRAIN = 'TRAIN';
+        TRAM = 'TRAM';
+      end;
+
+      TTransitRoutePreference = class external name 'TransitRoutePreference'
+      public const
+        FEWER_TRANSFERS = 'FEWER_TRANSFERS';
+        LESS_WALKING = 'LESS_WALKING';
+      end;
+
+      TTravelMode = class external name 'TravelMode'
+      public const
+        BICYCLING = 'BICYCLING';
+        DRIVING = 'DRIVING';
+        TRANSIT = 'TRANSIT';
+        WALKING = 'WALKING';
+      end;
+
+      TOverlayType = class external name 'OverlayType'
+      public const
+        CIRCLE = 'CIRCLE';
+        MARKER = 'MARKER';
+        POLYGON = 'POLYGON';
+        POLYLINE = 'POLYLINE';
+        RECTANGLE = 'RECTANGLE';
+      end;
+
+      TBusinessStatus = class external name 'BusinessStatus'
+      public const
+        CLOSED_PERMANENTLY = 'CLOSED_PERMANENTLY';
+        CLOSED_TEMPORARILY = 'CLOSED_TEMPORARILY';
+        OPERATIONAL = 'OPERATIONAL';
+      end;
+
+      TPlacesServiceStatus = class external name 'PlacesServiceStatus'
+      public const
+        INVALID_REQUEST = 'INVALID_REQUEST';
+        NOT_FOUND = 'NOT_FOUND';
+        OK = 'OK';
+        OVER_QUERY_LIMIT = 'OVER_QUERY_LIMIT';
+        REQUEST_DENIED = 'REQUEST_DENIED';
+        UNKNOWN_ERROR = 'UNKNOWN_ERROR';
+        ZERO_RESULTS = 'ZERO_RESULTS';
+      end;
+
+      TDistanceMatrixElementStatus = class
+      public const
+        NOT_FOUND = 'NOT_FOUND';
+        OK = 'OK';
+        ZERO_RESULTS = 'ZERO_RESULTS';
+      end;
+
+      TStreetViewSource = class
+      public const
+        DEFAULT = 'DEFAULT';
+        OUTDOOR = 'OUTDOOR';
+      end;
+
+      TVehicleType = class
+      public const
+        BUS = 'BUS';
+        CABLE_CAR = 'CABLE_CAR';
+        COMMUTER_TRAIN = 'COMMUTER_TRAIN';
+        COMMUTER_TRAINCOMMUTER_TRAINCOMMUTER_TRAINCOMMUTER_TRAINFERRY = 'COMMUTER_TRAINCOMMUTER_TRAINCOMMUTER_TRAINCOMMUTER_TRAINFERRY';
+        FUNICULAR = 'FUNICULAR';
+        GONDOLA_LIFT = 'GONDOLA_LIFT';
+        HEAVY_RAIL = 'HEAVY_RAIL';
+        HIGH_SPEED_TRAIN = 'HIGH_SPEED_TRAIN';
+        INTERCITY_BUS = 'INTERCITY_BUS';
+        METRO_RAIL = 'METRO_RAIL';
+        MONORAIL = 'MONORAIL';
+        OTHER = 'OTHER';
+        RAIL = 'RAIL';
+        SHARE_TAXI = 'SHARE_TAXI';
+        SUBWAY = 'SUBWAY';
+        TRAM = 'TRAM';
+        TROLLEYBUS = 'TROLLEYBUS';
+      end;
+    public
+      version: String;
+    end;
+  end;
+
+  TCircleOptions = class
+  public
+    center: JSValue;
+    clickable: Boolean;
+    draggable: Boolean;
+    editable: Boolean;
+    fillColor: String;
+    fillOpacity: Double;
+    map: TGoogle.TMaps.TMap;
+    radius: Double;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokePosition: TGoogle.TMaps.TStrokePosition;
+    strokeWeight: Double;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TCircleLiteral = class(TCircleOptions)
+  public
+    center: JSValue;
+    radius: Double;
+  end;
+
+  TAddFeatureEvent = class
+  public
+    feature: TGoogle.TMaps.TData.TFeature;
+  end;
+
+  TDataOptions = class
+  public
+    controlPosition: TGoogle.TMaps.TControlPosition;
+    controls: TArray<String>;
+    drawingMode: String;
+    featureFactory: TFunc<TGoogle.TMaps.TData.TGeometry, TGoogle.TMaps.TData.TFeature>;
+    map: TGoogle.TMaps.TMap;
+    style: TStyleOptions;
+    styleFunction: TFunc<TGoogle.TMaps.TData.TFeature, TStyleOptions>; external name 'style';
+  end;
+
+  TFeatureOptions = class
+  public
+    geometry: JSValue;
+    id: Double;
+    properties: TJSObject;
+  end;
+
+  TGeoJsonOptions = class
+  public
+    idPropertyName: String;
+  end;
+
+  TMapMouseEvent = class external name 'MapMouseEvent'
+  public
+    domEvent: TJSEvent;
+    latLng: TGoogle.TMaps.TLatLng;
+    procedure stop;
+  end;
+
+  TMouseEvent = class(TMapMouseEvent)
+  public
+    feature: TGoogle.TMaps.TData.TFeature;
+  end;
+
+  TRemoveFeatureEvent = class
+  public
+    feature: TGoogle.TMaps.TData.TFeature;
+  end;
+
+  TRemovePropertyEvent = class
+  public
+    feature: TGoogle.TMaps.TData.TFeature;
+    name: String;
+    oldValue: JSValue;
+  end;
+
+  TSetGeometryEvent = class
+  public
+    feature: TGoogle.TMaps.TData.TFeature;
+    newGeometry: TGoogle.TMaps.TData.TGeometry;
+    oldGeometry: TGoogle.TMaps.TData.TGeometry;
+  end;
+
+  TSetPropertyEvent = class
+    feature: TGoogle.TMaps.TData.TFeature;
+    name: String;
+    newValue: JSValue;
+    oldValue: JSValue;
+  end;
+
+  TStyleOptions = class
+  public
+    clickable: Boolean;
+    cursor: String;
+    draggable: Boolean;
+    editable: Boolean;
+    fillColor: String;
+    fillOpacity: Double;
+    icon: JSValue;
+    shape: TMarkerShape;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokeWeight: Double;
+    title: String;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TDirectionsGeocodedWaypoint = class
+  public
+    partial_match: Boolean;
+    place_id: String;
+    types: TArray<String>;
+  end;
+
+  TDirectionsLeg = class
+  public
+    arrival_time: TTime;
+    departure_time: TTime;
+    distance: TDistance;
+    duration: TDuration;
+    duration_in_traffic: TDuration;
+    end_address: String;
+    end_location: TGoogle.TMaps.TLatLng;
+    start_address: String;
+    start_location: TGoogle.TMaps.TLatLng;
+    steps: TArray<TDirectionsStep>;
+    via_waypoints: TArray<TGoogle.TMaps.TLatLng>;
+  end;
+
+  TDirectionsRendererOptions = class
+  public
+    directions: TDirectionsResult;
+    draggable: Boolean;
+    hideRouteList: Boolean;
+    infoWindow: TGoogle.TMaps.TInfoWindow;
+    map: TGoogle.TMaps.TMap;
+    markerOptions: TMarkerOptions;
+    panel: TJSNode;
+    polylineOptions: google.maps.TPolylineOptions;
+    preserveViewport: Boolean;
+    routeIndex: Double;
+    suppressBicyclingLayer: Boolean;
+    suppressInfoWindows: Boolean;
+    suppressMarkers: Boolean;
+    suppressPolylines: Boolean;
+  end;
+
+  TDirectionsRequest = class
+  public
+    avoidFerries: Boolean;
+    avoidHighways: Boolean;
+    avoidTolls: Boolean;
+    destination: JSValue;
+    drivingOptions: TDrivingOptions;
+    optimizeWaypoints: Boolean;
+    origin: JSValue;
+    provideRouteAlternatives: Boolean;
+    region: String;
+    transitOptions: TTransitOptions;
+    travelMode: TGoogle.TMaps.TTravelMode;
+    unitSystem: TGoogle.TMaps.TUnitSystem;
+    waypoints: TArray<TDirectionsWaypoint>;
+  end;
+
+  TDirectionsResult = class
+  public
+    geocoded_waypoints: TArray<TDirectionsGeocodedWaypoint>;
+    routes: TArray<TDirectionsRoute>;
+  end;
+
+  TDirectionsRoute = class
+  public
+    bounds: TGoogle.TMaps.TLatLngBounds;
+    copyrights: String;
+    fare: TArray<TTransitFare>;
+    legs: TArray<TDirectionsLeg>;
+    overview_path: TArray<TGoogle.TMaps.TLatLng>;
+    overview_polyline: String;
+    warnings: TArray<String>;
+    waypoint_order: TArray<Double>;
+  end;
+
+  TDirectionsStep = class
+    distance: TDistance;
+    duration: TDuration;
+    end_location: TGoogle.TMaps.TLatLng;
+    instructions: String;
+    path: TArray<TGoogle.TMaps.TLatLng>;
+    start_location: TGoogle.TMaps.TLatLng;
+    steps: TArray<TDirectionsStep>;
+    transit: TTransitDetails;
+    travel_mode: TGoogle.TMaps.TTravelMode;
+  end;
+
+  TDirectionsWaypoint = class
+    location: JSValue;
+    stopover: Boolean;
+  end;
+
+  TDistance = class
+  public
+    text: String;
+    value: Double;
+  end;
+
+  TDistanceMatrixRequest = class
+  public
+    avoidFerries: Boolean;
+    avoidHighways: Boolean;
+    avoidTolls: Boolean;
+    destinations: TArray<JSValue>;
+    drivingOptions: TDrivingOptions;
+    origins: TArray<JSValue>;
+    region: String;
+    transitOptions: TTransitOptions;
+    travelMode: TGoogle.TMaps.TTravelMode;
+    unitSystem: TGoogle.TMaps.TUnitSystem;
+  end;
+
+  TDistanceMatrixResponse = class
+  public
+    destinationAddresses: TArray<String>;
+    originAddresses: TArray<String>;
+    rows: TArray<TDistanceMatrixResponseRow>;
+  end;
+
+  TDistanceMatrixResponseElement = class
+  public
+    distance: TDistance;
+    duration: TDuration;
+    duration_in_traffic: TDuration;
+    fare: TTransitFare;
+    status: TGoogle.TMaps.TDistanceMatrixElementStatus;
+  end;
+
+  TDistanceMatrixResponseRow = class
+  public
+    elements: TArray<TDistanceMatrixResponseElement>;
+  end;
+
+  TDrivingOptions = class
+  public
+    departureTime: String;
+    trafficModel: TGoogle.TMaps.TTrafficModel;
+  end;
+
+  TDuration = class
+  public
+    text: String;
+    value: Double;
+  end;
+
+  TElevationResult = class
+  public
+    elevation: Double;
+    location: TGoogle.TMaps.TLatLng;
+    resolution: Double;
+  end;
+
+  TFullscreenControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TGeocoderAddressComponent = class
+  public
+    long_name: String;
+    short_name: String;
+    types: TArray<String>;
+  end;
+
+  TGeocoderComponentRestrictions = class
+  public
+    administrativeArea: String;
+    country: String;
+    locality: String;
+    postalCode: String;
+    route: String;
+  end;
+
+  TGeocoderGeometry = class
+  public
+    bounds: TGoogle.TMaps.TLatLngBounds;
+    location: TGoogle.TMaps.TLatLng;
+    location_type: TGoogle.TMaps.TGeocoderLocationType;
+    viewport: TGoogle.TMaps.TLatLngBounds;
+  end;
+
+  TGeocoderRequest = class
+  public
+    address: String;
+    bounds: JSValue;
+    componentRestrictions: TGeocoderComponentRestrictions;
+    location: JSValue;
+    placeId: String;
+    region: String;
+  end;
+
+  TGeocoderResponse = class
+  public
+    results: TArray<TGeocoderResult>;
+  end;
+
+  TGeocoderResult = class
+  public
+    address_components: TArray<TGeocoderAddressComponent>;
+    formatted_address: String;
+    geometry: TGeocoderGeometry;
+    partial_match: Boolean;
+    place_id: String;
+    postcode_localities: TArray<String>;
+    types: TArray<String>;
+  end;
+
+  TGroundOverlayOptions = class
+  public
+    clickable: Boolean;
+    map: TGoogle.TMaps.TMap;
+    opacity: Double;
+  end;
+
+  TIcon = class
+  public
+    anchor: TGoogle.TMaps.TPoint;
+    labelOrigin: TGoogle.TMaps.TPoint;
+    origin: TGoogle.TMaps.TPoint;
+    scaledSize: TGoogle.TMaps.TSize;
+    size: TGoogle.TMaps.TSize;
+    url: String;
+  end;
+
+  TIconMouseEvent = class(TMapMouseEvent)
+  public
+    placeId: String;
+  end;
+
+  TIconSequence = class
+  public
+    fixedRotation: Boolean;
+    icon: TSymbol;
+    offset: String;
+    &repeat: String;
+  end;
+
+  TImageMapTypeOptions = class
+  public
+    alt: String;
+    getTileUrl: TFunc<TGoogle.TMaps.TPoint, Double, String>;
+    maxZoom: Double;
+    minZoom: Double;
+    name: String;
+    opacity: Double;
+    tileSize: TGoogle.TMaps.TSize;
+  end;
+
+  TInfoWindowOptions = class
+  public
+    content: JSValue;
+    disableAutoPan: Boolean;
+    maxWidth: Double;
+    minWidth: Double;
+    pixelOffset: TGoogle.TMaps.TSize;
+    position: JSValue;
+    zIndex: Double;
+  end;
+
+  TKmlAuthor = class
+  public
+    email: String;
+    name: String;
+    uri: String;
+  end;
+
+  TKmlFeatureData = class
+  public
+    author: TKmlAuthor;
+    description: String;
+    id: String;
+    infoWindowHtml: String;
+    name: String;
+    snippet: String;
+  end;
+
+  TKmlLayerMetadata = class
+  public
+    author: TKmlAuthor;
+    description: String;
+    hasScreenOverlays: Boolean;
+    name: String;
+    snippet: String;
+  end;
+
+  TKmlLayerOptions = class
+  public
+    clickable: Boolean;
+    map: TGoogle.TMaps.TMap;
+    preserveViewport: Boolean;
+    screenOverlays: Boolean;
+    suppressInfoWindows: Boolean;
+    url: String;
+    zIndex: Double;
+  end;
+
+  TKmlMouseEvent = class
+  public
+    featureData: TKmlFeatureData;
+    latLng: TGoogle.TMaps.TLatLng;
+    pixelOffset: TGoogle.TMaps.TSize;
+  end;
+
+  TLatLngBoundsLiteral = class
+  public
+    east: Double;
+    north: Double;
+    south: Double;
+    west: Double;
+  end;
+
+  TLatLngLiteral = class
+  public
+    lat: Double;
+    lng: Double;
+
+    constructor Create(Lat, Lng: Double);
+  end;
+
+  TLocationElevationRequest = class
+  public
+    locations: TArray<JSValue>;
+  end;
+
+  TLocationElevationResponse = class
+  public
+    results: TArray<TElevationResult>;
+  end;
+
+  TMapCanvasProjection = class external name 'MapCanvasProjection' abstract
+  public
+    function fromContainerPixelToLatLng(pixel: TGoogle.TMaps.TPoint; nowrap: Boolean): TGoogle.TMaps.TLatLng;
+    function fromDivPixelToLatLng(pixel: TGoogle.TMaps.TPoint; nowrap: Boolean): TGoogle.TMaps.TLatLng;
+    function fromLatLngToContainerPixel(latLng: TGoogle.TMaps.TLatLng): TGoogle.TMaps.TPoint;
+    function fromLatLngToDivPixel(latLng: TGoogle.TMaps.TLatLng): TGoogle.TMaps.TPoint;
+    function getWorldWidth: Double;
+  end;
+
+  TMapOptions = class
+  private
+    FFullscreenControlOptions: TFullscreenControlOptions; external name 'fullscreenControlOptions';
+    Frestriction: TMapRestriction; external name 'restriction';
+    FzoomControlOptions: TZoomControlOptions; external name 'zoomControlOptions';
+    FscaleControlOptions: TScaleControlOptions; external name 'scaleControlOptions';
+    FmapTypeControlOptions: TMapTypeControlOptions; external name 'mapTypeControlOptions';
+    FpanControlOptions: TPanControlOptions; external name 'panControlOptions';
+    FstreetViewControlOptions: TStreetViewControlOptions; external name 'streetViewControlOptions';
+    FrotateControlOptions: TRotateControlOptions; external name 'rotateControlOptions';
+
+    function GetRestriction: TMapRestriction;
+    function GetRotateControlOptions: TRotateControlOptions;
+    function GetScaleControlOptions: TScaleControlOptions;
+    function GetStreetViewControlOptions: TStreetViewControlOptions;
+    function GetZoomControlOptions: TZoomControlOptions;
+    function GetfullscreenControlOptions: TFullscreenControlOptions;
+    function GetmapTypeControlOptions: TMapTypeControlOptions;
+    function GetpanControlOptions: TPanControlOptions;
+  public
+    backgroundColor: String;
+    center: JSValue;
+    clickableIcons: Boolean;
+    controlSize: Double;
+    disableDefaultUI: Boolean;
+    disableDoubleClickZoom: Boolean;
+    draggableCursor: String;
+    draggingCursor: String;
+    fullscreenControl: Boolean;
+    gestureHandling: String;
+    heading: Double;
+    keyboardShortcuts: Boolean;
+    mapTypeControl: Boolean;
+    mapTypeId: String;
+    maxZoom: Double;
+    minZoom: Double;
+    noClear: Boolean;
+    panControl: Boolean;
+    rotateControl: Boolean;
+    scaleControl: Boolean;
+    scrollwheel: Boolean;
+    streetView: TGoogle.TMaps.TStreetViewPanorama;
+    streetViewControl: Boolean;
+    styles: TArray<TMapTypeStyle>;
+    tilt: Double;
+    zoom: Double;
+    zoomControl: Boolean;
+
+    property fullscreenControlOptions: TFullscreenControlOptions read GetfullscreenControlOptions write FfullscreenControlOptions;
+    property mapTypeControlOptions: TMapTypeControlOptions read GetmapTypeControlOptions write FmapTypeControlOptions;
+    property panControlOptions: TPanControlOptions read GetpanControlOptions write FpanControlOptions;
+    property rotateControlOptions: TRotateControlOptions read GetrotateControlOptions write FrotateControlOptions;
+    property streetViewControlOptions: TStreetViewControlOptions read GetstreetViewControlOptions write FstreetViewControlOptions;
+    property restriction: TMapRestriction read Getrestriction write Frestriction;
+    property scaleControlOptions: TScaleControlOptions read GetscaleControlOptions write FscaleControlOptions;
+    property zoomControlOptions: TZoomControlOptions read GetzoomControlOptions write FzoomControlOptions;
+  end;
+
+  TMapPanes = class
+  public
+    floatPane: TJSHTMLElement;
+    mapPane: TJSHTMLElement;
+    markerLayer: TJSHTMLElement;
+    overlayLayer: TJSHTMLElement;
+    overlayMouseTarget: TJSHTMLElement;
+  end;
+
+  TMapRestriction = class
+  public
+    latLngBounds: JSValue;
+    strictBounds: Boolean;
+  end;
+
+  TMapType = class external name 'MapType' abstract
+  public
+    alt: String;
+    maxZoom: Double;
+    minZoom: Double;
+    name: String;
+    projection: TProjection;
+    radius: Double;
+    tileSize: TGoogle.TMaps.TSize;
+    procedure releaseTile(tile: TJSNode);
+    function getTile(tileCoord: TGoogle.TMaps.TPoint; zoom: Double; ownerDocument: TJSDocument): TJSNode;
+  end;
+
+  TMapTypeControlOptions = class
+  public
+    mapTypeIds: TArray<String>;
+    position: TGoogle.TMaps.TControlPosition;
+    style: TGoogle.TMaps.TMapTypeControlStyle;
+  end;
+
+  TMapTypeStyle = class
+  public
+    elementType: String;
+    featureType: String;
+    stylers: TArray<TJSObject>;
+  end;
+
+  TMapsEventListener = class external name 'MapsEventListener' abstract
+  public
+    procedure remove;
+  end;
+
+  TPadding = class
+  public
+    bottom: Double;
+    left: Double;
+    right: Double;
+    top: Double;
+  end;
+
+  TPanControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TPanoProviderOptions = class
+  public
+    cors: Boolean;
+  end;
+
+  TPathElevationRequest = class
+  public
+    path: TArray<JSValue>;
+    samples: Double;
+  end;
+
+  TPathElevationResponse = class
+  public
+    results: TArray<TElevationResult>;
+  end;
+
+  TPlace = class
+  public
+    location: JSValue;
+    placeId: String;
+    query: String;
+  end;
+
+  TPolyMouseEvent = class(TMapMouseEvent)
+  public
+    edge: Double;
+    path: Double;
+    vertex: Double;
+  end;
+
+  TMarkerLabel = class
+  public
+    className: String;
+    color: String;
+    fontFamily: String;
+    fontSize: String;
+    fontWeight: String;
+    text: String;
+  end;
+
+  TMarkerOptions = class
+  public
+    anchorPoint: TGoogle.TMaps.TPoint;
+    animation: TGoogle.TMaps.TAnimation;
+    clickable: Boolean;
+    crossOnDrag: Boolean;
+    cursor: String;
+    draggable: Boolean;
+    icon: JSValue;
+    &label: JSValue;
+    map: TGoogle.TMaps.TMap;
+    mapStreetViewPanorama: TGoogle.TMaps.TStreetViewPanorama; external name 'map';
+    opacity: Double;
+    optimized: Boolean;
+    position: JSValue;
+    shape: TMarkerShape;
+    title: String;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TMarkerShape = class
+  public
+    coords: TArray<Double>;
+    &type: String;
+  end;
+
+  TMaxZoomResult = class
+  public
+    status: TGoogle.TMaps.TMaxZoomStatus;
+    zoom: Double;
+  end;
+
+  TPolygonOptions = class
+  public
+    clickable: Boolean;
+    draggable: Boolean;
+    editable: Boolean;
+    fillColor: String;
+    fillOpacity: Double;
+    geodesic: Boolean;
+    map: TGoogle.TMaps.TMap;
+    paths: JSValue;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokePosition: TGoogle.TMaps.TStrokePosition;
+    strokeWeight: Double;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TPolylineOptions = class
+  public
+    clickable: Boolean;
+    draggable: Boolean;
+    editable: Boolean;
+    geodesic: Boolean;
+    icons: TArray<TIconSequence>;
+    map: TGoogle.TMaps.TMap;
+    path: TArray<JSValue>;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokeWeight: Double;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TProjection = class external name 'Projection' abstract
+  public
+    function fromLatLngToPoint(latLng: TGoogle.TMaps.TLatLng; point: TGoogle.TMaps.TPoint): TGoogle.TMaps.TPoint;
+    function fromPointToLatLng(pixel: TGoogle.TMaps.TPoint; noWrap: Boolean): TGoogle.TMaps.TLatLng;
+  end;
+
+  TRectangleOptions = class
+  public
+    bounds: JSValue;
+    clickable: Boolean;
+    draggable: Boolean;
+    editable: Boolean;
+    fillColor: String;
+    fillOpacity: Double;
+    map: TGoogle.TMaps.TMap;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokePosition: TGoogle.TMaps.TStrokePosition;
+    strokeWeight: Double;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TRotateControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TScaleControlOptions = class
+  public type
+    TScaleControlStyle = (scDEFAULT);
+  public
+    style: TScaleControlStyle;
+  end;
+
+  TMotionTrackingControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TStreetViewAddressControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TStreetViewControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TStreetViewLink = class
+  public
+    description: String;
+    heading: Double;
+    pano: String;
+  end;
+
+  TStreetViewLocation = class
+  public
+    description: String;
+    latLng: TGoogle.TMaps.TLatLng;
+    pano: String;
+    shortDescription: String;
+  end;
+
+  TStreetViewLocationRequest = class
+  public
+    location: JSValue;
+    preference: TGoogle.TMaps.TStreetViewPreference;
+    radius: Double;
+    source: TGoogle.TMaps.TStreetViewSource;
+  end;
+
+  TStreetViewPanoRequest = class
+  public
+    pano: String;
+  end;
+
+  TStreetViewPanoramaData = class
+  public
+    copyright: String;
+    imageDate: String;
+    links: TArray<TStreetViewLink>;
+    location: TStreetViewLocation;
+    tiles: TStreetViewTileData;
+  end;
+
+  TStreetViewPanoramaOptions = class
+  public
+    addressControl: Boolean;
+    addressControlOptions: TStreetViewAddressControlOptions;
+    clickToGo: Boolean;
+    controlSize: Double;
+    disableDefaultUI: Boolean;
+    disableDoubleClickZoom: Boolean;
+    enableCloseButton: Boolean;
+    fullscreenControl: Boolean;
+    fullscreenControlOptions: TFullscreenControlOptions;
+    imageDateControl: Boolean;
+    linksControl: Boolean;
+    motionTracking: Boolean;
+    motionTrackingControl: Boolean;
+    motionTrackingControlOptions: TMotionTrackingControlOptions;
+    panControl: Boolean;
+    panControlOptions: TPanControlOptions;
+    pano: String;
+    position: JSValue;
+    pov: TStreetViewPov;
+    scrollwheel: Boolean;
+    showRoadLabels: Boolean;
+    visible: Boolean;
+    zoom: Double;
+    zoomControl: Boolean;
+    zoomControlOptions: TZoomControlOptions;
+  end;
+
+  TStreetViewPov = class
+  public
+    heading: Double;
+    pitch: Double;
+  end;
+
+  TStreetViewResponse = class
+  public
+    data: TStreetViewPanoramaData;
+  end;
+
+  TStreetViewTileData = class
+  public
+    centerHeading: Double;
+    tileSize: TGoogle.TMaps.TSize;
+    worldSize: TGoogle.TMaps.TSize;
+
+    function getTileUrl(pano: String; tileZoom: Double; tileX: Double; tileY: Double): String; virtual; abstract;
+  end;
+
+  TStyledMapTypeOptions = class
+  public
+    alt: String;
+    maxZoom: Double;
+    minZoom: Double;
+    name: String;
+  end;
+
+  TSymbol = class
+  public
+    anchor: TGoogle.TMaps.TPoint;
+    fillColor: String;
+    fillOpacity: Double;
+    labelOrigin: TGoogle.TMaps.TPoint;
+    path: JSValue;
+    rotation: Double;
+    scale: Double;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokeWeight: Double;
+  end;
+
+  TTime = class
+  public
+    text: String;
+    time_zone: String;
+    value: String;
+  end;
+
+  TTrafficLayerOptions = class
+  public
+    autoRefresh: Boolean;
+    map: TGoogle.TMaps.TMap;
+  end;
+
+  TTransitAgency = class
+  public
+    name: String;
+    phone: String;
+    url: String;
+  end;
+
+  TTransitDetails = class
+  public
+    arrival_stop: TTransitStop;
+    arrival_time: TTime;
+    departure_stop: TTransitStop;
+    departure_time: TTime;
+    headsign: String;
+    headway: Double;
+    line: TTransitLine;
+    num_stops: Double;
+    trip_short_name: String;
+  end;
+
+  TTransitFare = class
+  public
+    currency: String;
+    value: Double;
+  end;
+
+  TTransitLine = class
+  public
+    agencies: TArray<TTransitAgency>;
+    color: String;
+    icon: String;
+    name: String;
+    short_name: String;
+    text_color: String;
+    url: String;
+    vehicle: TTransitVehicle;
+  end;
+
+  TTransitOptions = class
+  public
+    arrivalTime: String;
+    departureTime: String;
+    modes: TArray<TGoogle.TMaps.TTransitMode>;
+    routingPreference: TArray<TGoogle.TMaps.TTransitRoutePreference>;
+  end;
+
+  TTransitStop = class
+  public
+    location: TGoogle.TMaps.TLatLng;
+    name: String;
+  end;
+
+  TTransitVehicle = class
+  public
+    icon: String;
+    local_icon: String;
+    name: String;
+    &type: TGoogle.TMaps.TVehicleType;
+  end;
+
+  TZoomControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TDrawingControlOptions = class
+  public
+    drawingModes: TArray<TGoogle.TMaps.TOverlayType>;
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TDrawingManagerOptions = class
+  public
+    circleOptions: TCircleOptions;
+    drawingControl: Boolean;
+    drawingControlOptions: TDrawingControlOptions;
+    drawingMode: TGoogle.TMaps.TOverlayType;
+    map: TGoogle.TMaps.TMap;
+    markerOptions: TMarkerOptions;
+    polygonOptions: TPolygonOptions;
+    polylineOptions: TPolylineOptions;
+    rectangleOptions: TRectangleOptions;
+  end;
+
+  TOverlayCompleteEvent = class
+  public
+    overlay: JSValue;
+    &type: TGoogle.TMaps.TOverlayType;
+  end;
+
+  TPinOptions = class
+  public
+    background: String;
+    glyphColor: String;
+    scale: Double;
+  end;
+
+  TAutocompleteOptions = class
+  public
+    bounds: JSValue;
+    componentRestrictions: TComponentRestrictions;
+    fields: TArray<String>;
+    strictBounds: Boolean;
+    types: TArray<String>;
+  end;
+
+  TAutocompletePrediction = class
+  public
+    description: String;
+    distance_meters: Double;
+    matched_substrings: TArray<TPredictionSubstring>;
+    place_id: String;
+    structured_formatting: TStructuredFormatting;
+    terms: TArray<TPredictionTerm>;
+    types: TArray<String>;
+  end;
+
+  TAutocompleteResponse = class
+  public
+    predictions: TArray<TAutocompletePrediction>;
+  end;
+
+  TAutocompleteSessionToken = class
+  end;
+
+  TAutocompletionRequest = class
+  public
+    bounds: JSValue;
+    componentRestrictions: TComponentRestrictions;
+    input: String;
+    location: TGoogle.TMaps.TLatLng;
+    offset: Double;
+    origin: JSValue;
+    radius: Double;
+    sessionToken: TAutocompleteSessionToken;
+    types: TArray<String>;
+  end;
+
+  TComponentRestrictions = class
+  public
+    country: TArray<String>;
+  end;
+
+  TFindPlaceFromPhoneNumberRequest = class
+  public
+    fields: TArray<String>;
+    locationBias: JSValue;
+    phoneNumber: String;
+  end;
+
+  TFindPlaceFromQueryRequest = class
+  public
+    fields: TArray<String>;
+    locationBias: JSValue;
+    query: String;
+  end;
+
+  TPredictionSubstring = class
+  public
+    length: Double;
+    offset: Double;
+  end;
+
+  TPredictionTerm = class
+  public
+    offset: Double;
+    value: String;
+  end;
+
+  TQueryAutocompletionRequest = class
+  public
+    bounds: JSValue;
+    input: String;
+    location: TGoogle.TMaps.TLatLng;
+    offset: Double;
+    radius: Double;
+  end;
+
+  TSearchBoxOptions = class
+  public
+    bounds: JSValue;
+  end;
+
+  TStructuredFormatting = class
+  public
+    main_text: String;
+    main_text_matched_substrings: TArray<TPredictionSubstring>;
+    secondary_text: String;
+  end;
+
+  TTextSearchRequest = class
+  public
+    bounds: JSValue;
+    location: JSValue;
+    query: String;
+    radius: Double;
+    &type: String;
+  end;
+
+  THeatmapLayerOptions = class
+  public
+    data: JSValue;
+    dissipating: Boolean;
+    gradient: TArray<String>;
+    map: TGoogle.TMaps.TMap;
+    maxIntensity: Double;
+    opacity: Double;
+    radius: Double;
+  end;
+
+  TWeightedLocation = class
+  public
+    location: TGoogle.TMaps.TLatLng;
+    weight: Double;
+  end;
+
+function InitializeMap(Key: String): TJSPromise;
+
+implementation
+
+var
+  GResolvePromise: TJSPromiseResolver;
+
+procedure MapLoaded;
+begin
+  if Assigned(GResolvePromise) then
+    GResolvePromise(True);
+end;
+
+function InitializeMap(Key: String): TJSPromise;
+begin
+  GResolvePromise := nil;
+
+  MapLoaded;
+
+  Result := TJSPromise.New(
+    procedure(Resolve, Reject: TJSPromiseResolver)
+    var
+      Script: TJSHTMLScriptElement;
+
+    begin
+      GResolvePromise := Resolve;
+      Script := TJSHTMLScriptElement(document.createElement('script'));
+      Script.async := False;
+      Script.text := 'function GoogleMapLoaded(){pas["Google.Maps"].$impl.MapLoaded();}';
+
+      document.head.appendChild(Script);
+
+      Script := TJSHTMLScriptElement(document.createElement('script'));
+      Script.OnLoad :=
+        function (Event: TEventListenerEvent): Boolean
+        begin
+          Resolve(True);
+
+          Result := True;
+        end;
+      Script.src := Format('https://maps.googleapis.com/maps/api/js?key=%s&callback=GoogleMapLoaded', [Key]);
+      Script.type_ := 'text/javascript';
+
+      document.head.appendChild(Script);
+    end);
+end;
+
+{ TLatLngLiteral }
+
+constructor TLatLngLiteral.Create(Lat, Lng: Double);
+begin
+  Self.Lat := Lat;
+  Self.Lng := Lng;
+end;
+
+{ TMapOptions }
+
+function TMapOptions.GetfullscreenControlOptions: TFullscreenControlOptions;
+begin
+  if not Assigned(FfullscreenControlOptions) then
+    FfullscreenControlOptions := TFullscreenControlOptions.Create;
+
+  Result := FfullscreenControlOptions;
+end;
+
+function TMapOptions.GetmapTypeControlOptions: TMapTypeControlOptions;
+begin
+  if not Assigned(FmapTypeControlOptions) then
+    FmapTypeControlOptions := TMapTypeControlOptions.Create;
+
+  Result := FmapTypeControlOptions;
+end;
+
+function TMapOptions.GetpanControlOptions: TPanControlOptions;
+begin
+  if not Assigned(FpanControlOptions) then
+    FpanControlOptions := TPanControlOptions.Create;
+
+  Result := FpanControlOptions;
+end;
+
+function TMapOptions.GetRestriction: TMapRestriction;
+begin
+  if not Assigned(FRestriction) then
+    FRestriction := TMapRestriction.Create;
+
+  Result := FRestriction;
+end;
+
+function TMapOptions.GetRotateControlOptions: TRotateControlOptions;
+begin
+  if not Assigned(FRotateControlOptions) then
+    FRotateControlOptions := TRotateControlOptions.Create;
+
+  Result := FRotateControlOptions;
+end;
+
+function TMapOptions.GetScaleControlOptions: TScaleControlOptions;
+begin
+  if not Assigned(FScaleControlOptions) then
+    FScaleControlOptions := TScaleControlOptions.Create;
+
+  Result := FScaleControlOptions;
+end;
+
+function TMapOptions.GetZoomControlOptions: TZoomControlOptions;
+begin
+  if not Assigned(FZoomControlOptions) then
+    FZoomControlOptions := TZoomControlOptions.Create;
+
+  Result := FZoomControlOptions;
+end;
+
+function TMapOptions.GetStreetViewControlOptions: TStreetViewControlOptions;
+begin
+  if not Assigned(FStreetViewControlOptions) then
+    FStreetViewControlOptions := TStreetViewControlOptions.Create;
+
+  Result := FStreetViewControlOptions;
+end;
+
+end.
+
diff --git a/packages/maps/Leaflet.Maps.pas b/packages/maps/Leaflet.Maps.pas
new file mode 100644
index 00000000..94dc775a
--- /dev/null
+++ b/packages/maps/Leaflet.Maps.pas
@@ -0,0 +1,1856 @@
+unit Leaflet.Maps;
+
+interface
+
+{$modeswitch externalclass}
+
+uses JS, Web, SysUtils, GeoJSON;
+
+type
+//  TLatLngTuple = array[0..1] of Double;
+//  TPointTuple = array[0..1] of Double;
+//
+//  TBoundsLiteral = array[0..1] of TPointTuple;
+
+  TLatLngTuple = String;
+  TPointTuple = Char;
+
+  TBoundsLiteral = array of TPointTuple;
+
+  TAttributionOptions = class;
+  TBaseIconOptions = class;
+  TCircleMarkerOptions = class;
+  TControlOptions = class;
+  TDefaultMapPanes = class;
+  TDivIconOptions = class;
+  TDivOverlayOptions = class;
+  TDragEndEvent = class;
+  TError = class;
+  TErrorEvent = class;
+  TFitBoundsOptions = class;
+  TGeoJSONEvent = class;
+  TGeoJSONOptions = class;
+  TGridLayerOptions = class;
+  TIconOptions = class;
+  TImageOverlayOptions = class;
+  TInteractiveLayerOptions = class;
+  TInvalidateSizeOptions = class;
+  TLatLngLiteral = class;
+  TLayerEvent = class;
+  TLayerOptions = class;
+  TLayersControlEvent = class;
+  TLayersObject = class;
+  TLayersOptions = class;
+  TLeafletEvent = class;
+  TLeafletKeyboardEvent = class;
+  TLeafletMouseEvent = class;
+  TLocateOptions = class;
+  TLocationEvent = class;
+  TMapOptions = class;
+  TMarkerOptions = class;
+  TPanInsideOptions = class;
+  TPanOptions = class;
+  TPathOptions = class;
+  TPolylineOptions = class;
+  TPopupEvent = class;
+  TPopupOptions = class;
+  TRendererOptions = class;
+  TResizeEvent = class;
+  TScaleOptions = class;
+  TTileErrorEvent = class;
+  TTileEvent = class;
+  TTileLayerOptions = class;
+  TTooltipEvent = class;
+  TTooltipOptions = class;
+  TVideoOverlayOptions = class;
+  TWMSOptions = class;
+  TWMSParams = class;
+  TZoomAnimEvent = class;
+  TZoomControlOptions = class;
+  TZoomOptions = class;
+  TZoomPanOptions = class;
+
+  TLeaflet = class external name 'L'
+  public type
+    TBounds = class;
+    TLatLng = class;
+    TLatLngBounds = class;
+    TLayerGroup = class;
+    TMap = class;
+    TPoint = class;
+    TPopup = class;
+    TTooltip = class;
+
+    TLatLngBoundsLiteral = TArray<TLatLngTuple>;
+
+    TClass = class external name 'Class'
+    public
+      class function addInitHook(initHookFn: TProc): TClass; overload;
+      class function addInitHook(methodName: String): TClass; varargs; overload;
+      class function extend(props: JSValue): TClass;
+      class function include(props: JSValue): TClass;
+      class function mergeOptions(props: JSValue): TClass;
+    end;
+
+    TTransformation = class external name 'Transformation'
+    public
+      constructor Create(a, b, c, d: Double); external name '';
+
+      function transform(point: TPoint): TPoint; overload;
+      function transform(point: TPoint; scale: Double): TPoint; overload;
+      function untransform(point: TPoint): TPoint; overload;
+      function untransform(point: TPoint; scale: Double): TPoint; overload;
+    end;
+
+    TLineUtil = class external name 'LineUtil'
+    public
+      function simplify(points: TArray<TPoint>; tolerance: Double): TArray<TPoint>;
+      function pointToSegmentDistance(p, p1,p2: TPoint): Double;
+      function closestPointOnSegment(p, p1, p2: TPoint): TPoint;
+      function isFlat(latlngs: TArray<TLatLng>): Boolean; overload;
+      function isFlat(latlngs: TArray<TLatLngLiteral>): Boolean; overload;
+      function isFlat(latlngs: TArray<TLatLngTuple>): Boolean; overload;
+      function clipSegment(a, b: TPoint; bounds: TBounds): TArray<TPoint>; overload;
+      function clipSegment(a, b: TPoint; bounds: TBounds; useLastCode: Boolean): TArray<TPoint>; overload;
+      function clipSegment(a, b: TPoint; bounds: TBounds; useLastCode, round: Boolean): TArray<TPoint>; overload;
+    end;
+
+    TPolyUtil = class external name 'PolyUtil'
+    public
+      function clipPolygon(points: TArray<TPoint>; bounds: TBounds): TArray<TPoint>; overload;
+      function clipPolygon(points: TArray<TPoint>; bounds: TBoundsLiteral): TArray<TPoint>; overload;
+      function clipPolygon(points: TArray<TPoint>; bounds: TBounds; round: Boolean): TArray<TPoint>; overload;
+      function clipPolygon(points: TArray<TPoint>; bounds: TBoundsLiteral; round: Boolean): TArray<TPoint>; overload;
+    end;
+
+    TDomUtil = class external name 'DomUtil'
+    public
+      TRANSFORM: String;
+      TRANSITION: String;
+      TRANSITION_END: String;
+
+      function get(element: String): TJSHTMLElement; overload;
+      function get(element: TJSHTMLElement): TJSHTMLElement; overload;
+      function getStyle(el: TJSHTMLElement; styleAttrib: String): String;
+      function create(tagName: String): TJSHTMLElement; overload;
+      function create(tagName: String; className: String): TJSHTMLElement; overload;
+      function create(tagName: String; className: String; container: TJSHTMLElement): TJSHTMLElement; overload;
+      procedure remove(el: TJSHTMLElement);
+      procedure empty(el: TJSHTMLElement);
+      procedure toFront(el: TJSHTMLElement);
+      procedure toBack(el: TJSHTMLElement);
+      function hasClass(el: TJSHTMLElement; name: String): Boolean;
+      procedure addClass(el: TJSHTMLElement; name: String);
+      procedure removeClass(el: TJSHTMLElement; name: String);
+      procedure setClass(el: TJSHTMLElement; name: String);
+      function getClass(el: TJSHTMLElement): String;
+      procedure setOpacity(el: TJSHTMLElement; opacity: Double);
+      function testProp(props: TArray<String>): String;
+      procedure setTransform(el: TJSHTMLElement; offset: TPoint; scale: Double);
+      procedure setPosition(el: TJSHTMLElement; position: TPoint);
+      function getPosition(el: TJSHTMLElement): TPoint;
+      procedure disableTextSelection();
+      procedure enableTextSelection();
+      procedure disableImageDrag();
+      procedure enableImageDrag();
+      procedure preventOutline(el: TJSHTMLElement);
+      procedure restoreOutline();
+    end;
+
+    TCRS = class external name 'CRS'
+    public
+      const EPSG3395: TCRS;
+      const EPSG3857: TCRS;
+      const EPSG4326: TCRS;
+      const EPSG900913: TCRS;
+      const Earth: TCRS;
+      const Simple: TCRS;
+    public
+      code: String;
+      wrapLng: TArray<Double>;
+      wrapLat: TArray<Double>;
+      infinite: Boolean;
+
+      function latLngToPoint(latlng: TLatLng; zoom: Double): TPoint; overload;
+      function latLngToPoint(latlng: TLatLngLiteral; zoom: Double): TPoint; overload;
+      function latLngToPoint(latlng: TLatLngTuple; zoom: Double): TPoint; overload;
+      function pointToLatLng(point: TPoint; zoom: Double): TLatLng; overload;
+      function pointToLatLng(point: TPointTuple; zoom: Double): TLatLng; overload;
+      function project(latlng: TLatLng): TPoint; overload;
+      function project(latlng: TLatLngLiteral): TPoint; overload;
+      function unproject(point: TPoint): TLatLng; overload;
+      function unproject(point: TPointTuple): TLatLng; overload;
+      function scale(zoom: Double): Double;
+      function zoom(scale: Double): Double;
+      function getProjectedBounds(zoom: Double): TBounds;
+      function distance(latlng1, latlng2: TLatLng): Double; overload;
+      function distance(latlng1, latlng2: TLatLngLiteral): Double; overload;
+      function distance(latlng1, latlng2: TLatLngTuple): Double; overload;
+      function wrapLatLng(latlng: TLatLng): TLatLng; overload;
+      function wrapLatLng(latlng: TLatLngLiteral): TLatLng; overload;
+    end;
+
+    TProjection = class external name 'Projection'
+    public
+      bounds: TBounds;
+
+      const LonLat: TProjection;
+      const Mercator: TProjection;
+      const SphericalMercator: TProjection;
+
+      function project(latlng: TLatLng): TPoint; overload;
+      function project(latlng: TLatLngLiteral): TPoint; overload;
+      function unproject(point: TPoint): TLatLng; overload;
+      function unproject(point: TPointTuple): TLatLng; overload;
+    end;
+
+    TLatLng = class external name 'LatLng'
+    public
+      lat: Double;
+      lng: Double;
+      alt: Double;
+
+      constructor Create(latitude, longitude: Double); external name ''; overload;
+      constructor Create(latitude, longitude, altitude: Double); external name ''; overload;
+
+      function clone(): TLatLng;
+      function distanceTo(otherLatLng: TLatLng): Double; overload;
+      function distanceTo(otherLatLng: TLatLngLiteral): Double; overload;
+      function distanceTo(otherLatLng: TLatLngTuple): Double; overload;
+      function equals(otherLatLng: TLatLng): Boolean; overload;
+      function equals(otherLatLng: TLatLng; maxMargin: Double): Boolean; overload;
+      function equals(otherLatLng: TLatLngLiteral): Boolean; overload;
+      function equals(otherLatLng: TLatLngLiteral; maxMargin: Double): Boolean; overload;
+      function equals(otherLatLng: TLatLngTuple): Boolean; overload;
+      function equals(otherLatLng: TLatLngTuple; maxMargin: Double): Boolean; overload;
+      function toBounds(sizeInMeters: Double): TLatLngBounds;
+      function toString(): String;
+      function wrap(): TLatLng;
+    end;
+
+    TLatLngBounds = class external name 'LatLngBounds'
+    public
+      constructor Create(southWest, northEast: TLatLng); external name ''; overload;
+      constructor Create(southWest, northEast: TLatLngLiteral); external name ''; overload;
+      constructor Create(southWest, northEast: TLatLngTuple); external name ''; overload;
+      constructor Create(latlngs: TLatLngBoundsLiteral); external name ''; overload;
+
+      function extend(latlngOrBounds: TLatLng): TLatLngBounds; overload;
+      function extend(latlngOrBounds: TLatLngLiteral): TLatLngBounds; overload;
+      function extend(latlngOrBounds: TLatLngTuple): TLatLngBounds; overload;
+      function extend(latlngOrBounds: TLatLngBounds): TLatLngBounds; overload;
+      function extend(latlngOrBounds: TLatLngBoundsLiteral): TLatLngBounds; overload;
+      function pad(bufferRatio: Double): TLatLngBounds; // does this modify the current instance or does it return a new one?
+      function getCenter(): TLatLng;
+      function getSouthWest(): TLatLng;
+      function getNorthEast(): TLatLng;
+      function getNorthWest(): TLatLng;
+      function getSouthEast(): TLatLng;
+      function getWest(): Double;
+      function getSouth(): Double;
+      function getEast(): Double;
+      function getNorth(): Double;
+      function contains(otherBoundsOrLatLng: TLatLngBounds): Boolean; overload;
+      function contains(otherBoundsOrLatLng: TLatLngBoundsLiteral): Boolean; overload;
+      function contains(otherBoundsOrLatLng: TLatLng): Boolean; overload;
+      function contains(otherBoundsOrLatLng: TLatLngLiteral): Boolean; overload;
+      function contains(otherBoundsOrLatLng: TLatLngTuple): Boolean; overload;
+      function intersects(otherBounds: TLatLngBounds): Boolean; overload;
+      function intersects(otherBounds: TLatLngBoundsLiteral): Boolean; overload;
+      function overlaps(otherBounds: TLatLngBounds): Boolean; overload;
+      function overlaps(otherBounds: TLatLngBoundsLiteral): Boolean; overload;
+      function toBBoxString(): String;
+      function equals(otherBounds: TLatLngBounds): Boolean; overload;
+      function equals(otherBounds: TLatLngBoundsLiteral): Boolean; overload;
+      function isValid(): Boolean;
+    end;
+
+    TPoint = class external name 'TPoint'
+    public
+      x: Double;
+      y: Double;
+
+      constructor Create(x, y: Double); external name ''; overload;
+      constructor Create(x, y: Double; round: Boolean); external name ''; overload;
+      function clone(): TPoint;
+      function add(otherPoint: TPoint): TPoint; overload;
+      function add(otherPoint: TPointTuple): TPoint; overload;
+      function subtract(otherPoint: TPoint): TPoint; overload;
+      function subtract(otherPoint: TPointTuple): TPoint; overload;
+      function divideBy(num: Double): TPoint;
+      function multiplyBy(num: Double): TPoint;
+      function scaleBy(scale: TPoint): TPoint; overload;
+      function scaleBy(scale: TPointTuple): TPoint; overload;
+      function unscaleBy(scale: TPoint): TPoint; overload;
+      function unscaleBy(scale: TPointTuple): TPoint; overload;
+      function round(): TPoint;
+      function floor(): TPoint;
+      function ceil(): TPoint;
+      function distanceTo(otherPoint: TPoint): Double; overload;
+      function distanceTo(otherPoint: TPointTuple): Double; overload;
+      function equals(otherPoint: TPoint): Boolean; overload;
+      function equals(otherPoint: TPointTuple): Boolean; overload;
+      function contains(otherPoint: TPoint): Boolean; overload;
+      function contains(otherPoint: TPointTuple): Boolean; overload;
+      function toString(): String;
+    end;
+
+    TCoords = class external name 'Coords' (TPoint)
+    public
+      z: Double;
+    end;
+
+    TBounds = class external name 'Bounds'
+    public
+      min: TPoint;
+      max: TPoint;
+
+      constructor Create(points: TArray<TPoint>); external name ''; overload;
+      constructor Create(points: TBoundsLiteral); external name ''; overload;
+      constructor Create(topLeft, bottomRight: TPoint); external name ''; overload;
+      constructor Create(topLeft, bottomRight: TPointTuple); external name ''; overload;
+      function extend(point: TPoint): TBounds; overload;
+      function extend(point: TPointTuple): TBounds; overload;
+      function getCenter(round: Boolean): TPoint;
+      function getBottomLeft(): TPoint;
+      function getBottomRight(): TPoint;
+      function getTopLeft(): TPoint;
+      function getTopRight(): TPoint;
+      function getSize(): TPoint;
+      function contains(pointOrBounds: TBounds): Boolean; overload;
+      function contains(pointOrBounds: TBoundsLiteral): Boolean; overload;
+      function contains(pointOrBounds: TPoint): Boolean; overload;
+      function contains(pointOrBounds: TPointTuple): Boolean; overload;
+      function intersects(otherBounds: TBounds): Boolean; overload;
+      function intersects(otherBounds: TBoundsLiteral): Boolean; overload;
+      function overlaps(otherBounds: TBounds): Boolean; overload;
+      function overlaps(otherBounds: TBoundsLiteral): Boolean; overload;
+    end;
+
+    // Event handler types
+    TDragEndEventHandlerFn = TProc<TDragEndEvent>;
+    TErrorEventHandlerFn = TProc<TErrorEvent>;
+    TLayerEventHandlerFn = TProc<TLayerEvent>;
+    TLayersControlEventHandlerFn = TProc<TLayersControlEvent>;
+    TLeafletEventHandlerFn = TProc<TLeafletEvent>;
+    TLeafletKeyboardEventHandlerFn = TProc<TLeafletKeyboardEvent>;
+    TLeafletMouseEventHandlerFn = TProc<TLeafletMouseEvent>;
+    TLocationEventHandlerFn = TProc<TLocationEvent>;
+    TPopupEventHandlerFn = TProc<TPopupEvent>;
+    TResizeEventHandlerFn = TProc<TResizeEvent>;
+    TTileErrorEventHandlerFn = TProc<TTileErrorEvent>;
+    TTileEventHandlerFn = TProc<TTileEvent>;
+    TTooltipEventHandlerFn = TProc<TTooltipEvent>;
+    TZoomAnimEventHandlerFn = TProc<TZoomAnimEvent>;
+
+    TLeafletEventHandlerFnMap = class external name 'LeafletEventHandlerFnMap'
+    public
+      baselayerchange: TLayersControlEventHandlerFn;
+      overlayadd: TLayersControlEventHandlerFn;
+      overlayremove: TLayersControlEventHandlerFn;
+
+      layeradd: TLayerEventHandlerFn;
+      layerremove: TLayerEventHandlerFn;
+
+      zoomlevelschange: TLeafletEventHandlerFn;
+      unload: TLeafletEventHandlerFn;
+      viewreset: TLeafletEventHandlerFn;
+      load: TLeafletEventHandlerFn;
+      zoomstart: TLeafletEventHandlerFn;
+      movestart: TLeafletEventHandlerFn;
+      zoom: TLeafletEventHandlerFn;
+      move: TLeafletEventHandlerFn;
+      zoomend: TLeafletEventHandlerFn;
+      moveend: TLeafletEventHandlerFn;
+      autopanstart: TLeafletEventHandlerFn;
+      dragstart: TLeafletEventHandlerFn;
+      drag: TLeafletEventHandlerFn;
+      add: TLeafletEventHandlerFn;
+      remove: TLeafletEventHandlerFn;
+      loading: TLeafletEventHandlerFn;
+      error: TLeafletEventHandlerFn;
+      update: TLeafletEventHandlerFn;
+      down: TLeafletEventHandlerFn;
+      predrag: TLeafletEventHandlerFn;
+
+      resize: TResizeEventHandlerFn;
+
+      popupopen: TPopupEventHandlerFn;
+      popupclose: TPopupEventHandlerFn;
+
+      tooltipopen: TTooltipEventHandlerFn;
+      tooltipclose: TTooltipEventHandlerFn;
+
+      locationerror: TErrorEventHandlerFn;
+
+      locationfound: TLocationEventHandlerFn;
+
+      click: TLeafletMouseEventHandlerFn;
+      dblclick: TLeafletMouseEventHandlerFn;
+      mousedown: TLeafletMouseEventHandlerFn;
+      mouseup: TLeafletMouseEventHandlerFn;
+      mouseover: TLeafletMouseEventHandlerFn;
+      mouseout: TLeafletMouseEventHandlerFn;
+      mousemove: TLeafletMouseEventHandlerFn;
+      contextmenu: TLeafletMouseEventHandlerFn;
+      preclick: TLeafletMouseEventHandlerFn;
+
+      keypress: TLeafletKeyboardEventHandlerFn;
+      keydown: TLeafletKeyboardEventHandlerFn;
+      keyup: TLeafletKeyboardEventHandlerFn;
+
+      zoomanim: TZoomAnimEventHandlerFn;
+
+      dragend: TDragEndEventHandlerFn;
+
+      tileunload: TTileEventHandlerFn;
+      tileloadstart: TTileEventHandlerFn;
+      tileload: TTileEventHandlerFn;
+
+      tileerror: TTileErrorEventHandlerFn;
+    end;
+
+    TEvented = class external name 'Evented' (TClass)
+    public
+      function addEventListener(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TTileErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function addEventParent(obj: TEvented): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TTileErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function clearAllEventListeners(): TEvented; overload;
+      function fire(&type: String; data: JSValue): TEvented; overload;
+      function fire(&type: String; data: JSValue; propagate: Boolean): TEvented; overload;
+      function fireEvent(&type: String; data: JSValue): TEvented; overload;
+      function fireEvent(&type: String; data: JSValue; propagate: Boolean): TEvented; overload;
+      function hasEventListeners(&type: String): Boolean;
+      function listens(&type: String): Boolean; overload;
+      function off(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TTileErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(): TEvented; overload;
+      function off(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function &on(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TTileErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function once(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function removeEventListener(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TTileErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function removeEventParent(obj: TEvented): TEvented; overload;
+    end;
+
+    TDraggable = class external name 'Draggable' (TEvented)
+    public
+      constructor Create(element, dragStartTarget: TJSHTMLElement; preventOutline: Boolean); external name '';
+
+      procedure enable();
+      procedure disable();
+      procedure finishDrag();
+    end;
+
+    TLayer = class external name 'Layer' (TEvented)
+    public
+      constructor Create(options: TLayerOptions); external name '';
+
+      function addTo(map: TMap): TLayer; overload;
+      function addTo(map: TLayerGroup): TLayer; overload;
+      function remove(): TLayer;
+      function removeFrom(map: TMap): TLayer;
+      function getPane(name: String): TJSHTMLElement;
+
+      // Popup methods
+      function bindPopup(content: TFunc<TLayer, String>; options: TPopupOptions): TLayer; overload;
+      function bindPopup(content: TFunc<TLayer, TJSHTMLElement>; options: TPopupOptions): TLayer; overload;
+      function bindPopup(content: String; options: TPopupOptions): TLayer; overload;
+      function bindPopup(content: TJSHTMLElement; options: TPopupOptions): TLayer; overload;
+      function bindPopup(content: TPopup; options: TPopupOptions): TLayer; overload;
+      function unbindPopup(): TLayer;
+      function openPopup(latlng: TLatLng): TLayer; overload;
+      function openPopup(latlng: TLatLngLiteral): TLayer; overload;
+      function openPopup(latlng: TLatLngTuple): TLayer; overload;
+      function closePopup(): TLayer;
+      function togglePopup(): TLayer;
+      function isPopupOpen(): Boolean;
+      function setPopupContent(content: String): TLayer; overload;
+      function setPopupContent(content: TJSHTMLElement): TLayer; overload;
+      function setPopupContent(content: TPopup): TLayer; overload;
+      function getPopup(): TPopup;
+
+      // Tooltip methods
+      function bindTooltip(content: TFunc<TLayer, String>; options: TTooltipOptions): TLayer; overload;
+      function bindTooltip(content: TFunc<TLayer, TJSHTMLElement>; options: TTooltipOptions): TLayer; overload;
+      function bindTooltip(content: TTooltip; options: TTooltipOptions): TLayer; overload;
+      function bindTooltip(content: String; options: TTooltipOptions): TLayer; overload;
+      function bindTooltip(content: TJSHTMLElement; options: TTooltipOptions): TLayer; overload;
+      function unbindTooltip(): TLayer;
+      function openTooltip(latlng: TLatLng): TLayer; overload;
+      function openTooltip(latlng: TLatLngLiteral): TLayer; overload;
+      function openTooltip(latlng: TLatLngTuple): TLayer; overload;
+      function closeTooltip(): TLayer;
+      function toggleTooltip(): TLayer;
+      function isTooltipOpen(): Boolean;
+      function setTooltipContent(content: String): TLayer; overload;
+      function setTooltipContent(content: TJSHTMLElement): TLayer; overload;
+      function setTooltipContent(content: TTooltip): TLayer; overload;
+      function getTooltip(): TTooltip;
+
+      // Extension methods
+      function onAdd(map: TMap): TLayer;
+      function onRemove(map: TMap): TLayer;
+      function getEvents(): TJSObject;
+      function getAttribution(): String;
+      function beforeAdd(map: TMap): TLayer;
+    end;
+
+    TDoneCallback = TProc<TError, TJSHTMLElement>;
+
+    TGridLayer = class external name 'GridLayer' (TLayer)
+    public
+      constructor Create(options: TGridLayerOptions); external name '';
+      function bringToFront(): TGridLayer;
+      function bringToBack(): TGridLayer;
+      function getContainer(): TJSHTMLElement;
+      function setOpacity(opacity: Double): TGridLayer;
+      function setZIndex(zIndex: Double): TGridLayer;
+      function isLoading(): Boolean;
+      function redraw(): TGridLayer;
+      function getTileSize(): TPoint;
+    end;
+
+    TTileLayer = class external name 'TileLayer' (TGridLayer)
+    public type
+      TWMS = class external name 'WMS' (TTileLayer)
+      public
+        wmsParams: TWMSParams;
+        options: TWMSOptions;
+
+        constructor Create(baseUrl: String; options: TWMSOptions); external name '';
+        function setParams(params: TWMSParams; noRedraw: Boolean): TWMS;
+      end;
+    public
+      options: TTileLayerOptions;
+
+      constructor Create(urlTemplate: String; options: TTileLayerOptions); external name '';
+      function setUrl(url: String; noRedraw: Boolean): TTileLayer;
+      function getTileUrl(coords: TCoords): String;
+      function wms(baseUrl: String; options: TWMSOptions): TWMS;
+    end;
+
+    TImageOverlay = class external name 'ImageOverlay' (TLayer)
+    public
+      options: TImageOverlayOptions;
+
+      constructor Create(imageUrl: String; bounds: TLatLngBounds; options: TImageOverlayOptions); external name ''; overload;
+      constructor Create(imageUrl: String; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions); external name ''; overload;
+      function setOpacity(opacity: Double): TImageOverlay;
+      function bringToFront(): TImageOverlay;
+      function bringToBack(): TImageOverlay;
+      function setUrl(url: String): TImageOverlay;
+
+      function setBounds(bounds: TLatLngBounds): TImageOverlay;
+
+      function setZIndex(value: Double): TImageOverlay;
+
+      function getBounds(): TLatLngBounds;
+
+      function getElement(): TJSHTMLImageElement;
+    end;
+
+    TSVGOverlay = class external name 'SVGOverlay' (TLayer)
+    public
+      options: TImageOverlayOptions;
+
+      constructor Create(svgImage: String; bounds: TLatLngBounds; options: TImageOverlayOptions); external name ''; overload;
+      constructor Create(svgImage: String; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions); external name ''; overload;
+      constructor Create(svgImage: TJSHTMLElement; bounds: TLatLngBounds; options: TImageOverlayOptions); external name ''; overload;
+      constructor Create(svgImage: TJSHTMLElement; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions); external name ''; overload;
+
+      function setOpacity(opacity: Double): TSVGOverlay;
+      function bringToFront(): TSVGOverlay;
+      function bringToBack(): TSVGOverlay;
+      function setUrl(url: String): TSVGOverlay;
+
+      function setBounds(bounds: TLatLngBounds): TSVGOverlay;
+
+      function setZIndex(value: Double): TSVGOverlay;
+
+      function getBounds(): TLatLngBounds;
+
+      function getElement(): TJSHTMLElement;
+    end;
+
+    TVideoOverlay = class external name 'VideoOverlay' (TLayer)
+    public
+      options: TVideoOverlayOptions;
+
+      constructor Create(video: String; bounds: TLatLngBounds; options: TVideoOverlayOptions); external name ''; overload;
+      constructor Create(video: String; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions); external name ''; overload;
+      constructor Create(video: TArray<String>; bounds: TLatLngBounds; options: TVideoOverlayOptions); external name ''; overload;
+      constructor Create(video: TArray<String>; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions); external name ''; overload;
+      constructor Create(video: TJSHTMLVideoElement; bounds: TLatLngBounds; options: TVideoOverlayOptions); external name ''; overload;
+      constructor Create(video: TJSHTMLVideoElement; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions); external name ''; overload;
+
+      function setOpacity(opacity: Double): TVideoOverlay;
+      function bringToFront(): TVideoOverlay;
+      function bringToBack(): TVideoOverlay;
+      function setUrl(url: String): TVideoOverlay;
+
+      function setBounds(bounds: TLatLngBounds): TVideoOverlay;
+
+      function getBounds(): TLatLngBounds;
+
+      function getElement(): TJSHTMLVideoElement;
+    end;
+
+    TPath = class external name 'Path' abstract (TLayer)
+    public
+      options: TPathOptions;
+
+      function redraw(): TPath;
+      function setStyle(style: TPathOptions): TPath;
+      function bringToFront(): TPath;
+      function bringToBack(): TPath;
+      function getElement(): TJSHTMLElement;
+    end;
+
+    TPolyline = class external name 'Polyline' (TPath)
+    public
+      feature: TFeature;
+      options: TPolylineOptions;
+
+      constructor Create(latlngs: TArray<TLatLng>; options: TPolylineOptions); external name ''; overload;
+      constructor Create(latlngs: TArray<TArray<TLatLng>>; options: TPolylineOptions); external name ''; overload;
+      constructor Create(latlngs: TArray<TLatLngLiteral>; options: TPolylineOptions); external name ''; overload;
+      constructor Create(latlngs: TArray<TArray<TLatLngLiteral>>; options: TPolylineOptions); external name ''; overload;
+      constructor Create(latlngs: TArray<TLatLngTuple>; options: TPolylineOptions); external name ''; overload;
+      constructor Create(latlngs: TArray<TArray<TLatLngTuple>>; options: TPolylineOptions); external name ''; overload;
+
+      function toGeoJSON(precision: Double): TFeature;
+      function getLatLngs(): JSValue;
+      function setLatLngs(latlngs: TArray<TLatLng>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TLatLngLiteral>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TLatLngTuple>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TLatLng>>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TLatLngLiteral>>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TLatLngTuple>>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TArray<TLatLng>>>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TArray<TLatLngLiteral>>>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TArray<TLatLngTuple>>>): TPolyline; overload;
+      function isEmpty(): Boolean;
+      function getCenter(): TLatLng;
+      function getBounds(): TLatLngBounds;
+      function addLatLng(latlng: TLatLng): TPolyline; overload;
+      function addLatLng(latlng: TLatLngLiteral): TPolyline; overload;
+      function addLatLng(latlng: TLatLngTuple): TPolyline; overload;
+      function addLatLng(latlng: TLatLng; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TLatLngLiteral; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TLatLngTuple; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLngLiteral>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLngTuple>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLng>; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLngLiteral>; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLngTuple>; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function closestLayerPoint(p: TPoint): TPoint;
+    end;
+
+    TPolygon = class external name 'Polygon' (TPolyline)
+    public
+      constructor Create(latlngs: TArray<TLatLng>; options: TPolylineOptions); external name ''; overload;
+      constructor Create(latlngs: TArray<TArray<TLatLng>>; options: TPolylineOptions); external name ''; overload;
+      constructor Create(latlngs: TArray<TLatLngLiteral>; options: TPolylineOptions); external name ''; overload;
+      constructor Create(latlngs: TArray<TArray<TLatLngLiteral>>; options: TPolylineOptions); external name ''; overload;
+      constructor Create(latlngs: TArray<TLatLngTuple>; options: TPolylineOptions); external name ''; overload;
+      constructor Create(latlngs: TArray<TArray<TLatLngTuple>>; options: TPolylineOptions); external name ''; overload;
+    end;
+
+    TRectangle = class external name 'Rectangle' (TPolygon)
+    public
+      constructor Create(latLngBounds: TLatLngBounds; options: TPolylineOptions); external name ''; overload;
+      constructor Create(latLngBounds: TLatLngBoundsLiteral; options: TPolylineOptions); external name ''; overload;
+
+      function setBounds(latLngBounds: TLatLngBounds): TRectangle; overload;
+      function setBounds(latLngBounds: TLatLngBoundsLiteral): TRectangle; overload;
+    end;
+
+    TCircleMarker = class external name 'CircleMarker' (TPath)
+    public
+      options: TCircleMarkerOptions;
+      feature: TFeature;
+
+      constructor Create(latlng: TLatLng; options: TCircleMarkerOptions); external name ''; overload;
+      constructor Create(latlng: TLatLngLiteral; options: TCircleMarkerOptions); external name ''; overload;
+      constructor Create(latlng: TLatLngTuple; options: TCircleMarkerOptions); external name ''; overload;
+
+      function toGeoJSON(precision: Double): TFeature;
+      function setLatLng(latLng: JSValue): TCircleMarker;
+      function getLatLng(): TLatLng;
+      function setRadius(radius: Double): TCircleMarker;
+      function getRadius(): Double;
+    end;
+
+    TCircle = class external name 'Circle' (TCircleMarker)
+    public
+      constructor Create(latlng: TLatLng; options: TCircleMarkerOptions); external name ''; overload;
+      constructor Create(latlng: TLatLngLiteral; options: TCircleMarkerOptions); external name ''; overload;
+      constructor Create(latlng: TLatLngTuple; options: TCircleMarkerOptions); external name ''; overload;
+
+      function getBounds(): TLatLngBounds;
+    end;
+
+    TRenderer = class external name 'Renderer' (TLayer)
+    public
+      options: TRendererOptions;
+
+      constructor Create(options: TRendererOptions); external name '';
+    end;
+
+    TSVG = class external name 'SVG' (TRenderer)
+    public
+      class function create(name: String): TJSHTMLElement;
+      class function pointsToPath(rings: TPoint; close: Boolean): String; overload;
+      class function pointsToPath(rings: TArray<TPointTuple>; close: Boolean): String; overload;
+    end;
+
+    TCanvas = class external name 'Canvas' (TRenderer)
+    end;
+
+    TLayerGroup = class external name 'LayerGroup' (TLayer)
+    public
+      feature: JSValue;
+
+      constructor Create(layers: TArray<TLayer>); external name ''; overload;
+      constructor Create(layers: TArray<TLayer>; options: TLayerOptions); external name ''; overload;
+      constructor Create; external name ''; overload;
+
+      function addLayer(layer: TLayer): TLayerGroup;
+      function clearLayers(): TLayerGroup;
+      function eachLayer(fn: TProc<TLayer>; context: JSValue): TLayerGroup;
+      function getLayer(id: Double): TLayer;
+      function getLayerId(layer: TLayer): Double;
+      function getLayers(): TArray<TLayer>;
+      function hasLayer(layer: TLayer): Boolean;
+      function invoke(methodName: String): TLayerGroup; varargs;
+      function removeLayer(layer: TLayer): TLayerGroup;
+      function setZIndex(zIndex: Double): TLayerGroup;
+      function toGeoJSON(precision: Double): JSValue; overload;
+      function toGeoJSON: JSValue; overload;
+    end;
+
+    TFeatureGroup = class external name 'FeatureGroup' (TLayerGroup)
+    public
+      function bringToBack(): TFeatureGroup;
+      function bringToFront(): TFeatureGroup;
+      function getBounds(): TLatLngBounds;
+      function setStyle(style: TPathOptions): TFeatureGroup;
+    end;
+
+    TStyleFunction = TFunc<TFeature, TPathOptions>;
+
+    TGeoJSON = class external name 'GeoJSON' (TFeatureGroup)
+    public
+      options: TGeoJSONOptions;
+
+      constructor Create(geojson: TGeoJsonObject; options: TGeoJSONOptions) external name '';
+
+      class function asFeature(geojson: TFeature): TFeature;
+      class function coordsToLatLng(coords: TArray<Double>): TLatLng;
+      class function coordsToLatLngs(coords: TArray<JSValue>; levelsDeep: Double; coordsToLatLng: TFunc<TArray<Double>, TLatLng>): TArray<JSValue>; // Using TArray<JSValue> to avoid artificially limiting valid calls
+      class function geometryToLayer(featureData: TFeature; options: TGeoJSONOptions): TLayer;
+      class function latLngToCoords(latlng: TLatLng): TArray<Double>;
+      class function latLngsToCoords(latlngs: TArray<JSValue>; levelsDeep: Double; closed: Boolean): TArray<JSValue>;  // Using TArray<JSValue> to avoid artificially limiting valid calls
+
+      function addData(data: TGeoJsonObject): TLayer;
+      function resetStyle(layer: TLayer): TLayer;
+      function setStyle(style: TPathOptions): TGeoJSON; overload;
+      function setStyle(style: TStyleFunction): TGeoJSON; overload;
+    end;
+
+    TControl = class external name 'Control' (TClass)
+    public type
+      TZoom = class external name 'Zoom' (TControl)
+      public
+        options: TZoomControlOptions;
+        constructor Create(options: TZoomControlOptions); external name '';
+      end;
+
+      TAttribution = class external name 'Attribution' (TControl)
+      public
+        options: TAttributionOptions;
+
+        constructor Create(options: TAttributionOptions); external name '';
+        function setPrefix(prefix: String): TAttribution;
+        function addAttribution(text: String): TAttribution;
+        function removeAttribution(text: String): TAttribution;
+      end;
+
+      TLayers = class external name 'Layers' (TControl)
+      public
+        options: TLayersOptions;
+
+        constructor Create; external name ''; overload;
+        constructor Create(baseLayers: TLayersObject); external name ''; overload;
+        constructor Create(baseLayers, overlays: TLayersObject); external name ''; overload;
+        constructor Create(baseLayers, overlays: TLayersObject; options: TLayersOptions); external name ''; overload;
+
+        function addBaseLayer(layer: TLayer; name: String): TLayers;
+        function addOverlay(layer: TLayer; name: String): TLayers;
+        function removeLayer(layer: TLayer): TLayers;
+        function expand(): TLayers;
+        function collapse(): TLayers;
+      end;
+
+      TScale = class external name 'Scale' (TControl)
+      public
+        options: TScaleOptions;
+        constructor Create(options: TScaleOptions); external name '';
+      end;
+    public
+      // Extension methods
+      onAdd: TFunc<TMap, TJSHTMLElement>;
+      onRemove: TProc<TMap>;
+      options: TControlOptions;
+
+      constructor Create(options: TControlOptions); external name '';
+      function getPosition(): String;
+      function setPosition(position: String): TControl;
+      function getContainer(): TJSHTMLElement;
+      function addTo(map: TMap): TControl;
+      function remove(): TControl;
+      function zoom(options: TZoomControlOptions): TZoom;
+      function attribution(options: TAttributionOptions): TAttribution;
+      function layers(baseLayers, overlays: TLayersObject; options: TLayersOptions): TLayers;
+      function scale(options: TScaleOptions): TScale;
+    end;
+
+    TDivOverlay = class external name 'DivOverlay' abstract (TLayer)
+    public
+      options: TDivOverlayOptions;
+
+      constructor Create; external name ''; overload;
+      constructor Create(options: TDivOverlayOptions); external name ''; overload;
+      constructor Create(options: TDivOverlayOptions; source: TLayer); external name ''; overload;
+      function getLatLng(): TLatLng;
+      function setLatLng(latlng: TLatLng): TDivOverlay; overload;
+      function setLatLng(latlng: TLatLngLiteral): TDivOverlay; overload;
+      function setLatLng(latlng: TLatLngTuple): TDivOverlay; overload;
+      function getContent(): JSValue;
+      function setContent(htmlContent: TFunc<TLayer, String>): TDivOverlay; overload;
+      function setContent(htmlContent: TFunc<TLayer, TJSHTMLElement>): TDivOverlay; overload;
+      function setContent(htmlContent: String): TDivOverlay; overload;
+      function setContent(htmlContent: TJSHTMLElement): TDivOverlay; overload;
+      function getElement(): TJSHTMLElement;
+      procedure update();
+      function isOpen(): Boolean;
+      function bringToFront(): TDivOverlay;
+      function bringToBack(): TDivOverlay;
+    end;
+
+    TPopup = class external name 'Popup' (TDivOverlay)
+    public
+      options: TPopupOptions;
+
+      constructor Create; external name ''; overload;
+      constructor Create(options: TPopupOptions); external name ''; overload;
+      constructor Create(options: TPopupOptions; source: TLayer); external name ''; overload;
+      function openOn(map: TMap): TPopup;
+    end;
+
+    TTooltip = class external name 'Tooltip' (TDivOverlay)
+    public
+      options: TTooltipOptions;
+
+      constructor Create; external name ''; overload;
+      constructor Create(options: TTooltipOptions); external name ''; overload;
+      constructor Create(options: TTooltipOptions; source: TLayer); external name ''; overload;
+
+      procedure setOpacity(val: Double);
+    end;
+
+    THandler = class external name 'Handler' (TClass)
+    public
+      // Extension methods
+      addHooks: TProc;
+      removeHooks: TProc;
+
+      constructor Create(map: TMap); external name '';
+
+      function disable(): THandler;
+      function enable(): THandler;
+      function enabled(): Boolean;
+    end;
+
+    THandlerClass = class of THandler;
+
+    TDomEvent = class external name 'DomEvent'
+    public type
+      TEventHandlerFn = TProc<TLeafletEvent>;
+    public
+      function addListener(el: TJSHTMLElement; types: String; fn: TEventHandlerFn; context: JSValue): TDomEvent;
+      function disableClickPropagation(el: TJSHTMLElement): TDomEvent;
+      function disableScrollPropagation(el: TJSHTMLElement): TDomEvent;
+      function getMousePosition(ev: TLeafletMouseEvent; container: TJSHTMLElement): TPoint;
+      function getWheelDelta(ev: TLeafletEvent): Double;
+      function off(el: TJSHTMLElement; types: String; fn: TEventHandlerFn; context: JSValue): TDomEvent;
+      function &on(el: TJSHTMLElement; types: String; fn: TEventHandlerFn; context: JSValue): TDomEvent;
+      function preventDefault(ev: TLeafletEvent): TDomEvent;
+      function removeListener(el: TJSHTMLElement; types: String; fn: TEventHandlerFn; context: JSValue): TDomEvent;
+      function stop(ev: TLeafletEvent): TDomEvent;
+      function stopPropagation(ev: TLeafletEvent): TDomEvent;
+    end;
+
+    TMap = class external name 'Map' (TEvented)
+    public
+      // Properties
+      attributionControl: TLeaflet.TControl.TAttribution;
+      boxZoom: THandler;
+      doubleClickZoom: THandler;
+      dragging: THandler;
+      keyboard: THandler;
+      scrollWheelZoom: THandler;
+      tap: THandler;
+      touchZoom: THandler;
+      zoomControl: TControl.TZoom;
+
+      options: TMapOptions;
+
+      constructor Create(element: String); external name ''; overload;
+      constructor Create(element: String; options: TMapOptions); external name ''; overload;
+      constructor Create(element: TJSHTMLElement); external name ''; overload;
+      constructor Create(element: TJSHTMLElement; options: TMapOptions); external name ''; overload;
+
+      function getRenderer(layer: TPath): TRenderer;
+
+      // Methods for layers and controls
+      function addControl(control: TControl): TMap;
+      function addLayer(layer: TLayer): TMap;
+      function closePopup(popup: TPopup): TMap;
+      function closeTooltip(tooltip: TTooltip): TMap;
+      function eachLayer(fn: TProc<TLayer>; context: JSValue): TMap;
+      function hasLayer(layer: TLayer): Boolean;
+      function openPopup(content: String; latlng: TLatLng; options: TPopupOptions): TMap; overload;
+      function openPopup(content: String; latlng: TLatLngLiteral; options: TPopupOptions): TMap; overload;
+      function openPopup(content: String; latlng: TLatLngTuple; options: TPopupOptions): TMap; overload;
+      function openPopup(content: TJSHTMLElement; latlng: TLatLng; options: TPopupOptions): TMap; overload;
+      function openPopup(content: TJSHTMLElement; latlng: TLatLngLiteral; options: TPopupOptions): TMap; overload;
+      function openPopup(content: TJSHTMLElement; latlng: TLatLngTuple; options: TPopupOptions): TMap; overload;
+      function openPopup(popup: TPopup): TMap; overload;
+      function openTooltip(content: String; latlng: TLatLng; options: TTooltipOptions): TMap; overload;
+      function openTooltip(content: String; latlng: TLatLngLiteral; options: TTooltipOptions): TMap; overload;
+      function openTooltip(content: String; latlng: TLatLngTuple; options: TTooltipOptions): TMap; overload;
+      function openTooltip(content: TJSHTMLElement; latlng: TLatLng; options: TTooltipOptions): TMap; overload;
+      function openTooltip(content: TJSHTMLElement; latlng: TLatLngLiteral; options: TTooltipOptions): TMap; overload;
+      function openTooltip(content: TJSHTMLElement; latlng: TLatLngTuple; options: TTooltipOptions): TMap; overload;
+      function openTooltip(tooltip: TTooltip): TMap; overload;
+      function removeControl(control: TControl): TMap;
+      function removeLayer(layer: TLayer): TMap;
+
+      // Methods for modifying map state
+      function fitBounds(bounds: TLatLngBounds; options: TFitBoundsOptions): TMap; overload;
+      function fitBounds(bounds: TLatLngBoundsLiteral; options: TFitBoundsOptions): TMap; overload;
+      function fitWorld(options: TFitBoundsOptions): TMap;
+      function flyTo(latlng: TLatLng; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function flyTo(latlng: TLatLngLiteral; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function flyTo(latlng: TLatLngTuple; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function flyToBounds(bounds: TLatLngBounds): TMap; overload;
+      function flyToBounds(bounds: TLatLngBounds; options: TFitBoundsOptions): TMap; overload;
+      function flyToBounds(bounds: TLatLngBoundsLiteral): TMap; overload;
+      function flyToBounds(bounds: TLatLngBoundsLiteral; options: TFitBoundsOptions): TMap; overload;
+      function invalidateSize(options: Boolean): TMap; overload;
+      function invalidateSize(options: TInvalidateSizeOptions): TMap; overload;
+      function panBy(offset: TPoint; options: TPanOptions): TMap; overload;
+      function panBy(offset: TPointTuple; options: TPanOptions): TMap; overload;
+      function panInside(latLng: JSValue; options: TPanInsideOptions): TMap;
+      function panInsideBounds(bounds: TLatLngBounds; options: TPanOptions): TMap; overload;
+      function panInsideBounds(bounds: TLatLngBoundsLiteral; options: TPanOptions): TMap; overload;
+      function panTo(latlng: TLatLng; options: TPanOptions): TMap; overload;
+      function panTo(latlng: TLatLngLiteral; options: TPanOptions): TMap; overload;
+      function panTo(latlng: TLatLngTuple; options: TPanOptions): TMap; overload;
+      function setMaxBounds(bounds: TLatLngBounds): TMap; overload;
+      function setMaxBounds(bounds: TLatLngBoundsLiteral): TMap; overload;
+      function setMaxZoom(zoom: Double): TMap;
+      function setMinZoom(zoom: Double): TMap;
+      function setView(center: TLatLng; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function setView(center: TLatLngLiteral; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function setView(center: TLatLngTuple; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function setZoom(zoom: Double; options: TZoomPanOptions): TMap;
+      function setZoomAround(position: TLatLng; zoom: Double; options: TZoomOptions): TMap; overload;
+      function setZoomAround(position: TLatLngLiteral; zoom: Double; options: TZoomOptions): TMap; overload;
+      function setZoomAround(position: TLatLngTuple; zoom: Double; options: TZoomOptions): TMap; overload;
+      function setZoomAround(position: TPoint; zoom: Double; options: TZoomOptions): TMap; overload;
+      function stop(): TMap;
+      function zoomIn(delta: Double; options: TZoomOptions): TMap;
+      function zoomOut(delta: Double; options: TZoomOptions): TMap;
+
+      // Other methods
+      function addHandler(name: String; HandlerClass: THandlerClass): TMap; // Alternatively; HandlerClass: new(map: TMap) => THandler
+      function createPane(name: String; container: TJSHTMLElement): TJSHTMLElement;
+      function getContainer(): TJSHTMLElement;
+      function getPane(pane: String): TJSHTMLElement; overload;
+      function getPane(pane: TJSHTMLElement): TJSHTMLElement; overload;
+      function getPanes(): TDefaultMapPanes;
+      function remove(): TMap;
+      function whenReady(fn: TProc; context: JSValue): TMap;
+
+      // Methods for getting map state
+      function getBounds(): TLatLngBounds;
+      function getBoundsZoom(bounds: TLatLngBounds; inside: Boolean; padding: TPoint): Double; overload;
+      function getBoundsZoom(bounds: TLatLngBoundsLiteral; inside: Boolean; padding: TPoint): Double; overload;
+      function getCenter(): TLatLng;
+      function getMaxZoom(): Double;
+      function getMinZoom(): Double;
+      function getPixelBounds(): TBounds;
+      function getPixelOrigin(): TPoint;
+      function getPixelWorldBounds(zoom: Double): TBounds;
+      function getSize(): TPoint;
+      function getZoom(): Double;
+
+      // Conversion methods
+      function containerPointToLatLng(point: TPoint): TLatLng; overload;
+      function containerPointToLatLng(point: TPointTuple): TLatLng; overload;
+      function containerPointToLayerPoint(point: TPoint): TPoint; overload;
+      function containerPointToLayerPoint(point: TPointTuple): TPoint; overload;
+      function distance(latlng1, latlng2: TLatLng): Double; overload;
+      function distance(latlng1, latlng2: TLatLngLiteral): Double; overload;
+      function distance(latlng1, latlng2: TLatLngTuple): Double; overload;
+      function getScaleZoom(scale: Double; fromZoom: Double): Double;
+      function getZoomScale(toZoom: Double; fromZoom: Double): Double;
+      function latLngToContainerPoint(latlng: TLatLng): TPoint; overload;
+      function latLngToContainerPoint(latlng: TLatLngLiteral): TPoint; overload;
+      function latLngToContainerPoint(latlng: TLatLngTuple): TPoint; overload;
+      function latLngToLayerPoint(latlng: TLatLng): TPoint; overload;
+      function latLngToLayerPoint(latlng: TLatLngLiteral): TPoint; overload;
+      function latLngToLayerPoint(latlng: TLatLngTuple): TPoint; overload;
+      function layerPointToContainerPoint(point: TPoint): TPoint; overload;
+      function layerPointToContainerPoint(point: TPointTuple): TPoint; overload;
+      function layerPointToLatLng(point: TPoint): TLatLng; overload;
+      function layerPointToLatLng(point: TPointTuple): TLatLng; overload;
+      function mouseEventToContainerPoint(ev: TLeafletMouseEvent): TPoint;
+      function mouseEventToLatLng(ev: TLeafletMouseEvent): TLatLng;
+      function mouseEventToLayerPoint(ev: TLeafletMouseEvent): TPoint;
+      function project(latlng: TLatLng; zoom: Double): TPoint; overload;
+      function project(latlng: TLatLngLiteral; zoom: Double): TPoint; overload;
+      function project(latlng: TLatLngTuple; zoom: Double): TPoint; overload;
+      function unproject(point: TPoint; zoom: Double): TLatLng; overload;
+      function unproject(point: TPointTuple; zoom: Double): TLatLng; overload;
+      function wrapLatLng(latlng: TLatLng): TLatLng; overload;
+      function wrapLatLng(latlng: TLatLngLiteral): TLatLng; overload;
+      function wrapLatLng(latlng: TLatLngTuple): TLatLng; overload;
+      function wrapLatLngBounds(bounds: TLatLngBounds): TLatLngBounds;
+
+      // Geolocation methods
+      function locate(options: TLocateOptions): TMap;
+      function stopLocate(): TMap;
+    end;
+
+    TIcon = class external name 'Icon'
+    public type
+      TDefault = class external name 'Default' (TIcon)
+      public
+        constructor Create(options: TIconOptions); external name '';
+      end;
+    public
+      options: TBaseIconOptions;
+
+      constructor Create(options: TBaseIconOptions); external name '';
+      function createIcon(oldIcon: TJSHTMLElement): TJSHTMLElement;
+      function createShadow(oldIcon: TJSHTMLElement): TJSHTMLElement;
+    end;
+
+    TDivIcon = class external name 'DivIcon' (TIcon)
+    public
+      options: TDivIconOptions;
+
+      constructor Create(options: TDivIconOptions); external name '';
+    end;
+
+    TMarker = class external name 'Marker' (TLayer)
+    public
+      // Properties
+      options: TMarkerOptions;
+      dragging: THandler;
+      feature: TFeature;
+
+      constructor Create(latlng: TLatLng; options: TMarkerOptions); external name ''; overload;
+      constructor Create(latlng: TLatLngLiteral; options: TMarkerOptions); external name ''; overload;
+      constructor Create(latlng: TLatLngTuple; options: TMarkerOptions); external name ''; overload;
+
+      function toGeoJSON(precision: Double): TFeature;
+      function getLatLng(): TLatLng;
+      function setLatLng(latlng: TLatLng): TMarker; overload;
+      function setLatLng(latlng: TLatLngLiteral): TMarker; overload;
+      function setLatLng(latlng: TLatLngTuple): TMarker; overload;
+      function setZIndexOffset(offset: Double): TMarker;
+      function getIcon(): JSValue;
+      function setIcon(icon: JSValue): TMarker;
+      function setOpacity(opacity: Double): TMarker;
+      function getElement(): TJSHTMLElement;
+    end;
+
+    TBrowser = class external name 'Browser'
+    public const
+      ie: Boolean;
+      ielt9: Boolean;
+      edge: Boolean;
+      webkit: Boolean;
+      android: Boolean;
+      android23: Boolean;
+      androidStock: Boolean;
+      opera: Boolean;
+      chrome: Boolean;
+      gecko: Boolean;
+      safari: Boolean;
+      opera12: Boolean;
+      win: Boolean;
+      ie3d: Boolean;
+      webkit3d: Boolean;
+      gecko3d: Boolean;
+      any3d: Boolean;
+      mobile: Boolean;
+      mobileWebkit: Boolean;
+      mobileWebkit3d: Boolean;
+      msPointer: Boolean;
+      pointer: Boolean;
+      touch: Boolean;
+      mobileOpera: Boolean;
+      mobileGecko: Boolean;
+      retina: Boolean;
+      canvas: Boolean;
+      svg: Boolean;
+      vml: Boolean;
+    end;
+
+    TUtil = class external name 'Util'
+    public
+      function extend(dest: JSValue): JSValue; varargs;
+
+      function stamp(obj: JSValue): Double;
+      function throttle(fn: TProc; time: Double; context: JSValue): TProc;
+      function wrapNum(num: Double; range: TArray<Double>; includeMax: Boolean): Double;
+      function falseFn(): Boolean;
+      function formatNum(num: Double; digits: Double): Double;
+      function trim(str: String): String;
+      function splitWords(str: String): TArray<String>;
+      function setOptions(obj: JSValue; options: JSValue): JSValue;
+      function getParamString(obj: JSValue; existingUrl: String; uppercase: Boolean): String;
+      function template(str: String; data: JSValue): String;
+      function isArray(obj: JSValue): Boolean;
+      function indexOf(&array: TArray<JSValue>; el: JSValue): Double;
+      function requestAnimFrame(fn: TProc<Double>; context: JSValue; immediate: Boolean): Double;
+      procedure cancelAnimFrame(id: Double);
+    end;
+  public
+    lastId: Double;
+    emptyImageUrl: String;
+
+    function bounds(topLeft, bottomRight: TPoint): TBounds; overload;
+    function bounds(topLeft, bottomRight: TPointTuple): TBounds; overload;
+    function bounds(points: TArray<TPoint>): TBounds; overload;
+    function bounds(points: TBoundsLiteral): TBounds; overload;
+    function canvas(options: TRendererOptions): TCanvas;
+    function circle(latlng: TLatLng; options: TCircleMarkerOptions): TCircle; overload;
+    function circle(latlng: TLatLngLiteral; options: TCircleMarkerOptions): TCircle; overload;
+    function circle(latlng: TLatLngTuple; options: TCircleMarkerOptions): TCircle; overload;
+    function circleMarker(latlng: TLatLng; options: TCircleMarkerOptions): TCircleMarker; overload;
+    function circleMarker(latlng: TLatLngLiteral; options: TCircleMarkerOptions): TCircleMarker; overload;
+    function circleMarker(latlng: TLatLngTuple; options: TCircleMarkerOptions): TCircleMarker; overload;
+    function divIcon(options: TDivIconOptions): TDivIcon;
+    function featureGroup(layers: TArray<TLayer>): TFeatureGroup;
+    function geoJSON(geojson: TGeoJsonObject; options: TGeoJSONOptions): TGeoJSON;
+    function gridLayer(options: TGridLayerOptions): TGridLayer;
+    function icon(options: TIconOptions): TIcon;
+    function imageOverlay(imageUrl: String; bounds: TLatLngBounds; options: TImageOverlayOptions): TImageOverlay; overload;
+    function imageOverlay(imageUrl: String; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions): TImageOverlay; overload;
+    function latLng(coords: TArray<Double>): TLatLng; overload;
+    function latLng(latitude, longitude: Double): TLatLng; overload;
+    function latLng(latitude, longitude, altitude: Double): TLatLng; overload;
+    function latLngBounds(southWest, northEast: TLatLng): TLatLngBounds; overload;
+    function latLngBounds(southWest, northEast: TLatLngLiteral): TLatLngBounds; overload;
+    function latLngBounds(southWest, northEast: TLatLngTuple): TLatLngBounds; overload;
+    function latLngBounds(latlngs: TArray<TLatLng>): TLatLngBounds; overload;
+    function latLngBounds(latlngs: TArray<TLatLngLiteral>): TLatLngBounds; overload;
+    function latLngBounds(latlngs: TArray<TLatLngTuple>): TLatLngBounds; overload;
+    function layerGroup: TLayerGroup; overload;
+    function layerGroup(layers: TArray<TLayer>): TLayerGroup; overload;
+    function layerGroup(layers: TArray<TLayer>; options: TLayerOptions): TLayerGroup; overload;
+    function map(element: String; options: TMapOptions): TMap; overload;
+    function map(element: TJSHTMLElement; options: TMapOptions): TMap; overload;
+    function marker(latlng: TLatLng; options: TMarkerOptions): TMarker; overload;
+    function marker(latlng: TLatLngLiteral; options: TMarkerOptions): TMarker; overload;
+    function marker(latlng: TLatLngTuple; options: TMarkerOptions): TMarker; overload;
+    function point(x, y: Double): TPoint; overload;
+    function point(x, y: Double; round: Boolean): TPoint; overload;
+    function point(coords: TPointTuple): TPoint; overload;
+    function polyline(latlngs: TArray<TLatLng>; options: TPolylineOptions): TPolyline; overload;
+    function polyline(latlngs: TArray<TArray<TLatLng>>; options: TPolylineOptions): TPolyline; overload;
+    function polyline(latlngs: TArray<TLatLngLiteral>; options: TPolylineOptions): TPolyline; overload;
+    function polyline(latlngs: TArray<TArray<TLatLngLiteral>>; options: TPolylineOptions): TPolyline; overload;
+    function polyline(latlngs: TArray<TLatLngTuple>; options: TPolylineOptions): TPolyline; overload;
+    function polyline(latlngs: TArray<TArray<TLatLngTuple>>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TLatLng>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TArray<TLatLng>>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TLatLngLiteral>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TArray<TLatLngLiteral>>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TLatLngTuple>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TArray<TLatLngTuple>>; options: TPolylineOptions): TPolyline; overload;
+    function popup: TPopup; overload;
+    function popup(options: TPopupOptions): TPopup; overload;
+    function popup(options: TPopupOptions; source: TLayer): TPopup; overload;
+    function rectangle(latLngBounds: TLatLngBounds; options: TPolylineOptions): TRectangle; overload;
+    function rectangle(latLngBounds: TLatLngBoundsLiteral; options: TPolylineOptions): TRectangle; overload;
+    function svg(options: TRendererOptions): TSVG;
+    function svgOverlay(svgImage: String; bounds: TLatLngBounds; options: TImageOverlayOptions): TSVGOverlay; overload;
+    function svgOverlay(svgImage: String; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions): TSVGOverlay; overload;
+    function svgOverlay(svgImage: TJSHTMLElement; bounds: TLatLngBounds; options: TImageOverlayOptions): TSVGOverlay; overload;
+    function svgOverlay(svgImage: TJSHTMLElement; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions): TSVGOverlay; overload;
+    function tileLayer(urlTemplate: String; options: TTileLayerOptions): TTileLayer;
+    function tooltip: TTooltip; overload;
+    function tooltip(options: TTooltipOptions): TTooltip; overload;
+    function tooltip(options: TTooltipOptions; source: TLayer): TTooltip; overload;
+    function videoOverlay(video: String; bounds: TLatLngBounds; options: TVideoOverlayOptions): TVideoOverlay; overload;
+    function videoOverlay(video: String; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions): TVideoOverlay; overload;
+    function videoOverlay(video: TArray<String>; bounds: TLatLngBounds; options: TVideoOverlayOptions): TVideoOverlay; overload;
+    function videoOverlay(video: TArray<String>; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions): TVideoOverlay; overload;
+    function videoOverlay(video: TJSHTMLVideoElement; bounds: TLatLngBounds; options: TVideoOverlayOptions): TVideoOverlay; overload;
+    function videoOverlay(video: TJSHTMLVideoElement; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions): TVideoOverlay; overload;
+  end;
+
+  TLatLngLiteral = class
+  public
+    lat: Double;
+    lng: Double;
+  end;
+
+  TLayerOptions = class
+  public
+    pane: String;
+    attribution: String;
+  end;
+
+  TInteractiveLayerOptions = class(TLayerOptions)
+  public
+    interactive: Boolean;
+    bubblingMouseEvents: Boolean;
+  end;
+
+  TGridLayerOptions = class
+  public
+    tileSize: TPoint;
+    tileSizeNumber: Double; external name 'tileSize';
+    opacity: Double;
+    updateWhenIdle: Boolean;
+    updateWhenZooming: Boolean;
+    updateInterval: Double;
+    attribution: String;
+    zIndex: Double;
+    bounds: JSValue;
+    minZoom: Double;
+    maxZoom: Double;
+    noWrap: Boolean;
+    pane: String;
+    className: String;
+    keepBuffer: Double;
+  end;
+
+  TTileLayerOptions = class(TGridLayerOptions)
+  public
+    id: String;
+    accessToken: String;
+    minZoom: Double;
+    maxZoom: Double;
+    maxNativeZoom: Double;
+    minNativeZoom: Double;
+    subdomains: TArray<String>;
+    errorTileUrl: String;
+    zoomOffset: Double;
+    tms: Boolean;
+    zoomReverse: Boolean;
+    detectRetina: Boolean;
+    crossOrigin: String;
+  end;
+
+  TWMSOptions = class(TTileLayerOptions)
+  public
+    layers: String;
+    styles: String;
+    format: String;
+    transparent: Boolean;
+    version: String;
+    crs: TLeaflet.TCRS;
+    uppercase: Boolean;
+  end;
+
+  TWMSParams = class
+  public
+    format: String;
+    layers: String;
+    request: String;
+    service: String;
+    styles: String;
+    version: String;
+    transparent: Boolean;
+    width: Double;
+    height: Double;
+  end;
+
+  TImageOverlayOptions = class(TInteractiveLayerOptions)
+  public
+    opacity: Double;
+    alt: String;
+    interactive: Boolean;
+    attribution: String;
+    crossOrigin: String;
+    errorOverlayUrl: String;
+    zIndex: Double;
+    className: String;
+  end;
+
+  TVideoOverlayOptions = class(TImageOverlayOptions)
+  public
+    autoplay: Boolean;
+    loop: Boolean;
+    keepAspectRatio: Boolean;
+  end;
+
+  TPathOptions = class(TInteractiveLayerOptions)
+  public
+    stroke: Boolean;
+    color: String;
+    weight: Double;
+    opacity: Double;
+    lineCap: String;
+    lineJoin: String;
+    dashArray: TArray<Double>;
+    dashOffset: String;
+    fill: Boolean;
+    fillColor: String;
+    fillOpacity: Double;
+    fillRule: String;
+    renderer: TLeaflet.TRenderer;
+    className: String;
+  end;
+
+  TPolylineOptions = class(TPathOptions)
+  public
+    smoothFactor: Double;
+    noClip: Boolean;
+  end;
+
+  TCircleMarkerOptions = class(TPathOptions)
+  public
+    radius: Double;
+  end;
+
+  TRendererOptions = class (TLayerOptions)
+  public
+    padding: Double;
+    tolerance: Double;
+  end;
+
+  TGeoJSONOptions = class(TInteractiveLayerOptions)
+  public
+    coordsToLatLng: TFunc<TArray<Double>, TLeaflet.TLatLng>;
+    filter: TFunc<TFeature, Boolean>;
+    onEachFeature: TProc<TFeature, TLeaflet.TLayer>;
+    pointToLayer: TFunc<TFeature, TLeaflet.TLatLng, TLeaflet.TLayer>;
+    style: TPathOptions;
+    styleFunction: TLeaflet.TStyleFunction; external name 'style';
+  end;
+
+  TMapOptions = class
+  private
+    FCRS: TLeaflet.TCRS; external name 'crs';
+
+    function GetCRS: TLeaflet.TCRS;
+
+    procedure SetCRS(Value: TLeaflet.TCRS);
+  public
+    preferCanvas: Boolean;
+
+    // Control options
+    attributionControl: Boolean;
+    zoomControl: Boolean;
+
+    // Interaction options
+    closePopupOnClick: Boolean;
+    zoomSnap: Double;
+    zoomDelta: Double;
+    trackResize: Boolean;
+    boxZoom: Boolean;
+    doubleClickZoom: String;
+    dragging: Boolean;
+
+    // Map state options
+    center: JSValue;
+    zoom: Double;
+    minZoom: Double;
+    maxZoom: Double;
+    layers: TArray<TLeaflet.TLayer>;
+    maxBounds: JSValue;
+    renderer: TLeaflet.TRenderer;
+
+    // Animation options
+    fadeAnimation: Boolean;
+    markerZoomAnimation: Boolean;
+    transform3DLimit: Double;
+    zoomAnimation: Boolean;
+    zoomAnimationThreshold: Double;
+
+    // Panning inertia options
+    inertia: Boolean;
+    inertiaDeceleration: Double;
+    inertiaMaxSpeed: Double;
+    easeLinearity: Double;
+    worldCopyJump: Boolean;
+    maxBoundsViscosity: Double;
+
+    // Keyboard navigation options
+    keyboard: Boolean;
+    keyboardPanDelta: Double;
+
+    // Mousewheel options
+    scrollWheelZoom: TLeaflet.TControl.TZoom;
+    wheelDebounceTime: Double;
+    wheelPxPerZoomLevel: Double;
+
+    // Touch interaction options
+    tap: Boolean;
+    tapTolerance: Double;
+    touchZoom: TLeaflet.TControl.TZoom;
+    bounceAtZoomLimits: Boolean;
+
+    property crs: TLeaflet.TCRS read GetCRS write SetCRS;
+  end;
+
+  TControlOptions = class
+  public
+    position: String;
+  end;
+
+  TZoomControlOptions = class(TControlOptions)
+  public
+    zoomInText: String;
+    zoomInTitle: String;
+    zoomOutText: String;
+    zoomOutTitle: String;
+  end;
+
+  TAttributionOptions = class(TControlOptions)
+  public
+    prefix: String;
+  end;
+
+  TLayersOptions = class(TControlOptions)
+  public
+    collapsed: Boolean;
+    autoZIndex: Boolean;
+    hideSingleBase: Boolean;
+  end;
+
+  TLayersObject = class
+  private
+    function GetLayers(name: String): TLeaflet.TLayer; external name '[]';
+
+    procedure SetLayers(name: String; Value: TLeaflet.TLayer); external name '[]';
+  public
+    property Layers[name: String]: TLeaflet.TLayer read GetLayers write SetLayers;
+  end;
+
+  TScaleOptions = class(TControlOptions)
+  public
+    maxWidth: Double;
+    metric: Boolean;
+    imperial: Boolean;
+    updateWhenIdle: Boolean;
+  end;
+
+  TDivOverlayOptions = class
+  public
+    offset: TPoint;
+    zoomAnimation: Boolean;
+    className: String;
+    pane: String;
+  end;
+
+  TPopupOptions = class(TDivOverlayOptions)
+  public
+    maxWidth: Double;
+    minWidth: Double;
+    maxHeight: Double;
+    keepInView: Boolean;
+    closeButton: Boolean;
+    autoPan: Boolean;
+    autoPanPaddingTopLeft: TPoint;
+    autoPanPaddingBottomRight: TPoint;
+    autoPanPadding: TPoint;
+    autoClose: Boolean;
+    closeOnClick: Boolean;
+    closeOnEscapeKey: Boolean;
+  end;
+
+  TTooltipOptions = class(TDivOverlayOptions)
+  public
+    pane: String;
+    offset: TPoint;
+    direction: String;
+    permanent: Boolean;
+    sticky: Boolean;
+    interactive: Boolean;
+    opacity: Double;
+  end;
+
+  TZoomOptions = class
+  public
+    animate: Boolean;
+  end;
+
+  TPanOptions = class(TZoomOptions)
+  public
+    duration: Double;
+    easeLinearity: Double;
+    noMoveStart: Boolean;
+  end;
+
+  TZoomPanOptions = class(TZoomOptions)
+  end;
+
+  TInvalidateSizeOptions = class(TZoomPanOptions)
+  public
+    debounceMoveend: Boolean;
+    pan: Boolean;
+  end;
+
+  TFitBoundsOptions = class(TZoomPanOptions)
+  public
+    paddingTopLeft: TPoint;
+    paddingBottomRight: TPoint;
+    padding: TPoint;
+    maxZoom: Double;
+  end;
+
+  TPanInsideOptions = class
+  public
+    paddingTopLeft: TPoint;
+    paddingBottomRight: TPoint;
+    padding: TPoint;
+  end;
+
+  TLocateOptions = class
+  public
+    watch: Boolean;
+    setView: Boolean;
+    maxZoom: Double;
+    timeout: Double;
+    maximumAge: Double;
+    enableHighAccuracy: Boolean;
+  end;
+
+  TLeafletEvent = class
+  public
+    &type: String;
+    target: JSValue;
+    sourceTarget: JSValue;
+    propagatedFrom: JSValue;
+  end;
+
+  TLeafletMouseEvent = class(TLeafletEvent)
+  public
+    latlng: TLeaflet.TLatLng;
+    layerPoint: TPoint;
+    containerPoint: TPoint;
+    originalEvent: TLeafletMouseEvent;
+  end;
+
+  TLeafletKeyboardEvent = class(TLeafletEvent)
+  public
+    originalEvent: TLeafletKeyboardEvent;
+  end;
+
+  TLocationEvent = class(TLeafletEvent)
+  public
+    latlng: TLeaflet.TLatLng;
+    bounds: TLeaflet.TLatLngBounds;
+    accuracy: Double;
+    altitude: Double;
+    altitudeAccuracy: Double;
+    heading: Double;
+    speed: Double;
+    timestamp: Double;
+  end;
+
+  TErrorEvent = class(TLeafletEvent)
+  public
+    message: String;
+    code: Double;
+  end;
+
+  TLayerEvent = class(TLeafletEvent)
+  public
+    layer: TLeaflet.TLayer;
+  end;
+
+  TLayersControlEvent = class(TLayerEvent)
+  public
+    name: String;
+  end;
+
+  TTileEvent = class(TLeafletEvent)
+  public
+    tile: TJSHTMLImageElement;
+    coords: TLeaflet.TCoords;
+  end;
+
+  TTileErrorEvent = class(TTileEvent)
+  public
+    error: TError;
+  end;
+
+  TResizeEvent = class(TLeafletEvent)
+  public
+    oldSize: TPoint;
+    newSize: TPoint;
+  end;
+
+  TGeoJSONEvent = class(TLeafletEvent)
+  public
+    layer: TLeaflet.TLayer;
+    properties: JSValue;
+    geometryType: String;
+    id: String;
+  end;
+
+  TPopupEvent = class(TLeafletEvent)
+  public
+    popup: TLeaflet.TPopup;
+  end;
+
+  TTooltipEvent = class(TLeafletEvent)
+  public
+    tooltip: TLeaflet.TTooltip;
+  end;
+
+  TDragEndEvent = class(TLeafletEvent)
+  public
+    distance: Double;
+  end;
+
+  TZoomAnimEvent = class(TLeafletEvent)
+  public
+    center: TLeaflet.TLatLng;
+    zoom: Double;
+    noUpdate: Boolean;
+  end;
+
+  TDefaultMapPanes = class
+  public
+    mapPane: TJSHTMLElement;
+    tilePane: TJSHTMLElement;
+    overlayPane: TJSHTMLElement;
+    shadowPane: TJSHTMLElement;
+    markerPane: TJSHTMLElement;
+    tooltipPane: TJSHTMLElement;
+    popupPane: TJSHTMLElement;
+  end;
+
+  TBaseIconOptions = class(TLayerOptions)
+  public
+    iconUrl: String;
+    iconRetinaUrl: String;
+    iconSize: TPoint;
+    iconAnchor: TPoint;
+    popupAnchor: TPoint;
+    tooltipAnchor: TPoint;
+    shadowUrl: String;
+    shadowRetinaUrl: String;
+    shadowSize: TPoint;
+    shadowAnchor: TPoint;
+    className: String;
+  end;
+
+  TIconOptions = class(TBaseIconOptions)
+  public
+    iconUrl: String;
+  end;
+
+  TDivIconOptions = class (TBaseIconOptions)
+  public
+    html: JSValue;
+    bgPos: TPoint;
+    iconSize: TPoint;
+    iconAnchor: TPoint;
+    popupAnchor: TPoint;
+    className: String;
+  end;
+
+  TMarkerOptions = class(TInteractiveLayerOptions)
+  public
+    icon: JSValue;
+    draggable: Boolean;
+    keyboard: Boolean;
+    title: String;
+    alt: String;
+    zIndexOffset: Double;
+    opacity: Double;
+    riseOnHover: Boolean;
+    riseOffset: Double;
+    shadowPane: String;
+    autoPan: Boolean;
+    autoPanPadding: TPoint;
+    autoPanSpeed: Double;
+  end;
+
+  TError = class
+  end;
+
+  TMapboxLayerOptions = class(TTileLayerOptions)
+  public
+    AccessToken: String; external name 'accessToken';
+    Style: String; external name 'style';
+
+    constructor Create(Style, AccessToken: String);
+  end;
+
+var
+  Leaflet: TLeaflet; external name 'L';
+
+function InitializeMap: TJSPromise;
+
+implementation
+
+function InitializeMap: TJSPromise;
+begin
+  Result := TJSPromise.New(
+    procedure(Resolve, Reject: TJSPromiseResolver)
+    var
+      Script: TJSHTMLScriptElement;
+
+      Link: TJSHTMLLinkElement;
+
+    begin
+      Link := TJSHTMLLinkElement(document.createElement('link'));
+      Link.HRef := 'https://unpkg.com/leaflet/dist/leaflet.css';
+      Link.Rel := 'stylesheet';
+
+      document.head.appendChild(Link);
+
+      Script := TJSHTMLScriptElement(document.createElement('script'));
+      Script.async := False;
+      Script.OnLoad :=
+        function (Event: TEventListenerEvent): Boolean
+        begin
+          Resolve(True);
+
+          Result := True;
+        end;
+
+      Script.src := 'https://unpkg.com/leaflet/dist/leaflet.js';
+      Script.type_ := 'text/javascript';
+
+      document.head.appendChild(Script);
+    end);
+end;
+
+{ TMapOptions }
+
+function TMapOptions.GetCRS: TLeaflet.TCRS;
+begin
+  if not Assigned(FCRS) then
+    FCRS := TLeaflet.TCRS.EPSG3857;
+
+  Result := FCRS;
+end;
+
+procedure TMapOptions.SetCRS(Value: TLeaflet.TCRS);
+begin
+  FCRS := Value;
+end;
+
+{ TMapboxLayerOptions }
+
+constructor TMapboxLayerOptions.Create(Style, AccessToken: String);
+begin
+  inherited Create;
+
+  Attribution := 'Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>';
+  Self.AccessToken := AccessToken;
+  Self.Style := Style;
+  TileSizeNumber := 512;
+  ZoomOffset := -1;
+end;
+
+end.
+
-- 
2.31.1.windows.1

Michael Van Canneyt

2021-05-12 07:00

administrator   ~0130824

Your code does not compile.
It misses TProc, so I need to add the Types unit, at least a {$mode objfpc} or {$mode delphi}, and when I add those, It complains about

      TCircle = class external name 'Circle' (TMVCObject)
      public
        constructor Create(opts: TCircleOptions); external name '';

See the related bugreport on how to solve that.

henrique

2021-05-12 17:44

reporter   ~0130835

To compile like without must be implemented the 0038858 and 0038859. And another task, about SysUtils, with the declaration of TProc, and another types.

Michael Van Canneyt

2021-05-12 18:02

administrator   ~0130837

We should first finish the other tasks (if they must be finished, this is still debatable)

Without those other tasks done first, this bugreport makes no sense.

henrique

2021-05-13 11:02

reporter   ~0130851

I've adjusted the implementations, but the Leaflet unit doesn't compile for an error, which I've already opened the 0038883. I'm using the trunk version to compile.
0001-Implementa-o-da-base-dos-mapas-2.patch (182,857 bytes)   
From ea6b80ab829ec87c229fdebfe2bb8d0d0803b656 Mon Sep 17 00:00:00 2001
From: Henrique Gottardi Werlang <henriquewerlang@hotmail.com>
Date: Tue, 11 May 2021 16:17:36 -0300
Subject: [PATCH] =?UTF-8?q?Implementa=C3=A7=C3=A3o=20da=20base=20dos=20map?=
 =?UTF-8?q?as.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 packages/maps/Bing.Maps.pas    |  870 +++++++++++++
 packages/maps/GeoJSON.pas      |  166 +++
 packages/maps/Google.Maps.pas  | 2171 ++++++++++++++++++++++++++++++++
 packages/maps/Leaflet.Maps.pas | 1849 +++++++++++++++++++++++++++
 4 files changed, 5056 insertions(+)
 create mode 100644 packages/maps/Bing.Maps.pas
 create mode 100644 packages/maps/GeoJSON.pas
 create mode 100644 packages/maps/Google.Maps.pas
 create mode 100644 packages/maps/Leaflet.Maps.pas

diff --git a/packages/maps/Bing.Maps.pas b/packages/maps/Bing.Maps.pas
new file mode 100644
index 00000000..b2754856
--- /dev/null
+++ b/packages/maps/Bing.Maps.pas
@@ -0,0 +1,870 @@
+unit Bing.Maps;
+
+interface
+
+{$modeswitch externalclass}
+
+uses Web, JS, SysUtils;
+
+type
+  TAddress = class;
+  TAnimatedFrameEventArgs = class;
+  TAnimatedTileLayerOptions  = class;
+  TBorderedMapElementStyle = class;
+  TCustomMapStyle = class;
+  TCustomOverlayOptions = class;
+  TGroundOverlayOptions = class;
+  THandlerId = class;
+  TInfoboxEventArgs = class;
+  TInfoboxOptions  = class;
+  TMapElementStyle = class;
+  TMapElements = class;
+  TMapOptions = class;
+  TMapTypeChangeEventArgs = class;
+  TModuleOptions = class;
+  TMouseEventArgs = class;
+  TPanoramaInfo = class;
+  TPolygonOptions = class;
+  TPolylineOptions = class;
+  TPrimitiveChangedEventArgs = class;
+  TPrimitiveOptions = class;
+  TPushpinOptions = class;
+  TRange = class;
+  TSettingsStyle = class;
+  TStreetsideOptions  = class;
+  TStyleUrl = class;
+  TStylesOptions = class;
+  TTileLayerOptions = class;
+  TTileSourceOptions = class;
+  TViewOptions = class;
+
+  TMicrosoft = class external name 'Microsoft'
+  public type
+    TMaps = class external name 'Maps'
+    public type
+      TCustomOverlay = class;
+      TInfobox = class;
+      TLayer = class;
+      TLocation = class;
+      TLocationRect = class;
+      TMap = class;
+      TPoint = class;
+      TPolygon = class;
+      TPolyline = class;
+      TPushpin = class;
+      TTileSource = class;
+
+      TLabelOverlay = (loHidden, loVisible);
+      TMapTypeId = (mtAerial, mtBirdseye, mtCanvasDark, mtCanvasLight, mtGrayscale, mtMercator, mtOrdnanceSurvey, mtRoad, mtStreetside);
+      TNavigationBarMode = (nbCompact, nbDefault, nbMinified);
+      TNavigationBarOrientation = (nboHorizontal, nboVertical);
+      TOverviewMapMode = (omExpanded, omHidden, omMinimized);
+      TPixelReference = (prControl, prPage, prViewport);
+
+      TPrimitive = class external name 'Primitive' abstract
+      public
+        function getCursor: String;
+        function getVisible: Boolean;
+        procedure setOptions(options: TPrimitiveOptions);
+      end;
+
+      TAnimatedTileLayer = class external name 'AnimatedTileLayer'
+      public
+        constructor new(options: TAnimatedTileLayerOptions);
+
+        function getFrameRate: Double;
+        function getLoadingScreen: TCustomOverlay;
+        function getMaxTotalLoadTime: Double;
+        function getTileSources: TArray<TTileSource>;
+        function getVisible: Boolean;
+
+        procedure pause;
+        procedure play;
+        procedure setOptions(options: TAnimatedTileLayerOptions);
+        procedure stop;
+      end;
+
+      TColor = class external name 'Color'
+      public
+        a: Double;
+        r: Double;
+        g: Double;
+        b: Double;
+
+        constructor new(a: Double; r: Double; g: Double; b: Double);
+
+        class function clone(color: TColor): TColor; overload;
+        class function fromHex(hex: String): TColor;
+
+        function clone: TColor; overload;
+        function getOpacity: Double;
+        function toHex: String;
+        function toRgba: String;
+      end;
+
+      TLayer = class external name 'Layer'
+      public
+        metadata: JSValue;
+
+        constructor new(id: String);
+
+        function getId: String;
+        function getPrimitives: TArray<TPrimitive>;
+        function getVisible: Boolean;
+        function getZIndex: Double;
+        function remove(primitive: TPrimitive): TPrimitive;
+        function removeAt(index: Double): TPrimitive;
+
+        procedure add(primitive: TArray<TPrimitive>; index: Double);
+        procedure clear;
+        procedure dispose;
+        procedure setPrimitives(primitives: TArray<TPrimitive>);
+        procedure setVisible(value: Boolean);
+        procedure setZIndex(zIndex: Double);
+      end;
+
+      TCustomOverlay = class external name 'CustomOverlay' (TLayer)
+      public
+        _map: TMap;
+
+        constructor new(options: TCustomOverlayOptions);
+
+        function getHtmlElement: TJSHTMLElement;
+        function getMap: TMap;
+
+        procedure onAdd;
+        procedure onLoad;
+        procedure onRemove;
+        procedure setHtmlElement(htmlElement: TJSHTMLElement);
+      end;
+
+      TEvents = class external name 'Events'
+      public
+        function addHandler(target: JSValue; eventName: String; handler: TProc<JSValue>): THandlerId; overload;
+        function addHandler(target: TInfobox; eventName: String; handler: TProc<TInfoboxEventArgs>): THandlerId; overload;
+        function addHandler(target: TLayer; eventName: String; handler: TProc<TMouseEventArgs>): THandlerId; overload;
+        function addHandler(target: TMap; eventName: String; handler: TProc<TMapTypeChangeEventArgs>): THandlerId; overload;
+        function addHandler(target: TMap; eventName: String; handler: TProc<TMouseEventArgs>): THandlerId; overload;
+        function addHandler(target: TPolygon; eventName: String; handler: TProc<TMouseEventArgs>): THandlerId; overload;
+        function addHandler(target: TPolygon; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>): THandlerId; overload;
+        function addHandler(target: TPolyline; eventName: String; handler: TProc<TMouseEventArgs>): THandlerId; overload;
+        function addHandler(target: TPolyline; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>): THandlerId; overload;
+        function addHandler(target: TPushpin; eventName: String; handler: TProc<TMouseEventArgs>): THandlerId; overload;
+        function addHandler(target: TPushpin; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>): THandlerId; overload;
+        function addThrottledHandler(target: JSValue; eventName: String; handler: TProc<JSValue>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TInfobox; eventName: String; handler: TProc<TInfoboxEventArgs>): THandlerId; overload;
+        function addThrottledHandler(target: TLayer; eventName: String; handler: TProc<TMouseEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TMap; eventName: String; handler: TProc<TMapTypeChangeEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TMap; eventName: String; handler: TProc<TMouseEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPolygon; eventName: String; handler: TProc<TMouseEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPolygon; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPolyline; eventName: String; handler: TProc<TMouseEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPolyline; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPushpin; eventName: String; handler: TProc<TMouseEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPushpin; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function hasHandler(target: JSValue; eventName: String): Boolean;
+
+        procedure addOne(target: JSValue; eventName: String; handler: TProc<JSValue>); overload;
+        procedure addOne(target: TInfobox; eventName: String; handler: TProc<TInfoboxEventArgs>); overload;
+        procedure addOne(target: TLayer; eventName: String; handler: TProc<TMouseEventArgs>); overload;
+        procedure addOne(target: TMap; eventName: String; handler: TProc<TMapTypeChangeEventArgs>); overload;
+        procedure addOne(target: TMap; eventName: String; handler: TProc<TMouseEventArgs>); overload;
+        procedure addOne(target: TPolygon; eventName: String; handler: TProc<TMouseEventArgs>); overload;
+        procedure addOne(target: TPolygon; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>); overload;
+        procedure addOne(target: TPolyline; eventName: String; handler: TProc<TMouseEventArgs>); overload;
+        procedure addOne(target: TPolyline; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>); overload;
+        procedure addOne(target: TPushpin; eventName: String; handler: TProc<TMouseEventArgs>); overload;
+        procedure addOne(target: TPushpin; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>); overload;
+        procedure invoke(target: JSValue; evenName: String; args: JSValue);
+        procedure removeHandler(handlerId: THandlerId);
+      end;
+
+      TGroundOverlay = class external name 'GroundOverlay' (TCustomOverlay)
+      public
+        metadata: JSValue; external name 'metadata';
+
+        constructor new(options: TGroundOverlayOptions);
+
+        function getBackgroundColor: TColor;
+        function getBounds: TLocationRect;
+        function getImageUrl: String;
+        function getMap: TMap;
+        function getOpacity: Double;
+        function getRotation: Double;
+        function getVisible: Boolean;
+
+        procedure setOptions(options: TGroundOverlayOptions);
+        procedure setVisible(visible: Boolean);
+      end;
+
+      THeading = class external name 'Heading'
+      public
+        class var East: Double;
+        class var North: Double;
+        class var South: Double;
+        class var West: Double;
+      end;
+
+      TInfobox = class external name 'Infobox'
+      public
+        constructor new(location: TLocation; options: TInfoboxOptions);
+
+        function getAnchor: TPoint;
+        function getDescription: String;
+        function getHeight: Double;
+        function getHtmlContent: String;
+        function getLocation: TLocation;
+        function getMaxHeight: Double;
+        function getMaxWidth: Double;
+        function getOffset: TPoint;
+        function getOptions: TInfoboxOptions;
+        function getShowCloseButton: Boolean;
+        function getShowPointer: Boolean;
+        function getTitle: String;
+        function getVisible: Boolean;
+        function getWidth: Double;
+        function getZIndex: Double;
+
+        procedure setHtmlContent(content: String);
+        procedure setLocation(loc: TLocation);
+        procedure setMap(Map: TMap);
+        procedure setOptions(options: TInfoboxOptions; ignoreDelay: Boolean);
+      end;
+
+      TLayerCollection = class external name 'LayerCollection'
+      public
+        length: Double;
+
+        function indexOf(layer: TLayer): Double;
+
+        procedure clear;
+        procedure insert(layer: TLayer);
+        procedure insertAll(layers: TArray<TLayer>);
+        procedure remove(layer: TLayer);
+        procedure removeAt(idx: Double);
+      end;
+
+      TLocation = class external name 'Location'
+      public
+        latitude: Double;
+        longitude: Double;
+
+        constructor new(latitude, longitude: Double);
+
+        class function areEqual(location1: TLocation; location2: TLocation): Boolean;
+        class function cloneFrom(source: TLocation): TLocation;
+        class function normalizeLongitude(longitude: Double): Double;
+        class function parseLatLong(str: String): TLocation;
+
+        function clone: TLocation;
+        function toString: String;
+      end;
+
+      TLocationRect = class external name 'LocationRect'
+      public
+        center: TLocation;
+        height: Double;
+        width: Double;
+
+        constructor new(center: TLocation; width: Double; height: Double);
+
+        class function fromCorners(northwest: TLocation; southeast: TLocation): TLocationRect;
+        class function fromEdges(north: Double; west: Double; south: Double; east: Double): TLocationRect;
+        class function fromLocations(locations: TArray<TLocation>): TLocationRect;
+        class function fromShapes(shapes: TArray<TArray<TPrimitive>>): TLocationRect; overload;
+        class function fromShapes(shapes: TArray<TPrimitive>): TLocationRect; overload;
+        class function fromString(str: String): TLocationRect;
+        class function merge(rect1: TLocationRect; rect2: TLocationRect): TLocationRect;
+
+        function clone: TLocationRect;
+        function contains(location: TLocation): Boolean;
+        function crossesInternationalDateLine: Boolean;
+        function getEast: Double;
+        function getNorth: Double;
+        function getNorthwest: TLocation;
+        function getSouth: Double;
+        function getSoutheast: TLocation;
+        function getWest: Double;
+        function intersects(rect: TLocationRect): Boolean;
+        function splitByInternationalDateLine: TArray<TLocationRect>;
+        function toString: String;
+
+        procedure buffer(percentage: Double);
+      end;
+
+      TMap = class external name 'Map'
+      public
+        layers: TLayerCollection;
+
+        constructor new(parentElement: String); overload;
+        constructor new(parentElement: String; options: TMapOptions); overload;
+        constructor new(parentElement: String; options: TViewOptions); overload;
+        constructor new(parentElement: TJSHTMLElement); overload;
+        constructor new(parentElement: TJSHTMLElement; options: TMapOptions); overload;
+        constructor new(parentElement: TJSHTMLElement; options: TViewOptions); overload;
+
+        class function getVersion: String;
+
+        function getBounds: TLocationRect;
+        function getCenter: TLocation;
+        function getCulture: String;
+        function getHeading: Double;
+        function getHeight: Double;
+        function getImageryId: String;
+        function getMapTypeId: TMapTypeId;
+        function getMetersPerPixel: Double;
+        function getOptions: TMapOptions;
+        function getPageX: Double;
+        function getPageY: Double;
+        function getPitch: Double;
+        function getRootElement: TJSHTMLElement;
+        function getUserRegion: String;
+        function getWidth: Double;
+        function getZoom: Double;
+        function getZoomRange: TRange;
+        function isMercator: Boolean;
+        function isRotationEnabled: Boolean;
+        function tryLocationToPixel(location: TArray<TLocation>; reference: JSValue): TArray<TPoint>;
+        function tryPixelToLocation(point: TArray<TPoint>; reference: JSValue): TArray<TLocation>;
+
+        class procedure getClosestPanorama(bounds: TLocationRect; success: TProc<TPanoramaInfo>; missingCoverage: TProc);
+
+        procedure dispose;
+        procedure getCopyrights(callback: TProc<TArray<String>>);
+        procedure getCredentials(callback: TProc<String>);
+        procedure setMapType(mapTypeId: TMapTypeId);
+        procedure setOptions(options: TMapOptions);
+        procedure setView(viewOptions: TViewOptions);
+      end;
+
+      TPoint = class external name 'Point'
+      public
+        x: Double;
+        y: Double;
+
+        constructor new(x: Double; y: Double);
+
+        function add(point: TPoint): TPoint;
+        function clone: TPoint;
+        function equals(point: TPoint; tolerance: Double): Boolean;
+        function subtract(point: TPoint): TPoint;
+        function toString: String;
+      end;
+
+      TPointCompression = class external name 'ointCompression'
+      public
+        class function decode(value: String): TArray<TLocation>;
+        class function encode(locations: TArray<TLocation>): String;
+      end;
+
+      TPolygon = class external name 'Polygon' (TPrimitive)
+      public
+        metadata: JSValue;
+
+        constructor new(rings: TArray<TArray<TLocation>>; options: TPolygonOptions); overload;
+        constructor new(rings: TArray<TLocation>; options: TPolygonOptions); overload;
+
+        function getCursor: String;
+        function getFillColor: TColor;
+        function getGeneralizable: Boolean;
+        function getLocations: TArray<TLocation>;
+        function getRings: TArray<TArray<TLocation>>;
+        function getStrokeColor: TColor;
+        function getStrokeDashArray: TArray<Double>;
+        function getStrokeDashArrayString: String; external name 'getStrokeDashArray';
+        function getStrokeThickness: Double;
+        function getVisible: Boolean;
+
+        procedure setLocations(locations: TArray<TLocation>);
+        procedure setOptions(options: TPolygonOptions);
+        procedure setRings(rings: TArray<TArray<TLocation>>); overload;
+        procedure setRings(rings: TArray<TLocation>); overload;
+      end;
+
+      TPolyline = class external name 'Polyline' (TPrimitive)
+      public
+        metadata: JSValue;
+
+        constructor new(locations: TArray<TLocation>; options: TPolylineOptions);
+
+        function getCursor: String;
+        function getGeneralizable: Boolean;
+        function getLocations: TArray<TLocation>;
+        function getStrokeColor: TColor;
+        function getStrokeDashArray: TArray<Double>;
+        function getStrokeDashArrayString: String; external name 'getStrokeDashArray';
+        function getStrokeThickness: Double;
+        function getVisible: Boolean;
+
+        procedure setLocations(locations: TArray<TLocation>);
+        procedure setOptions(options: TPolylineOptions);
+      end;
+
+      TPushpin = class external name 'Pushpin' (TPrimitive)
+      public
+        metadata: JSValue;
+
+        constructor new(location: TLocation; options: TPushpinOptions);
+
+        function getAnchor: TPoint;
+        function getClickedStyleEnabled: Boolean;
+        function getColor: TColor;
+        function getCursor: String;
+        function getDraggable: Boolean;
+        function getHoverStyleEnabled: Boolean;
+        function getIcon: String;
+        function getLocation: TLocation;
+        function getRoundClickableArea: Boolean;
+        function getSubTitle: String;
+        function getText: String;
+        function getTextOffset: TPoint;
+        function getTitle: String;
+        function getVisible: Boolean;
+
+        procedure setLocation(location: TLocation);
+        procedure setOptions(options: TPushpinOptions);
+      end;
+
+      TPyramidTileId = class external name 'PyramidTileId'
+      public
+        pixelHeight: Double;
+        pixelWidth: Double;
+        quadKey: String;
+        x: Double;
+        y: Double;
+        zoom: Double;
+
+        constructor new(x: Double; y: Double; zoom: Double; width: Double; height: Double);
+
+        class function areEqual(tileId1: TPyramidTileId; tileId2: TPyramidTileId): Boolean;
+        class function fromQuadKey(quadkey: String; width: Double; height: Double): TPyramidTileId;
+      end;
+
+      TTileLayer = class external name 'TileLayer' (TLayer)
+      public
+        metadata: JSValue;
+
+        constructor new(options: TTileLayerOptions);
+
+        function getOpacity: Double;
+        function getTileSource: TTileSource;
+        function getVisible: Boolean;
+        function getZIndex: Double;
+
+        procedure setOpacity(opacity: Double);
+        procedure setOptions(options: TTileLayerOptions);
+        procedure setVisible(show: Boolean);
+        procedure setZIndex(idx: Double);
+      end;
+
+      TTileSource = class external name 'TileSource'
+      public
+        constructor new(options: TTileSourceOptions);
+
+        function getBounds: TLocationRect;
+        function getHeight: Double;
+        function getMaxZoom: Double;
+        function getMinZoom: Double;
+        function getUriConstructor(tile: TPyramidTileId): String; overload;
+        function getUriConstructor: String; overload;
+        function getWidth: Double;
+      end;
+    public
+      class var Credentials: String;
+
+      procedure getIsBirdseyeAvailable(loc: TLocation; heading: Double; callback: TProc<Boolean>); overload;
+      procedure getIsBirdseyeAvailable(loc: TLocation; heading: THeading; callback: TProc<Boolean>); overload;
+      procedure loadModule(moduleName: TArray<String>; options: TModuleOptions); overload;
+      procedure loadModule(moduleName: TArray<String>; options: TProc); overload;
+      procedure moduleLoaded(moduleName: String);
+      procedure registerModule(moduleName: String; url: String; styles: TStyleUrl);
+    end;
+  end;
+
+  TAddress = class
+  public
+    addressLine: String;
+    adminDistrict: String;
+    countryRegion: String;
+    countryRegionISO2: String;
+    district: String;
+    formattedAddress: String;
+    locality: String;
+    postalCode: String;
+  end;
+
+  TAnimatedFrameEventArgs = class
+  public
+    animatedTileLayer: TMicrosoft.TMaps.TAnimatedTileLayer;
+    index: Double;
+  end;
+
+  TAnimatedTileLayerOptions = class
+  public
+    autoPlay: Boolean;
+    frameRate: Double;
+    loadingScreen: TMicrosoft.TMaps.TCustomOverlay;
+    maxTotalLoadTime: Double;
+    mercator: TArray<TMicrosoft.TMaps.TTileSource>;
+    visible: Boolean;
+  end;
+
+  TCustomOverlayOptions = class
+  public
+    beneathLabels: Boolean;
+  end;
+
+  TGroundOverlayOptions = class(TCustomOverlayOptions)
+  public
+    backgroundColor: TMicrosoft.TMaps.TColor;
+    bounds: TMicrosoft.TMaps.TLocationRect;
+    imageUrl: String;
+    opacity: Double;
+    rotation: Double;
+    visible: Boolean;
+  end;
+
+  THandlerId = class
+  end;
+
+  TInfoboxOptions  = class
+  public
+    description: String;
+    closeDelayTime: Double;
+    htmlContent: String;
+    location: TMicrosoft.TMaps.TLocation;
+    maxHeight: Double;
+    maxWidth: Double;
+    offset: TMicrosoft.TMaps.TPoint;
+    showCloseButton: Boolean;
+    showPointer: Boolean;
+    title: String;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TInfoboxEventArgs = class
+  public
+    eventName: String;
+    pageX: Double;
+    pageY: Double;
+    target: TMicrosoft.TMaps.TInfobox;
+    targetType: String;
+    originalEvent: TJSMouseEvent;
+  end;
+
+  TMapOptions = class
+  public
+    allowHidingLabelsOfRoad: Boolean;
+    allowInfoboxOverflow: Boolean;
+    backgroundColor: TMicrosoft.TMaps.TColor;
+    customMapStyle: TCustomMapStyle;
+    disableBirdseye: Boolean;
+    disableKeyboardInput: Boolean;
+    disableMapTypeSelectorMouseOver: Boolean;
+    disablePanning: Boolean;
+    disableScrollWheelZoom: Boolean;
+    disableStreetside: Boolean;
+    disableStreetsideAutoCoverage: Boolean;
+    disableZooming: Boolean;
+    enableClickableLogo: Boolean;
+    enableCORS: Boolean;
+    enableHighDpi: Boolean;
+    enableInertia: Boolean;
+    liteMode: Boolean;
+    maxBounds: TMicrosoft.TMaps.TLocationRect;
+    maxZoom: Double;
+    minZoom: Double;
+    navigationBarMode: TMicrosoft.TMaps.TNavigationBarMode;
+    navigationBarOrientation: TMicrosoft.TMaps.TNavigationBarOrientation;
+    showBreadcrumb: Boolean;
+    showDashboard: Boolean;
+    showLocateMeButton: Boolean;
+    showLogo: Boolean;
+    showMapTypeSelector: Boolean;
+    showScalebar: Boolean;
+    showTrafficButton: Boolean;
+    showTermsLink: Boolean;
+    showZoomButtons: Boolean;
+    streetsideOptions: TStreetsideOptions;
+    supportedMapTypes: TArray<TMicrosoft.TMaps.TMapTypeId>;
+  end;
+
+  TMapTypeChangeEventArgs = class
+  public
+    newMapTypeId: TMicrosoft.TMaps.TMapTypeId;
+    oldMapTypeId: TMicrosoft.TMaps.TMapTypeId;
+    target: TMicrosoft.TMaps.TMap;
+    targetType: String;
+  end;
+
+  TModuleOptions = class
+  public
+    errorCallback: TProc;
+    credentials: String;
+  end;
+
+  TMouseEventArgs = class
+  public
+    eventName: String;
+    isPrimary: Boolean;
+    isSecondary: Boolean;
+    layer: TMicrosoft.TMaps.TLayer;
+    location: TMicrosoft.TMaps.TLocation;
+    pageX: Double;
+    pageY: Double;
+    point: TMicrosoft.TMaps.TPoint;
+    target: TMicrosoft.TMaps.TMap;
+    targetPrimitive: TMicrosoft.TMaps.TPrimitive; external name 'target';
+    targetType: String;
+    wheelDelta: Double;
+  end;
+
+  TPanoramaInfo = class
+  public
+    cd: String;
+  end;
+
+  TPrimitiveChangedEventArgs = class
+  public
+    sender: TMicrosoft.TMaps.TPrimitive;
+    name: String;
+  end;
+
+  TPrimitiveOptions = class
+  public
+    cursor: String;
+    visible: Boolean;
+  end;
+
+  TPolylineOptions = class(TPrimitiveOptions)
+  public
+    generalizable: Boolean;
+    strokeColor: TMicrosoft.TMaps.TColor;
+    strokeDashArray: TArray<Double>;
+    strokeDashArrayString: String; external name 'strokeDashArray';
+    strokeThickness: Double;
+  end;
+
+  TPolygonOptions = class(TPolylineOptions)
+  public
+    fillColor: TMicrosoft.TMaps.TColor;
+  end;
+
+  TPushpinOptions = class(TPrimitiveOptions)
+  public
+    anchor: TMicrosoft.TMaps.TPoint;
+    color: TMicrosoft.TMaps.TColor;
+    draggable: Boolean;
+    enableClickedStyle: Boolean;
+    enableHoverStyle: Boolean;
+    icon: String;
+    roundClickableArea: Boolean;
+    subTitle: String;
+    title: String;
+    text: String;
+    textOffset: TMicrosoft.TMaps.TPoint;
+  end;
+
+  TRange = class
+  public
+    min: Double;
+    max: Double;
+  end;
+
+  TStreetsideOptions  = class
+  public
+    disablePanoramaNavigation: Boolean;
+    locationToLookAt: TMicrosoft.TMaps.TLocation;
+    onErrorLoading: TProc;
+    onSuccessLoading: TProc;
+    overviewMapMode: TMicrosoft.TMaps.TOverviewMapMode;
+    panoramaInfo: TPanoramaInfo;
+    panoramaLookupRadius: Double;
+    showCurrentAddress: Boolean;
+    showExitButton: Boolean;
+    showHeadingCompass: Boolean;
+    showProblemReporting: Boolean;
+    showZoomButtons: Boolean;
+  end;
+
+  TStylesOptions = class
+  public
+    pushpinOptions: TPushpinOptions;
+    polylineOptions: TPolylineOptions;
+    polygonOptions: TPolygonOptions;
+  end;
+
+  TStyleUrl = class
+  public
+    styleURLs: TArray<String>;
+  end;
+
+  TTileLayerOptions = class
+  public
+    enableCORS: Boolean;
+    downloadTimeout: Double;
+    mercator: TMicrosoft.TMaps.TTileSource;
+    opacity: Double;
+    useCredentialsForCORS: Boolean;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TTileSourceOptions = class
+  public
+    bounds: TMicrosoft.TMaps.TLocationRect;
+    maxZoom: Double;
+    minZoom: Double;
+    uriConstructor: String;
+    uriConstructorFunction: TFunc<TMicrosoft.TMaps.TPyramidTileId, String>; external name 'uriConstructor';
+  end;
+
+  TViewOptions = class
+  public
+    bounds: TMicrosoft.TMaps.TLocationRect;
+    center: TMicrosoft.TMaps.TLocation;
+    centerOffset: TMicrosoft.TMaps.TPoint;
+    heading: Double;
+    labelOverlay: TMicrosoft.TMaps.TLabelOverlay;
+    mapTypeId: TMicrosoft.TMaps.TMapTypeId;
+    padding: Double;
+    pitch: Double;
+    zoom: Double;
+  end;
+
+  TMapElementStyle = class
+  public
+    fillColor: String;
+    labelColor: String;
+    labelOutlineColor: String;
+    labelVisible: boolean;
+    strokeColor: String;
+    visible: Boolean;
+  end;
+
+  TBorderedMapElementStyle = class(TMapElementStyle)
+  public
+    borderOutlineColor: String;
+    borderStrokeColor: String;
+    borderVisible: Boolean;
+  end;
+
+  TSettingsStyle = class
+  public
+    landColor: String;
+    shadedReliefVisible: Boolean;
+  end;
+
+  TMapElements = class
+  public
+    adminDistrict: TBorderedMapElementStyle;
+    adminDistrictCapital: TMapElementStyle;
+    airport: TMapElementStyle;
+    area: TMapElementStyle;
+    arterialRoad: TMapElementStyle;
+    building: TMapElementStyle;
+    business: TMapElementStyle;
+    capital: TMapElementStyle;
+    cemetery: TMapElementStyle;
+    continent: TMapElementStyle;
+    controlledAccessHighway: TMapElementStyle;
+    countryRegion: TBorderedMapElementStyle;
+    countryRegionCapital: TMapElementStyle;
+    district: TBorderedMapElementStyle;
+    education: TMapElementStyle;
+    educationBuilding: TMapElementStyle;
+    foodPoint: TMapElementStyle;
+    forest: TMapElementStyle;
+    golfCourse: TMapElementStyle;
+    highSpeedRamp: TMapElementStyle;
+    highway: TMapElementStyle;
+    indigenousPeoplesReserve: TMapElementStyle;
+    island: TMapElementStyle;
+    majorRoad: TMapElementStyle;
+    mapElement: TMapElementStyle;
+    medical: TMapElementStyle;
+    medicalBuilding: TMapElementStyle;
+    military: TMapElementStyle;
+    naturalPoint: TMapElementStyle;
+    nautical: TMapElementStyle;
+    neighborhood: TMapElementStyle;
+    park: TMapElementStyle;
+    peak: TMapElementStyle;
+    playingField: TMapElementStyle;
+    point: TMapElementStyle;
+    pointOfInterest: TMapElementStyle;
+    political: TBorderedMapElementStyle;
+    populatedPlace: TMapElementStyle;
+    railway: TMapElementStyle;
+    ramp: TMapElementStyle;
+    reserve: TMapElementStyle;
+    river: TMapElementStyle;
+    road: TMapElementStyle;
+    roadExit: TMapElementStyle;
+    runway: TMapElementStyle;
+    sand: TMapElementStyle;
+    shoppingCenter: TMapElementStyle;
+    stadium: TMapElementStyle;
+    street: TMapElementStyle;
+    structure: TMapElementStyle;
+    tollRoad: TMapElementStyle;
+    trail: TMapElementStyle;
+    transit: TMapElementStyle;
+    transitBuilding: TMapElementStyle;
+    transportation: TMapElementStyle;
+    unpavedStreet: TMapElementStyle;
+    vegetation: TMapElementStyle;
+    volcanicPeak: TMapElementStyle;
+    water: TMapElementStyle;
+    waterPoint: TMapElementStyle;
+    waterRoute: TMapElementStyle;
+  end;
+
+  TCustomMapStyle = class
+  public
+    elements: TMapElements;
+    settings: TSettingsStyle;
+    version: String;
+  end;
+
+function InitializeMap(Key: String): TJSPromise;
+
+implementation
+
+var
+  GResolvePromise: TJSPromiseResolver;
+
+procedure MapLoaded;
+begin
+  if Assigned(GResolvePromise) then
+    GResolvePromise(True);
+end;
+
+function InitializeMap(Key: String): TJSPromise;
+begin
+  GResolvePromise := nil;
+
+  MapLoaded;
+
+  Result := TJSPromise.New(
+    procedure(Resolve, Reject: TJSPromiseResolver)
+    var
+      Script: TJSHTMLScriptElement;
+
+    begin
+      GResolvePromise := Resolve;
+      Script := TJSHTMLScriptElement(document.createElement('script'));
+      Script.text := 'function BingMapLoaded(){pas["Bing.Maps"].$impl.MapLoaded();}';
+
+      document.head.appendChild(Script);
+
+      Script := TJSHTMLScriptElement(document.createElement('script'));
+      Script.src := Format('https://www.bing.com/maps/sdk/mapcontrol?key=%s&callback=BingMapLoaded', [Key]);
+
+      document.head.appendChild(Script);
+    end);
+end;
+
+end.
+
diff --git a/packages/maps/GeoJSON.pas b/packages/maps/GeoJSON.pas
new file mode 100644
index 00000000..ca5ad2cc
--- /dev/null
+++ b/packages/maps/GeoJSON.pas
@@ -0,0 +1,166 @@
+unit GeoJSON;
+
+interface
+
+{$modeswitch externalclass}
+
+uses JS;
+
+type
+  TBBox = TArray<Double>;
+  TPosition = TArray<Double>;
+
+  TGeoJsonObject = class
+  private
+    function GetForeignMember(name: String): JSValue; external name '[]';
+
+    procedure SetForeignMember(name: String; value: JSValue); external name '[]';
+  public
+    &type: String;
+    bbox: TBBox;
+
+    constructor Create(&type: String);
+
+    property ForeignMember[name: String]: JSValue read GetForeignMember write SetForeignMember; default;
+  end;
+
+  TGeometryObject = class(TGeoJsonObject)
+
+  end;
+
+  TPoint = class (TGeometryObject)
+  public
+    coordinates: TPosition;
+
+    constructor Create;
+  end;
+
+  TMultiPoint = class (TGeometryObject)
+  public
+    coordinates: TArray<TPosition>;
+    constructor Create;
+  end;
+
+  TLineString = class (TGeometryObject)
+  public
+    coordinates: TArray<TPosition>;
+
+    constructor Create;
+  end;
+
+  TMultiLineString = class (TGeometryObject)
+  public
+    coordinates: TArray<TArray<TPosition>>;
+
+    constructor Create;
+  end;
+
+  TPolygon = class(TGeometryObject)
+  public
+    coordinates: TArray<TArray<TPosition>>;
+
+    constructor Create;
+  end;
+
+  TMultiPolygon = class(TGeometryObject)
+  public
+    coordinates: TArray<TArray<TArray<TPosition>>>;
+
+    constructor Create;
+  end;
+
+  TGeometryCollection = class(TGeoJsonObject)
+  public
+    geometries: TArray<TGeometryObject>;
+
+    constructor Create;
+  end;
+
+  TFeature = class (TGeoJsonObject)
+    geometry: TGeometryObject;
+    id: String;
+    properties: TJSObject;
+
+    constructor Create;
+  end;
+
+  TFeatureCollection = class (TGeoJsonObject)
+  public
+    features: TArray<TGeoJsonObject>;
+
+    constructor Create;
+  end;
+
+implementation
+
+{ TGeoJsonObject }
+
+constructor TGeoJsonObject.Create(&type: String);
+begin
+  Self.&type := &type;
+end;
+
+{ TPoint }
+
+constructor TPoint.Create;
+begin
+  inherited Create('Point');
+end;
+
+{ TMultiPoint }
+
+constructor TMultiPoint.Create;
+begin
+  inherited Create('MultiPoint');
+end;
+
+{ TLineString }
+
+constructor TLineString.Create;
+begin
+  inherited Create('LineString');
+end;
+
+{ TMultiLineString }
+
+constructor TMultiLineString.Create;
+begin
+  inherited Create('MultiLineString');
+end;
+
+{ TPolygon }
+
+constructor TPolygon.Create;
+begin
+  inherited Create('Polygon');
+end;
+
+{ TMultiPolygon }
+
+constructor TMultiPolygon.Create;
+begin
+  inherited Create('MultiPolygon');
+end;
+
+{ TGeometryCollection }
+
+constructor TGeometryCollection.Create;
+begin
+  inherited Create('GeometryCollection');
+end;
+
+{ TFeature }
+
+constructor TFeature.Create;
+begin
+  inherited Create('Feature');
+end;
+
+{ TFeatureCollection }
+
+constructor TFeatureCollection.Create;
+begin
+  inherited Create('FeatureCollection');
+end;
+
+end.
diff --git a/packages/maps/Google.Maps.pas b/packages/maps/Google.Maps.pas
new file mode 100644
index 00000000..7d953ff5
--- /dev/null
+++ b/packages/maps/Google.Maps.pas
@@ -0,0 +1,2171 @@
+unit Google.Maps;
+
+interface
+
+{$modeswitch externalclass}
+
+uses JS, SysUtils, GeoJSON, Web;
+
+type
+  TAddFeatureEvent = class;
+  TAutocompleteOptions = class;
+  TAutocompletePrediction = class;
+  TAutocompleteResponse = class;
+  TAutocompleteSessionToken = class;
+  TAutocompletionRequest = class;
+  TCircleLiteral = class;
+  TCircleOptions = class;
+  TComponentRestrictions = class;
+  TDataOptions = class;
+  TDirectionsGeocodedWaypoint = class;
+  TDirectionsLeg = class;
+  TDirectionsRendererOptions = class;
+  TDirectionsRequest = class;
+  TDirectionsResult = class;
+  TDirectionsRoute = class;
+  TDirectionsStep = class;
+  TDirectionsWaypoint = class;
+  TDistance = class;
+  TDistanceMatrixRequest = class;
+  TDistanceMatrixResponse = class;
+  TDistanceMatrixResponseElement = class;
+  TDistanceMatrixResponseRow = class;
+  TDrawingControlOptions = class;
+  TDrawingManagerOptions = class;
+  TDrivingOptions = class;
+  TDuration = class;
+  TElevationResult = class;
+  TFeatureOptions = class;
+  TFindPlaceFromPhoneNumberRequest = class;
+  TFindPlaceFromQueryRequest = class;
+  TFullscreenControlOptions = class;
+  TGeoJsonOptions = class;
+  TGeocoderAddressComponent = class;
+  TGeocoderComponentRestrictions = class;
+  TGeocoderGeometry = class;
+  TGeocoderRequest = class;
+  TGeocoderResponse = class;
+  TGeocoderResult = class;
+  TGroundOverlayOptions = class;
+  THeatmapLayerOptions = class;
+  TIcon = class;
+  TIconMouseEvent = class;
+  TIconSequence = class;
+  TImageMapTypeOptions = class;
+  TInfoWindowOptions = class;
+  TKmlAuthor = class;
+  TKmlFeatureData = class;
+  TKmlLayerMetadata = class;
+  TKmlLayerOptions = class;
+  TKmlMouseEvent = class;
+  TLatLngBoundsLiteral = class;
+  TLatLngLiteral = class;
+  TLocationElevationRequest = class;
+  TLocationElevationResponse = class;
+  TMapCanvasProjection = class;
+  TMapMouseEvent = class;
+  TMapOptions = class;
+  TMapPanes = class;
+  TMapRestriction = class;
+  TMapType = class;
+  TMapTypeControlOptions = class;
+  TMapTypeStyle = class;
+  TMapsEventListener = class;
+  TMarkerLabel = class;
+  TMarkerOptions = class;
+  TMarkerShape = class;
+  TMaxZoomResult = class;
+  TMotionTrackingControlOptions = class;
+  TMouseEvent = class;
+  TOverlayCompleteEvent = class;
+  TPadding = class;
+  TPanControlOptions = class;
+  TPanoProviderOptions = class;
+  TPathElevationRequest = class;
+  TPathElevationResponse = class;
+  TPinOptions = class;
+  TPlace = class;
+  TPolyMouseEvent = class;
+  TPolygonOptions = class;
+  TPolylineOptions = class;
+  TPredictionSubstring = class;
+  TPredictionTerm = class;
+  TProjection = class;
+  TQueryAutocompletionRequest = class;
+  TRectangleOptions = class;
+  TRemoveFeatureEvent = class;
+  TRemovePropertyEvent = class;
+  TRotateControlOptions = class;
+  TScaleControlOptions = class;
+  TSearchBoxOptions = class;
+  TSetGeometryEvent = class;
+  TSetPropertyEvent = class;
+  TStreetViewAddressControlOptions = class;
+  TStreetViewControlOptions = class;
+  TStreetViewLink = class;
+  TStreetViewLocation = class;
+  TStreetViewLocationRequest = class;
+  TStreetViewPanoRequest = class;
+  TStreetViewPanoramaData = class;
+  TStreetViewPanoramaOptions = class;
+  TStreetViewPov = class;
+  TStreetViewResponse = class;
+  TStreetViewTileData = class;
+  TStructuredFormatting = class;
+  TStyleOptions = class;
+  TStyledMapTypeOptions = class;
+  TSymbol = class;
+  TTextSearchRequest = class;
+  TTimeGoogle = class;
+  TTrafficLayerOptions = class;
+  TTransitAgency = class;
+  TTransitDetails = class;
+  TTransitFare = class;
+  TTransitLine = class;
+  TTransitOptions = class;
+  TTransitStop = class;
+  TTransitVehicle = class;
+  TWeightedLocation = class;
+  TZoomControlOptions = class;
+
+  TGoogle = class external name 'google'
+  public type
+    TMaps = class external name 'maps'
+    public type
+      TLatLng = class;
+      TLatLngBounds = class;
+      TMap = class;
+      TMapTypeRegistry = class;
+      TOverlayType = class;
+      TPlacesServiceStatus = class;
+      TPoint = class;
+      TSize = class;
+      TStreetViewPanorama = class;
+
+      TAnimation = (BOUNCE, DROP);
+      TControlPosition = (BOTTOM_CENTER, BOTTOM_LEFT, BOTTOM_RIGHT, LEFT_BOTTOM, LEFT_CENTER, LEFT_TOP, RIGHT_BOTTOM, RIGHT_CENTER, RIGHT_TOP, TOP_CENTER, TOP_LEFT, TOP_RIGHT);
+      TMapTypeControlStyle = (DEFAULT, DROPDOWN_MENU, HORIZONTAL_BAR);
+      TStrokePosition = (CENTER, INSIDE, OUTSIDE);
+      TSymbolPath = (BACKWARD_CLOSED_ARROW, BACKWARD_OPEN_ARROW, CIRCLE, FORWARD_CLOSED_ARROW, FORWARD_OPEN_ARROW);
+      TUnitSystem = (IMPERIAL, METRIC);
+      TRankBy = (DISTANCE, PROMINENCE);
+
+      TMVCObject = class external name 'MVCObject'
+      public
+        function addListener(eventName: String; handler: TProc): TMapsEventListener;
+        procedure bindTo(key: String; target: TMVCObject; targetKey: String; noNotify: Boolean);
+        function get(key: String): JSValue;
+        procedure notify(key: String);
+        procedure &set(key: String; value: JSValue);
+        procedure setValues(values: TJSObject);
+        procedure unbind(key: String);
+        procedure unbindAll;
+      end;
+
+      TBicyclingLayer = class external name 'BicyclingLayer' (TMVCObject)
+      public
+        function getMap: TMap;
+        procedure setMap(map: TMap);
+      end;
+
+      TCircle = class external name 'Circle' (TMVCObject)
+      public
+        constructor new(opts: TCircleOptions);
+        function getBounds: TLatLngBounds;
+        function getCenter: TLatLng;
+        function getDraggable: Boolean;
+        function getEditable: Boolean;
+        function getMap: TMap;
+        function getRadius: Double;
+        function getVisible: Boolean;
+        procedure setCenter(center: TLatLng); overload;
+        procedure setCenter(center: TLatLngLiteral); overload;
+        procedure setDraggable(draggable: Boolean);
+        procedure setEditable(editable: Boolean);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TCircleOptions);
+        procedure setRadius(radius: Double);
+        procedure setVisible(visible: Boolean);
+      end;
+
+      TData = class external name 'Data' (TMVCObject)
+      public type
+        TGeometry = class;
+        TPolygon = class;
+
+        TFeature = class external name 'Feature'
+        public
+          constructor new(options: TFeatureOptions);
+
+          procedure forEachProperty(callback: TProc<JSValue, String>);
+          function getGeometry: TGeometry;
+          function getId: Double;
+          function getIdString: String; external name 'getId';
+          function getProperty(name: String): JSValue;
+          procedure removeProperty(name: String);
+          procedure setGeometry(newGeometry: TGeometry); overload;
+          procedure setGeometry(newGeometry: TLatLng); overload;
+          procedure setGeometry(newGeometry: TLatLngLiteral); overload;
+          procedure setProperty(name: String; newValue: JSValue);
+          procedure toGeoJson(callback: TProc<TJSObject>);
+        end;
+
+        TGeometry = class external name 'Geometry'
+        public
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getType: String;
+        end;
+
+        TGeometryCollection = class external name 'GeometryCollection' (TGeometry)
+        public
+          constructor new(elements: TArray<TGeometry>); overload;
+          constructor new(elements: TArray<TLatLng>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TGeometry>;
+          function getAt(n: Double): TGeometry;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TLineString = class external name 'LineString' (TGeometry)
+        public
+          constructor new(elements: TArray<TLatLng>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TLatLng>;
+          function getAt(n: Double): TLatLng;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TLinearRing = class external name 'LinearRing' (TGeometry)
+        public
+          constructor new(elements: TArray<TLatLng>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TLatLng>;
+          function getAt(n: Double): TLatLng;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TMultiLineString = class external name 'MultiLineString' (TGeometry)
+        public
+          constructor new(elements: TArray<TLatLng>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TLineString>;
+          function getAt(n: Double): TLineString;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TMultiPoint = class external name 'MultiPoint' (TGeometry)
+        public
+          constructor new(elements: TArray<TLatLng>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TLatLng>;
+          function getAt(n: Double): TLatLng;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TMultiPolygon = class external name 'MultiPolygon' (TGeometry)
+        public
+          constructor new(elements: TArray<TLatLng>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+          constructor new(elements: TArray<TLinearRing>); overload;
+          constructor new(elements: TArray<TPolygon>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+
+          function getArray: TArray<TPolygon>;
+          function getAt(n: Double): TPolygon;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TPoint = class external name 'Point' (TGeometry)
+        public
+          constructor new(elements: TArray<TLatLng>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function get: TLatLng;
+          function getType: String;
+        end;
+
+        TPolygon = class external name 'Polygon' (TGeometry)
+        public
+          constructor new(elements: TArray<TArray<TLatLng>>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TLinearRing>;
+          function getAt(n: Double): TLinearRing;
+          function getLength: Double;
+          function getType: String;
+        end;
+      public
+        constructor new(options: TDataOptions);
+        function add(feature: TFeature): TFeature; overload;
+        function add(feature: TFeatureOptions): TFeature; overload;
+        function addGeoJson(geoJson: TGeoJSONObject; options: TGeoJsonOptions): TArray<TFeature>;
+        function contains(feature: TFeature): Boolean;
+        procedure forEach(callback: TProc<TFeature>);
+        function getControlPosition: TControlPosition;
+        function getControls: TArray<String>;
+        function getDrawingMode: String;
+        function getFeatureById(id: Double): TFeature; overload;
+        function getFeatureById(id: String): TFeature; overload;
+        function getMap: TMap;
+        function getStyle: TStyleOptions;
+        function getStyleFunction: TFunc<TFeature, TStyleOptions>; external name 'getStyle';
+        procedure loadGeoJson(url: String; options: TGeoJsonOptions; callback: TProc<TArray<TFeature>>);
+        procedure overrideStyle(feature: TFeature; style: TStyleOptions);
+        procedure remove(feature: TFeature);
+        procedure revertStyle(feature: TFeature);
+        procedure setControlPosition(controlPosition: TControlPosition);
+        procedure setControls(controls: TArray<String>);
+        procedure setDrawingMode(drawingMode: String);
+        procedure setMap(map: TMap);
+        procedure setStyle(style: TStyleOptions); overload;
+        procedure setStyle(style: TFunc<TFeature, TStyleOptions>); overload;
+        procedure toGeoJson(callback: TProc<TGeoJSONObject>);
+      end;
+
+      TDirectionsRenderer = class external name 'DirectionsRenderer' (TMVCObject)
+      public
+        constructor new(opts: TDirectionsRendererOptions);
+        function getDirections: TDirectionsResult;
+        function getMap: TMap;
+        function getPanel: TJSNode;
+        function getRouteIndex: Double;
+        procedure setDirections(directions: TDirectionsResult);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TDirectionsRendererOptions);
+        procedure setPanel(panel: TJSNode);
+        procedure setRouteIndex(routeIndex: Double);
+      end;
+
+      TDirectionsStatus = class
+      public const
+        INVALID_REQUEST = 'INVALID_REQUEST';
+        MAX_WAYPOINTS_EXCEEDED = 'MAX_WAYPOINTS_EXCEEDED';
+        NOT_FOUND = 'NOT_FOUND';
+        OK = 'OK';
+        OVER_QUERY_LIMIT = 'OVER_QUERY_LIMIT';
+        REQUEST_DENIED = 'REQUEST_DENIED';
+        UNKNOWN_ERROR = 'UNKNOWN_ERROR';
+        ZERO_RESULTS = 'ZERO_RESULTS';
+      end;
+
+      TDirectionsService = class external name 'DirectionsService'
+      public
+        function route(request: TDirectionsRequest; callback: TProc<TDirectionsResult, TDirectionsStatus>): TJSPromise;
+      end;
+
+      TDistanceMatrixService = class external name 'DistanceMatrixService'
+      public type
+        TDistanceMatrixStatus = (INVALID_REQUEST, MAX_DIMENSIONS_EXCEEDED, MAX_ELEMENTS_EXCEEDED, OK, OVER_QUERY_LIMIT, REQUEST_DENIED, UNKNOWN_ERROR);
+      public
+        function getDistanceMatrix(request: TDistanceMatrixRequest; callback: TProc<TDistanceMatrixResponse, TDistanceMatrixStatus>): TJSPromise;
+      end;
+
+      TElevationStatus = class
+      public const
+        INVALID_REQUEST = 'INVALID_REQUEST';
+        OK = 'OK';
+        OVER_QUERY_LIMIT = 'OVER_QUERY_LIMIT';
+        REQUEST_DENIED = 'REQUEST_DENIED';
+        UNKNOWN_ERROR = 'UNKNOWN_ERROR';
+      end;
+
+      TElevationService = class external name 'ElevationService'
+      public
+        function getElevationAlongPath(request: TPathElevationRequest; callback: TProc<TArray<TElevationResult>, TElevationStatus>): TJSPromise;
+        function getElevationForLocations(request: TLocationElevationRequest; callback: TProc<TArray<TElevationResult>, TElevationStatus>): TJSPromise;
+      end;
+
+      TGeocoderStatus = class
+      public const
+        ERROR = 'ERROR';
+        INVALID_REQUEST = 'INVALID_REQUEST';
+        OK = 'OK';
+        OVER_QUERY_LIMIT = 'OVER_QUERY_LIMIT';
+        REQUEST_DENIED = 'REQUEST_DENIED';
+        UNKNOWN_ERROR = 'UNKNOWN_ERROR';
+        ZERO_RESULTS = 'ZERO_RESULTS';
+      end;
+
+      TGeocoder = class external name 'Geocoder'
+      public
+        function geocode(request: TGeocoderRequest; callback: TProc<TArray<TGeocoderResult>, TGeocoderStatus>): TJSPromise;
+      end;
+
+      TGroundOverlay = class external name 'GroundOverlay' (TMVCObject)
+      public
+        constructor new(url: String; bounds: TLatLngBounds; opts: TGroundOverlayOptions); overload;
+        constructor new(url: String; bounds: TLatLngBoundsLiteral; opts: TGroundOverlayOptions); overload;
+        function getBounds: TLatLngBounds;
+        function getMap: TMap;
+        function getOpacity: Double;
+        function getUrl: String;
+        procedure setMap(map: TMap);
+        procedure setOpacity(opacity: Double);
+      end;
+
+      TImageMapType = class external name 'ImageMapType' (TMVCObject)
+      public
+        alt: String;
+        maxZoom: Double;
+        minZoom: Double;
+        name: String;
+        projection: TProjection;
+        radius: Double;
+        tileSize: TSize;
+
+        constructor new(opts: TImageMapTypeOptions);
+
+        function getOpacity: Double;
+        function getTile(tileCoord: TPoint; zoom: Double; ownerDocument: TJSDocument): TJSNode;
+        procedure releaseTile(tileDiv: TJSNode);
+        procedure setOpacity(opacity: Double);
+      end;
+
+      TInfoWindow = class external name 'InfoWindow' (TMVCObject)
+      public
+        constructor new(opts: TInfoWindowOptions);
+        procedure close;
+        function getContent: TJSNode;
+        function getContentString: String; external name 'getContent';
+        function getPosition: TLatLng;
+        function getZIndex: Double;
+        procedure open(map: TMap; anchor: TMVCObject); overload;
+        procedure open(map: TStreetViewPanorama; anchor: TMVCObject); overload;
+        procedure setContent(content: TJSNode); overload;
+        procedure setContent(content: String); overload;
+        procedure setOptions(options: TInfoWindowOptions);
+        procedure setPosition(position: TLatLng); overload;
+        procedure setPosition(position: TLatLngLiteral); overload;
+        procedure setZIndex(zIndex: Double);
+      end;
+
+      TKmlLayerStatus = class external name 'KmlLayerStatus'
+      public const
+        DOCUMENT_NOT_FOUND = 'DOCUMENT_NOT_FOUND';
+        DOCUMENT_TOO_LARGE = 'DOCUMENT_TOO_LARGE';
+        FETCH_ERROR = 'FETCH_ERROR';
+        INVALID_DOCUMENT = 'INVALID_DOCUMENT';
+        INVALID_REQUEST = 'INVALID_REQUEST';
+        LIMITS_EXCEEDED = 'LIMITS_EXCEEDED';
+        OK = 'OK';
+        TIMED_OUT = 'TIMED_OUT';
+        UNKNOWN = 'UNKNOWN';
+      end;
+
+      TKmlLayer = class external name 'KmlLayer' (TMVCObject)
+      public
+        constructor new(opts: TKmlLayerOptions);
+        function getDefaultViewport: TLatLngBounds;
+        function getMap: TMap;
+        function getMetadata: TKmlLayerMetadata;
+        function getStatus: TKmlLayerStatus;
+        function getUrl: String;
+        function getZIndex: Double;
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TKmlLayerOptions);
+        procedure setUrl(url: String);
+        procedure setZIndex(zIndex: Double);
+      end;
+
+      TLatLng = class external name 'LatLng'
+      public
+        constructor new(lat, lng: Double); overload;
+        constructor new(lat, lng: Double; lngOrNoWrap, noWrap: Boolean); overload;
+        constructor new(latLngLiteral: TLatLngLiteral); overload;
+        constructor new(latLngLiteral: TLatLngLiteral; lngOrNoWrap, noWrap: Boolean); overload;
+        function equals(other: TLatLng): Boolean;
+        function lat: Double;
+        function lng: Double;
+        function toJSON: TLatLngLiteral;
+        function toString: String;
+        function toUrlValue(precision: Double): String;
+      end;
+
+      TLatLngBounds = class external name 'LatLngBounds'
+      public
+        constructor new(sw, ne: TLatLng); overload;
+        constructor new(sw, ne: TLatLngLiteral); overload;
+        function contains(latLng: TLatLng): Boolean; overload;
+        function contains(latLng: TLatLngLiteral): Boolean; overload;
+        function equals(other: TLatLng): Boolean; overload;
+        function equals(other: TLatLngBounds): Boolean; overload;
+        function extend(point: TLatLng): TLatLngBounds; overload;
+        function extend(point: TLatLngLiteral): TLatLngBounds; overload;
+        function getCenter: TLatLng;
+        function getNorthEast: TLatLng;
+        function getSouthWest: TLatLng;
+        function intersects(other: TLatLngBounds): Boolean; overload;
+        function intersects(other: TLatLngBoundsLiteral): Boolean; overload;
+        function isEmpty: Boolean;
+        function toJSON: TLatLngBoundsLiteral;
+        function toSpan: TLatLng;
+        function toString: String;
+        function toUrlValue(precision: Double): String;
+        function union(other: TLatLngBounds): TLatLngBounds; overload;
+        function union(other: TLatLngBoundsLiteral): TLatLngBounds; overload;
+      end;
+
+      TMVCArray<T> = class external name 'MVCArray' (TMVCObject)
+      public
+        constructor new(&array: TArray<T>);
+        procedure clear;
+        procedure forEach(callback: TProc<T, Double>);
+        function getArray: TArray<T>;
+        function getAt(i: Double): T;
+        function getLength: Double;
+        procedure insertAt(i: Double; elem: T);
+        function pop: T;
+        function push(elem: T): Double;
+        function removeAt(i: Double): T;
+        procedure setAt(i: Double; elem: T);
+      end;
+
+      TMapTypeId = class external name 'MapTypeId'
+      public const
+        HYBRID = 'HYBRID';
+        ROADMAP = 'ROADMAP';
+        SATELLITE = 'SATELLITE';
+        TERRAIN = 'TERRAIN';
+      end;
+
+      TMap = class external name 'Map' (TMVCObject)
+      public
+        controls: TArray<TMVCArray<JSValue>>;
+        data: TData;
+        mapTypes: TMapTypeRegistry;
+        overlayMapTypes: TMVCArray<JSValue>;
+
+        constructor new(mapDiv: TJSHTMLElement; opts: TMapOptions);
+
+        function getBounds: TLatLngBounds;
+        function getCenter: TLatLng;
+        function getClickableIcons: Boolean;
+        function getDiv: TJSHTMLElement;
+        function getHeading: Double;
+        function getMapTypeId: String;
+        function getProjection: TProjection;
+        function getStreetView: TStreetViewPanorama;
+        function getTilt: Double;
+        function getZoom: Double;
+
+        procedure fitBounds(bounds: TLatLngBounds; padding: Double); overload;
+        procedure fitBounds(bounds: TLatLngBounds; padding: TPadding); overload;
+        procedure fitBounds(bounds: TLatLngBoundsLiteral; padding: Double); overload;
+        procedure fitBounds(bounds: TLatLngBoundsLiteral; padding: TPadding); overload;
+        procedure panBy(x, y: Double);
+        procedure panTo(latLng: TLatLng); overload;
+        procedure panTo(latLng: TLatLngLiteral); overload;
+        procedure panToBounds(bounds: TLatLngBounds; padding: Double); overload;
+        procedure panToBounds(bounds: TLatLngBounds; padding: TPadding); overload;
+        procedure panToBounds(bounds: TLatLngBoundsLiteral; padding: Double); overload;
+        procedure panToBounds(bounds: TLatLngBoundsLiteral; padding: TPadding); overload;
+        procedure setCenter(latlng: TLatLng); overload;
+        procedure setCenter(latlng: TLatLngLiteral); overload;
+        procedure setClickableIcons(value: Boolean);
+        procedure setHeading(heading: Double);
+        procedure setMapTypeId(mapTypeId: String);
+        procedure setOptions(options: TMapOptions);
+        procedure setStreetView(panorama: TStreetViewPanorama);
+        procedure setTilt(tilt: Double);
+        procedure setZoom(zoom: Double);
+      end;
+
+      TMapTypeRegistry = class external name 'MapTypeRegistry' (TMVCObject)
+      public
+        procedure &set(id: String; mapType: JSValue);
+      end;
+
+      TMarker = class external name 'Marker' (TMVCObject)
+      public
+        constructor new(opts: TMarkerOptions);
+        function getAnimation: TAnimation;
+        function getClickable: Boolean;
+        function getCursor: String;
+        function getDraggable: Boolean;
+        function getIcon: JSValue;
+        function getLabel: TMarkerLabel;
+        function getMap: TMap;
+        function getStreetViewPanorama: TStreetViewPanorama; external name 'getMap';
+        function getOpacity: Double;
+        function getPosition: TLatLng;
+        function getShape: TMarkerShape;
+        function getTitle: String;
+        function getVisible: Boolean;
+        function getZIndex: Double;
+        procedure setAnimation(animation: TAnimation);
+        procedure setClickable(flag: Boolean);
+        procedure setCursor(cursor: String);
+        procedure setDraggable(flag: Boolean);
+        procedure setIcon(icon: String); overload;
+        procedure setIcon(icon: TIcon); overload;
+        procedure setIcon(icon: TSymbol); overload;
+        procedure setLabel(&label: String); overload;
+        procedure setLabel(&label: TMarkerLabel); overload;
+        procedure setMap(map: TMap); overload;
+        procedure setMap(map: TStreetViewPanorama); overload;
+        procedure setOpacity(opacity: Double);
+        procedure setOptions(options: TMarkerOptions);
+        procedure setPosition(latlng: TLatLng); overload;
+        procedure setPosition(latlng: TLatLngLiteral); overload;
+        procedure setShape(shape: TMarkerShape);
+        procedure setTitle(title: String);
+        procedure setVisible(visible: Boolean);
+        procedure setZIndex(zIndex: Double);
+
+        class var MAX_ZINDEX: Double;
+      end;
+
+      TMaxZoomService = class external name 'MaxZoomService'
+      public
+        function getMaxZoomAtLatLng(latlng: TLatLng; callback: TProc<TMaxZoomResult>): TJSPromise; overload;
+        function getMaxZoomAtLatLng(latlng: TLatLngLiteral; callback: TProc<TMaxZoomResult>): TJSPromise; overload;
+      end;
+
+      TOverlayView = class external name 'OverlayView' (TMVCObject)
+      public
+        procedure draw;
+        function getMap: TMap;
+        function getMapStreetViewPanorama: TStreetViewPanorama; external name 'getMap';
+        function getPanes: TMapPanes;
+        function getProjection: TMapCanvasProjection;
+        procedure onAdd;
+        procedure onRemove;
+        procedure setMap(map: TMap); overload;
+        procedure setMap(map: TStreetViewPanorama); overload;
+        class procedure preventMapHitsAndGesturesFrom(this: JSValue; element: TJSHTMLElement);
+        class procedure preventMapHitsFrom(this: JSValue; element: TJSHTMLElement);
+      end;
+
+      TPoint = class external name 'Point'
+      public
+        x: Double;
+        y: Double;
+
+        constructor new(x, y: Double);
+        function equals(other: TPoint): Boolean;
+        function toString: String;
+      end;
+
+      TPolygon = class external name 'Polygon' (TMVCObject)
+      public
+        constructor new(opts: TPolygonOptions);
+        function getDraggable: Boolean;
+        function getEditable: Boolean;
+        function getMap: TMap;
+        function getPath: TMVCArray<JSValue>;
+        function getPaths: TMVCArray<JSValue>;
+        function getVisible: Boolean;
+        procedure setDraggable(draggable: Boolean);
+        procedure setEditable(editable: Boolean);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TPolygonOptions);
+        procedure setPath(path: TMVCArray<JSValue>); overload;
+        procedure setPath(path: TArray<TLatLng>); overload;
+        procedure setPath(path: TArray<TLatLngLiteral>); overload;
+        procedure setPaths(paths: TMVCArray<JSValue>); overload;
+        procedure setPaths(paths: TArray<JSValue>); overload;
+        procedure setVisible(visible: Boolean);
+      end;
+
+      TPolyline = class external name 'Polyline' (TMVCObject)
+      public
+        constructor new(opts: TPolylineOptions);
+        function getDraggable: Boolean;
+        function getEditable: Boolean;
+        function getMap: TMap;
+        function getPath: TMVCArray<JSValue>;
+        function getVisible: Boolean;
+        procedure setDraggable(draggable: Boolean);
+        procedure setEditable(editable: Boolean);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TPolylineOptions);
+        procedure setPath(path: TMVCArray<JSValue>); overload;
+        procedure setPath(path: TArray<TLatLng>); overload;
+        procedure setPath(path: TArray<TLatLngLiteral>); overload;
+        procedure setVisible(visible: Boolean);
+      end;
+
+      TRectangle = class external name 'Rectangle' (TMVCObject)
+      public
+        constructor new(opts: TRectangleOptions);
+        function getBounds: TLatLngBounds;
+        function getDraggable: Boolean;
+        function getEditable: Boolean;
+        function getMap: TMap;
+        function getVisible: Boolean;
+        procedure setBounds(bounds: TLatLngBounds); overload;
+        procedure setBounds(bounds: TLatLngBoundsLiteral); overload;
+        procedure setDraggable(draggable: Boolean);
+        procedure setEditable(editable: Boolean);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TRectangleOptions);
+        procedure setVisible(visible: Boolean);
+      end;
+
+      TSize = class external name 'Size'
+      public
+        height: Double;
+        width: Double;
+
+        constructor new(width, height: Double; widthUnit, heightUnit: String);
+        function equals(other: TSize): Boolean;
+        function toString: String;
+      end;
+
+      TStreetViewCoverageLayer = class external name 'StreetViewCoverageLayer' (TMVCObject)
+      public
+        function getMap: TMap;
+        procedure setMap(map: TMap);
+      end;
+
+      TStreetViewStatus = class external name 'StreetViewStatus'
+      public const
+        OK = 'OK';
+        UNKNOWN_ERROR = 'UNKNOWN_ERROR';
+        ZERO_RESULTS = 'ZERO_RESULTS';
+      end;
+
+      TStreetViewPanorama = class external name 'StreetViewPanorama' (TMVCObject)
+      public
+        controls: TArray<TMVCArray<JSValue>>;
+
+        constructor new(container: TJSHTMLElement; opts: TStreetViewPanoramaOptions);
+        function getLinks: TArray<TStreetViewLink>;
+        function getLocation: TStreetViewLocation;
+        function getMotionTracking: Boolean;
+        function getPano: String;
+        function getPhotographerPov: TStreetViewPov;
+        function getPosition: TLatLng;
+        function getPov: TStreetViewPov;
+        function getStatus: TStreetViewStatus;
+        function getVisible: Boolean;
+        function getZoom: Double;
+        procedure registerPanoProvider(provider: TFunc<String, TStreetViewPanoramaData>; opt_options: TPanoProviderOptions);
+        procedure setLinks(links: TArray<TStreetViewLink>);
+        procedure setMotionTracking(motionTracking: Boolean);
+        procedure setOptions(options: TStreetViewPanoramaOptions);
+        procedure setPano(pano: String);
+        procedure setPosition(latLng: TLatLng); overload;
+        procedure setPosition(latLng: TLatLngLiteral); overload;
+        procedure setPov(pov: TStreetViewPov);
+        procedure setVisible(flag: Boolean);
+        procedure setZoom(zoom: Double);
+      end;
+
+      TStreetViewService = class external name 'StreetViewService'
+      public
+        function getPanorama(request: TStreetViewLocationRequest; callback: TProc<TStreetViewPanoramaData, TStreetViewStatus>): TJSPromise; overload;
+        function getPanorama(request: TStreetViewPanoRequest; callback: TProc<TStreetViewPanoramaData, TStreetViewStatus>): TJSPromise; overload;
+      end;
+
+      TStyledMapType = class external name 'StyledMapType' (TMVCObject)
+      public
+        alt: String;
+        maxZoom: Double;
+        minZoom: Double;
+        name: String;
+        projection: TProjection;
+        radius: Double;
+        tileSize: TSize;
+        constructor new(styles: TArray<TMapTypeStyle>; options: TStyledMapTypeOptions);
+        function getTile(tileCoord: TPoint; zoom: Double; ownerDocument: TJSDocument): TJSNode;
+        procedure releaseTile(tile: TJSNode);
+      end;
+
+      TTrafficLayer = class external name 'TrafficLayer' (TMVCObject)
+      public
+        constructor new(opts: TTrafficLayerOptions);
+        function getMap: TMap;
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TTrafficLayerOptions);
+      end;
+
+      TTransitLayer = class external name 'TransitLayer' (TMVCObject)
+      public
+        function getMap: TMap;
+        procedure setMap(map: TMap);
+      end;
+
+      TDrawingManager = class external name 'DrawingManager' (TMVCObject)
+      public
+        constructor new(options: TDrawingManagerOptions);
+        function getDrawingMode: TOverlayType;
+        function getMap: TMap;
+        procedure setDrawingMode(drawingMode: TOverlayType);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TDrawingManagerOptions);
+      end;
+
+      TEvent = class external name 'event'
+      public
+        function addDomListener(instance: TJSObject; eventName: String; handler: TProc; capture: Boolean): TMapsEventListener;
+        function addDomListenerOnce(instance: TJSObject; eventName: String; handler: TProc; capture: Boolean): TMapsEventListener;
+        function addListener(instance: TJSObject; eventName: String; handler: TProc): TMapsEventListener;
+        function addListenerOnce(instance: TJSObject; eventName: String; handler: TProc): TMapsEventListener;
+        procedure clearInstanceListeners(instance: TJSObject);
+        procedure clearListeners(instance: TJSObject; eventName: String);
+        procedure removeListener(listener: TMapsEventListener);
+        procedure trigger(instance: TJSObject; eventName: String); varargs;
+      end;
+
+      TGeometry = class external name 'geometry'
+      public type
+        TEncoding = class external name 'encoding'
+        public
+          function decodePath(encodedPath: String): TArray<TLatLng>;
+          function encodePath(path: TArray<TLatLng>): String; overload;
+          function encodePath(path: TMVCArray<JSValue>): String; overload;
+        end;
+
+        TPoly = class external name 'poly'
+        public
+          function containsLocation(point: TLatLng; polygon: TGoogle.TMaps.TPolygon): Boolean;
+          function isLocationOnEdge(point: TLatLng; poly: TGoogle.TMaps.TPolygon; tolerance: Double): Boolean; overload;
+          function isLocationOnEdge(point: TLatLng; poly: TGoogle.TMaps.TPolyline; tolerance: Double): Boolean; overload;
+        end;
+
+        TSpherical = class external name 'spherical'
+        public
+          function computeArea(path: TArray<TLatLng>; radius: Double): Double; overload;
+          function computeArea(path: TMVCArray<JSValue>; radius: Double): Double; overload;
+          function computeDistanceBetween(from: TLatLng; &to: TLatLng; radius: Double): Double;
+          function computeHeading(from: TLatLng; &to: TLatLng): Double;
+          function computeLength(path: TArray<TLatLng>; radius: Double): Double; overload;
+          function computeLength(path: TMVCArray<JSValue>; radius: Double): Double; overload;
+          function computeOffset(from: TLatLng; distance, heading, radius: Double): TLatLng;
+          function computeOffsetOrigin(&to: TLatLng; distance, heading, radius: Double): TLatLng;
+          function computeSignedArea(loop: TArray<TLatLng>; radius: Double): Double; overload;
+          function computeSignedArea(loop: TMVCArray<JSValue>; radius: Double): Double; overload;
+          function interpolate(from, &to: TLatLng; fraction: Double): TLatLng;
+        end;
+      end;
+
+      TVisualization = class external name 'visualization'
+      public type
+        THeatmapLayer = class external name 'HeatmapLayer' (TMVCObject)
+        public
+          constructor new(opts: THeatmapLayerOptions);
+          function getData: TMVCArray<JSValue>;
+          function getMap: TMaps;
+          procedure setData(data: TMVCArray<JSValue>); overload;
+          procedure setData(data: TArray<TLatLng>); overload;
+          procedure setData(data: TArray<TWeightedLocation>); overload;
+          procedure setMap(map: TMap);
+          procedure setOptions(options: THeatmapLayerOptions);
+        end;
+      end;
+
+      TStreetViewPreference = class external name 'StreetViewPreference'
+      public const
+        BEST = 'BEST';
+        NEAREST = 'NEAREST';
+      end;
+
+      TMaxZoomStatus = class external name 'MaxZoomStatus'
+      public const
+        ERROR = 'ERROR';
+        OK = 'OK';
+      end;
+
+      TGeocoderLocationType = class external name 'GeocoderLocationType'
+      public const
+        APPROXIMATE = 'APPROXIMATE';
+        GEOMETRIC_CENTER = 'GEOMETRIC_CENTER';
+        RANGE_INTERPOLATED = 'RANGE_INTERPOLATED';
+        ROOFTOP = 'ROOFTOP';
+      end;
+
+      TTrafficModel = class external name 'TrafficModel'
+      public const
+        BEST_GUESS = 'BEST_GUESS';
+        OPTIMISTIC = 'OPTIMISTIC';
+        PESSIMISTIC = 'PESSIMISTIC';
+      end;
+
+      TTransitMode = class external name 'TransitMode'
+      public const
+        BUS = 'BUS';
+        RAIL = 'RAIL';
+        SUBWAY = 'SUBWAY';
+        TRAIN = 'TRAIN';
+        TRAM = 'TRAM';
+      end;
+
+      TTransitRoutePreference = class external name 'TransitRoutePreference'
+      public const
+        FEWER_TRANSFERS = 'FEWER_TRANSFERS';
+        LESS_WALKING = 'LESS_WALKING';
+      end;
+
+      TTravelMode = class external name 'TravelMode'
+      public const
+        BICYCLING = 'BICYCLING';
+        DRIVING = 'DRIVING';
+        TRANSIT = 'TRANSIT';
+        WALKING = 'WALKING';
+      end;
+
+      TOverlayType = class external name 'OverlayType'
+      public const
+        CIRCLE = 'CIRCLE';
+        MARKER = 'MARKER';
+        POLYGON = 'POLYGON';
+        POLYLINE = 'POLYLINE';
+        RECTANGLE = 'RECTANGLE';
+      end;
+
+      TBusinessStatus = class external name 'BusinessStatus'
+      public const
+        CLOSED_PERMANENTLY = 'CLOSED_PERMANENTLY';
+        CLOSED_TEMPORARILY = 'CLOSED_TEMPORARILY';
+        OPERATIONAL = 'OPERATIONAL';
+      end;
+
+      TPlacesServiceStatus = class external name 'PlacesServiceStatus'
+      public const
+        INVALID_REQUEST = 'INVALID_REQUEST';
+        NOT_FOUND = 'NOT_FOUND';
+        OK = 'OK';
+        OVER_QUERY_LIMIT = 'OVER_QUERY_LIMIT';
+        REQUEST_DENIED = 'REQUEST_DENIED';
+        UNKNOWN_ERROR = 'UNKNOWN_ERROR';
+        ZERO_RESULTS = 'ZERO_RESULTS';
+      end;
+
+      TDistanceMatrixElementStatus = class
+      public const
+        NOT_FOUND = 'NOT_FOUND';
+        OK = 'OK';
+        ZERO_RESULTS = 'ZERO_RESULTS';
+      end;
+
+      TStreetViewSource = class
+      public const
+        DEFAULT = 'DEFAULT';
+        OUTDOOR = 'OUTDOOR';
+      end;
+
+      TVehicleType = class
+      public const
+        BUS = 'BUS';
+        CABLE_CAR = 'CABLE_CAR';
+        COMMUTER_TRAIN = 'COMMUTER_TRAIN';
+        COMMUTER_TRAINCOMMUTER_TRAINCOMMUTER_TRAINCOMMUTER_TRAINFERRY = 'COMMUTER_TRAINCOMMUTER_TRAINCOMMUTER_TRAINCOMMUTER_TRAINFERRY';
+        FUNICULAR = 'FUNICULAR';
+        GONDOLA_LIFT = 'GONDOLA_LIFT';
+        HEAVY_RAIL = 'HEAVY_RAIL';
+        HIGH_SPEED_TRAIN = 'HIGH_SPEED_TRAIN';
+        INTERCITY_BUS = 'INTERCITY_BUS';
+        METRO_RAIL = 'METRO_RAIL';
+        MONORAIL = 'MONORAIL';
+        OTHER = 'OTHER';
+        RAIL = 'RAIL';
+        SHARE_TAXI = 'SHARE_TAXI';
+        SUBWAY = 'SUBWAY';
+        TRAM = 'TRAM';
+        TROLLEYBUS = 'TROLLEYBUS';
+      end;
+    public
+      version: String;
+    end;
+  end;
+
+  TCircleOptions = class
+  public
+    center: JSValue;
+    clickable: Boolean;
+    draggable: Boolean;
+    editable: Boolean;
+    fillColor: String;
+    fillOpacity: Double;
+    map: TGoogle.TMaps.TMap;
+    radius: Double;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokePosition: TGoogle.TMaps.TStrokePosition;
+    strokeWeight: Double;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TCircleLiteral = class(TCircleOptions)
+  public
+    center: JSValue;
+    radius: Double;
+  end;
+
+  TAddFeatureEvent = class
+  public
+    feature: TGoogle.TMaps.TData.TFeature;
+  end;
+
+  TDataOptions = class
+  public
+    controlPosition: TGoogle.TMaps.TControlPosition;
+    controls: TArray<String>;
+    drawingMode: String;
+    featureFactory: TFunc<TGoogle.TMaps.TData.TGeometry, TGoogle.TMaps.TData.TFeature>;
+    map: TGoogle.TMaps.TMap;
+    style: TStyleOptions;
+    styleFunction: TFunc<TGoogle.TMaps.TData.TFeature, TStyleOptions>; external name 'style';
+  end;
+
+  TFeatureOptions = class
+  public
+    geometry: JSValue;
+    id: Double;
+    properties: TJSObject;
+  end;
+
+  TGeoJsonOptions = class
+  public
+    idPropertyName: String;
+  end;
+
+  TMapMouseEvent = class external name 'MapMouseEvent'
+  public
+    domEvent: TJSEvent;
+    latLng: TGoogle.TMaps.TLatLng;
+    procedure stop;
+  end;
+
+  TMouseEvent = class(TMapMouseEvent)
+  public
+    feature: TGoogle.TMaps.TData.TFeature;
+  end;
+
+  TRemoveFeatureEvent = class
+  public
+    feature: TGoogle.TMaps.TData.TFeature;
+  end;
+
+  TRemovePropertyEvent = class
+  public
+    feature: TGoogle.TMaps.TData.TFeature;
+    name: String;
+    oldValue: JSValue;
+  end;
+
+  TSetGeometryEvent = class
+  public
+    feature: TGoogle.TMaps.TData.TFeature;
+    newGeometry: TGoogle.TMaps.TData.TGeometry;
+    oldGeometry: TGoogle.TMaps.TData.TGeometry;
+  end;
+
+  TSetPropertyEvent = class
+    feature: TGoogle.TMaps.TData.TFeature;
+    name: String;
+    newValue: JSValue;
+    oldValue: JSValue;
+  end;
+
+  TStyleOptions = class
+  public
+    clickable: Boolean;
+    cursor: String;
+    draggable: Boolean;
+    editable: Boolean;
+    fillColor: String;
+    fillOpacity: Double;
+    icon: JSValue;
+    shape: TMarkerShape;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokeWeight: Double;
+    title: String;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TDirectionsGeocodedWaypoint = class
+  public
+    partial_match: Boolean;
+    place_id: String;
+    types: TArray<String>;
+  end;
+
+  TDirectionsLeg = class
+  public
+    arrival_time: TTimeGoogle;
+    departure_time: TTimeGoogle;
+    distance: TDistance;
+    duration: TDuration;
+    duration_in_traffic: TDuration;
+    end_address: String;
+    end_location: TGoogle.TMaps.TLatLng;
+    start_address: String;
+    start_location: TGoogle.TMaps.TLatLng;
+    steps: TArray<TDirectionsStep>;
+    via_waypoints: TArray<TGoogle.TMaps.TLatLng>;
+  end;
+
+  TDirectionsRendererOptions = class
+  public
+    directions: TDirectionsResult;
+    draggable: Boolean;
+    hideRouteList: Boolean;
+    infoWindow: TGoogle.TMaps.TInfoWindow;
+    map: TGoogle.TMaps.TMap;
+    markerOptions: TMarkerOptions;
+    panel: TJSNode;
+    polylineOptions: google.maps.TPolylineOptions;
+    preserveViewport: Boolean;
+    routeIndex: Double;
+    suppressBicyclingLayer: Boolean;
+    suppressInfoWindows: Boolean;
+    suppressMarkers: Boolean;
+    suppressPolylines: Boolean;
+  end;
+
+  TDirectionsRequest = class
+  public
+    avoidFerries: Boolean;
+    avoidHighways: Boolean;
+    avoidTolls: Boolean;
+    destination: JSValue;
+    drivingOptions: TDrivingOptions;
+    optimizeWaypoints: Boolean;
+    origin: JSValue;
+    provideRouteAlternatives: Boolean;
+    region: String;
+    transitOptions: TTransitOptions;
+    travelMode: TGoogle.TMaps.TTravelMode;
+    unitSystem: TGoogle.TMaps.TUnitSystem;
+    waypoints: TArray<TDirectionsWaypoint>;
+  end;
+
+  TDirectionsResult = class
+  public
+    geocoded_waypoints: TArray<TDirectionsGeocodedWaypoint>;
+    routes: TArray<TDirectionsRoute>;
+  end;
+
+  TDirectionsRoute = class
+  public
+    bounds: TGoogle.TMaps.TLatLngBounds;
+    copyrights: String;
+    fare: TArray<TTransitFare>;
+    legs: TArray<TDirectionsLeg>;
+    overview_path: TArray<TGoogle.TMaps.TLatLng>;
+    overview_polyline: String;
+    warnings: TArray<String>;
+    waypoint_order: TArray<Double>;
+  end;
+
+  TDirectionsStep = class
+    distance: TDistance;
+    duration: TDuration;
+    end_location: TGoogle.TMaps.TLatLng;
+    instructions: String;
+    path: TArray<TGoogle.TMaps.TLatLng>;
+    start_location: TGoogle.TMaps.TLatLng;
+    steps: TArray<TDirectionsStep>;
+    transit: TTransitDetails;
+    travel_mode: TGoogle.TMaps.TTravelMode;
+  end;
+
+  TDirectionsWaypoint = class
+    location: JSValue;
+    stopover: Boolean;
+  end;
+
+  TDistance = class
+  public
+    text: String;
+    value: Double;
+  end;
+
+  TDistanceMatrixRequest = class
+  public
+    avoidFerries: Boolean;
+    avoidHighways: Boolean;
+    avoidTolls: Boolean;
+    destinations: TArray<JSValue>;
+    drivingOptions: TDrivingOptions;
+    origins: TArray<JSValue>;
+    region: String;
+    transitOptions: TTransitOptions;
+    travelMode: TGoogle.TMaps.TTravelMode;
+    unitSystem: TGoogle.TMaps.TUnitSystem;
+  end;
+
+  TDistanceMatrixResponse = class
+  public
+    destinationAddresses: TArray<String>;
+    originAddresses: TArray<String>;
+    rows: TArray<TDistanceMatrixResponseRow>;
+  end;
+
+  TDistanceMatrixResponseElement = class
+  public
+    distance: TDistance;
+    duration: TDuration;
+    duration_in_traffic: TDuration;
+    fare: TTransitFare;
+    status: TGoogle.TMaps.TDistanceMatrixElementStatus;
+  end;
+
+  TDistanceMatrixResponseRow = class
+  public
+    elements: TArray<TDistanceMatrixResponseElement>;
+  end;
+
+  TDrivingOptions = class
+  public
+    departureTime: String;
+    trafficModel: TGoogle.TMaps.TTrafficModel;
+  end;
+
+  TDuration = class
+  public
+    text: String;
+    value: Double;
+  end;
+
+  TElevationResult = class
+  public
+    elevation: Double;
+    location: TGoogle.TMaps.TLatLng;
+    resolution: Double;
+  end;
+
+  TFullscreenControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TGeocoderAddressComponent = class
+  public
+    long_name: String;
+    short_name: String;
+    types: TArray<String>;
+  end;
+
+  TGeocoderComponentRestrictions = class
+  public
+    administrativeArea: String;
+    country: String;
+    locality: String;
+    postalCode: String;
+    route: String;
+  end;
+
+  TGeocoderGeometry = class
+  public
+    bounds: TGoogle.TMaps.TLatLngBounds;
+    location: TGoogle.TMaps.TLatLng;
+    location_type: TGoogle.TMaps.TGeocoderLocationType;
+    viewport: TGoogle.TMaps.TLatLngBounds;
+  end;
+
+  TGeocoderRequest = class
+  public
+    address: String;
+    bounds: JSValue;
+    componentRestrictions: TGeocoderComponentRestrictions;
+    location: JSValue;
+    placeId: String;
+    region: String;
+  end;
+
+  TGeocoderResponse = class
+  public
+    results: TArray<TGeocoderResult>;
+  end;
+
+  TGeocoderResult = class
+  public
+    address_components: TArray<TGeocoderAddressComponent>;
+    formatted_address: String;
+    geometry: TGeocoderGeometry;
+    partial_match: Boolean;
+    place_id: String;
+    postcode_localities: TArray<String>;
+    types: TArray<String>;
+  end;
+
+  TGroundOverlayOptions = class
+  public
+    clickable: Boolean;
+    map: TGoogle.TMaps.TMap;
+    opacity: Double;
+  end;
+
+  TIcon = class
+  public
+    anchor: TGoogle.TMaps.TPoint;
+    labelOrigin: TGoogle.TMaps.TPoint;
+    origin: TGoogle.TMaps.TPoint;
+    scaledSize: TGoogle.TMaps.TSize;
+    size: TGoogle.TMaps.TSize;
+    url: String;
+  end;
+
+  TIconMouseEvent = class(TMapMouseEvent)
+  public
+    placeId: String;
+  end;
+
+  TIconSequence = class
+  public
+    fixedRotation: Boolean;
+    icon: TSymbol;
+    offset: String;
+    &repeat: String;
+  end;
+
+  TImageMapTypeOptions = class
+  public
+    alt: String;
+    getTileUrl: TFunc<TGoogle.TMaps.TPoint, Double, String>;
+    maxZoom: Double;
+    minZoom: Double;
+    name: String;
+    opacity: Double;
+    tileSize: TGoogle.TMaps.TSize;
+  end;
+
+  TInfoWindowOptions = class
+  public
+    content: JSValue;
+    disableAutoPan: Boolean;
+    maxWidth: Double;
+    minWidth: Double;
+    pixelOffset: TGoogle.TMaps.TSize;
+    position: JSValue;
+    zIndex: Double;
+  end;
+
+  TKmlAuthor = class
+  public
+    email: String;
+    name: String;
+    uri: String;
+  end;
+
+  TKmlFeatureData = class
+  public
+    author: TKmlAuthor;
+    description: String;
+    id: String;
+    infoWindowHtml: String;
+    name: String;
+    snippet: String;
+  end;
+
+  TKmlLayerMetadata = class
+  public
+    author: TKmlAuthor;
+    description: String;
+    hasScreenOverlays: Boolean;
+    name: String;
+    snippet: String;
+  end;
+
+  TKmlLayerOptions = class
+  public
+    clickable: Boolean;
+    map: TGoogle.TMaps.TMap;
+    preserveViewport: Boolean;
+    screenOverlays: Boolean;
+    suppressInfoWindows: Boolean;
+    url: String;
+    zIndex: Double;
+  end;
+
+  TKmlMouseEvent = class
+  public
+    featureData: TKmlFeatureData;
+    latLng: TGoogle.TMaps.TLatLng;
+    pixelOffset: TGoogle.TMaps.TSize;
+  end;
+
+  TLatLngBoundsLiteral = class
+  public
+    east: Double;
+    north: Double;
+    south: Double;
+    west: Double;
+  end;
+
+  TLatLngLiteral = class
+  public
+    lat: Double;
+    lng: Double;
+
+    constructor Create(Lat, Lng: Double);
+  end;
+
+  TLocationElevationRequest = class
+  public
+    locations: TArray<JSValue>;
+  end;
+
+  TLocationElevationResponse = class
+  public
+    results: TArray<TElevationResult>;
+  end;
+
+  TMapCanvasProjection = class external name 'MapCanvasProjection' abstract
+  public
+    function fromContainerPixelToLatLng(pixel: TGoogle.TMaps.TPoint; nowrap: Boolean): TGoogle.TMaps.TLatLng;
+    function fromDivPixelToLatLng(pixel: TGoogle.TMaps.TPoint; nowrap: Boolean): TGoogle.TMaps.TLatLng;
+    function fromLatLngToContainerPixel(latLng: TGoogle.TMaps.TLatLng): TGoogle.TMaps.TPoint;
+    function fromLatLngToDivPixel(latLng: TGoogle.TMaps.TLatLng): TGoogle.TMaps.TPoint;
+    function getWorldWidth: Double;
+  end;
+
+  TMapOptions = class
+  private
+    FFullscreenControlOptions: TFullscreenControlOptions; external name 'fullscreenControlOptions';
+    Frestriction: TMapRestriction; external name 'restriction';
+    FzoomControlOptions: TZoomControlOptions; external name 'zoomControlOptions';
+    FscaleControlOptions: TScaleControlOptions; external name 'scaleControlOptions';
+    FmapTypeControlOptions: TMapTypeControlOptions; external name 'mapTypeControlOptions';
+    FpanControlOptions: TPanControlOptions; external name 'panControlOptions';
+    FstreetViewControlOptions: TStreetViewControlOptions; external name 'streetViewControlOptions';
+    FrotateControlOptions: TRotateControlOptions; external name 'rotateControlOptions';
+
+    function GetRestriction: TMapRestriction;
+    function GetRotateControlOptions: TRotateControlOptions;
+    function GetScaleControlOptions: TScaleControlOptions;
+    function GetStreetViewControlOptions: TStreetViewControlOptions;
+    function GetZoomControlOptions: TZoomControlOptions;
+    function GetfullscreenControlOptions: TFullscreenControlOptions;
+    function GetmapTypeControlOptions: TMapTypeControlOptions;
+    function GetpanControlOptions: TPanControlOptions;
+  public
+    backgroundColor: String;
+    center: JSValue;
+    clickableIcons: Boolean;
+    controlSize: Double;
+    disableDefaultUI: Boolean;
+    disableDoubleClickZoom: Boolean;
+    draggableCursor: String;
+    draggingCursor: String;
+    fullscreenControl: Boolean;
+    gestureHandling: String;
+    heading: Double;
+    keyboardShortcuts: Boolean;
+    mapTypeControl: Boolean;
+    mapTypeId: String;
+    maxZoom: Double;
+    minZoom: Double;
+    noClear: Boolean;
+    panControl: Boolean;
+    rotateControl: Boolean;
+    scaleControl: Boolean;
+    scrollwheel: Boolean;
+    streetView: TGoogle.TMaps.TStreetViewPanorama;
+    streetViewControl: Boolean;
+    styles: TArray<TMapTypeStyle>;
+    tilt: Double;
+    zoom: Double;
+    zoomControl: Boolean;
+
+    property fullscreenControlOptions: TFullscreenControlOptions read GetfullscreenControlOptions write FfullscreenControlOptions;
+    property mapTypeControlOptions: TMapTypeControlOptions read GetmapTypeControlOptions write FmapTypeControlOptions;
+    property panControlOptions: TPanControlOptions read GetpanControlOptions write FpanControlOptions;
+    property rotateControlOptions: TRotateControlOptions read GetrotateControlOptions write FrotateControlOptions;
+    property streetViewControlOptions: TStreetViewControlOptions read GetstreetViewControlOptions write FstreetViewControlOptions;
+    property restriction: TMapRestriction read Getrestriction write Frestriction;
+    property scaleControlOptions: TScaleControlOptions read GetscaleControlOptions write FscaleControlOptions;
+    property zoomControlOptions: TZoomControlOptions read GetzoomControlOptions write FzoomControlOptions;
+  end;
+
+  TMapPanes = class
+  public
+    floatPane: TJSHTMLElement;
+    mapPane: TJSHTMLElement;
+    markerLayer: TJSHTMLElement;
+    overlayLayer: TJSHTMLElement;
+    overlayMouseTarget: TJSHTMLElement;
+  end;
+
+  TMapRestriction = class
+  public
+    latLngBounds: JSValue;
+    strictBounds: Boolean;
+  end;
+
+  TMapType = class external name 'MapType' abstract
+  public
+    alt: String;
+    maxZoom: Double;
+    minZoom: Double;
+    name: String;
+    projection: TProjection;
+    radius: Double;
+    tileSize: TGoogle.TMaps.TSize;
+    procedure releaseTile(tile: TJSNode);
+    function getTile(tileCoord: TGoogle.TMaps.TPoint; zoom: Double; ownerDocument: TJSDocument): TJSNode;
+  end;
+
+  TMapTypeControlOptions = class
+  public
+    mapTypeIds: TArray<String>;
+    position: TGoogle.TMaps.TControlPosition;
+    style: TGoogle.TMaps.TMapTypeControlStyle;
+  end;
+
+  TMapTypeStyle = class
+  public
+    elementType: String;
+    featureType: String;
+    stylers: TArray<TJSObject>;
+  end;
+
+  TMapsEventListener = class external name 'MapsEventListener' abstract
+  public
+    procedure remove;
+  end;
+
+  TPadding = class
+  public
+    bottom: Double;
+    left: Double;
+    right: Double;
+    top: Double;
+  end;
+
+  TPanControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TPanoProviderOptions = class
+  public
+    cors: Boolean;
+  end;
+
+  TPathElevationRequest = class
+  public
+    path: TArray<JSValue>;
+    samples: Double;
+  end;
+
+  TPathElevationResponse = class
+  public
+    results: TArray<TElevationResult>;
+  end;
+
+  TPlace = class
+  public
+    location: JSValue;
+    placeId: String;
+    query: String;
+  end;
+
+  TPolyMouseEvent = class(TMapMouseEvent)
+  public
+    edge: Double;
+    path: Double;
+    vertex: Double;
+  end;
+
+  TMarkerLabel = class
+  public
+    className: String;
+    color: String;
+    fontFamily: String;
+    fontSize: String;
+    fontWeight: String;
+    text: String;
+  end;
+
+  TMarkerOptions = class
+  public
+    anchorPoint: TGoogle.TMaps.TPoint;
+    animation: TGoogle.TMaps.TAnimation;
+    clickable: Boolean;
+    crossOnDrag: Boolean;
+    cursor: String;
+    draggable: Boolean;
+    icon: JSValue;
+    &label: JSValue;
+    map: TGoogle.TMaps.TMap;
+    mapStreetViewPanorama: TGoogle.TMaps.TStreetViewPanorama; external name 'map';
+    opacity: Double;
+    optimized: Boolean;
+    position: JSValue;
+    shape: TMarkerShape;
+    title: String;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TMarkerShape = class
+  public
+    coords: TArray<Double>;
+    &type: String;
+  end;
+
+  TMaxZoomResult = class
+  public
+    status: TGoogle.TMaps.TMaxZoomStatus;
+    zoom: Double;
+  end;
+
+  TPolygonOptions = class
+  public
+    clickable: Boolean;
+    draggable: Boolean;
+    editable: Boolean;
+    fillColor: String;
+    fillOpacity: Double;
+    geodesic: Boolean;
+    map: TGoogle.TMaps.TMap;
+    paths: JSValue;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokePosition: TGoogle.TMaps.TStrokePosition;
+    strokeWeight: Double;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TPolylineOptions = class
+  public
+    clickable: Boolean;
+    draggable: Boolean;
+    editable: Boolean;
+    geodesic: Boolean;
+    icons: TArray<TIconSequence>;
+    map: TGoogle.TMaps.TMap;
+    path: TArray<JSValue>;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokeWeight: Double;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TProjection = class external name 'Projection' abstract
+  public
+    function fromLatLngToPoint(latLng: TGoogle.TMaps.TLatLng; point: TGoogle.TMaps.TPoint): TGoogle.TMaps.TPoint;
+    function fromPointToLatLng(pixel: TGoogle.TMaps.TPoint; noWrap: Boolean): TGoogle.TMaps.TLatLng;
+  end;
+
+  TRectangleOptions = class
+  public
+    bounds: JSValue;
+    clickable: Boolean;
+    draggable: Boolean;
+    editable: Boolean;
+    fillColor: String;
+    fillOpacity: Double;
+    map: TGoogle.TMaps.TMap;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokePosition: TGoogle.TMaps.TStrokePosition;
+    strokeWeight: Double;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TRotateControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TScaleControlOptions = class
+  public type
+    TScaleControlStyle = (scDEFAULT);
+  public
+    style: TScaleControlStyle;
+  end;
+
+  TMotionTrackingControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TStreetViewAddressControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TStreetViewControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TStreetViewLink = class
+  public
+    description: String;
+    heading: Double;
+    pano: String;
+  end;
+
+  TStreetViewLocation = class
+  public
+    description: String;
+    latLng: TGoogle.TMaps.TLatLng;
+    pano: String;
+    shortDescription: String;
+  end;
+
+  TStreetViewLocationRequest = class
+  public
+    location: JSValue;
+    preference: TGoogle.TMaps.TStreetViewPreference;
+    radius: Double;
+    source: TGoogle.TMaps.TStreetViewSource;
+  end;
+
+  TStreetViewPanoRequest = class
+  public
+    pano: String;
+  end;
+
+  TStreetViewPanoramaData = class
+  public
+    copyright: String;
+    imageDate: String;
+    links: TArray<TStreetViewLink>;
+    location: TStreetViewLocation;
+    tiles: TStreetViewTileData;
+  end;
+
+  TStreetViewPanoramaOptions = class
+  public
+    addressControl: Boolean;
+    addressControlOptions: TStreetViewAddressControlOptions;
+    clickToGo: Boolean;
+    controlSize: Double;
+    disableDefaultUI: Boolean;
+    disableDoubleClickZoom: Boolean;
+    enableCloseButton: Boolean;
+    fullscreenControl: Boolean;
+    fullscreenControlOptions: TFullscreenControlOptions;
+    imageDateControl: Boolean;
+    linksControl: Boolean;
+    motionTracking: Boolean;
+    motionTrackingControl: Boolean;
+    motionTrackingControlOptions: TMotionTrackingControlOptions;
+    panControl: Boolean;
+    panControlOptions: TPanControlOptions;
+    pano: String;
+    position: JSValue;
+    pov: TStreetViewPov;
+    scrollwheel: Boolean;
+    showRoadLabels: Boolean;
+    visible: Boolean;
+    zoom: Double;
+    zoomControl: Boolean;
+    zoomControlOptions: TZoomControlOptions;
+  end;
+
+  TStreetViewPov = class
+  public
+    heading: Double;
+    pitch: Double;
+  end;
+
+  TStreetViewResponse = class
+  public
+    data: TStreetViewPanoramaData;
+  end;
+
+  TStreetViewTileData = class
+  public
+    centerHeading: Double;
+    tileSize: TGoogle.TMaps.TSize;
+    worldSize: TGoogle.TMaps.TSize;
+
+    function getTileUrl(pano: String; tileZoom: Double; tileX: Double; tileY: Double): String; virtual; abstract;
+  end;
+
+  TStyledMapTypeOptions = class
+  public
+    alt: String;
+    maxZoom: Double;
+    minZoom: Double;
+    name: String;
+  end;
+
+  TSymbol = class
+  public
+    anchor: TGoogle.TMaps.TPoint;
+    fillColor: String;
+    fillOpacity: Double;
+    labelOrigin: TGoogle.TMaps.TPoint;
+    path: JSValue;
+    rotation: Double;
+    scale: Double;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokeWeight: Double;
+  end;
+
+  TTimeGoogle = class
+  public
+    text: String;
+    time_zone: String;
+    value: String;
+  end;
+
+  TTrafficLayerOptions = class
+  public
+    autoRefresh: Boolean;
+    map: TGoogle.TMaps.TMap;
+  end;
+
+  TTransitAgency = class
+  public
+    name: String;
+    phone: String;
+    url: String;
+  end;
+
+  TTransitDetails = class
+  public
+    arrival_stop: TTransitStop;
+    arrival_time: TTimeGoogle;
+    departure_stop: TTransitStop;
+    departure_time: TTimeGoogle;
+    headsign: String;
+    headway: Double;
+    line: TTransitLine;
+    num_stops: Double;
+    trip_short_name: String;
+  end;
+
+  TTransitFare = class
+  public
+    currency: String;
+    value: Double;
+  end;
+
+  TTransitLine = class
+  public
+    agencies: TArray<TTransitAgency>;
+    color: String;
+    icon: String;
+    name: String;
+    short_name: String;
+    text_color: String;
+    url: String;
+    vehicle: TTransitVehicle;
+  end;
+
+  TTransitOptions = class
+  public
+    arrivalTime: String;
+    departureTime: String;
+    modes: TArray<TGoogle.TMaps.TTransitMode>;
+    routingPreference: TArray<TGoogle.TMaps.TTransitRoutePreference>;
+  end;
+
+  TTransitStop = class
+  public
+    location: TGoogle.TMaps.TLatLng;
+    name: String;
+  end;
+
+  TTransitVehicle = class
+  public
+    icon: String;
+    local_icon: String;
+    name: String;
+    &type: TGoogle.TMaps.TVehicleType;
+  end;
+
+  TZoomControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TDrawingControlOptions = class
+  public
+    drawingModes: TArray<TGoogle.TMaps.TOverlayType>;
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TDrawingManagerOptions = class
+  public
+    circleOptions: TCircleOptions;
+    drawingControl: Boolean;
+    drawingControlOptions: TDrawingControlOptions;
+    drawingMode: TGoogle.TMaps.TOverlayType;
+    map: TGoogle.TMaps.TMap;
+    markerOptions: TMarkerOptions;
+    polygonOptions: TPolygonOptions;
+    polylineOptions: TPolylineOptions;
+    rectangleOptions: TRectangleOptions;
+  end;
+
+  TOverlayCompleteEvent = class
+  public
+    overlay: JSValue;
+    &type: TGoogle.TMaps.TOverlayType;
+  end;
+
+  TPinOptions = class
+  public
+    background: String;
+    glyphColor: String;
+    scale: Double;
+  end;
+
+  TAutocompleteOptions = class
+  public
+    bounds: JSValue;
+    componentRestrictions: TComponentRestrictions;
+    fields: TArray<String>;
+    strictBounds: Boolean;
+    types: TArray<String>;
+  end;
+
+  TAutocompletePrediction = class
+  public
+    description: String;
+    distance_meters: Double;
+    matched_substrings: TArray<TPredictionSubstring>;
+    place_id: String;
+    structured_formatting: TStructuredFormatting;
+    terms: TArray<TPredictionTerm>;
+    types: TArray<String>;
+  end;
+
+  TAutocompleteResponse = class
+  public
+    predictions: TArray<TAutocompletePrediction>;
+  end;
+
+  TAutocompleteSessionToken = class
+  end;
+
+  TAutocompletionRequest = class
+  public
+    bounds: JSValue;
+    componentRestrictions: TComponentRestrictions;
+    input: String;
+    location: TGoogle.TMaps.TLatLng;
+    offset: Double;
+    origin: JSValue;
+    radius: Double;
+    sessionToken: TAutocompleteSessionToken;
+    types: TArray<String>;
+  end;
+
+  TComponentRestrictions = class
+  public
+    country: TArray<String>;
+  end;
+
+  TFindPlaceFromPhoneNumberRequest = class
+  public
+    fields: TArray<String>;
+    locationBias: JSValue;
+    phoneNumber: String;
+  end;
+
+  TFindPlaceFromQueryRequest = class
+  public
+    fields: TArray<String>;
+    locationBias: JSValue;
+    query: String;
+  end;
+
+  TPredictionSubstring = class
+  public
+    length: Double;
+    offset: Double;
+  end;
+
+  TPredictionTerm = class
+  public
+    offset: Double;
+    value: String;
+  end;
+
+  TQueryAutocompletionRequest = class
+  public
+    bounds: JSValue;
+    input: String;
+    location: TGoogle.TMaps.TLatLng;
+    offset: Double;
+    radius: Double;
+  end;
+
+  TSearchBoxOptions = class
+  public
+    bounds: JSValue;
+  end;
+
+  TStructuredFormatting = class
+  public
+    main_text: String;
+    main_text_matched_substrings: TArray<TPredictionSubstring>;
+    secondary_text: String;
+  end;
+
+  TTextSearchRequest = class
+  public
+    bounds: JSValue;
+    location: JSValue;
+    query: String;
+    radius: Double;
+    &type: String;
+  end;
+
+  THeatmapLayerOptions = class
+  public
+    data: JSValue;
+    dissipating: Boolean;
+    gradient: TArray<String>;
+    map: TGoogle.TMaps.TMap;
+    maxIntensity: Double;
+    opacity: Double;
+    radius: Double;
+  end;
+
+  TWeightedLocation = class
+  public
+    location: TGoogle.TMaps.TLatLng;
+    weight: Double;
+  end;
+
+function InitializeMap(Key: String): TJSPromise;
+
+implementation
+
+var
+  GResolvePromise: TJSPromiseResolver;
+
+procedure MapLoaded;
+begin
+  if Assigned(GResolvePromise) then
+    GResolvePromise(True);
+end;
+
+function InitializeMap(Key: String): TJSPromise;
+begin
+  GResolvePromise := nil;
+
+  MapLoaded;
+
+  Result := TJSPromise.New(
+    procedure(Resolve, Reject: TJSPromiseResolver)
+    var
+      Script: TJSHTMLScriptElement;
+
+    begin
+      GResolvePromise := Resolve;
+      Script := TJSHTMLScriptElement(document.createElement('script'));
+      Script.text := 'function GoogleMapLoaded(){pas["Google.Maps"].$impl.MapLoaded();}';
+
+      document.head.appendChild(Script);
+
+      Script := TJSHTMLScriptElement(document.createElement('script'));
+      Script.OnLoad :=
+        function (Event: TEventListenerEvent): Boolean
+        begin
+          Resolve(True);
+
+          Result := True;
+        end;
+      Script.src := Format('https://maps.googleapis.com/maps/api/js?key=%s&callback=GoogleMapLoaded', [Key]);
+      Script.type_ := 'text/javascript';
+
+      document.head.appendChild(Script);
+    end);
+end;
+
+{ TLatLngLiteral }
+
+constructor TLatLngLiteral.Create(Lat, Lng: Double);
+begin
+  Self.Lat := Lat;
+  Self.Lng := Lng;
+end;
+
+{ TMapOptions }
+
+function TMapOptions.GetfullscreenControlOptions: TFullscreenControlOptions;
+begin
+  if not Assigned(FfullscreenControlOptions) then
+    FfullscreenControlOptions := TFullscreenControlOptions.Create;
+
+  Result := FfullscreenControlOptions;
+end;
+
+function TMapOptions.GetmapTypeControlOptions: TMapTypeControlOptions;
+begin
+  if not Assigned(FmapTypeControlOptions) then
+    FmapTypeControlOptions := TMapTypeControlOptions.Create;
+
+  Result := FmapTypeControlOptions;
+end;
+
+function TMapOptions.GetpanControlOptions: TPanControlOptions;
+begin
+  if not Assigned(FpanControlOptions) then
+    FpanControlOptions := TPanControlOptions.Create;
+
+  Result := FpanControlOptions;
+end;
+
+function TMapOptions.GetRestriction: TMapRestriction;
+begin
+  if not Assigned(FRestriction) then
+    FRestriction := TMapRestriction.Create;
+
+  Result := FRestriction;
+end;
+
+function TMapOptions.GetRotateControlOptions: TRotateControlOptions;
+begin
+  if not Assigned(FRotateControlOptions) then
+    FRotateControlOptions := TRotateControlOptions.Create;
+
+  Result := FRotateControlOptions;
+end;
+
+function TMapOptions.GetScaleControlOptions: TScaleControlOptions;
+begin
+  if not Assigned(FScaleControlOptions) then
+    FScaleControlOptions := TScaleControlOptions.Create;
+
+  Result := FScaleControlOptions;
+end;
+
+function TMapOptions.GetZoomControlOptions: TZoomControlOptions;
+begin
+  if not Assigned(FZoomControlOptions) then
+    FZoomControlOptions := TZoomControlOptions.Create;
+
+  Result := FZoomControlOptions;
+end;
+
+function TMapOptions.GetStreetViewControlOptions: TStreetViewControlOptions;
+begin
+  if not Assigned(FStreetViewControlOptions) then
+    FStreetViewControlOptions := TStreetViewControlOptions.Create;
+
+  Result := FStreetViewControlOptions;
+end;
+
+end.
+
diff --git a/packages/maps/Leaflet.Maps.pas b/packages/maps/Leaflet.Maps.pas
new file mode 100644
index 00000000..e945a05e
--- /dev/null
+++ b/packages/maps/Leaflet.Maps.pas
@@ -0,0 +1,1849 @@
+unit Leaflet.Maps;
+
+interface
+
+{$modeswitch externalclass}
+
+uses JS, Web, SysUtils, GeoJSON;
+
+type
+  TAttributionOptions = class;
+  TBaseIconOptions = class;
+  TCircleMarkerOptions = class;
+  TControlOptions = class;
+  TDefaultMapPanes = class;
+  TDivIconOptions = class;
+  TDivOverlayOptions = class;
+  TDragEndEvent = class;
+  TError = class;
+  TErrorEvent = class;
+  TFitBoundsOptions = class;
+  TGeoJSONEvent = class;
+  TGeoJSONOptions = class;
+  TGridLayerOptions = class;
+  TIconOptions = class;
+  TImageOverlayOptions = class;
+  TInteractiveLayerOptions = class;
+  TInvalidateSizeOptions = class;
+  TLatLngLiteral = class;
+  TLayerEvent = class;
+  TLayerOptions = class;
+  TLayersControlEvent = class;
+  TLayersObject = class;
+  TLayersOptions = class;
+  TLeafletEvent = class;
+  TLeafletKeyboardEvent = class;
+  TLeafletMouseEvent = class;
+  TLocateOptions = class;
+  TLocationEvent = class;
+  TMapOptions = class;
+  TMarkerOptions = class;
+  TPanInsideOptions = class;
+  TPanOptions = class;
+  TPathOptions = class;
+  TPolylineOptions = class;
+  TPopupEvent = class;
+  TPopupOptions = class;
+  TRendererOptions = class;
+  TResizeEvent = class;
+  TScaleOptions = class;
+  TTileErrorEvent = class;
+  TTileEvent = class;
+  TTileLayerOptions = class;
+  TTooltipEvent = class;
+  TTooltipOptions = class;
+  TVideoOverlayOptions = class;
+  TWMSOptions = class;
+  TWMSParams = class;
+  TZoomAnimEvent = class;
+  TZoomControlOptions = class;
+  TZoomOptions = class;
+  TZoomPanOptions = class;
+
+  TLatLngTuple = array[0..1] of Double;
+  TPointTuple = array[0..1] of Double;
+
+  TBoundsLiteral = array[0..1] of TPointTuple;
+
+  TLeaflet = class external name 'L'
+  public type
+    TBounds = class;
+    TLatLng = class;
+    TLatLngBounds = class;
+    TLayerGroup = class;
+    TMap = class;
+    TPoint = class;
+    TPopup = class;
+    TTooltip = class;
+
+    TLatLngBoundsLiteral = TArray<TLatLngTuple>;
+
+    TClass = class external name 'Class'
+    public
+      class function addInitHook(initHookFn: TProc): TClass; overload;
+      class function addInitHook(methodName: String): TClass; varargs; overload;
+      class function extend(props: JSValue): TClass;
+      class function include(props: JSValue): TClass;
+      class function mergeOptions(props: JSValue): TClass;
+    end;
+
+    TTransformation = class external name 'Transformation'
+    public
+      constructor new(a, b, c, d: Double);
+
+      function transform(point: TPoint): TPoint; overload;
+      function transform(point: TPoint; scale: Double): TPoint; overload;
+      function untransform(point: TPoint): TPoint; overload;
+      function untransform(point: TPoint; scale: Double): TPoint; overload;
+    end;
+
+    TLineUtil = class external name 'LineUtil'
+    public
+      function simplify(points: TArray<TPoint>; tolerance: Double): TArray<TPoint>;
+      function pointToSegmentDistance(p, p1,p2: TPoint): Double;
+      function closestPointOnSegment(p, p1, p2: TPoint): TPoint;
+      function isFlat(latlngs: TArray<TLatLng>): Boolean; overload;
+      function isFlat(latlngs: TArray<TLatLngLiteral>): Boolean; overload;
+      function isFlat(latlngs: TArray<TLatLngTuple>): Boolean; overload;
+      function clipSegment(a, b: TPoint; bounds: TBounds): TArray<TPoint>; overload;
+      function clipSegment(a, b: TPoint; bounds: TBounds; useLastCode: Boolean): TArray<TPoint>; overload;
+      function clipSegment(a, b: TPoint; bounds: TBounds; useLastCode, round: Boolean): TArray<TPoint>; overload;
+    end;
+
+    TPolyUtil = class external name 'PolyUtil'
+    public
+      function clipPolygon(points: TArray<TPoint>; bounds: TBounds): TArray<TPoint>; overload;
+      function clipPolygon(points: TArray<TPoint>; bounds: TBoundsLiteral): TArray<TPoint>; overload;
+      function clipPolygon(points: TArray<TPoint>; bounds: TBounds; round: Boolean): TArray<TPoint>; overload;
+      function clipPolygon(points: TArray<TPoint>; bounds: TBoundsLiteral; round: Boolean): TArray<TPoint>; overload;
+    end;
+
+    TDomUtil = class external name 'DomUtil'
+    public
+      TRANSFORM: String;
+      TRANSITION: String;
+      TRANSITION_END: String;
+
+      function get(element: String): TJSHTMLElement; overload;
+      function get(element: TJSHTMLElement): TJSHTMLElement; overload;
+      function getStyle(el: TJSHTMLElement; styleAttrib: String): String;
+      function create(tagName: String): TJSHTMLElement; overload;
+      function create(tagName: String; className: String): TJSHTMLElement; overload;
+      function create(tagName: String; className: String; container: TJSHTMLElement): TJSHTMLElement; overload;
+      procedure remove(el: TJSHTMLElement);
+      procedure empty(el: TJSHTMLElement);
+      procedure toFront(el: TJSHTMLElement);
+      procedure toBack(el: TJSHTMLElement);
+      function hasClass(el: TJSHTMLElement; name: String): Boolean;
+      procedure addClass(el: TJSHTMLElement; name: String);
+      procedure removeClass(el: TJSHTMLElement; name: String);
+      procedure setClass(el: TJSHTMLElement; name: String);
+      function getClass(el: TJSHTMLElement): String;
+      procedure setOpacity(el: TJSHTMLElement; opacity: Double);
+      function testProp(props: TArray<String>): String;
+      procedure setTransform(el: TJSHTMLElement; offset: TPoint; scale: Double);
+      procedure setPosition(el: TJSHTMLElement; position: TPoint);
+      function getPosition(el: TJSHTMLElement): TPoint;
+      procedure disableTextSelection();
+      procedure enableTextSelection();
+      procedure disableImageDrag();
+      procedure enableImageDrag();
+      procedure preventOutline(el: TJSHTMLElement);
+      procedure restoreOutline();
+    end;
+
+    TCRS = class external name 'CRS'
+    public class var
+      EPSG3395: TCRS;
+      EPSG3857: TCRS;
+      EPSG4326: TCRS;
+      EPSG900913: TCRS;
+      Earth: TCRS;
+      Simple: TCRS;
+    public
+      code: String;
+      wrapLng: TArray<Double>;
+      wrapLat: TArray<Double>;
+      infinite: Boolean;
+
+      function latLngToPoint(latlng: TLatLng; zoom: Double): TPoint; overload;
+      function latLngToPoint(latlng: TLatLngLiteral; zoom: Double): TPoint; overload;
+      function latLngToPoint(latlng: TLatLngTuple; zoom: Double): TPoint; overload;
+      function pointToLatLng(point: TPoint; zoom: Double): TLatLng; overload;
+      function pointToLatLng(point: TPointTuple; zoom: Double): TLatLng; overload;
+      function project(latlng: TLatLng): TPoint; overload;
+      function project(latlng: TLatLngLiteral): TPoint; overload;
+      function unproject(point: TPoint): TLatLng; overload;
+      function unproject(point: TPointTuple): TLatLng; overload;
+      function scale(zoom: Double): Double;
+      function zoom(scale: Double): Double;
+      function getProjectedBounds(zoom: Double): TBounds;
+      function distance(latlng1, latlng2: TLatLng): Double; overload;
+      function distance(latlng1, latlng2: TLatLngLiteral): Double; overload;
+      function distance(latlng1, latlng2: TLatLngTuple): Double; overload;
+      function wrapLatLng(latlng: TLatLng): TLatLng; overload;
+      function wrapLatLng(latlng: TLatLngLiteral): TLatLng; overload;
+    end;
+
+    TProjection = class external name 'Projection'
+    public
+      bounds: TBounds;
+
+      const LonLat: TProjection;
+      const Mercator: TProjection;
+      const SphericalMercator: TProjection;
+
+      function project(latlng: TLatLng): TPoint; overload;
+      function project(latlng: TLatLngLiteral): TPoint; overload;
+      function unproject(point: TPoint): TLatLng; overload;
+      function unproject(point: TPointTuple): TLatLng; overload;
+    end;
+
+    TLatLng = class external name 'LatLng'
+    public
+      lat: Double;
+      lng: Double;
+      alt: Double;
+
+      constructor new(latitude, longitude: Double); overload;
+      constructor new(latitude, longitude, altitude: Double); overload;
+
+      function clone(): TLatLng;
+      function distanceTo(otherLatLng: TLatLng): Double; overload;
+      function distanceTo(otherLatLng: TLatLngLiteral): Double; overload;
+      function distanceTo(otherLatLng: TLatLngTuple): Double; overload;
+      function equals(otherLatLng: TLatLng): Boolean; overload;
+      function equals(otherLatLng: TLatLng; maxMargin: Double): Boolean; overload;
+      function equals(otherLatLng: TLatLngLiteral): Boolean; overload;
+      function equals(otherLatLng: TLatLngLiteral; maxMargin: Double): Boolean; overload;
+      function equals(otherLatLng: TLatLngTuple): Boolean; overload;
+      function equals(otherLatLng: TLatLngTuple; maxMargin: Double): Boolean; overload;
+      function toBounds(sizeInMeters: Double): TLatLngBounds;
+      function toString(): String;
+      function wrap(): TLatLng;
+    end;
+
+    TLatLngBounds = class external name 'LatLngBounds'
+    public
+      constructor new(southWest, northEast: TLatLng); overload;
+      constructor new(southWest, northEast: TLatLngLiteral); overload;
+      constructor new(southWest, northEast: TLatLngTuple); overload;
+      constructor new(latlngs: TLatLngBoundsLiteral); overload;
+
+      function extend(latlngOrBounds: TLatLng): TLatLngBounds; overload;
+      function extend(latlngOrBounds: TLatLngLiteral): TLatLngBounds; overload;
+      function extend(latlngOrBounds: TLatLngTuple): TLatLngBounds; overload;
+      function extend(latlngOrBounds: TLatLngBounds): TLatLngBounds; overload;
+      function extend(latlngOrBounds: TLatLngBoundsLiteral): TLatLngBounds; overload;
+      function pad(bufferRatio: Double): TLatLngBounds; // does this modify the current instance or does it return a new one?
+      function getCenter(): TLatLng;
+      function getSouthWest(): TLatLng;
+      function getNorthEast(): TLatLng;
+      function getNorthWest(): TLatLng;
+      function getSouthEast(): TLatLng;
+      function getWest(): Double;
+      function getSouth(): Double;
+      function getEast(): Double;
+      function getNorth(): Double;
+      function contains(otherBoundsOrLatLng: TLatLngBounds): Boolean; overload;
+      function contains(otherBoundsOrLatLng: TLatLngBoundsLiteral): Boolean; overload;
+      function contains(otherBoundsOrLatLng: TLatLng): Boolean; overload;
+      function contains(otherBoundsOrLatLng: TLatLngLiteral): Boolean; overload;
+      function contains(otherBoundsOrLatLng: TLatLngTuple): Boolean; overload;
+      function intersects(otherBounds: TLatLngBounds): Boolean; overload;
+      function intersects(otherBounds: TLatLngBoundsLiteral): Boolean; overload;
+      function overlaps(otherBounds: TLatLngBounds): Boolean; overload;
+      function overlaps(otherBounds: TLatLngBoundsLiteral): Boolean; overload;
+      function toBBoxString(): String;
+      function equals(otherBounds: TLatLngBounds): Boolean; overload;
+      function equals(otherBounds: TLatLngBoundsLiteral): Boolean; overload;
+      function isValid(): Boolean;
+    end;
+
+    TPoint = class external name 'TPoint'
+    public
+      x: Double;
+      y: Double;
+
+      constructor new(x, y: Double); overload;
+      constructor new(x, y: Double; round: Boolean); overload;
+      function clone(): TPoint;
+      function add(otherPoint: TPoint): TPoint; overload;
+      function add(otherPoint: TPointTuple): TPoint; overload;
+      function subtract(otherPoint: TPoint): TPoint; overload;
+      function subtract(otherPoint: TPointTuple): TPoint; overload;
+      function divideBy(num: Double): TPoint;
+      function multiplyBy(num: Double): TPoint;
+      function scaleBy(scale: TPoint): TPoint; overload;
+      function scaleBy(scale: TPointTuple): TPoint; overload;
+      function unscaleBy(scale: TPoint): TPoint; overload;
+      function unscaleBy(scale: TPointTuple): TPoint; overload;
+      function round(): TPoint;
+      function floor(): TPoint;
+      function ceil(): TPoint;
+      function distanceTo(otherPoint: TPoint): Double; overload;
+      function distanceTo(otherPoint: TPointTuple): Double; overload;
+      function equals(otherPoint: TPoint): Boolean; overload;
+      function equals(otherPoint: TPointTuple): Boolean; overload;
+      function contains(otherPoint: TPoint): Boolean; overload;
+      function contains(otherPoint: TPointTuple): Boolean; overload;
+      function toString(): String;
+    end;
+
+    TCoords = class external name 'Coords' (TPoint)
+    public
+      z: Double;
+    end;
+
+    TBounds = class external name 'Bounds'
+    public
+      min: TPoint;
+      max: TPoint;
+
+      constructor new(points: TArray<TPoint>); overload;
+      constructor new(points: TBoundsLiteral); overload;
+      constructor new(topLeft, bottomRight: TPoint); overload;
+      constructor new(topLeft, bottomRight: TPointTuple); overload;
+      function extend(point: TPoint): TBounds; overload;
+      function extend(point: TPointTuple): TBounds; overload;
+      function getCenter(round: Boolean): TPoint;
+      function getBottomLeft(): TPoint;
+      function getBottomRight(): TPoint;
+      function getTopLeft(): TPoint;
+      function getTopRight(): TPoint;
+      function getSize(): TPoint;
+      function contains(pointOrBounds: TBounds): Boolean; overload;
+      function contains(pointOrBounds: TBoundsLiteral): Boolean; overload;
+      function contains(pointOrBounds: TPoint): Boolean; overload;
+      function contains(pointOrBounds: TPointTuple): Boolean; overload;
+      function intersects(otherBounds: TBounds): Boolean; overload;
+      function intersects(otherBounds: TBoundsLiteral): Boolean; overload;
+      function overlaps(otherBounds: TBounds): Boolean; overload;
+      function overlaps(otherBounds: TBoundsLiteral): Boolean; overload;
+    end;
+
+    // Event handler types
+    TDragEndEventHandlerFn = TProc<TDragEndEvent>;
+    TErrorEventHandlerFn = TProc<TErrorEvent>;
+    TLayerEventHandlerFn = TProc<TLayerEvent>;
+    TLayersControlEventHandlerFn = TProc<TLayersControlEvent>;
+    TLeafletEventHandlerFn = TProc<TLeafletEvent>;
+    TLeafletKeyboardEventHandlerFn = TProc<TLeafletKeyboardEvent>;
+    TLeafletMouseEventHandlerFn = TProc<TLeafletMouseEvent>;
+    TLocationEventHandlerFn = TProc<TLocationEvent>;
+    TPopupEventHandlerFn = TProc<TPopupEvent>;
+    TResizeEventHandlerFn = TProc<TResizeEvent>;
+    TTileErrorEventHandlerFn = TProc<TTileErrorEvent>;
+    TTileEventHandlerFn = TProc<TTileEvent>;
+    TTooltipEventHandlerFn = TProc<TTooltipEvent>;
+    TZoomAnimEventHandlerFn = TProc<TZoomAnimEvent>;
+
+    TLeafletEventHandlerFnMap = class external name 'LeafletEventHandlerFnMap'
+    public
+      baselayerchange: TLayersControlEventHandlerFn;
+      overlayadd: TLayersControlEventHandlerFn;
+      overlayremove: TLayersControlEventHandlerFn;
+
+      layeradd: TLayerEventHandlerFn;
+      layerremove: TLayerEventHandlerFn;
+
+      zoomlevelschange: TLeafletEventHandlerFn;
+      unload: TLeafletEventHandlerFn;
+      viewreset: TLeafletEventHandlerFn;
+      load: TLeafletEventHandlerFn;
+      zoomstart: TLeafletEventHandlerFn;
+      movestart: TLeafletEventHandlerFn;
+      zoom: TLeafletEventHandlerFn;
+      move: TLeafletEventHandlerFn;
+      zoomend: TLeafletEventHandlerFn;
+      moveend: TLeafletEventHandlerFn;
+      autopanstart: TLeafletEventHandlerFn;
+      dragstart: TLeafletEventHandlerFn;
+      drag: TLeafletEventHandlerFn;
+      add: TLeafletEventHandlerFn;
+      remove: TLeafletEventHandlerFn;
+      loading: TLeafletEventHandlerFn;
+      error: TLeafletEventHandlerFn;
+      update: TLeafletEventHandlerFn;
+      down: TLeafletEventHandlerFn;
+      predrag: TLeafletEventHandlerFn;
+
+      resize: TResizeEventHandlerFn;
+
+      popupopen: TPopupEventHandlerFn;
+      popupclose: TPopupEventHandlerFn;
+
+      tooltipopen: TTooltipEventHandlerFn;
+      tooltipclose: TTooltipEventHandlerFn;
+
+      locationerror: TErrorEventHandlerFn;
+
+      locationfound: TLocationEventHandlerFn;
+
+      click: TLeafletMouseEventHandlerFn;
+      dblclick: TLeafletMouseEventHandlerFn;
+      mousedown: TLeafletMouseEventHandlerFn;
+      mouseup: TLeafletMouseEventHandlerFn;
+      mouseover: TLeafletMouseEventHandlerFn;
+      mouseout: TLeafletMouseEventHandlerFn;
+      mousemove: TLeafletMouseEventHandlerFn;
+      contextmenu: TLeafletMouseEventHandlerFn;
+      preclick: TLeafletMouseEventHandlerFn;
+
+      keypress: TLeafletKeyboardEventHandlerFn;
+      keydown: TLeafletKeyboardEventHandlerFn;
+      keyup: TLeafletKeyboardEventHandlerFn;
+
+      zoomanim: TZoomAnimEventHandlerFn;
+
+      dragend: TDragEndEventHandlerFn;
+
+      tileunload: TTileEventHandlerFn;
+      tileloadstart: TTileEventHandlerFn;
+      tileload: TTileEventHandlerFn;
+
+      tileerror: TTileErrorEventHandlerFn;
+    end;
+
+    TEvented = class external name 'Evented' (TClass)
+    public
+      function addEventListener(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TTileErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function addEventParent(obj: TEvented): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TTileErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function clearAllEventListeners(): TEvented; overload;
+      function fire(&type: String; data: JSValue): TEvented; overload;
+      function fire(&type: String; data: JSValue; propagate: Boolean): TEvented; overload;
+      function fireEvent(&type: String; data: JSValue): TEvented; overload;
+      function fireEvent(&type: String; data: JSValue; propagate: Boolean): TEvented; overload;
+      function hasEventListeners(&type: String): Boolean;
+      function listens(&type: String): Boolean; overload;
+      function off(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TTileErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(): TEvented; overload;
+      function off(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function &on(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TTileErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function once(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function removeEventListener(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TTileErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function removeEventParent(obj: TEvented): TEvented; overload;
+    end;
+
+    TDraggable = class external name 'Draggable' (TEvented)
+    public
+      constructor new(element, dragStartTarget: TJSHTMLElement; preventOutline: Boolean);
+
+      procedure enable();
+      procedure disable();
+      procedure finishDrag();
+    end;
+
+    TLayer = class external name 'Layer' (TEvented)
+    public
+      constructor new(options: TLayerOptions);
+
+      function addTo(map: TMap): TLayer; overload;
+      function addTo(map: TLayerGroup): TLayer; overload;
+      function remove(): TLayer;
+      function removeFrom(map: TMap): TLayer;
+      function getPane(name: String): TJSHTMLElement;
+
+      // Popup methods
+      function bindPopup(content: TFunc<TLayer, String>; options: TPopupOptions): TLayer; overload;
+      function bindPopup(content: TFunc<TLayer, TJSHTMLElement>; options: TPopupOptions): TLayer; overload;
+      function bindPopup(content: String; options: TPopupOptions): TLayer; overload;
+      function bindPopup(content: TJSHTMLElement; options: TPopupOptions): TLayer; overload;
+      function bindPopup(content: TPopup; options: TPopupOptions): TLayer; overload;
+      function unbindPopup(): TLayer;
+      function openPopup(latlng: TLatLng): TLayer; overload;
+      function openPopup(latlng: TLatLngLiteral): TLayer; overload;
+      function openPopup(latlng: TLatLngTuple): TLayer; overload;
+      function closePopup(): TLayer;
+      function togglePopup(): TLayer;
+      function isPopupOpen(): Boolean;
+      function setPopupContent(content: String): TLayer; overload;
+      function setPopupContent(content: TJSHTMLElement): TLayer; overload;
+      function setPopupContent(content: TPopup): TLayer; overload;
+      function getPopup(): TPopup;
+
+      // Tooltip methods
+      function bindTooltip(content: TFunc<TLayer, String>; options: TTooltipOptions): TLayer; overload;
+      function bindTooltip(content: TFunc<TLayer, TJSHTMLElement>; options: TTooltipOptions): TLayer; overload;
+      function bindTooltip(content: TTooltip; options: TTooltipOptions): TLayer; overload;
+      function bindTooltip(content: String; options: TTooltipOptions): TLayer; overload;
+      function bindTooltip(content: TJSHTMLElement; options: TTooltipOptions): TLayer; overload;
+      function unbindTooltip(): TLayer;
+      function openTooltip(latlng: TLatLng): TLayer; overload;
+      function openTooltip(latlng: TLatLngLiteral): TLayer; overload;
+      function openTooltip(latlng: TLatLngTuple): TLayer; overload;
+      function closeTooltip(): TLayer;
+      function toggleTooltip(): TLayer;
+      function isTooltipOpen(): Boolean;
+      function setTooltipContent(content: String): TLayer; overload;
+      function setTooltipContent(content: TJSHTMLElement): TLayer; overload;
+      function setTooltipContent(content: TTooltip): TLayer; overload;
+      function getTooltip(): TTooltip;
+
+      // Extension methods
+      function onAdd(map: TMap): TLayer;
+      function onRemove(map: TMap): TLayer;
+      function getEvents(): TJSObject;
+      function getAttribution(): String;
+      function beforeAdd(map: TMap): TLayer;
+    end;
+
+    TDoneCallback = TProc<TError, TJSHTMLElement>;
+
+    TGridLayer = class external name 'GridLayer' (TLayer)
+    public
+      constructor new(options: TGridLayerOptions);
+      function bringToFront(): TGridLayer;
+      function bringToBack(): TGridLayer;
+      function getContainer(): TJSHTMLElement;
+      function setOpacity(opacity: Double): TGridLayer;
+      function setZIndex(zIndex: Double): TGridLayer;
+      function isLoading(): Boolean;
+      function redraw(): TGridLayer;
+      function getTileSize(): TPoint;
+    end;
+
+    TTileLayer = class external name 'TileLayer' (TGridLayer)
+    public type
+      TWMS = class external name 'WMS' (TTileLayer)
+      public
+        wmsParams: TWMSParams;
+        options: TWMSOptions;
+
+        constructor new(baseUrl: String; options: TWMSOptions);
+        function setParams(params: TWMSParams; noRedraw: Boolean): TWMS;
+      end;
+    public
+      options: TTileLayerOptions;
+
+      constructor new(urlTemplate: String; options: TTileLayerOptions);
+      function setUrl(url: String; noRedraw: Boolean): TTileLayer;
+      function getTileUrl(coords: TCoords): String;
+      function wms(baseUrl: String; options: TWMSOptions): TWMS;
+    end;
+
+    TImageOverlay = class external name 'ImageOverlay' (TLayer)
+    public
+      options: TImageOverlayOptions;
+
+      constructor new(imageUrl: String; bounds: TLatLngBounds; options: TImageOverlayOptions); overload;
+      constructor new(imageUrl: String; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions); overload;
+      function setOpacity(opacity: Double): TImageOverlay;
+      function bringToFront(): TImageOverlay;
+      function bringToBack(): TImageOverlay;
+      function setUrl(url: String): TImageOverlay;
+
+      function setBounds(bounds: TLatLngBounds): TImageOverlay;
+
+      function setZIndex(value: Double): TImageOverlay;
+
+      function getBounds(): TLatLngBounds;
+
+      function getElement(): TJSHTMLImageElement;
+    end;
+
+    TSVGOverlay = class external name 'SVGOverlay' (TLayer)
+    public
+      options: TImageOverlayOptions;
+
+      constructor new(svgImage: String; bounds: TLatLngBounds; options: TImageOverlayOptions); overload;
+      constructor new(svgImage: String; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions); overload;
+      constructor new(svgImage: TJSHTMLElement; bounds: TLatLngBounds; options: TImageOverlayOptions); overload;
+      constructor new(svgImage: TJSHTMLElement; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions); overload;
+
+      function setOpacity(opacity: Double): TSVGOverlay;
+      function bringToFront(): TSVGOverlay;
+      function bringToBack(): TSVGOverlay;
+      function setUrl(url: String): TSVGOverlay;
+
+      function setBounds(bounds: TLatLngBounds): TSVGOverlay;
+
+      function setZIndex(value: Double): TSVGOverlay;
+
+      function getBounds(): TLatLngBounds;
+
+      function getElement(): TJSHTMLElement;
+    end;
+
+    TVideoOverlay = class external name 'VideoOverlay' (TLayer)
+    public
+      options: TVideoOverlayOptions;
+
+      constructor new(video: String; bounds: TLatLngBounds; options: TVideoOverlayOptions); overload;
+      constructor new(video: String; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions); overload;
+      constructor new(video: TArray<String>; bounds: TLatLngBounds; options: TVideoOverlayOptions); overload;
+      constructor new(video: TArray<String>; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions); overload;
+      constructor new(video: TJSHTMLVideoElement; bounds: TLatLngBounds; options: TVideoOverlayOptions); overload;
+      constructor new(video: TJSHTMLVideoElement; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions); overload;
+
+      function setOpacity(opacity: Double): TVideoOverlay;
+      function bringToFront(): TVideoOverlay;
+      function bringToBack(): TVideoOverlay;
+      function setUrl(url: String): TVideoOverlay;
+
+      function setBounds(bounds: TLatLngBounds): TVideoOverlay;
+
+      function getBounds(): TLatLngBounds;
+
+      function getElement(): TJSHTMLVideoElement;
+    end;
+
+    TPath = class external name 'Path' abstract (TLayer)
+    public
+      options: TPathOptions;
+
+      function redraw(): TPath;
+      function setStyle(style: TPathOptions): TPath;
+      function bringToFront(): TPath;
+      function bringToBack(): TPath;
+      function getElement(): TJSHTMLElement;
+    end;
+
+    TPolyline = class external name 'Polyline' (TPath)
+    public
+      feature: TFeature;
+      options: TPolylineOptions;
+
+      constructor new(latlngs: TArray<TLatLng>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TArray<TLatLng>>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TLatLngLiteral>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TArray<TLatLngLiteral>>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TLatLngTuple>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TArray<TLatLngTuple>>; options: TPolylineOptions); overload;
+
+      function toGeoJSON(precision: Double): TFeature;
+      function getLatLngs(): JSValue;
+      function setLatLngs(latlngs: TArray<TLatLng>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TLatLngLiteral>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TLatLngTuple>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TLatLng>>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TLatLngLiteral>>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TLatLngTuple>>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TArray<TLatLng>>>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TArray<TLatLngLiteral>>>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TArray<TLatLngTuple>>>): TPolyline; overload;
+      function isEmpty(): Boolean;
+      function getCenter(): TLatLng;
+      function getBounds(): TLatLngBounds;
+      function addLatLng(latlng: TLatLng): TPolyline; overload;
+      function addLatLng(latlng: TLatLngLiteral): TPolyline; overload;
+      function addLatLng(latlng: TLatLngTuple): TPolyline; overload;
+      function addLatLng(latlng: TLatLng; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TLatLngLiteral; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TLatLngTuple; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLngLiteral>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLngTuple>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLng>; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLngLiteral>; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLngTuple>; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function closestLayerPoint(p: TPoint): TPoint;
+    end;
+
+    TPolygon = class external name 'Polygon' (TPolyline)
+    public
+      constructor new(latlngs: TArray<TLatLng>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TArray<TLatLng>>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TLatLngLiteral>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TArray<TLatLngLiteral>>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TLatLngTuple>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TArray<TLatLngTuple>>; options: TPolylineOptions); overload;
+    end;
+
+    TRectangle = class external name 'Rectangle' (TPolygon)
+    public
+      constructor new(latLngBounds: TLatLngBounds; options: TPolylineOptions); overload;
+      constructor new(latLngBounds: TLatLngBoundsLiteral; options: TPolylineOptions); overload;
+
+      function setBounds(latLngBounds: TLatLngBounds): TRectangle; overload;
+      function setBounds(latLngBounds: TLatLngBoundsLiteral): TRectangle; overload;
+    end;
+
+    TCircleMarker = class external name 'CircleMarker' (TPath)
+    public
+      options: TCircleMarkerOptions;
+      feature: TFeature;
+
+      constructor new(latlng: TLatLng; options: TCircleMarkerOptions); overload;
+      constructor new(latlng: TLatLngLiteral; options: TCircleMarkerOptions); overload;
+      constructor new(latlng: TLatLngTuple; options: TCircleMarkerOptions); overload;
+
+      function toGeoJSON(precision: Double): TFeature;
+      function setLatLng(latLng: JSValue): TCircleMarker;
+      function getLatLng(): TLatLng;
+      function setRadius(radius: Double): TCircleMarker;
+      function getRadius(): Double;
+    end;
+
+    TCircle = class external name 'Circle' (TCircleMarker)
+    public
+      constructor new(latlng: TLatLng; options: TCircleMarkerOptions); overload;
+      constructor new(latlng: TLatLngLiteral; options: TCircleMarkerOptions); overload;
+      constructor new(latlng: TLatLngTuple; options: TCircleMarkerOptions); overload;
+
+      function getBounds(): TLatLngBounds;
+    end;
+
+    TRenderer = class external name 'Renderer' (TLayer)
+    public
+      options: TRendererOptions;
+
+      constructor new(options: TRendererOptions);
+    end;
+
+    TSVG = class external name 'SVG' (TRenderer)
+    public
+      class function create(name: String): TJSHTMLElement;
+      class function pointsToPath(rings: TPoint; close: Boolean): String; overload;
+      class function pointsToPath(rings: TArray<TPointTuple>; close: Boolean): String; overload;
+    end;
+
+    TCanvas = class external name 'Canvas' (TRenderer)
+    end;
+
+    TLayerGroup = class external name 'LayerGroup' (TLayer)
+    public
+      feature: JSValue;
+
+      constructor new(layers: TArray<TLayer>); overload;
+      constructor new(layers: TArray<TLayer>; options: TLayerOptions); overload;
+      constructor new; overload;
+
+      function addLayer(layer: TLayer): TLayerGroup;
+      function clearLayers(): TLayerGroup;
+      function eachLayer(fn: TProc<TLayer>; context: JSValue): TLayerGroup;
+      function getLayer(id: Double): TLayer;
+      function getLayerId(layer: TLayer): Double;
+      function getLayers(): TArray<TLayer>;
+      function hasLayer(layer: TLayer): Boolean;
+      function invoke(methodName: String): TLayerGroup; varargs;
+      function removeLayer(layer: TLayer): TLayerGroup;
+      function setZIndex(zIndex: Double): TLayerGroup;
+      function toGeoJSON(precision: Double): JSValue; overload;
+      function toGeoJSON: JSValue; overload;
+    end;
+
+    TFeatureGroup = class external name 'FeatureGroup' (TLayerGroup)
+    public
+      function bringToBack(): TFeatureGroup;
+      function bringToFront(): TFeatureGroup;
+      function getBounds(): TLatLngBounds;
+      function setStyle(style: TPathOptions): TFeatureGroup;
+    end;
+
+    TStyleFunction = TFunc<TFeature, TPathOptions>;
+
+    TGeoJSON = class external name 'GeoJSON' (TFeatureGroup)
+    public
+      options: TGeoJSONOptions;
+
+      constructor new(geojson: TGeoJsonObject; options: TGeoJSONOptions);
+
+      class function asFeature(geojson: TFeature): TFeature;
+      class function coordsToLatLng(coords: TArray<Double>): TLatLng;
+      class function coordsToLatLngs(coords: TArray<JSValue>; levelsDeep: Double; coordsToLatLng: TFunc<TArray<Double>, TLatLng>): TArray<JSValue>; // Using TArray<JSValue> to avoid artificially limiting valid calls
+      class function geometryToLayer(featureData: TFeature; options: TGeoJSONOptions): TLayer;
+      class function latLngToCoords(latlng: TLatLng): TArray<Double>;
+      class function latLngsToCoords(latlngs: TArray<JSValue>; levelsDeep: Double; closed: Boolean): TArray<JSValue>;  // Using TArray<JSValue> to avoid artificially limiting valid calls
+
+      function addData(data: TGeoJsonObject): TLayer;
+      function resetStyle(layer: TLayer): TLayer;
+      function setStyle(style: TPathOptions): TGeoJSON; overload;
+      function setStyle(style: TStyleFunction): TGeoJSON; overload;
+    end;
+
+    TControl = class external name 'Control' (TClass)
+    public type
+      TZoom = class external name 'Zoom' (TControl)
+      public
+        options: TZoomControlOptions;
+        constructor new(options: TZoomControlOptions);
+      end;
+
+      TAttribution = class external name 'Attribution' (TControl)
+      public
+        options: TAttributionOptions;
+
+        constructor new(options: TAttributionOptions);
+        function setPrefix(prefix: String): TAttribution;
+        function addAttribution(text: String): TAttribution;
+        function removeAttribution(text: String): TAttribution;
+      end;
+
+      TLayers = class external name 'Layers' (TControl)
+      public
+        options: TLayersOptions;
+
+        constructor new; overload;
+        constructor new(baseLayers: TLayersObject); overload;
+        constructor new(baseLayers, overlays: TLayersObject); overload;
+        constructor new(baseLayers, overlays: TLayersObject; options: TLayersOptions); overload;
+
+        function addBaseLayer(layer: TLayer; name: String): TLayers;
+        function addOverlay(layer: TLayer; name: String): TLayers;
+        function removeLayer(layer: TLayer): TLayers;
+        function expand(): TLayers;
+        function collapse(): TLayers;
+      end;
+
+      TScale = class external name 'Scale' (TControl)
+      public
+        options: TScaleOptions;
+        constructor new(options: TScaleOptions);
+      end;
+    public
+      // Extension methods
+      onAdd: TFunc<TMap, TJSHTMLElement>;
+      onRemove: TProc<TMap>;
+      options: TControlOptions;
+
+      constructor new(options: TControlOptions);
+      function getPosition(): String;
+      function setPosition(position: String): TControl;
+      function getContainer(): TJSHTMLElement;
+      function addTo(map: TMap): TControl;
+      function remove(): TControl;
+      function zoom(options: TZoomControlOptions): TZoom;
+      function attribution(options: TAttributionOptions): TAttribution;
+      function layers(baseLayers, overlays: TLayersObject; options: TLayersOptions): TLayers;
+      function scale(options: TScaleOptions): TScale;
+    end;
+
+    TDivOverlay = class external name 'DivOverlay' abstract (TLayer)
+    public
+      options: TDivOverlayOptions;
+
+      constructor new; overload;
+      constructor new(options: TDivOverlayOptions); overload;
+      constructor new(options: TDivOverlayOptions; source: TLayer); overload;
+      function getLatLng(): TLatLng;
+      function setLatLng(latlng: TLatLng): TDivOverlay; overload;
+      function setLatLng(latlng: TLatLngLiteral): TDivOverlay; overload;
+      function setLatLng(latlng: TLatLngTuple): TDivOverlay; overload;
+      function getContent(): JSValue;
+      function setContent(htmlContent: TFunc<TLayer, String>): TDivOverlay; overload;
+      function setContent(htmlContent: TFunc<TLayer, TJSHTMLElement>): TDivOverlay; overload;
+      function setContent(htmlContent: String): TDivOverlay; overload;
+      function setContent(htmlContent: TJSHTMLElement): TDivOverlay; overload;
+      function getElement(): TJSHTMLElement;
+      procedure update();
+      function isOpen(): Boolean;
+      function bringToFront(): TDivOverlay;
+      function bringToBack(): TDivOverlay;
+    end;
+
+    TPopup = class external name 'Popup' (TDivOverlay)
+    public
+      options: TPopupOptions;
+
+      constructor new; overload;
+      constructor new(options: TPopupOptions); overload;
+      constructor new(options: TPopupOptions; source: TLayer); overload;
+      function openOn(map: TMap): TPopup;
+    end;
+
+    TTooltip = class external name 'Tooltip' (TDivOverlay)
+    public
+      options: TTooltipOptions;
+
+      constructor new; overload;
+      constructor new(options: TTooltipOptions); overload;
+      constructor new(options: TTooltipOptions; source: TLayer); overload;
+
+      procedure setOpacity(val: Double);
+    end;
+
+    THandler = class external name 'Handler' (TClass)
+    public
+      // Extension methods
+      addHooks: TProc;
+      removeHooks: TProc;
+
+      constructor new(map: TMap);
+
+      function disable(): THandler;
+      function enable(): THandler;
+      function enabled(): Boolean;
+    end;
+
+    THandlerClass = class of THandler;
+
+    TDomEvent = class external name 'DomEvent'
+    public type
+      TEventHandlerFn = TProc<TLeafletEvent>;
+    public
+      function addListener(el: TJSHTMLElement; types: String; fn: TEventHandlerFn; context: JSValue): TDomEvent;
+      function disableClickPropagation(el: TJSHTMLElement): TDomEvent;
+      function disableScrollPropagation(el: TJSHTMLElement): TDomEvent;
+      function getMousePosition(ev: TLeafletMouseEvent; container: TJSHTMLElement): TPoint;
+      function getWheelDelta(ev: TLeafletEvent): Double;
+      function off(el: TJSHTMLElement; types: String; fn: TEventHandlerFn; context: JSValue): TDomEvent;
+      function &on(el: TJSHTMLElement; types: String; fn: TEventHandlerFn; context: JSValue): TDomEvent;
+      function preventDefault(ev: TLeafletEvent): TDomEvent;
+      function removeListener(el: TJSHTMLElement; types: String; fn: TEventHandlerFn; context: JSValue): TDomEvent;
+      function stop(ev: TLeafletEvent): TDomEvent;
+      function stopPropagation(ev: TLeafletEvent): TDomEvent;
+    end;
+
+    TMap = class external name 'Map' (TEvented)
+    public
+      // Properties
+      attributionControl: TLeaflet.TControl.TAttribution;
+      boxZoom: THandler;
+      doubleClickZoom: THandler;
+      dragging: THandler;
+      keyboard: THandler;
+      scrollWheelZoom: THandler;
+      tap: THandler;
+      touchZoom: THandler;
+      zoomControl: TControl.TZoom;
+
+      options: TMapOptions;
+
+      constructor new(element: String); overload;
+      constructor new(element: String; options: TMapOptions); overload;
+      constructor new(element: TJSHTMLElement); overload;
+      constructor new(element: TJSHTMLElement; options: TMapOptions); overload;
+
+      function getRenderer(layer: TPath): TRenderer;
+
+      // Methods for layers and controls
+      function addControl(control: TControl): TMap;
+      function addLayer(layer: TLayer): TMap;
+      function closePopup(popup: TPopup): TMap;
+      function closeTooltip(tooltip: TTooltip): TMap;
+      function eachLayer(fn: TProc<TLayer>; context: JSValue): TMap;
+      function hasLayer(layer: TLayer): Boolean;
+      function openPopup(content: String; latlng: TLatLng; options: TPopupOptions): TMap; overload;
+      function openPopup(content: String; latlng: TLatLngLiteral; options: TPopupOptions): TMap; overload;
+      function openPopup(content: String; latlng: TLatLngTuple; options: TPopupOptions): TMap; overload;
+      function openPopup(content: TJSHTMLElement; latlng: TLatLng; options: TPopupOptions): TMap; overload;
+      function openPopup(content: TJSHTMLElement; latlng: TLatLngLiteral; options: TPopupOptions): TMap; overload;
+      function openPopup(content: TJSHTMLElement; latlng: TLatLngTuple; options: TPopupOptions): TMap; overload;
+      function openPopup(popup: TPopup): TMap; overload;
+      function openTooltip(content: String; latlng: TLatLng; options: TTooltipOptions): TMap; overload;
+      function openTooltip(content: String; latlng: TLatLngLiteral; options: TTooltipOptions): TMap; overload;
+      function openTooltip(content: String; latlng: TLatLngTuple; options: TTooltipOptions): TMap; overload;
+      function openTooltip(content: TJSHTMLElement; latlng: TLatLng; options: TTooltipOptions): TMap; overload;
+      function openTooltip(content: TJSHTMLElement; latlng: TLatLngLiteral; options: TTooltipOptions): TMap; overload;
+      function openTooltip(content: TJSHTMLElement; latlng: TLatLngTuple; options: TTooltipOptions): TMap; overload;
+      function openTooltip(tooltip: TTooltip): TMap; overload;
+      function removeControl(control: TControl): TMap;
+      function removeLayer(layer: TLayer): TMap;
+
+      // Methods for modifying map state
+      function fitBounds(bounds: TLatLngBounds; options: TFitBoundsOptions): TMap; overload;
+      function fitBounds(bounds: TLatLngBoundsLiteral; options: TFitBoundsOptions): TMap; overload;
+      function fitWorld(options: TFitBoundsOptions): TMap;
+      function flyTo(latlng: TLatLng; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function flyTo(latlng: TLatLngLiteral; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function flyTo(latlng: TLatLngTuple; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function flyToBounds(bounds: TLatLngBounds): TMap; overload;
+      function flyToBounds(bounds: TLatLngBounds; options: TFitBoundsOptions): TMap; overload;
+      function flyToBounds(bounds: TLatLngBoundsLiteral): TMap; overload;
+      function flyToBounds(bounds: TLatLngBoundsLiteral; options: TFitBoundsOptions): TMap; overload;
+      function invalidateSize(options: Boolean): TMap; overload;
+      function invalidateSize(options: TInvalidateSizeOptions): TMap; overload;
+      function panBy(offset: TPoint; options: TPanOptions): TMap; overload;
+      function panBy(offset: TPointTuple; options: TPanOptions): TMap; overload;
+      function panInside(latLng: JSValue; options: TPanInsideOptions): TMap;
+      function panInsideBounds(bounds: TLatLngBounds; options: TPanOptions): TMap; overload;
+      function panInsideBounds(bounds: TLatLngBoundsLiteral; options: TPanOptions): TMap; overload;
+      function panTo(latlng: TLatLng; options: TPanOptions): TMap; overload;
+      function panTo(latlng: TLatLngLiteral; options: TPanOptions): TMap; overload;
+      function panTo(latlng: TLatLngTuple; options: TPanOptions): TMap; overload;
+      function setMaxBounds(bounds: TLatLngBounds): TMap; overload;
+      function setMaxBounds(bounds: TLatLngBoundsLiteral): TMap; overload;
+      function setMaxZoom(zoom: Double): TMap;
+      function setMinZoom(zoom: Double): TMap;
+      function setView(center: TLatLngLiteral; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function setView(center: TLatLngTuple; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function setView(center: TLatLng; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function setZoom(zoom: Double; options: TZoomPanOptions): TMap;
+      function setZoomAround(position: TLatLng; zoom: Double; options: TZoomOptions): TMap; overload;
+      function setZoomAround(position: TLatLngLiteral; zoom: Double; options: TZoomOptions): TMap; overload;
+      function setZoomAround(position: TLatLngTuple; zoom: Double; options: TZoomOptions): TMap; overload;
+      function setZoomAround(position: TPoint; zoom: Double; options: TZoomOptions): TMap; overload;
+      function stop(): TMap;
+      function zoomIn(delta: Double; options: TZoomOptions): TMap;
+      function zoomOut(delta: Double; options: TZoomOptions): TMap;
+
+      // Other methods
+      function addHandler(name: String; HandlerClass: THandlerClass): TMap; // Alternatively; HandlerClass: new(map: TMap) => THandler
+      function createPane(name: String; container: TJSHTMLElement): TJSHTMLElement;
+      function getContainer(): TJSHTMLElement;
+      function getPane(pane: String): TJSHTMLElement; overload;
+      function getPane(pane: TJSHTMLElement): TJSHTMLElement; overload;
+      function getPanes(): TDefaultMapPanes;
+      function remove(): TMap;
+      function whenReady(fn: TProc; context: JSValue): TMap;
+
+      // Methods for getting map state
+      function getBounds(): TLatLngBounds;
+      function getBoundsZoom(bounds: TLatLngBounds; inside: Boolean; padding: TPoint): Double; overload;
+      function getBoundsZoom(bounds: TLatLngBoundsLiteral; inside: Boolean; padding: TPoint): Double; overload;
+      function getCenter(): TLatLng;
+      function getMaxZoom(): Double;
+      function getMinZoom(): Double;
+      function getPixelBounds(): TBounds;
+      function getPixelOrigin(): TPoint;
+      function getPixelWorldBounds(zoom: Double): TBounds;
+      function getSize(): TPoint;
+      function getZoom(): Double;
+
+      // Conversion methods
+      function containerPointToLatLng(point: TPoint): TLatLng; overload;
+      function containerPointToLatLng(point: TPointTuple): TLatLng; overload;
+      function containerPointToLayerPoint(point: TPoint): TPoint; overload;
+      function containerPointToLayerPoint(point: TPointTuple): TPoint; overload;
+      function distance(latlng1, latlng2: TLatLng): Double; overload;
+      function distance(latlng1, latlng2: TLatLngLiteral): Double; overload;
+      function distance(latlng1, latlng2: TLatLngTuple): Double; overload;
+      function getScaleZoom(scale: Double; fromZoom: Double): Double;
+      function getZoomScale(toZoom: Double; fromZoom: Double): Double;
+      function latLngToContainerPoint(latlng: TLatLng): TPoint; overload;
+      function latLngToContainerPoint(latlng: TLatLngLiteral): TPoint; overload;
+      function latLngToContainerPoint(latlng: TLatLngTuple): TPoint; overload;
+      function latLngToLayerPoint(latlng: TLatLng): TPoint; overload;
+      function latLngToLayerPoint(latlng: TLatLngLiteral): TPoint; overload;
+      function latLngToLayerPoint(latlng: TLatLngTuple): TPoint; overload;
+      function layerPointToContainerPoint(point: TPoint): TPoint; overload;
+      function layerPointToContainerPoint(point: TPointTuple): TPoint; overload;
+      function layerPointToLatLng(point: TPoint): TLatLng; overload;
+      function layerPointToLatLng(point: TPointTuple): TLatLng; overload;
+      function mouseEventToContainerPoint(ev: TLeafletMouseEvent): TPoint;
+      function mouseEventToLatLng(ev: TLeafletMouseEvent): TLatLng;
+      function mouseEventToLayerPoint(ev: TLeafletMouseEvent): TPoint;
+      function project(latlng: TLatLng; zoom: Double): TPoint; overload;
+      function project(latlng: TLatLngLiteral; zoom: Double): TPoint; overload;
+      function project(latlng: TLatLngTuple; zoom: Double): TPoint; overload;
+      function unproject(point: TPoint; zoom: Double): TLatLng; overload;
+      function unproject(point: TPointTuple; zoom: Double): TLatLng; overload;
+      function wrapLatLng(latlng: TLatLng): TLatLng; overload;
+      function wrapLatLng(latlng: TLatLngLiteral): TLatLng; overload;
+      function wrapLatLng(latlng: TLatLngTuple): TLatLng; overload;
+      function wrapLatLngBounds(bounds: TLatLngBounds): TLatLngBounds;
+
+      // Geolocation methods
+      function locate(options: TLocateOptions): TMap;
+      function stopLocate(): TMap;
+    end;
+
+    TIcon = class external name 'Icon'
+    public type
+      TDefault = class external name 'Default' (TIcon)
+      public
+        constructor new(options: TIconOptions);
+      end;
+    public
+      options: TBaseIconOptions;
+
+      constructor new(options: TBaseIconOptions);
+      function createIcon(oldIcon: TJSHTMLElement): TJSHTMLElement;
+      function createShadow(oldIcon: TJSHTMLElement): TJSHTMLElement;
+    end;
+
+    TDivIcon = class external name 'DivIcon' (TIcon)
+    public
+      options: TDivIconOptions;
+
+      constructor new(options: TDivIconOptions);
+    end;
+
+    TMarker = class external name 'Marker' (TLayer)
+    public
+      // Properties
+      options: TMarkerOptions;
+      dragging: THandler;
+      feature: TFeature;
+
+      constructor new(latlng: TLatLng; options: TMarkerOptions); overload;
+      constructor new(latlng: TLatLngLiteral; options: TMarkerOptions); overload;
+      constructor new(latlng: TLatLngTuple; options: TMarkerOptions); overload;
+
+      function toGeoJSON(precision: Double): TFeature;
+      function getLatLng(): TLatLng;
+      function setLatLng(latlng: TLatLng): TMarker; overload;
+      function setLatLng(latlng: TLatLngLiteral): TMarker; overload;
+      function setLatLng(latlng: TLatLngTuple): TMarker; overload;
+      function setZIndexOffset(offset: Double): TMarker;
+      function getIcon(): JSValue;
+      function setIcon(icon: JSValue): TMarker;
+      function setOpacity(opacity: Double): TMarker;
+      function getElement(): TJSHTMLElement;
+    end;
+
+    TBrowser = class external name 'Browser'
+    public const
+      ie: Boolean;
+      ielt9: Boolean;
+      edge: Boolean;
+      webkit: Boolean;
+      android: Boolean;
+      android23: Boolean;
+      androidStock: Boolean;
+      opera: Boolean;
+      chrome: Boolean;
+      gecko: Boolean;
+      safari: Boolean;
+      opera12: Boolean;
+      win: Boolean;
+      ie3d: Boolean;
+      webkit3d: Boolean;
+      gecko3d: Boolean;
+      any3d: Boolean;
+      mobile: Boolean;
+      mobileWebkit: Boolean;
+      mobileWebkit3d: Boolean;
+      msPointer: Boolean;
+      pointer: Boolean;
+      touch: Boolean;
+      mobileOpera: Boolean;
+      mobileGecko: Boolean;
+      retina: Boolean;
+      canvas: Boolean;
+      svg: Boolean;
+      vml: Boolean;
+    end;
+
+    TUtil = class external name 'Util'
+    public
+      function extend(dest: JSValue): JSValue; varargs;
+
+      function stamp(obj: JSValue): Double;
+      function throttle(fn: TProc; time: Double; context: JSValue): TProc;
+      function wrapNum(num: Double; range: TArray<Double>; includeMax: Boolean): Double;
+      function falseFn(): Boolean;
+      function formatNum(num: Double; digits: Double): Double;
+      function trim(str: String): String;
+      function splitWords(str: String): TArray<String>;
+      function setOptions(obj: JSValue; options: JSValue): JSValue;
+      function getParamString(obj: JSValue; existingUrl: String; uppercase: Boolean): String;
+      function template(str: String; data: JSValue): String;
+      function isArray(obj: JSValue): Boolean;
+      function indexOf(&array: TArray<JSValue>; el: JSValue): Double;
+      function requestAnimFrame(fn: TProc<Double>; context: JSValue; immediate: Boolean): Double;
+      procedure cancelAnimFrame(id: Double);
+    end;
+  public
+    lastId: Double;
+    emptyImageUrl: String;
+
+    function bounds(topLeft, bottomRight: TPoint): TBounds; overload;
+    function bounds(topLeft, bottomRight: TPointTuple): TBounds; overload;
+    function bounds(points: TArray<TPoint>): TBounds; overload;
+    function bounds(points: TBoundsLiteral): TBounds; overload;
+    function canvas(options: TRendererOptions): TCanvas;
+    function circle(latlng: TLatLng; options: TCircleMarkerOptions): TCircle; overload;
+    function circle(latlng: TLatLngLiteral; options: TCircleMarkerOptions): TCircle; overload;
+    function circle(latlng: TLatLngTuple; options: TCircleMarkerOptions): TCircle; overload;
+    function circleMarker(latlng: TLatLng; options: TCircleMarkerOptions): TCircleMarker; overload;
+    function circleMarker(latlng: TLatLngLiteral; options: TCircleMarkerOptions): TCircleMarker; overload;
+    function circleMarker(latlng: TLatLngTuple; options: TCircleMarkerOptions): TCircleMarker; overload;
+    function divIcon(options: TDivIconOptions): TDivIcon;
+    function featureGroup(layers: TArray<TLayer>): TFeatureGroup;
+    function geoJSON(geojson: TGeoJsonObject; options: TGeoJSONOptions): TGeoJSON;
+    function gridLayer(options: TGridLayerOptions): TGridLayer;
+    function icon(options: TIconOptions): TIcon;
+    function imageOverlay(imageUrl: String; bounds: TLatLngBounds; options: TImageOverlayOptions): TImageOverlay; overload;
+    function imageOverlay(imageUrl: String; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions): TImageOverlay; overload;
+    function latLng(coords: TArray<Double>): TLatLng; overload;
+    function latLng(latitude, longitude: Double): TLatLng; overload;
+    function latLng(latitude, longitude, altitude: Double): TLatLng; overload;
+    function latLngBounds(southWest, northEast: TLatLng): TLatLngBounds; overload;
+    function latLngBounds(southWest, northEast: TLatLngLiteral): TLatLngBounds; overload;
+    function latLngBounds(southWest, northEast: TLatLngTuple): TLatLngBounds; overload;
+    function latLngBounds(latlngs: TArray<TLatLng>): TLatLngBounds; overload;
+    function latLngBounds(latlngs: TArray<TLatLngLiteral>): TLatLngBounds; overload;
+    function latLngBounds(latlngs: TArray<TLatLngTuple>): TLatLngBounds; overload;
+    function layerGroup: TLayerGroup; overload;
+    function layerGroup(layers: TArray<TLayer>): TLayerGroup; overload;
+    function layerGroup(layers: TArray<TLayer>; options: TLayerOptions): TLayerGroup; overload;
+    function map(element: String; options: TMapOptions): TMap; overload;
+    function map(element: TJSHTMLElement; options: TMapOptions): TMap; overload;
+    function marker(latlng: TLatLng; options: TMarkerOptions): TMarker; overload;
+    function marker(latlng: TLatLngLiteral; options: TMarkerOptions): TMarker; overload;
+    function marker(latlng: TLatLngTuple; options: TMarkerOptions): TMarker; overload;
+    function point(x, y: Double): TPoint; overload;
+    function point(x, y: Double; round: Boolean): TPoint; overload;
+    function point(coords: TPointTuple): TPoint; overload;
+    function polyline(latlngs: TArray<TLatLng>; options: TPolylineOptions): TPolyline; overload;
+    function polyline(latlngs: TArray<TArray<TLatLng>>; options: TPolylineOptions): TPolyline; overload;
+    function polyline(latlngs: TArray<TLatLngLiteral>; options: TPolylineOptions): TPolyline; overload;
+    function polyline(latlngs: TArray<TArray<TLatLngLiteral>>; options: TPolylineOptions): TPolyline; overload;
+    function polyline(latlngs: TArray<TLatLngTuple>; options: TPolylineOptions): TPolyline; overload;
+    function polyline(latlngs: TArray<TArray<TLatLngTuple>>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TLatLng>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TArray<TLatLng>>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TLatLngLiteral>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TArray<TLatLngLiteral>>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TLatLngTuple>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TArray<TLatLngTuple>>; options: TPolylineOptions): TPolyline; overload;
+    function popup: TPopup; overload;
+    function popup(options: TPopupOptions): TPopup; overload;
+    function popup(options: TPopupOptions; source: TLayer): TPopup; overload;
+    function rectangle(latLngBounds: TLatLngBounds; options: TPolylineOptions): TRectangle; overload;
+    function rectangle(latLngBounds: TLatLngBoundsLiteral; options: TPolylineOptions): TRectangle; overload;
+    function svg(options: TRendererOptions): TSVG;
+    function svgOverlay(svgImage: String; bounds: TLatLngBounds; options: TImageOverlayOptions): TSVGOverlay; overload;
+    function svgOverlay(svgImage: String; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions): TSVGOverlay; overload;
+    function svgOverlay(svgImage: TJSHTMLElement; bounds: TLatLngBounds; options: TImageOverlayOptions): TSVGOverlay; overload;
+    function svgOverlay(svgImage: TJSHTMLElement; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions): TSVGOverlay; overload;
+    function tileLayer(urlTemplate: String; options: TTileLayerOptions): TTileLayer;
+    function tooltip: TTooltip; overload;
+    function tooltip(options: TTooltipOptions): TTooltip; overload;
+    function tooltip(options: TTooltipOptions; source: TLayer): TTooltip; overload;
+    function videoOverlay(video: String; bounds: TLatLngBounds; options: TVideoOverlayOptions): TVideoOverlay; overload;
+    function videoOverlay(video: String; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions): TVideoOverlay; overload;
+    function videoOverlay(video: TArray<String>; bounds: TLatLngBounds; options: TVideoOverlayOptions): TVideoOverlay; overload;
+    function videoOverlay(video: TArray<String>; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions): TVideoOverlay; overload;
+    function videoOverlay(video: TJSHTMLVideoElement; bounds: TLatLngBounds; options: TVideoOverlayOptions): TVideoOverlay; overload;
+    function videoOverlay(video: TJSHTMLVideoElement; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions): TVideoOverlay; overload;
+  end;
+
+  TLatLngLiteral = class
+  public
+    lat: Double;
+    lng: Double;
+  end;
+
+  TLayerOptions = class
+  public
+    pane: String;
+    attribution: String;
+  end;
+
+  TInteractiveLayerOptions = class(TLayerOptions)
+  public
+    interactive: Boolean;
+    bubblingMouseEvents: Boolean;
+  end;
+
+  TGridLayerOptions = class(TLayerOptions)
+  public
+    tileSize: TPoint;
+    tileSizeNumber: Double; external name 'tileSize';
+    opacity: Double;
+    updateWhenIdle: Boolean;
+    updateWhenZooming: Boolean;
+    updateInterval: Double;
+    attribution: String;
+    zIndex: Double;
+    bounds: JSValue;
+    minZoom: Double;
+    maxZoom: Double;
+    noWrap: Boolean;
+    pane: String;
+    className: String;
+    keepBuffer: Double;
+  end;
+
+  TTileLayerOptions = class(TGridLayerOptions)
+  public
+    id: String;
+    accessToken: String;
+    minZoom: Double;
+    maxZoom: Double;
+    maxNativeZoom: Double;
+    minNativeZoom: Double;
+    subdomains: TArray<String>;
+    errorTileUrl: String;
+    zoomOffset: Double;
+    tms: Boolean;
+    zoomReverse: Boolean;
+    detectRetina: Boolean;
+    crossOrigin: String;
+  end;
+
+  TWMSOptions = class(TTileLayerOptions)
+  public
+    layers: String;
+    styles: String;
+    format: String;
+    transparent: Boolean;
+    version: String;
+    crs: TLeaflet.TCRS;
+    uppercase: Boolean;
+  end;
+
+  TWMSParams = class
+  public
+    format: String;
+    layers: String;
+    request: String;
+    service: String;
+    styles: String;
+    version: String;
+    transparent: Boolean;
+    width: Double;
+    height: Double;
+  end;
+
+  TImageOverlayOptions = class(TInteractiveLayerOptions)
+  public
+    opacity: Double;
+    alt: String;
+    interactive: Boolean;
+    attribution: String;
+    crossOrigin: String;
+    errorOverlayUrl: String;
+    zIndex: Double;
+    className: String;
+  end;
+
+  TVideoOverlayOptions = class(TImageOverlayOptions)
+  public
+    autoplay: Boolean;
+    loop: Boolean;
+    keepAspectRatio: Boolean;
+  end;
+
+  TPathOptions = class(TInteractiveLayerOptions)
+  public
+    stroke: Boolean;
+    color: String;
+    weight: Double;
+    opacity: Double;
+    lineCap: String;
+    lineJoin: String;
+    dashArray: TArray<Double>;
+    dashOffset: String;
+    fill: Boolean;
+    fillColor: String;
+    fillOpacity: Double;
+    fillRule: String;
+    renderer: TLeaflet.TRenderer;
+    className: String;
+  end;
+
+  TPolylineOptions = class(TPathOptions)
+  public
+    smoothFactor: Double;
+    noClip: Boolean;
+  end;
+
+  TCircleMarkerOptions = class(TPathOptions)
+  public
+    radius: Double;
+  end;
+
+  TRendererOptions = class (TLayerOptions)
+  public
+    padding: Double;
+    tolerance: Double;
+  end;
+
+  TGeoJSONOptions = class(TInteractiveLayerOptions)
+  public
+    coordsToLatLng: TFunc<TArray<Double>, TLeaflet.TLatLng>;
+    filter: TFunc<TFeature, Boolean>;
+    onEachFeature: TProc<TFeature, TLeaflet.TLayer>;
+    pointToLayer: TFunc<TFeature, TLeaflet.TLatLng, TLeaflet.TLayer>;
+    style: TPathOptions;
+    styleFunction: TLeaflet.TStyleFunction; external name 'style';
+  end;
+
+  TMapOptions = class
+  private
+    FCRS: TLeaflet.TCRS; external name 'crs';
+
+    function GetCRS: TLeaflet.TCRS;
+
+    procedure SetCRS(Value: TLeaflet.TCRS);
+  public
+    preferCanvas: Boolean;
+
+    // Control options
+    attributionControl: Boolean;
+    zoomControl: Boolean;
+
+    // Interaction options
+    closePopupOnClick: Boolean;
+    zoomSnap: Double;
+    zoomDelta: Double;
+    trackResize: Boolean;
+    boxZoom: Boolean;
+    doubleClickZoom: String;
+    dragging: Boolean;
+
+    // Map state options
+    center: JSValue;
+    zoom: Double;
+    minZoom: Double;
+    maxZoom: Double;
+    layers: TArray<TLeaflet.TLayer>;
+    maxBounds: JSValue;
+    renderer: TLeaflet.TRenderer;
+
+    // Animation options
+    fadeAnimation: Boolean;
+    markerZoomAnimation: Boolean;
+    transform3DLimit: Double;
+    zoomAnimation: Boolean;
+    zoomAnimationThreshold: Double;
+
+    // Panning inertia options
+    inertia: Boolean;
+    inertiaDeceleration: Double;
+    inertiaMaxSpeed: Double;
+    easeLinearity: Double;
+    worldCopyJump: Boolean;
+    maxBoundsViscosity: Double;
+
+    // Keyboard navigation options
+    keyboard: Boolean;
+    keyboardPanDelta: Double;
+
+    // Mousewheel options
+    scrollWheelZoom: TLeaflet.TControl.TZoom;
+    wheelDebounceTime: Double;
+    wheelPxPerZoomLevel: Double;
+
+    // Touch interaction options
+    tap: Boolean;
+    tapTolerance: Double;
+    touchZoom: TLeaflet.TControl.TZoom;
+    bounceAtZoomLimits: Boolean;
+
+    property crs: TLeaflet.TCRS read GetCRS write SetCRS;
+  end;
+
+  TControlOptions = class
+  public
+    position: String;
+  end;
+
+  TZoomControlOptions = class(TControlOptions)
+  public
+    zoomInText: String;
+    zoomInTitle: String;
+    zoomOutText: String;
+    zoomOutTitle: String;
+  end;
+
+  TAttributionOptions = class(TControlOptions)
+  public
+    prefix: String;
+  end;
+
+  TLayersOptions = class(TControlOptions)
+  public
+    collapsed: Boolean;
+    autoZIndex: Boolean;
+    hideSingleBase: Boolean;
+  end;
+
+  TLayersObject = class
+  private
+    function GetLayers(name: String): TLeaflet.TLayer; external name '[]';
+
+    procedure SetLayers(name: String; Value: TLeaflet.TLayer); external name '[]';
+  public
+    property Layers[name: String]: TLeaflet.TLayer read GetLayers write SetLayers;
+  end;
+
+  TScaleOptions = class(TControlOptions)
+  public
+    maxWidth: Double;
+    metric: Boolean;
+    imperial: Boolean;
+    updateWhenIdle: Boolean;
+  end;
+
+  TDivOverlayOptions = class
+  public
+    offset: TPoint;
+    zoomAnimation: Boolean;
+    className: String;
+    pane: String;
+  end;
+
+  TPopupOptions = class(TDivOverlayOptions)
+  public
+    maxWidth: Double;
+    minWidth: Double;
+    maxHeight: Double;
+    keepInView: Boolean;
+    closeButton: Boolean;
+    autoPan: Boolean;
+    autoPanPaddingTopLeft: TPoint;
+    autoPanPaddingBottomRight: TPoint;
+    autoPanPadding: TPoint;
+    autoClose: Boolean;
+    closeOnClick: Boolean;
+    closeOnEscapeKey: Boolean;
+  end;
+
+  TTooltipOptions = class(TDivOverlayOptions)
+  public
+    pane: String;
+    offset: TPoint;
+    direction: String;
+    permanent: Boolean;
+    sticky: Boolean;
+    interactive: Boolean;
+    opacity: Double;
+  end;
+
+  TZoomOptions = class
+  public
+    animate: Boolean;
+  end;
+
+  TPanOptions = class(TZoomOptions)
+  public
+    duration: Double;
+    easeLinearity: Double;
+    noMoveStart: Boolean;
+  end;
+
+  TZoomPanOptions = class(TZoomOptions)
+  end;
+
+  TInvalidateSizeOptions = class(TZoomPanOptions)
+  public
+    debounceMoveend: Boolean;
+    pan: Boolean;
+  end;
+
+  TFitBoundsOptions = class(TZoomPanOptions)
+  public
+    paddingTopLeft: TPoint;
+    paddingBottomRight: TPoint;
+    padding: TPoint;
+    maxZoom: Double;
+  end;
+
+  TPanInsideOptions = class
+  public
+    paddingTopLeft: TPoint;
+    paddingBottomRight: TPoint;
+    padding: TPoint;
+  end;
+
+  TLocateOptions = class
+  public
+    watch: Boolean;
+    setView: Boolean;
+    maxZoom: Double;
+    timeout: Double;
+    maximumAge: Double;
+    enableHighAccuracy: Boolean;
+  end;
+
+  TLeafletEvent = class
+  public
+    &type: String;
+    target: JSValue;
+    sourceTarget: JSValue;
+    propagatedFrom: JSValue;
+  end;
+
+  TLeafletMouseEvent = class(TLeafletEvent)
+  public
+    latlng: TLeaflet.TLatLng;
+    layerPoint: TPoint;
+    containerPoint: TPoint;
+    originalEvent: TLeafletMouseEvent;
+  end;
+
+  TLeafletKeyboardEvent = class(TLeafletEvent)
+  public
+    originalEvent: TLeafletKeyboardEvent;
+  end;
+
+  TLocationEvent = class(TLeafletEvent)
+  public
+    latlng: TLeaflet.TLatLng;
+    bounds: TLeaflet.TLatLngBounds;
+    accuracy: Double;
+    altitude: Double;
+    altitudeAccuracy: Double;
+    heading: Double;
+    speed: Double;
+    timestamp: Double;
+  end;
+
+  TErrorEvent = class(TLeafletEvent)
+  public
+    message: String;
+    code: Double;
+  end;
+
+  TLayerEvent = class(TLeafletEvent)
+  public
+    layer: TLeaflet.TLayer;
+  end;
+
+  TLayersControlEvent = class(TLayerEvent)
+  public
+    name: String;
+  end;
+
+  TTileEvent = class(TLeafletEvent)
+  public
+    tile: TJSHTMLImageElement;
+    coords: TLeaflet.TCoords;
+  end;
+
+  TTileErrorEvent = class(TTileEvent)
+  public
+    error: TError;
+  end;
+
+  TResizeEvent = class(TLeafletEvent)
+  public
+    oldSize: TPoint;
+    newSize: TPoint;
+  end;
+
+  TGeoJSONEvent = class(TLeafletEvent)
+  public
+    layer: TLeaflet.TLayer;
+    properties: JSValue;
+    geometryType: String;
+    id: String;
+  end;
+
+  TPopupEvent = class(TLeafletEvent)
+  public
+    popup: TLeaflet.TPopup;
+  end;
+
+  TTooltipEvent = class(TLeafletEvent)
+  public
+    tooltip: TLeaflet.TTooltip;
+  end;
+
+  TDragEndEvent = class(TLeafletEvent)
+  public
+    distance: Double;
+  end;
+
+  TZoomAnimEvent = class(TLeafletEvent)
+  public
+    center: TLeaflet.TLatLng;
+    zoom: Double;
+    noUpdate: Boolean;
+  end;
+
+  TDefaultMapPanes = class
+  public
+    mapPane: TJSHTMLElement;
+    tilePane: TJSHTMLElement;
+    overlayPane: TJSHTMLElement;
+    shadowPane: TJSHTMLElement;
+    markerPane: TJSHTMLElement;
+    tooltipPane: TJSHTMLElement;
+    popupPane: TJSHTMLElement;
+  end;
+
+  TBaseIconOptions = class(TLayerOptions)
+  public
+    iconUrl: String;
+    iconRetinaUrl: String;
+    iconSize: TPoint;
+    iconAnchor: TPoint;
+    popupAnchor: TPoint;
+    tooltipAnchor: TPoint;
+    shadowUrl: String;
+    shadowRetinaUrl: String;
+    shadowSize: TPoint;
+    shadowAnchor: TPoint;
+    className: String;
+  end;
+
+  TIconOptions = class(TBaseIconOptions)
+  public
+    iconUrl: String;
+  end;
+
+  TDivIconOptions = class (TBaseIconOptions)
+  public
+    html: JSValue;
+    bgPos: TPoint;
+    iconSize: TPoint;
+    iconAnchor: TPoint;
+    popupAnchor: TPoint;
+    className: String;
+  end;
+
+  TMarkerOptions = class(TInteractiveLayerOptions)
+  public
+    icon: JSValue;
+    draggable: Boolean;
+    keyboard: Boolean;
+    title: String;
+    alt: String;
+    zIndexOffset: Double;
+    opacity: Double;
+    riseOnHover: Boolean;
+    riseOffset: Double;
+    shadowPane: String;
+    autoPan: Boolean;
+    autoPanPadding: TPoint;
+    autoPanSpeed: Double;
+  end;
+
+  TError = class
+  end;
+
+  TMapboxLayerOptions = class(TTileLayerOptions)
+  public
+    AccessToken: String; external name 'accessToken';
+    Style: String; external name 'style';
+
+    constructor Create(Style, AccessToken: String);
+  end;
+
+var
+  Leaflet: TLeaflet; external name 'L';
+
+function InitializeMap: TJSPromise;
+
+implementation
+
+function InitializeMap: TJSPromise;
+begin
+  Result := TJSPromise.New(
+    procedure(Resolve, Reject: TJSPromiseResolver)
+    var
+      Script: TJSHTMLScriptElement;
+
+      Link: TJSHTMLLinkElement;
+
+    begin
+      Link := TJSHTMLLinkElement(document.createElement('link'));
+      Link.HRef := 'https://unpkg.com/leaflet/dist/leaflet.css';
+      Link.Rel := 'stylesheet';
+
+      document.head.appendChild(Link);
+
+      Script := TJSHTMLScriptElement(document.createElement('script'));
+      Script.OnLoad :=
+        function (Event: TEventListenerEvent): Boolean
+        begin
+          Resolve(True);
+
+          Result := True;
+        end;
+      Script.src := 'https://unpkg.com/leaflet/dist/leaflet.js';
+      Script.type_ := 'text/javascript';
+
+      document.head.appendChild(Script);
+    end);
+end;
+
+{ TMapOptions }
+
+function TMapOptions.GetCRS: TLeaflet.TCRS;
+begin
+  if not Assigned(FCRS) then
+    FCRS := TLeaflet.TCRS.EPSG3857;
+
+  Result := FCRS;
+end;
+
+procedure TMapOptions.SetCRS(Value: TLeaflet.TCRS);
+begin
+  FCRS := Value;
+end;
+
+{ TMapboxLayerOptions }
+
+constructor TMapboxLayerOptions.Create(Style, AccessToken: String);
+begin
+  inherited Create;
+
+  Attribution := 'Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>';
+  Self.AccessToken := AccessToken;
+  Self.Style := Style;
+  TileSizeNumber := 512;
+  ZoomOffset := -1;
+end;
+
+end.
+
-- 
2.31.1.windows.1

henrique

2021-05-20 13:13

reporter   ~0130969

I've made some changes to the loading of maps, so i no longer need a global script to resolve the promise. For this implementation to work, you need task 0038912 to be applied as well.
0001-Implementa-o-da-base-dos-mapas-3.patch (182,460 bytes)   
From ec4d0c2115f8606d34f07774dbfb186f601089b5 Mon Sep 17 00:00:00 2001
From: Henrique Gottardi Werlang <henriquewerlang@hotmail.com>
Date: Thu, 20 May 2021 10:07:19 -0300
Subject: [PATCH] =?UTF-8?q?Implementa=C3=A7=C3=A3o=20da=20base=20dos=20map?=
 =?UTF-8?q?as.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 packages/maps/Bing.Maps.pas    |  869 +++++++++++++
 packages/maps/GeoJSON.pas      |  166 +++
 packages/maps/Google.Maps.pas  | 2156 ++++++++++++++++++++++++++++++++
 packages/maps/Leaflet.Maps.pas | 1845 +++++++++++++++++++++++++++
 4 files changed, 5036 insertions(+)
 create mode 100644 packages/maps/Bing.Maps.pas
 create mode 100644 packages/maps/GeoJSON.pas
 create mode 100644 packages/maps/Google.Maps.pas
 create mode 100644 packages/maps/Leaflet.Maps.pas

diff --git a/packages/maps/Bing.Maps.pas b/packages/maps/Bing.Maps.pas
new file mode 100644
index 00000000..ca27a46e
--- /dev/null
+++ b/packages/maps/Bing.Maps.pas
@@ -0,0 +1,869 @@
+unit Bing.Maps;
+
+interface
+
+{$modeswitch externalclass}
+
+uses Web, JS, SysUtils;
+
+type
+  TAddress = class;
+  TAnimatedFrameEventArgs = class;
+  TAnimatedTileLayerOptions  = class;
+  TBorderedMapElementStyle = class;
+  TCustomMapStyle = class;
+  TCustomOverlayOptions = class;
+  TGroundOverlayOptions = class;
+  THandlerId = class;
+  TInfoboxEventArgs = class;
+  TInfoboxOptions  = class;
+  TMapElementStyle = class;
+  TMapElements = class;
+  TMapOptions = class;
+  TMapTypeChangeEventArgs = class;
+  TModuleOptions = class;
+  TMouseEventArgs = class;
+  TPanoramaInfo = class;
+  TPolygonOptions = class;
+  TPolylineOptions = class;
+  TPrimitiveChangedEventArgs = class;
+  TPrimitiveOptions = class;
+  TPushpinOptions = class;
+  TRange = class;
+  TSettingsStyle = class;
+  TStreetsideOptions  = class;
+  TStyleUrl = class;
+  TStylesOptions = class;
+  TTileLayerOptions = class;
+  TTileSourceOptions = class;
+  TViewOptions = class;
+
+  TMicrosoft = class external name 'Microsoft'
+  public type
+    TMaps = class external name 'Maps'
+    public type
+      TCustomOverlay = class;
+      TInfobox = class;
+      TLayer = class;
+      TLocation = class;
+      TLocationRect = class;
+      TMap = class;
+      TPoint = class;
+      TPolygon = class;
+      TPolyline = class;
+      TPushpin = class;
+      TTileSource = class;
+
+      TLabelOverlay = (loHidden, loVisible);
+      TMapTypeId = (mtAerial, mtBirdseye, mtCanvasDark, mtCanvasLight, mtGrayscale, mtMercator, mtOrdnanceSurvey, mtRoad, mtStreetside);
+      TNavigationBarMode = (nbCompact, nbDefault, nbMinified);
+      TNavigationBarOrientation = (nboHorizontal, nboVertical);
+      TOverviewMapMode = (omExpanded, omHidden, omMinimized);
+      TPixelReference = (prControl, prPage, prViewport);
+
+      TPrimitive = class external name 'Primitive' abstract
+      public
+        function getCursor: String;
+        function getVisible: Boolean;
+        procedure setOptions(options: TPrimitiveOptions);
+      end;
+
+      TAnimatedTileLayer = class external name 'AnimatedTileLayer'
+      public
+        constructor new(options: TAnimatedTileLayerOptions);
+
+        function getFrameRate: Double;
+        function getLoadingScreen: TCustomOverlay;
+        function getMaxTotalLoadTime: Double;
+        function getTileSources: TArray<TTileSource>;
+        function getVisible: Boolean;
+
+        procedure pause;
+        procedure play;
+        procedure setOptions(options: TAnimatedTileLayerOptions);
+        procedure stop;
+      end;
+
+      TColor = class external name 'Color'
+      public
+        a: Double;
+        r: Double;
+        g: Double;
+        b: Double;
+
+        constructor new(a: Double; r: Double; g: Double; b: Double);
+
+        class function clone(color: TColor): TColor; overload;
+        class function fromHex(hex: String): TColor;
+
+        function clone: TColor; overload;
+        function getOpacity: Double;
+        function toHex: String;
+        function toRgba: String;
+      end;
+
+      TLayer = class external name 'Layer'
+      public
+        metadata: JSValue;
+
+        constructor new(id: String);
+
+        function getId: String;
+        function getPrimitives: TArray<TPrimitive>;
+        function getVisible: Boolean;
+        function getZIndex: Double;
+        function remove(primitive: TPrimitive): TPrimitive;
+        function removeAt(index: Double): TPrimitive;
+
+        procedure add(primitive: TArray<TPrimitive>; index: Double);
+        procedure clear;
+        procedure dispose;
+        procedure setPrimitives(primitives: TArray<TPrimitive>);
+        procedure setVisible(value: Boolean);
+        procedure setZIndex(zIndex: Double);
+      end;
+
+      TCustomOverlay = class external name 'CustomOverlay' (TLayer)
+      public
+        _map: TMap;
+
+        constructor new(options: TCustomOverlayOptions);
+
+        function getHtmlElement: TJSHTMLElement;
+        function getMap: TMap;
+
+        procedure onAdd;
+        procedure onLoad;
+        procedure onRemove;
+        procedure setHtmlElement(htmlElement: TJSHTMLElement);
+      end;
+
+      TEvents = class external name 'Events'
+      public
+        function addHandler(target: JSValue; eventName: String; handler: TProc<JSValue>): THandlerId; overload;
+        function addHandler(target: TInfobox; eventName: String; handler: TProc<TInfoboxEventArgs>): THandlerId; overload;
+        function addHandler(target: TLayer; eventName: String; handler: TProc<TMouseEventArgs>): THandlerId; overload;
+        function addHandler(target: TMap; eventName: String; handler: TProc<TMapTypeChangeEventArgs>): THandlerId; overload;
+        function addHandler(target: TMap; eventName: String; handler: TProc<TMouseEventArgs>): THandlerId; overload;
+        function addHandler(target: TPolygon; eventName: String; handler: TProc<TMouseEventArgs>): THandlerId; overload;
+        function addHandler(target: TPolygon; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>): THandlerId; overload;
+        function addHandler(target: TPolyline; eventName: String; handler: TProc<TMouseEventArgs>): THandlerId; overload;
+        function addHandler(target: TPolyline; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>): THandlerId; overload;
+        function addHandler(target: TPushpin; eventName: String; handler: TProc<TMouseEventArgs>): THandlerId; overload;
+        function addHandler(target: TPushpin; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>): THandlerId; overload;
+        function addThrottledHandler(target: JSValue; eventName: String; handler: TProc<JSValue>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TInfobox; eventName: String; handler: TProc<TInfoboxEventArgs>): THandlerId; overload;
+        function addThrottledHandler(target: TLayer; eventName: String; handler: TProc<TMouseEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TMap; eventName: String; handler: TProc<TMapTypeChangeEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TMap; eventName: String; handler: TProc<TMouseEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPolygon; eventName: String; handler: TProc<TMouseEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPolygon; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPolyline; eventName: String; handler: TProc<TMouseEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPolyline; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPushpin; eventName: String; handler: TProc<TMouseEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPushpin; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function hasHandler(target: JSValue; eventName: String): Boolean;
+
+        procedure addOne(target: JSValue; eventName: String; handler: TProc<JSValue>); overload;
+        procedure addOne(target: TInfobox; eventName: String; handler: TProc<TInfoboxEventArgs>); overload;
+        procedure addOne(target: TLayer; eventName: String; handler: TProc<TMouseEventArgs>); overload;
+        procedure addOne(target: TMap; eventName: String; handler: TProc<TMapTypeChangeEventArgs>); overload;
+        procedure addOne(target: TMap; eventName: String; handler: TProc<TMouseEventArgs>); overload;
+        procedure addOne(target: TPolygon; eventName: String; handler: TProc<TMouseEventArgs>); overload;
+        procedure addOne(target: TPolygon; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>); overload;
+        procedure addOne(target: TPolyline; eventName: String; handler: TProc<TMouseEventArgs>); overload;
+        procedure addOne(target: TPolyline; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>); overload;
+        procedure addOne(target: TPushpin; eventName: String; handler: TProc<TMouseEventArgs>); overload;
+        procedure addOne(target: TPushpin; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>); overload;
+        procedure invoke(target: JSValue; evenName: String; args: JSValue);
+        procedure removeHandler(handlerId: THandlerId);
+      end;
+
+      TGroundOverlay = class external name 'GroundOverlay' (TCustomOverlay)
+      public
+        metadata: JSValue; external name 'metadata';
+
+        constructor new(options: TGroundOverlayOptions);
+
+        function getBackgroundColor: TColor;
+        function getBounds: TLocationRect;
+        function getImageUrl: String;
+        function getMap: TMap;
+        function getOpacity: Double;
+        function getRotation: Double;
+        function getVisible: Boolean;
+
+        procedure setOptions(options: TGroundOverlayOptions);
+        procedure setVisible(visible: Boolean);
+      end;
+
+      THeading = class external name 'Heading'
+      public
+        class var East: Double;
+        class var North: Double;
+        class var South: Double;
+        class var West: Double;
+      end;
+
+      TInfobox = class external name 'Infobox'
+      public
+        constructor new(location: TLocation; options: TInfoboxOptions);
+
+        function getAnchor: TPoint;
+        function getDescription: String;
+        function getHeight: Double;
+        function getHtmlContent: String;
+        function getLocation: TLocation;
+        function getMaxHeight: Double;
+        function getMaxWidth: Double;
+        function getOffset: TPoint;
+        function getOptions: TInfoboxOptions;
+        function getShowCloseButton: Boolean;
+        function getShowPointer: Boolean;
+        function getTitle: String;
+        function getVisible: Boolean;
+        function getWidth: Double;
+        function getZIndex: Double;
+
+        procedure setHtmlContent(content: String);
+        procedure setLocation(loc: TLocation);
+        procedure setMap(Map: TMap);
+        procedure setOptions(options: TInfoboxOptions; ignoreDelay: Boolean);
+      end;
+
+      TLayerCollection = class external name 'LayerCollection'
+      public
+        length: Double;
+
+        function indexOf(layer: TLayer): Double;
+
+        procedure clear;
+        procedure insert(layer: TLayer);
+        procedure insertAll(layers: TArray<TLayer>);
+        procedure remove(layer: TLayer);
+        procedure removeAt(idx: Double);
+      end;
+
+      TLocation = class external name 'Location'
+      public
+        latitude: Double;
+        longitude: Double;
+
+        constructor new(latitude, longitude: Double);
+
+        class function areEqual(location1: TLocation; location2: TLocation): Boolean;
+        class function cloneFrom(source: TLocation): TLocation;
+        class function normalizeLongitude(longitude: Double): Double;
+        class function parseLatLong(str: String): TLocation;
+
+        function clone: TLocation;
+        function toString: String;
+      end;
+
+      TLocationRect = class external name 'LocationRect'
+      public
+        center: TLocation;
+        height: Double;
+        width: Double;
+
+        constructor new(center: TLocation; width: Double; height: Double);
+
+        class function fromCorners(northwest: TLocation; southeast: TLocation): TLocationRect;
+        class function fromEdges(north: Double; west: Double; south: Double; east: Double): TLocationRect;
+        class function fromLocations(locations: TArray<TLocation>): TLocationRect;
+        class function fromShapes(shapes: TArray<TArray<TPrimitive>>): TLocationRect; overload;
+        class function fromShapes(shapes: TArray<TPrimitive>): TLocationRect; overload;
+        class function fromString(str: String): TLocationRect;
+        class function merge(rect1: TLocationRect; rect2: TLocationRect): TLocationRect;
+
+        function clone: TLocationRect;
+        function contains(location: TLocation): Boolean;
+        function crossesInternationalDateLine: Boolean;
+        function getEast: Double;
+        function getNorth: Double;
+        function getNorthwest: TLocation;
+        function getSouth: Double;
+        function getSoutheast: TLocation;
+        function getWest: Double;
+        function intersects(rect: TLocationRect): Boolean;
+        function splitByInternationalDateLine: TArray<TLocationRect>;
+        function toString: String;
+
+        procedure buffer(percentage: Double);
+      end;
+
+      TMap = class external name 'Map'
+      public
+        layers: TLayerCollection;
+
+        constructor new(parentElement: String); overload;
+        constructor new(parentElement: String; options: TMapOptions); overload;
+        constructor new(parentElement: String; options: TViewOptions); overload;
+        constructor new(parentElement: TJSHTMLElement); overload;
+        constructor new(parentElement: TJSHTMLElement; options: TMapOptions); overload;
+        constructor new(parentElement: TJSHTMLElement; options: TViewOptions); overload;
+
+        class function getVersion: String;
+
+        function getBounds: TLocationRect;
+        function getCenter: TLocation;
+        function getCulture: String;
+        function getHeading: Double;
+        function getHeight: Double;
+        function getImageryId: String;
+        function getMapTypeId: TMapTypeId;
+        function getMetersPerPixel: Double;
+        function getOptions: TMapOptions;
+        function getPageX: Double;
+        function getPageY: Double;
+        function getPitch: Double;
+        function getRootElement: TJSHTMLElement;
+        function getUserRegion: String;
+        function getWidth: Double;
+        function getZoom: Double;
+        function getZoomRange: TRange;
+        function isMercator: Boolean;
+        function isRotationEnabled: Boolean;
+        function tryLocationToPixel(location: TArray<TLocation>; reference: JSValue): TArray<TPoint>;
+        function tryPixelToLocation(point: TArray<TPoint>; reference: JSValue): TArray<TLocation>;
+
+        class procedure getClosestPanorama(bounds: TLocationRect; success: TProc<TPanoramaInfo>; missingCoverage: TProc);
+
+        procedure dispose;
+        procedure getCopyrights(callback: TProc<TArray<String>>);
+        procedure getCredentials(callback: TProc<String>);
+        procedure setMapType(mapTypeId: TMapTypeId);
+        procedure setOptions(options: TMapOptions);
+        procedure setView(viewOptions: TViewOptions);
+      end;
+
+      TPoint = class external name 'Point'
+      public
+        x: Double;
+        y: Double;
+
+        constructor new(x: Double; y: Double);
+
+        function add(point: TPoint): TPoint;
+        function clone: TPoint;
+        function equals(point: TPoint; tolerance: Double): Boolean;
+        function subtract(point: TPoint): TPoint;
+        function toString: String;
+      end;
+
+      TPointCompression = class external name 'ointCompression'
+      public
+        class function decode(value: String): TArray<TLocation>;
+        class function encode(locations: TArray<TLocation>): String;
+      end;
+
+      TPolygon = class external name 'Polygon' (TPrimitive)
+      public
+        metadata: JSValue;
+
+        constructor new(rings: TArray<TArray<TLocation>>; options: TPolygonOptions); overload;
+        constructor new(rings: TArray<TLocation>; options: TPolygonOptions); overload;
+
+        function getCursor: String;
+        function getFillColor: TColor;
+        function getGeneralizable: Boolean;
+        function getLocations: TArray<TLocation>;
+        function getRings: TArray<TArray<TLocation>>;
+        function getStrokeColor: TColor;
+        function getStrokeDashArray: TArray<Double>;
+        function getStrokeDashArrayString: String; external name 'getStrokeDashArray';
+        function getStrokeThickness: Double;
+        function getVisible: Boolean;
+
+        procedure setLocations(locations: TArray<TLocation>);
+        procedure setOptions(options: TPolygonOptions);
+        procedure setRings(rings: TArray<TArray<TLocation>>); overload;
+        procedure setRings(rings: TArray<TLocation>); overload;
+      end;
+
+      TPolyline = class external name 'Polyline' (TPrimitive)
+      public
+        metadata: JSValue;
+
+        constructor new(locations: TArray<TLocation>; options: TPolylineOptions);
+
+        function getCursor: String;
+        function getGeneralizable: Boolean;
+        function getLocations: TArray<TLocation>;
+        function getStrokeColor: TColor;
+        function getStrokeDashArray: TArray<Double>;
+        function getStrokeDashArrayString: String; external name 'getStrokeDashArray';
+        function getStrokeThickness: Double;
+        function getVisible: Boolean;
+
+        procedure setLocations(locations: TArray<TLocation>);
+        procedure setOptions(options: TPolylineOptions);
+      end;
+
+      TPushpin = class external name 'Pushpin' (TPrimitive)
+      public
+        metadata: JSValue;
+
+        constructor new(location: TLocation; options: TPushpinOptions);
+
+        function getAnchor: TPoint;
+        function getClickedStyleEnabled: Boolean;
+        function getColor: TColor;
+        function getCursor: String;
+        function getDraggable: Boolean;
+        function getHoverStyleEnabled: Boolean;
+        function getIcon: String;
+        function getLocation: TLocation;
+        function getRoundClickableArea: Boolean;
+        function getSubTitle: String;
+        function getText: String;
+        function getTextOffset: TPoint;
+        function getTitle: String;
+        function getVisible: Boolean;
+
+        procedure setLocation(location: TLocation);
+        procedure setOptions(options: TPushpinOptions);
+      end;
+
+      TPyramidTileId = class external name 'PyramidTileId'
+      public
+        pixelHeight: Double;
+        pixelWidth: Double;
+        quadKey: String;
+        x: Double;
+        y: Double;
+        zoom: Double;
+
+        constructor new(x: Double; y: Double; zoom: Double; width: Double; height: Double);
+
+        class function areEqual(tileId1: TPyramidTileId; tileId2: TPyramidTileId): Boolean;
+        class function fromQuadKey(quadkey: String; width: Double; height: Double): TPyramidTileId;
+      end;
+
+      TTileLayer = class external name 'TileLayer' (TLayer)
+      public
+        metadata: JSValue;
+
+        constructor new(options: TTileLayerOptions);
+
+        function getOpacity: Double;
+        function getTileSource: TTileSource;
+        function getVisible: Boolean;
+        function getZIndex: Double;
+
+        procedure setOpacity(opacity: Double);
+        procedure setOptions(options: TTileLayerOptions);
+        procedure setVisible(show: Boolean);
+        procedure setZIndex(idx: Double);
+      end;
+
+      TTileSource = class external name 'TileSource'
+      public
+        constructor new(options: TTileSourceOptions);
+
+        function getBounds: TLocationRect;
+        function getHeight: Double;
+        function getMaxZoom: Double;
+        function getMinZoom: Double;
+        function getUriConstructor(tile: TPyramidTileId): String; overload;
+        function getUriConstructor: String; overload;
+        function getWidth: Double;
+      end;
+    public
+      class var Credentials: String;
+
+      procedure getIsBirdseyeAvailable(loc: TLocation; heading: Double; callback: TProc<Boolean>); overload;
+      procedure getIsBirdseyeAvailable(loc: TLocation; heading: THeading; callback: TProc<Boolean>); overload;
+      procedure loadModule(moduleName: TArray<String>; options: TModuleOptions); overload;
+      procedure loadModule(moduleName: TArray<String>; options: TProc); overload;
+      procedure moduleLoaded(moduleName: String);
+      procedure registerModule(moduleName: String; url: String; styles: TStyleUrl);
+    end;
+  end;
+
+  TAddress = class
+  public
+    addressLine: String;
+    adminDistrict: String;
+    countryRegion: String;
+    countryRegionISO2: String;
+    district: String;
+    formattedAddress: String;
+    locality: String;
+    postalCode: String;
+  end;
+
+  TAnimatedFrameEventArgs = class
+  public
+    animatedTileLayer: TMicrosoft.TMaps.TAnimatedTileLayer;
+    index: Double;
+  end;
+
+  TAnimatedTileLayerOptions = class
+  public
+    autoPlay: Boolean;
+    frameRate: Double;
+    loadingScreen: TMicrosoft.TMaps.TCustomOverlay;
+    maxTotalLoadTime: Double;
+    mercator: TArray<TMicrosoft.TMaps.TTileSource>;
+    visible: Boolean;
+  end;
+
+  TCustomOverlayOptions = class
+  public
+    beneathLabels: Boolean;
+  end;
+
+  TGroundOverlayOptions = class(TCustomOverlayOptions)
+  public
+    backgroundColor: TMicrosoft.TMaps.TColor;
+    bounds: TMicrosoft.TMaps.TLocationRect;
+    imageUrl: String;
+    opacity: Double;
+    rotation: Double;
+    visible: Boolean;
+  end;
+
+  THandlerId = class
+  end;
+
+  TInfoboxOptions  = class
+  public
+    description: String;
+    closeDelayTime: Double;
+    htmlContent: String;
+    location: TMicrosoft.TMaps.TLocation;
+    maxHeight: Double;
+    maxWidth: Double;
+    offset: TMicrosoft.TMaps.TPoint;
+    showCloseButton: Boolean;
+    showPointer: Boolean;
+    title: String;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TInfoboxEventArgs = class
+  public
+    eventName: String;
+    pageX: Double;
+    pageY: Double;
+    target: TMicrosoft.TMaps.TInfobox;
+    targetType: String;
+    originalEvent: TJSMouseEvent;
+  end;
+
+  TMapOptions = class
+  public
+    allowHidingLabelsOfRoad: Boolean;
+    allowInfoboxOverflow: Boolean;
+    backgroundColor: TMicrosoft.TMaps.TColor;
+    customMapStyle: TCustomMapStyle;
+    disableBirdseye: Boolean;
+    disableKeyboardInput: Boolean;
+    disableMapTypeSelectorMouseOver: Boolean;
+    disablePanning: Boolean;
+    disableScrollWheelZoom: Boolean;
+    disableStreetside: Boolean;
+    disableStreetsideAutoCoverage: Boolean;
+    disableZooming: Boolean;
+    enableClickableLogo: Boolean;
+    enableCORS: Boolean;
+    enableHighDpi: Boolean;
+    enableInertia: Boolean;
+    liteMode: Boolean;
+    maxBounds: TMicrosoft.TMaps.TLocationRect;
+    maxZoom: Double;
+    minZoom: Double;
+    navigationBarMode: TMicrosoft.TMaps.TNavigationBarMode;
+    navigationBarOrientation: TMicrosoft.TMaps.TNavigationBarOrientation;
+    showBreadcrumb: Boolean;
+    showDashboard: Boolean;
+    showLocateMeButton: Boolean;
+    showLogo: Boolean;
+    showMapTypeSelector: Boolean;
+    showScalebar: Boolean;
+    showTrafficButton: Boolean;
+    showTermsLink: Boolean;
+    showZoomButtons: Boolean;
+    streetsideOptions: TStreetsideOptions;
+    supportedMapTypes: TArray<TMicrosoft.TMaps.TMapTypeId>;
+  end;
+
+  TMapTypeChangeEventArgs = class
+  public
+    newMapTypeId: TMicrosoft.TMaps.TMapTypeId;
+    oldMapTypeId: TMicrosoft.TMaps.TMapTypeId;
+    target: TMicrosoft.TMaps.TMap;
+    targetType: String;
+  end;
+
+  TModuleOptions = class
+  public
+    errorCallback: TProc;
+    credentials: String;
+  end;
+
+  TMouseEventArgs = class
+  public
+    eventName: String;
+    isPrimary: Boolean;
+    isSecondary: Boolean;
+    layer: TMicrosoft.TMaps.TLayer;
+    location: TMicrosoft.TMaps.TLocation;
+    pageX: Double;
+    pageY: Double;
+    point: TMicrosoft.TMaps.TPoint;
+    target: TMicrosoft.TMaps.TMap;
+    targetPrimitive: TMicrosoft.TMaps.TPrimitive; external name 'target';
+    targetType: String;
+    wheelDelta: Double;
+  end;
+
+  TPanoramaInfo = class
+  public
+    cd: String;
+  end;
+
+  TPrimitiveChangedEventArgs = class
+  public
+    sender: TMicrosoft.TMaps.TPrimitive;
+    name: String;
+  end;
+
+  TPrimitiveOptions = class
+  public
+    cursor: String;
+    visible: Boolean;
+  end;
+
+  TPolylineOptions = class(TPrimitiveOptions)
+  public
+    generalizable: Boolean;
+    strokeColor: TMicrosoft.TMaps.TColor;
+    strokeDashArray: TArray<Double>;
+    strokeDashArrayString: String; external name 'strokeDashArray';
+    strokeThickness: Double;
+  end;
+
+  TPolygonOptions = class(TPolylineOptions)
+  public
+    fillColor: TMicrosoft.TMaps.TColor;
+  end;
+
+  TPushpinOptions = class(TPrimitiveOptions)
+  public
+    anchor: TMicrosoft.TMaps.TPoint;
+    color: TMicrosoft.TMaps.TColor;
+    draggable: Boolean;
+    enableClickedStyle: Boolean;
+    enableHoverStyle: Boolean;
+    icon: String;
+    roundClickableArea: Boolean;
+    subTitle: String;
+    title: String;
+    text: String;
+    textOffset: TMicrosoft.TMaps.TPoint;
+  end;
+
+  TRange = class
+  public
+    min: Double;
+    max: Double;
+  end;
+
+  TStreetsideOptions  = class
+  public
+    disablePanoramaNavigation: Boolean;
+    locationToLookAt: TMicrosoft.TMaps.TLocation;
+    onErrorLoading: TProc;
+    onSuccessLoading: TProc;
+    overviewMapMode: TMicrosoft.TMaps.TOverviewMapMode;
+    panoramaInfo: TPanoramaInfo;
+    panoramaLookupRadius: Double;
+    showCurrentAddress: Boolean;
+    showExitButton: Boolean;
+    showHeadingCompass: Boolean;
+    showProblemReporting: Boolean;
+    showZoomButtons: Boolean;
+  end;
+
+  TStylesOptions = class
+  public
+    pushpinOptions: TPushpinOptions;
+    polylineOptions: TPolylineOptions;
+    polygonOptions: TPolygonOptions;
+  end;
+
+  TStyleUrl = class
+  public
+    styleURLs: TArray<String>;
+  end;
+
+  TTileLayerOptions = class
+  public
+    enableCORS: Boolean;
+    downloadTimeout: Double;
+    mercator: TMicrosoft.TMaps.TTileSource;
+    opacity: Double;
+    useCredentialsForCORS: Boolean;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TTileSourceOptions = class
+  public
+    bounds: TMicrosoft.TMaps.TLocationRect;
+    maxZoom: Double;
+    minZoom: Double;
+    uriConstructor: String;
+    uriConstructorFunction: TFunc<TMicrosoft.TMaps.TPyramidTileId, String>; external name 'uriConstructor';
+  end;
+
+  TViewOptions = class
+  public
+    bounds: TMicrosoft.TMaps.TLocationRect;
+    center: TMicrosoft.TMaps.TLocation;
+    centerOffset: TMicrosoft.TMaps.TPoint;
+    heading: Double;
+    labelOverlay: TMicrosoft.TMaps.TLabelOverlay;
+    mapTypeId: TMicrosoft.TMaps.TMapTypeId;
+    padding: Double;
+    pitch: Double;
+    zoom: Double;
+  end;
+
+  TMapElementStyle = class
+  public
+    fillColor: String;
+    labelColor: String;
+    labelOutlineColor: String;
+    labelVisible: boolean;
+    strokeColor: String;
+    visible: Boolean;
+  end;
+
+  TBorderedMapElementStyle = class(TMapElementStyle)
+  public
+    borderOutlineColor: String;
+    borderStrokeColor: String;
+    borderVisible: Boolean;
+  end;
+
+  TSettingsStyle = class
+  public
+    landColor: String;
+    shadedReliefVisible: Boolean;
+  end;
+
+  TMapElements = class
+  public
+    adminDistrict: TBorderedMapElementStyle;
+    adminDistrictCapital: TMapElementStyle;
+    airport: TMapElementStyle;
+    area: TMapElementStyle;
+    arterialRoad: TMapElementStyle;
+    building: TMapElementStyle;
+    business: TMapElementStyle;
+    capital: TMapElementStyle;
+    cemetery: TMapElementStyle;
+    continent: TMapElementStyle;
+    controlledAccessHighway: TMapElementStyle;
+    countryRegion: TBorderedMapElementStyle;
+    countryRegionCapital: TMapElementStyle;
+    district: TBorderedMapElementStyle;
+    education: TMapElementStyle;
+    educationBuilding: TMapElementStyle;
+    foodPoint: TMapElementStyle;
+    forest: TMapElementStyle;
+    golfCourse: TMapElementStyle;
+    highSpeedRamp: TMapElementStyle;
+    highway: TMapElementStyle;
+    indigenousPeoplesReserve: TMapElementStyle;
+    island: TMapElementStyle;
+    majorRoad: TMapElementStyle;
+    mapElement: TMapElementStyle;
+    medical: TMapElementStyle;
+    medicalBuilding: TMapElementStyle;
+    military: TMapElementStyle;
+    naturalPoint: TMapElementStyle;
+    nautical: TMapElementStyle;
+    neighborhood: TMapElementStyle;
+    park: TMapElementStyle;
+    peak: TMapElementStyle;
+    playingField: TMapElementStyle;
+    point: TMapElementStyle;
+    pointOfInterest: TMapElementStyle;
+    political: TBorderedMapElementStyle;
+    populatedPlace: TMapElementStyle;
+    railway: TMapElementStyle;
+    ramp: TMapElementStyle;
+    reserve: TMapElementStyle;
+    river: TMapElementStyle;
+    road: TMapElementStyle;
+    roadExit: TMapElementStyle;
+    runway: TMapElementStyle;
+    sand: TMapElementStyle;
+    shoppingCenter: TMapElementStyle;
+    stadium: TMapElementStyle;
+    street: TMapElementStyle;
+    structure: TMapElementStyle;
+    tollRoad: TMapElementStyle;
+    trail: TMapElementStyle;
+    transit: TMapElementStyle;
+    transitBuilding: TMapElementStyle;
+    transportation: TMapElementStyle;
+    unpavedStreet: TMapElementStyle;
+    vegetation: TMapElementStyle;
+    volcanicPeak: TMapElementStyle;
+    water: TMapElementStyle;
+    waterPoint: TMapElementStyle;
+    waterRoute: TMapElementStyle;
+  end;
+
+  TCustomMapStyle = class
+  public
+    elements: TMapElements;
+    settings: TSettingsStyle;
+    version: String;
+  end;
+
+function InitializeMap(Key: String): TJSPromise;
+
+implementation
+
+function InitializeMap(Key: String): TJSPromise;
+begin
+  Result := TJSPromise.New(
+    procedure(Resolve, Reject: TJSPromiseResolver)
+    var
+      Script: TJSHTMLScriptElement;
+
+    begin
+      Script := TJSHTMLScriptElement(document.createElement('script'));
+      Script.async := False;
+      Script.src := Format('https://www.bing.com/maps/sdk/mapcontrol?key=%s', [Key]);
+      Script.onload :=
+        function(Event: TEventListenerEvent): Boolean
+        var
+          Options: TJSIdleCallbackOptions;
+
+        begin
+          Options := TJSIdleCallbackOptions.Create;
+          Options.timeOut := 100;
+
+          Window.requestIdleCallback(
+            procedure (idleDeadline: TJSIdleDeadline)
+            begin
+              Resolve(True);
+            end, Options);
+
+          Result := True;
+        end;
+
+      document.head.appendChild(Script);
+    end);
+end;
+
+end.
+
diff --git a/packages/maps/GeoJSON.pas b/packages/maps/GeoJSON.pas
new file mode 100644
index 00000000..ca5ad2cc
--- /dev/null
+++ b/packages/maps/GeoJSON.pas
@@ -0,0 +1,166 @@
+unit GeoJSON;
+
+interface
+
+{$modeswitch externalclass}
+
+uses JS;
+
+type
+  TBBox = TArray<Double>;
+  TPosition = TArray<Double>;
+
+  TGeoJsonObject = class
+  private
+    function GetForeignMember(name: String): JSValue; external name '[]';
+
+    procedure SetForeignMember(name: String; value: JSValue); external name '[]';
+  public
+    &type: String;
+    bbox: TBBox;
+
+    constructor Create(&type: String);
+
+    property ForeignMember[name: String]: JSValue read GetForeignMember write SetForeignMember; default;
+  end;
+
+  TGeometryObject = class(TGeoJsonObject)
+
+  end;
+
+  TPoint = class (TGeometryObject)
+  public
+    coordinates: TPosition;
+
+    constructor Create;
+  end;
+
+  TMultiPoint = class (TGeometryObject)
+  public
+    coordinates: TArray<TPosition>;
+    constructor Create;
+  end;
+
+  TLineString = class (TGeometryObject)
+  public
+    coordinates: TArray<TPosition>;
+
+    constructor Create;
+  end;
+
+  TMultiLineString = class (TGeometryObject)
+  public
+    coordinates: TArray<TArray<TPosition>>;
+
+    constructor Create;
+  end;
+
+  TPolygon = class(TGeometryObject)
+  public
+    coordinates: TArray<TArray<TPosition>>;
+
+    constructor Create;
+  end;
+
+  TMultiPolygon = class(TGeometryObject)
+  public
+    coordinates: TArray<TArray<TArray<TPosition>>>;
+
+    constructor Create;
+  end;
+
+  TGeometryCollection = class(TGeoJsonObject)
+  public
+    geometries: TArray<TGeometryObject>;
+
+    constructor Create;
+  end;
+
+  TFeature = class (TGeoJsonObject)
+    geometry: TGeometryObject;
+    id: String;
+    properties: TJSObject;
+
+    constructor Create;
+  end;
+
+  TFeatureCollection = class (TGeoJsonObject)
+  public
+    features: TArray<TGeoJsonObject>;
+
+    constructor Create;
+  end;
+
+implementation
+
+{ TGeoJsonObject }
+
+constructor TGeoJsonObject.Create(&type: String);
+begin
+  Self.&type := &type;
+end;
+
+{ TPoint }
+
+constructor TPoint.Create;
+begin
+  inherited Create('Point');
+end;
+
+{ TMultiPoint }
+
+constructor TMultiPoint.Create;
+begin
+  inherited Create('MultiPoint');
+end;
+
+{ TLineString }
+
+constructor TLineString.Create;
+begin
+  inherited Create('LineString');
+end;
+
+{ TMultiLineString }
+
+constructor TMultiLineString.Create;
+begin
+  inherited Create('MultiLineString');
+end;
+
+{ TPolygon }
+
+constructor TPolygon.Create;
+begin
+  inherited Create('Polygon');
+end;
+
+{ TMultiPolygon }
+
+constructor TMultiPolygon.Create;
+begin
+  inherited Create('MultiPolygon');
+end;
+
+{ TGeometryCollection }
+
+constructor TGeometryCollection.Create;
+begin
+  inherited Create('GeometryCollection');
+end;
+
+{ TFeature }
+
+constructor TFeature.Create;
+begin
+  inherited Create('Feature');
+end;
+
+{ TFeatureCollection }
+
+constructor TFeatureCollection.Create;
+begin
+  inherited Create('FeatureCollection');
+end;
+
+end.
diff --git a/packages/maps/Google.Maps.pas b/packages/maps/Google.Maps.pas
new file mode 100644
index 00000000..050675e2
--- /dev/null
+++ b/packages/maps/Google.Maps.pas
@@ -0,0 +1,2156 @@
+unit Google.Maps;
+
+interface
+
+{$modeswitch externalclass}
+
+uses JS, SysUtils, GeoJSON, Web;
+
+type
+  TAddFeatureEvent = class;
+  TAutocompleteOptions = class;
+  TAutocompletePrediction = class;
+  TAutocompleteResponse = class;
+  TAutocompleteSessionToken = class;
+  TAutocompletionRequest = class;
+  TCircleLiteral = class;
+  TCircleOptions = class;
+  TComponentRestrictions = class;
+  TDataOptions = class;
+  TDirectionsGeocodedWaypoint = class;
+  TDirectionsLeg = class;
+  TDirectionsRendererOptions = class;
+  TDirectionsRequest = class;
+  TDirectionsResult = class;
+  TDirectionsRoute = class;
+  TDirectionsStep = class;
+  TDirectionsWaypoint = class;
+  TDistance = class;
+  TDistanceMatrixRequest = class;
+  TDistanceMatrixResponse = class;
+  TDistanceMatrixResponseElement = class;
+  TDistanceMatrixResponseRow = class;
+  TDrawingControlOptions = class;
+  TDrawingManagerOptions = class;
+  TDrivingOptions = class;
+  TDuration = class;
+  TElevationResult = class;
+  TFeatureOptions = class;
+  TFindPlaceFromPhoneNumberRequest = class;
+  TFindPlaceFromQueryRequest = class;
+  TFullscreenControlOptions = class;
+  TGeoJsonOptions = class;
+  TGeocoderAddressComponent = class;
+  TGeocoderComponentRestrictions = class;
+  TGeocoderGeometry = class;
+  TGeocoderRequest = class;
+  TGeocoderResponse = class;
+  TGeocoderResult = class;
+  TGroundOverlayOptions = class;
+  THeatmapLayerOptions = class;
+  TIcon = class;
+  TIconMouseEvent = class;
+  TIconSequence = class;
+  TImageMapTypeOptions = class;
+  TInfoWindowOptions = class;
+  TKmlAuthor = class;
+  TKmlFeatureData = class;
+  TKmlLayerMetadata = class;
+  TKmlLayerOptions = class;
+  TKmlMouseEvent = class;
+  TLatLngBoundsLiteral = class;
+  TLatLngLiteral = class;
+  TLocationElevationRequest = class;
+  TLocationElevationResponse = class;
+  TMapCanvasProjection = class;
+  TMapMouseEvent = class;
+  TMapOptions = class;
+  TMapPanes = class;
+  TMapRestriction = class;
+  TMapType = class;
+  TMapTypeControlOptions = class;
+  TMapTypeStyle = class;
+  TMapsEventListener = class;
+  TMarkerLabel = class;
+  TMarkerOptions = class;
+  TMarkerShape = class;
+  TMaxZoomResult = class;
+  TMotionTrackingControlOptions = class;
+  TMouseEvent = class;
+  TOverlayCompleteEvent = class;
+  TPadding = class;
+  TPanControlOptions = class;
+  TPanoProviderOptions = class;
+  TPathElevationRequest = class;
+  TPathElevationResponse = class;
+  TPinOptions = class;
+  TPlace = class;
+  TPolyMouseEvent = class;
+  TPolygonOptions = class;
+  TPolylineOptions = class;
+  TPredictionSubstring = class;
+  TPredictionTerm = class;
+  TProjection = class;
+  TQueryAutocompletionRequest = class;
+  TRectangleOptions = class;
+  TRemoveFeatureEvent = class;
+  TRemovePropertyEvent = class;
+  TRotateControlOptions = class;
+  TScaleControlOptions = class;
+  TSearchBoxOptions = class;
+  TSetGeometryEvent = class;
+  TSetPropertyEvent = class;
+  TStreetViewAddressControlOptions = class;
+  TStreetViewControlOptions = class;
+  TStreetViewLink = class;
+  TStreetViewLocation = class;
+  TStreetViewLocationRequest = class;
+  TStreetViewPanoRequest = class;
+  TStreetViewPanoramaData = class;
+  TStreetViewPanoramaOptions = class;
+  TStreetViewPov = class;
+  TStreetViewResponse = class;
+  TStreetViewTileData = class;
+  TStructuredFormatting = class;
+  TStyleOptions = class;
+  TStyledMapTypeOptions = class;
+  TSymbol = class;
+  TTextSearchRequest = class;
+  TTimeGoogle = class;
+  TTrafficLayerOptions = class;
+  TTransitAgency = class;
+  TTransitDetails = class;
+  TTransitFare = class;
+  TTransitLine = class;
+  TTransitOptions = class;
+  TTransitStop = class;
+  TTransitVehicle = class;
+  TWeightedLocation = class;
+  TZoomControlOptions = class;
+
+  TGoogle = class external name 'google'
+  public type
+    TMaps = class external name 'maps'
+    public type
+      TLatLng = class;
+      TLatLngBounds = class;
+      TMap = class;
+      TMapTypeRegistry = class;
+      TOverlayType = class;
+      TPlacesServiceStatus = class;
+      TPoint = class;
+      TSize = class;
+      TStreetViewPanorama = class;
+
+      TAnimation = (BOUNCE, DROP);
+      TControlPosition = (BOTTOM_CENTER, BOTTOM_LEFT, BOTTOM_RIGHT, LEFT_BOTTOM, LEFT_CENTER, LEFT_TOP, RIGHT_BOTTOM, RIGHT_CENTER, RIGHT_TOP, TOP_CENTER, TOP_LEFT, TOP_RIGHT);
+      TMapTypeControlStyle = (DEFAULT, DROPDOWN_MENU, HORIZONTAL_BAR);
+      TStrokePosition = (CENTER, INSIDE, OUTSIDE);
+      TSymbolPath = (BACKWARD_CLOSED_ARROW, BACKWARD_OPEN_ARROW, CIRCLE, FORWARD_CLOSED_ARROW, FORWARD_OPEN_ARROW);
+      TUnitSystem = (IMPERIAL, METRIC);
+      TRankBy = (DISTANCE, PROMINENCE);
+
+      TMVCObject = class external name 'MVCObject'
+      public
+        function addListener(eventName: String; handler: TProc): TMapsEventListener;
+        procedure bindTo(key: String; target: TMVCObject; targetKey: String; noNotify: Boolean);
+        function get(key: String): JSValue;
+        procedure notify(key: String);
+        procedure &set(key: String; value: JSValue);
+        procedure setValues(values: TJSObject);
+        procedure unbind(key: String);
+        procedure unbindAll;
+      end;
+
+      TBicyclingLayer = class external name 'BicyclingLayer' (TMVCObject)
+      public
+        function getMap: TMap;
+        procedure setMap(map: TMap);
+      end;
+
+      TCircle = class external name 'Circle' (TMVCObject)
+      public
+        constructor new(opts: TCircleOptions);
+        function getBounds: TLatLngBounds;
+        function getCenter: TLatLng;
+        function getDraggable: Boolean;
+        function getEditable: Boolean;
+        function getMap: TMap;
+        function getRadius: Double;
+        function getVisible: Boolean;
+        procedure setCenter(center: TLatLng); overload;
+        procedure setCenter(center: TLatLngLiteral); overload;
+        procedure setDraggable(draggable: Boolean);
+        procedure setEditable(editable: Boolean);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TCircleOptions);
+        procedure setRadius(radius: Double);
+        procedure setVisible(visible: Boolean);
+      end;
+
+      TData = class external name 'Data' (TMVCObject)
+      public type
+        TGeometry = class;
+        TPolygon = class;
+
+        TFeature = class external name 'Feature'
+        public
+          constructor new(options: TFeatureOptions);
+
+          procedure forEachProperty(callback: TProc<JSValue, String>);
+          function getGeometry: TGeometry;
+          function getId: Double;
+          function getIdString: String; external name 'getId';
+          function getProperty(name: String): JSValue;
+          procedure removeProperty(name: String);
+          procedure setGeometry(newGeometry: TGeometry); overload;
+          procedure setGeometry(newGeometry: TLatLng); overload;
+          procedure setGeometry(newGeometry: TLatLngLiteral); overload;
+          procedure setProperty(name: String; newValue: JSValue);
+          procedure toGeoJson(callback: TProc<TJSObject>);
+        end;
+
+        TGeometry = class external name 'Geometry'
+        public
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getType: String;
+        end;
+
+        TGeometryCollection = class external name 'GeometryCollection' (TGeometry)
+        public
+          constructor new(elements: TArray<TGeometry>); overload;
+          constructor new(elements: TArray<TLatLng>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TGeometry>;
+          function getAt(n: Double): TGeometry;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TLineString = class external name 'LineString' (TGeometry)
+        public
+          constructor new(elements: TArray<TLatLng>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TLatLng>;
+          function getAt(n: Double): TLatLng;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TLinearRing = class external name 'LinearRing' (TGeometry)
+        public
+          constructor new(elements: TArray<TLatLng>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TLatLng>;
+          function getAt(n: Double): TLatLng;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TMultiLineString = class external name 'MultiLineString' (TGeometry)
+        public
+          constructor new(elements: TArray<TLatLng>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TLineString>;
+          function getAt(n: Double): TLineString;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TMultiPoint = class external name 'MultiPoint' (TGeometry)
+        public
+          constructor new(elements: TArray<TLatLng>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TLatLng>;
+          function getAt(n: Double): TLatLng;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TMultiPolygon = class external name 'MultiPolygon' (TGeometry)
+        public
+          constructor new(elements: TArray<TLatLng>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+          constructor new(elements: TArray<TLinearRing>); overload;
+          constructor new(elements: TArray<TPolygon>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+
+          function getArray: TArray<TPolygon>;
+          function getAt(n: Double): TPolygon;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TPoint = class external name 'Point' (TGeometry)
+        public
+          constructor new(elements: TArray<TLatLng>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function get: TLatLng;
+          function getType: String;
+        end;
+
+        TPolygon = class external name 'Polygon' (TGeometry)
+        public
+          constructor new(elements: TArray<TArray<TLatLng>>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TLinearRing>;
+          function getAt(n: Double): TLinearRing;
+          function getLength: Double;
+          function getType: String;
+        end;
+      public
+        constructor new(options: TDataOptions);
+        function add(feature: TFeature): TFeature; overload;
+        function add(feature: TFeatureOptions): TFeature; overload;
+        function addGeoJson(geoJson: TGeoJSONObject; options: TGeoJsonOptions): TArray<TFeature>;
+        function contains(feature: TFeature): Boolean;
+        procedure forEach(callback: TProc<TFeature>);
+        function getControlPosition: TControlPosition;
+        function getControls: TArray<String>;
+        function getDrawingMode: String;
+        function getFeatureById(id: Double): TFeature; overload;
+        function getFeatureById(id: String): TFeature; overload;
+        function getMap: TMap;
+        function getStyle: TStyleOptions;
+        function getStyleFunction: TFunc<TFeature, TStyleOptions>; external name 'getStyle';
+        procedure loadGeoJson(url: String; options: TGeoJsonOptions; callback: TProc<TArray<TFeature>>);
+        procedure overrideStyle(feature: TFeature; style: TStyleOptions);
+        procedure remove(feature: TFeature);
+        procedure revertStyle(feature: TFeature);
+        procedure setControlPosition(controlPosition: TControlPosition);
+        procedure setControls(controls: TArray<String>);
+        procedure setDrawingMode(drawingMode: String);
+        procedure setMap(map: TMap);
+        procedure setStyle(style: TStyleOptions); overload;
+        procedure setStyle(style: TFunc<TFeature, TStyleOptions>); overload;
+        procedure toGeoJson(callback: TProc<TGeoJSONObject>);
+      end;
+
+      TDirectionsRenderer = class external name 'DirectionsRenderer' (TMVCObject)
+      public
+        constructor new(opts: TDirectionsRendererOptions);
+        function getDirections: TDirectionsResult;
+        function getMap: TMap;
+        function getPanel: TJSNode;
+        function getRouteIndex: Double;
+        procedure setDirections(directions: TDirectionsResult);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TDirectionsRendererOptions);
+        procedure setPanel(panel: TJSNode);
+        procedure setRouteIndex(routeIndex: Double);
+      end;
+
+      TDirectionsStatus = class
+      public const
+        INVALID_REQUEST = 'INVALID_REQUEST';
+        MAX_WAYPOINTS_EXCEEDED = 'MAX_WAYPOINTS_EXCEEDED';
+        NOT_FOUND = 'NOT_FOUND';
+        OK = 'OK';
+        OVER_QUERY_LIMIT = 'OVER_QUERY_LIMIT';
+        REQUEST_DENIED = 'REQUEST_DENIED';
+        UNKNOWN_ERROR = 'UNKNOWN_ERROR';
+        ZERO_RESULTS = 'ZERO_RESULTS';
+      end;
+
+      TDirectionsService = class external name 'DirectionsService'
+      public
+        function route(request: TDirectionsRequest; callback: TProc<TDirectionsResult, TDirectionsStatus>): TJSPromise;
+      end;
+
+      TDistanceMatrixService = class external name 'DistanceMatrixService'
+      public type
+        TDistanceMatrixStatus = (INVALID_REQUEST, MAX_DIMENSIONS_EXCEEDED, MAX_ELEMENTS_EXCEEDED, OK, OVER_QUERY_LIMIT, REQUEST_DENIED, UNKNOWN_ERROR);
+      public
+        function getDistanceMatrix(request: TDistanceMatrixRequest; callback: TProc<TDistanceMatrixResponse, TDistanceMatrixStatus>): TJSPromise;
+      end;
+
+      TElevationStatus = class
+      public const
+        INVALID_REQUEST = 'INVALID_REQUEST';
+        OK = 'OK';
+        OVER_QUERY_LIMIT = 'OVER_QUERY_LIMIT';
+        REQUEST_DENIED = 'REQUEST_DENIED';
+        UNKNOWN_ERROR = 'UNKNOWN_ERROR';
+      end;
+
+      TElevationService = class external name 'ElevationService'
+      public
+        function getElevationAlongPath(request: TPathElevationRequest; callback: TProc<TArray<TElevationResult>, TElevationStatus>): TJSPromise;
+        function getElevationForLocations(request: TLocationElevationRequest; callback: TProc<TArray<TElevationResult>, TElevationStatus>): TJSPromise;
+      end;
+
+      TGeocoderStatus = class
+      public const
+        ERROR = 'ERROR';
+        INVALID_REQUEST = 'INVALID_REQUEST';
+        OK = 'OK';
+        OVER_QUERY_LIMIT = 'OVER_QUERY_LIMIT';
+        REQUEST_DENIED = 'REQUEST_DENIED';
+        UNKNOWN_ERROR = 'UNKNOWN_ERROR';
+        ZERO_RESULTS = 'ZERO_RESULTS';
+      end;
+
+      TGeocoder = class external name 'Geocoder'
+      public
+        function geocode(request: TGeocoderRequest; callback: TProc<TArray<TGeocoderResult>, TGeocoderStatus>): TJSPromise;
+      end;
+
+      TGroundOverlay = class external name 'GroundOverlay' (TMVCObject)
+      public
+        constructor new(url: String; bounds: TLatLngBounds; opts: TGroundOverlayOptions); overload;
+        constructor new(url: String; bounds: TLatLngBoundsLiteral; opts: TGroundOverlayOptions); overload;
+        function getBounds: TLatLngBounds;
+        function getMap: TMap;
+        function getOpacity: Double;
+        function getUrl: String;
+        procedure setMap(map: TMap);
+        procedure setOpacity(opacity: Double);
+      end;
+
+      TImageMapType = class external name 'ImageMapType' (TMVCObject)
+      public
+        alt: String;
+        maxZoom: Double;
+        minZoom: Double;
+        name: String;
+        projection: TProjection;
+        radius: Double;
+        tileSize: TSize;
+
+        constructor new(opts: TImageMapTypeOptions);
+
+        function getOpacity: Double;
+        function getTile(tileCoord: TPoint; zoom: Double; ownerDocument: TJSDocument): TJSNode;
+        procedure releaseTile(tileDiv: TJSNode);
+        procedure setOpacity(opacity: Double);
+      end;
+
+      TInfoWindow = class external name 'InfoWindow' (TMVCObject)
+      public
+        constructor new(opts: TInfoWindowOptions);
+        procedure close;
+        function getContent: TJSNode;
+        function getContentString: String; external name 'getContent';
+        function getPosition: TLatLng;
+        function getZIndex: Double;
+        procedure open(map: TMap; anchor: TMVCObject); overload;
+        procedure open(map: TStreetViewPanorama; anchor: TMVCObject); overload;
+        procedure setContent(content: TJSNode); overload;
+        procedure setContent(content: String); overload;
+        procedure setOptions(options: TInfoWindowOptions);
+        procedure setPosition(position: TLatLng); overload;
+        procedure setPosition(position: TLatLngLiteral); overload;
+        procedure setZIndex(zIndex: Double);
+      end;
+
+      TKmlLayerStatus = class external name 'KmlLayerStatus'
+      public const
+        DOCUMENT_NOT_FOUND = 'DOCUMENT_NOT_FOUND';
+        DOCUMENT_TOO_LARGE = 'DOCUMENT_TOO_LARGE';
+        FETCH_ERROR = 'FETCH_ERROR';
+        INVALID_DOCUMENT = 'INVALID_DOCUMENT';
+        INVALID_REQUEST = 'INVALID_REQUEST';
+        LIMITS_EXCEEDED = 'LIMITS_EXCEEDED';
+        OK = 'OK';
+        TIMED_OUT = 'TIMED_OUT';
+        UNKNOWN = 'UNKNOWN';
+      end;
+
+      TKmlLayer = class external name 'KmlLayer' (TMVCObject)
+      public
+        constructor new(opts: TKmlLayerOptions);
+        function getDefaultViewport: TLatLngBounds;
+        function getMap: TMap;
+        function getMetadata: TKmlLayerMetadata;
+        function getStatus: TKmlLayerStatus;
+        function getUrl: String;
+        function getZIndex: Double;
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TKmlLayerOptions);
+        procedure setUrl(url: String);
+        procedure setZIndex(zIndex: Double);
+      end;
+
+      TLatLng = class external name 'LatLng'
+      public
+        constructor new(lat, lng: Double); overload;
+        constructor new(lat, lng: Double; lngOrNoWrap, noWrap: Boolean); overload;
+        constructor new(latLngLiteral: TLatLngLiteral); overload;
+        constructor new(latLngLiteral: TLatLngLiteral; lngOrNoWrap, noWrap: Boolean); overload;
+        function equals(other: TLatLng): Boolean;
+        function lat: Double;
+        function lng: Double;
+        function toJSON: TLatLngLiteral;
+        function toString: String;
+        function toUrlValue(precision: Double): String;
+      end;
+
+      TLatLngBounds = class external name 'LatLngBounds'
+      public
+        constructor new(sw, ne: TLatLng); overload;
+        constructor new(sw, ne: TLatLngLiteral); overload;
+        function contains(latLng: TLatLng): Boolean; overload;
+        function contains(latLng: TLatLngLiteral): Boolean; overload;
+        function equals(other: TLatLng): Boolean; overload;
+        function equals(other: TLatLngBounds): Boolean; overload;
+        function extend(point: TLatLng): TLatLngBounds; overload;
+        function extend(point: TLatLngLiteral): TLatLngBounds; overload;
+        function getCenter: TLatLng;
+        function getNorthEast: TLatLng;
+        function getSouthWest: TLatLng;
+        function intersects(other: TLatLngBounds): Boolean; overload;
+        function intersects(other: TLatLngBoundsLiteral): Boolean; overload;
+        function isEmpty: Boolean;
+        function toJSON: TLatLngBoundsLiteral;
+        function toSpan: TLatLng;
+        function toString: String;
+        function toUrlValue(precision: Double): String;
+        function union(other: TLatLngBounds): TLatLngBounds; overload;
+        function union(other: TLatLngBoundsLiteral): TLatLngBounds; overload;
+      end;
+
+      TMVCArray<T> = class external name 'MVCArray' (TMVCObject)
+      public
+        constructor new(&array: TArray<T>);
+        procedure clear;
+        procedure forEach(callback: TProc<T, Double>);
+        function getArray: TArray<T>;
+        function getAt(i: Double): T;
+        function getLength: Double;
+        procedure insertAt(i: Double; elem: T);
+        function pop: T;
+        function push(elem: T): Double;
+        function removeAt(i: Double): T;
+        procedure setAt(i: Double; elem: T);
+      end;
+
+      TMapTypeId = class external name 'MapTypeId'
+      public const
+        HYBRID = 'HYBRID';
+        ROADMAP = 'ROADMAP';
+        SATELLITE = 'SATELLITE';
+        TERRAIN = 'TERRAIN';
+      end;
+
+      TMap = class external name 'Map' (TMVCObject)
+      public
+        controls: TArray<TMVCArray<JSValue>>;
+        data: TData;
+        mapTypes: TMapTypeRegistry;
+        overlayMapTypes: TMVCArray<JSValue>;
+
+        constructor new(mapDiv: TJSHTMLElement; opts: TMapOptions);
+
+        function getBounds: TLatLngBounds;
+        function getCenter: TLatLng;
+        function getClickableIcons: Boolean;
+        function getDiv: TJSHTMLElement;
+        function getHeading: Double;
+        function getMapTypeId: String;
+        function getProjection: TProjection;
+        function getStreetView: TStreetViewPanorama;
+        function getTilt: Double;
+        function getZoom: Double;
+
+        procedure fitBounds(bounds: TLatLngBounds; padding: Double); overload;
+        procedure fitBounds(bounds: TLatLngBounds; padding: TPadding); overload;
+        procedure fitBounds(bounds: TLatLngBoundsLiteral; padding: Double); overload;
+        procedure fitBounds(bounds: TLatLngBoundsLiteral; padding: TPadding); overload;
+        procedure panBy(x, y: Double);
+        procedure panTo(latLng: TLatLng); overload;
+        procedure panTo(latLng: TLatLngLiteral); overload;
+        procedure panToBounds(bounds: TLatLngBounds; padding: Double); overload;
+        procedure panToBounds(bounds: TLatLngBounds; padding: TPadding); overload;
+        procedure panToBounds(bounds: TLatLngBoundsLiteral; padding: Double); overload;
+        procedure panToBounds(bounds: TLatLngBoundsLiteral; padding: TPadding); overload;
+        procedure setCenter(latlng: TLatLng); overload;
+        procedure setCenter(latlng: TLatLngLiteral); overload;
+        procedure setClickableIcons(value: Boolean);
+        procedure setHeading(heading: Double);
+        procedure setMapTypeId(mapTypeId: String);
+        procedure setOptions(options: TMapOptions);
+        procedure setStreetView(panorama: TStreetViewPanorama);
+        procedure setTilt(tilt: Double);
+        procedure setZoom(zoom: Double);
+      end;
+
+      TMapTypeRegistry = class external name 'MapTypeRegistry' (TMVCObject)
+      public
+        procedure &set(id: String; mapType: JSValue);
+      end;
+
+      TMarker = class external name 'Marker' (TMVCObject)
+      public
+        constructor new(opts: TMarkerOptions);
+        function getAnimation: TAnimation;
+        function getClickable: Boolean;
+        function getCursor: String;
+        function getDraggable: Boolean;
+        function getIcon: JSValue;
+        function getLabel: TMarkerLabel;
+        function getMap: TMap;
+        function getStreetViewPanorama: TStreetViewPanorama; external name 'getMap';
+        function getOpacity: Double;
+        function getPosition: TLatLng;
+        function getShape: TMarkerShape;
+        function getTitle: String;
+        function getVisible: Boolean;
+        function getZIndex: Double;
+        procedure setAnimation(animation: TAnimation);
+        procedure setClickable(flag: Boolean);
+        procedure setCursor(cursor: String);
+        procedure setDraggable(flag: Boolean);
+        procedure setIcon(icon: String); overload;
+        procedure setIcon(icon: TIcon); overload;
+        procedure setIcon(icon: TSymbol); overload;
+        procedure setLabel(&label: String); overload;
+        procedure setLabel(&label: TMarkerLabel); overload;
+        procedure setMap(map: TMap); overload;
+        procedure setMap(map: TStreetViewPanorama); overload;
+        procedure setOpacity(opacity: Double);
+        procedure setOptions(options: TMarkerOptions);
+        procedure setPosition(latlng: TLatLng); overload;
+        procedure setPosition(latlng: TLatLngLiteral); overload;
+        procedure setShape(shape: TMarkerShape);
+        procedure setTitle(title: String);
+        procedure setVisible(visible: Boolean);
+        procedure setZIndex(zIndex: Double);
+
+        class var MAX_ZINDEX: Double;
+      end;
+
+      TMaxZoomService = class external name 'MaxZoomService'
+      public
+        function getMaxZoomAtLatLng(latlng: TLatLng; callback: TProc<TMaxZoomResult>): TJSPromise; overload;
+        function getMaxZoomAtLatLng(latlng: TLatLngLiteral; callback: TProc<TMaxZoomResult>): TJSPromise; overload;
+      end;
+
+      TOverlayView = class external name 'OverlayView' (TMVCObject)
+      public
+        procedure draw;
+        function getMap: TMap;
+        function getMapStreetViewPanorama: TStreetViewPanorama; external name 'getMap';
+        function getPanes: TMapPanes;
+        function getProjection: TMapCanvasProjection;
+        procedure onAdd;
+        procedure onRemove;
+        procedure setMap(map: TMap); overload;
+        procedure setMap(map: TStreetViewPanorama); overload;
+        class procedure preventMapHitsAndGesturesFrom(this: JSValue; element: TJSHTMLElement);
+        class procedure preventMapHitsFrom(this: JSValue; element: TJSHTMLElement);
+      end;
+
+      TPoint = class external name 'Point'
+      public
+        x: Double;
+        y: Double;
+
+        constructor new(x, y: Double);
+        function equals(other: TPoint): Boolean;
+        function toString: String;
+      end;
+
+      TPolygon = class external name 'Polygon' (TMVCObject)
+      public
+        constructor new(opts: TPolygonOptions);
+        function getDraggable: Boolean;
+        function getEditable: Boolean;
+        function getMap: TMap;
+        function getPath: TMVCArray<JSValue>;
+        function getPaths: TMVCArray<JSValue>;
+        function getVisible: Boolean;
+        procedure setDraggable(draggable: Boolean);
+        procedure setEditable(editable: Boolean);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TPolygonOptions);
+        procedure setPath(path: TMVCArray<JSValue>); overload;
+        procedure setPath(path: TArray<TLatLng>); overload;
+        procedure setPath(path: TArray<TLatLngLiteral>); overload;
+        procedure setPaths(paths: TMVCArray<JSValue>); overload;
+        procedure setPaths(paths: TArray<JSValue>); overload;
+        procedure setVisible(visible: Boolean);
+      end;
+
+      TPolyline = class external name 'Polyline' (TMVCObject)
+      public
+        constructor new(opts: TPolylineOptions);
+        function getDraggable: Boolean;
+        function getEditable: Boolean;
+        function getMap: TMap;
+        function getPath: TMVCArray<JSValue>;
+        function getVisible: Boolean;
+        procedure setDraggable(draggable: Boolean);
+        procedure setEditable(editable: Boolean);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TPolylineOptions);
+        procedure setPath(path: TMVCArray<JSValue>); overload;
+        procedure setPath(path: TArray<TLatLng>); overload;
+        procedure setPath(path: TArray<TLatLngLiteral>); overload;
+        procedure setVisible(visible: Boolean);
+      end;
+
+      TRectangle = class external name 'Rectangle' (TMVCObject)
+      public
+        constructor new(opts: TRectangleOptions);
+        function getBounds: TLatLngBounds;
+        function getDraggable: Boolean;
+        function getEditable: Boolean;
+        function getMap: TMap;
+        function getVisible: Boolean;
+        procedure setBounds(bounds: TLatLngBounds); overload;
+        procedure setBounds(bounds: TLatLngBoundsLiteral); overload;
+        procedure setDraggable(draggable: Boolean);
+        procedure setEditable(editable: Boolean);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TRectangleOptions);
+        procedure setVisible(visible: Boolean);
+      end;
+
+      TSize = class external name 'Size'
+      public
+        height: Double;
+        width: Double;
+
+        constructor new(width, height: Double; widthUnit, heightUnit: String);
+        function equals(other: TSize): Boolean;
+        function toString: String;
+      end;
+
+      TStreetViewCoverageLayer = class external name 'StreetViewCoverageLayer' (TMVCObject)
+      public
+        function getMap: TMap;
+        procedure setMap(map: TMap);
+      end;
+
+      TStreetViewStatus = class external name 'StreetViewStatus'
+      public const
+        OK = 'OK';
+        UNKNOWN_ERROR = 'UNKNOWN_ERROR';
+        ZERO_RESULTS = 'ZERO_RESULTS';
+      end;
+
+      TStreetViewPanorama = class external name 'StreetViewPanorama' (TMVCObject)
+      public
+        controls: TArray<TMVCArray<JSValue>>;
+
+        constructor new(container: TJSHTMLElement; opts: TStreetViewPanoramaOptions);
+        function getLinks: TArray<TStreetViewLink>;
+        function getLocation: TStreetViewLocation;
+        function getMotionTracking: Boolean;
+        function getPano: String;
+        function getPhotographerPov: TStreetViewPov;
+        function getPosition: TLatLng;
+        function getPov: TStreetViewPov;
+        function getStatus: TStreetViewStatus;
+        function getVisible: Boolean;
+        function getZoom: Double;
+        procedure registerPanoProvider(provider: TFunc<String, TStreetViewPanoramaData>; opt_options: TPanoProviderOptions);
+        procedure setLinks(links: TArray<TStreetViewLink>);
+        procedure setMotionTracking(motionTracking: Boolean);
+        procedure setOptions(options: TStreetViewPanoramaOptions);
+        procedure setPano(pano: String);
+        procedure setPosition(latLng: TLatLng); overload;
+        procedure setPosition(latLng: TLatLngLiteral); overload;
+        procedure setPov(pov: TStreetViewPov);
+        procedure setVisible(flag: Boolean);
+        procedure setZoom(zoom: Double);
+      end;
+
+      TStreetViewService = class external name 'StreetViewService'
+      public
+        function getPanorama(request: TStreetViewLocationRequest; callback: TProc<TStreetViewPanoramaData, TStreetViewStatus>): TJSPromise; overload;
+        function getPanorama(request: TStreetViewPanoRequest; callback: TProc<TStreetViewPanoramaData, TStreetViewStatus>): TJSPromise; overload;
+      end;
+
+      TStyledMapType = class external name 'StyledMapType' (TMVCObject)
+      public
+        alt: String;
+        maxZoom: Double;
+        minZoom: Double;
+        name: String;
+        projection: TProjection;
+        radius: Double;
+        tileSize: TSize;
+        constructor new(styles: TArray<TMapTypeStyle>; options: TStyledMapTypeOptions);
+        function getTile(tileCoord: TPoint; zoom: Double; ownerDocument: TJSDocument): TJSNode;
+        procedure releaseTile(tile: TJSNode);
+      end;
+
+      TTrafficLayer = class external name 'TrafficLayer' (TMVCObject)
+      public
+        constructor new(opts: TTrafficLayerOptions);
+        function getMap: TMap;
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TTrafficLayerOptions);
+      end;
+
+      TTransitLayer = class external name 'TransitLayer' (TMVCObject)
+      public
+        function getMap: TMap;
+        procedure setMap(map: TMap);
+      end;
+
+      TDrawingManager = class external name 'DrawingManager' (TMVCObject)
+      public
+        constructor new(options: TDrawingManagerOptions);
+        function getDrawingMode: TOverlayType;
+        function getMap: TMap;
+        procedure setDrawingMode(drawingMode: TOverlayType);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TDrawingManagerOptions);
+      end;
+
+      TEvent = class external name 'event'
+      public
+        function addDomListener(instance: TJSObject; eventName: String; handler: TProc; capture: Boolean): TMapsEventListener;
+        function addDomListenerOnce(instance: TJSObject; eventName: String; handler: TProc; capture: Boolean): TMapsEventListener;
+        function addListener(instance: TJSObject; eventName: String; handler: TProc): TMapsEventListener;
+        function addListenerOnce(instance: TJSObject; eventName: String; handler: TProc): TMapsEventListener;
+        procedure clearInstanceListeners(instance: TJSObject);
+        procedure clearListeners(instance: TJSObject; eventName: String);
+        procedure removeListener(listener: TMapsEventListener);
+        procedure trigger(instance: TJSObject; eventName: String); varargs;
+      end;
+
+      TGeometry = class external name 'geometry'
+      public type
+        TEncoding = class external name 'encoding'
+        public
+          function decodePath(encodedPath: String): TArray<TLatLng>;
+          function encodePath(path: TArray<TLatLng>): String; overload;
+          function encodePath(path: TMVCArray<JSValue>): String; overload;
+        end;
+
+        TPoly = class external name 'poly'
+        public
+          function containsLocation(point: TLatLng; polygon: TGoogle.TMaps.TPolygon): Boolean;
+          function isLocationOnEdge(point: TLatLng; poly: TGoogle.TMaps.TPolygon; tolerance: Double): Boolean; overload;
+          function isLocationOnEdge(point: TLatLng; poly: TGoogle.TMaps.TPolyline; tolerance: Double): Boolean; overload;
+        end;
+
+        TSpherical = class external name 'spherical'
+        public
+          function computeArea(path: TArray<TLatLng>; radius: Double): Double; overload;
+          function computeArea(path: TMVCArray<JSValue>; radius: Double): Double; overload;
+          function computeDistanceBetween(from: TLatLng; &to: TLatLng; radius: Double): Double;
+          function computeHeading(from: TLatLng; &to: TLatLng): Double;
+          function computeLength(path: TArray<TLatLng>; radius: Double): Double; overload;
+          function computeLength(path: TMVCArray<JSValue>; radius: Double): Double; overload;
+          function computeOffset(from: TLatLng; distance, heading, radius: Double): TLatLng;
+          function computeOffsetOrigin(&to: TLatLng; distance, heading, radius: Double): TLatLng;
+          function computeSignedArea(loop: TArray<TLatLng>; radius: Double): Double; overload;
+          function computeSignedArea(loop: TMVCArray<JSValue>; radius: Double): Double; overload;
+          function interpolate(from, &to: TLatLng; fraction: Double): TLatLng;
+        end;
+      end;
+
+      TVisualization = class external name 'visualization'
+      public type
+        THeatmapLayer = class external name 'HeatmapLayer' (TMVCObject)
+        public
+          constructor new(opts: THeatmapLayerOptions);
+          function getData: TMVCArray<JSValue>;
+          function getMap: TMaps;
+          procedure setData(data: TMVCArray<JSValue>); overload;
+          procedure setData(data: TArray<TLatLng>); overload;
+          procedure setData(data: TArray<TWeightedLocation>); overload;
+          procedure setMap(map: TMap);
+          procedure setOptions(options: THeatmapLayerOptions);
+        end;
+      end;
+
+      TStreetViewPreference = class external name 'StreetViewPreference'
+      public const
+        BEST = 'BEST';
+        NEAREST = 'NEAREST';
+      end;
+
+      TMaxZoomStatus = class external name 'MaxZoomStatus'
+      public const
+        ERROR = 'ERROR';
+        OK = 'OK';
+      end;
+
+      TGeocoderLocationType = class external name 'GeocoderLocationType'
+      public const
+        APPROXIMATE = 'APPROXIMATE';
+        GEOMETRIC_CENTER = 'GEOMETRIC_CENTER';
+        RANGE_INTERPOLATED = 'RANGE_INTERPOLATED';
+        ROOFTOP = 'ROOFTOP';
+      end;
+
+      TTrafficModel = class external name 'TrafficModel'
+      public const
+        BEST_GUESS = 'BEST_GUESS';
+        OPTIMISTIC = 'OPTIMISTIC';
+        PESSIMISTIC = 'PESSIMISTIC';
+      end;
+
+      TTransitMode = class external name 'TransitMode'
+      public const
+        BUS = 'BUS';
+        RAIL = 'RAIL';
+        SUBWAY = 'SUBWAY';
+        TRAIN = 'TRAIN';
+        TRAM = 'TRAM';
+      end;
+
+      TTransitRoutePreference = class external name 'TransitRoutePreference'
+      public const
+        FEWER_TRANSFERS = 'FEWER_TRANSFERS';
+        LESS_WALKING = 'LESS_WALKING';
+      end;
+
+      TTravelMode = class external name 'TravelMode'
+      public const
+        BICYCLING = 'BICYCLING';
+        DRIVING = 'DRIVING';
+        TRANSIT = 'TRANSIT';
+        WALKING = 'WALKING';
+      end;
+
+      TOverlayType = class external name 'OverlayType'
+      public const
+        CIRCLE = 'CIRCLE';
+        MARKER = 'MARKER';
+        POLYGON = 'POLYGON';
+        POLYLINE = 'POLYLINE';
+        RECTANGLE = 'RECTANGLE';
+      end;
+
+      TBusinessStatus = class external name 'BusinessStatus'
+      public const
+        CLOSED_PERMANENTLY = 'CLOSED_PERMANENTLY';
+        CLOSED_TEMPORARILY = 'CLOSED_TEMPORARILY';
+        OPERATIONAL = 'OPERATIONAL';
+      end;
+
+      TPlacesServiceStatus = class external name 'PlacesServiceStatus'
+      public const
+        INVALID_REQUEST = 'INVALID_REQUEST';
+        NOT_FOUND = 'NOT_FOUND';
+        OK = 'OK';
+        OVER_QUERY_LIMIT = 'OVER_QUERY_LIMIT';
+        REQUEST_DENIED = 'REQUEST_DENIED';
+        UNKNOWN_ERROR = 'UNKNOWN_ERROR';
+        ZERO_RESULTS = 'ZERO_RESULTS';
+      end;
+
+      TDistanceMatrixElementStatus = class
+      public const
+        NOT_FOUND = 'NOT_FOUND';
+        OK = 'OK';
+        ZERO_RESULTS = 'ZERO_RESULTS';
+      end;
+
+      TStreetViewSource = class
+      public const
+        DEFAULT = 'DEFAULT';
+        OUTDOOR = 'OUTDOOR';
+      end;
+
+      TVehicleType = class
+      public const
+        BUS = 'BUS';
+        CABLE_CAR = 'CABLE_CAR';
+        COMMUTER_TRAIN = 'COMMUTER_TRAIN';
+        COMMUTER_TRAINCOMMUTER_TRAINCOMMUTER_TRAINCOMMUTER_TRAINFERRY = 'COMMUTER_TRAINCOMMUTER_TRAINCOMMUTER_TRAINCOMMUTER_TRAINFERRY';
+        FUNICULAR = 'FUNICULAR';
+        GONDOLA_LIFT = 'GONDOLA_LIFT';
+        HEAVY_RAIL = 'HEAVY_RAIL';
+        HIGH_SPEED_TRAIN = 'HIGH_SPEED_TRAIN';
+        INTERCITY_BUS = 'INTERCITY_BUS';
+        METRO_RAIL = 'METRO_RAIL';
+        MONORAIL = 'MONORAIL';
+        OTHER = 'OTHER';
+        RAIL = 'RAIL';
+        SHARE_TAXI = 'SHARE_TAXI';
+        SUBWAY = 'SUBWAY';
+        TRAM = 'TRAM';
+        TROLLEYBUS = 'TROLLEYBUS';
+      end;
+    public
+      version: String;
+    end;
+  end;
+
+  TCircleOptions = class
+  public
+    center: JSValue;
+    clickable: Boolean;
+    draggable: Boolean;
+    editable: Boolean;
+    fillColor: String;
+    fillOpacity: Double;
+    map: TGoogle.TMaps.TMap;
+    radius: Double;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokePosition: TGoogle.TMaps.TStrokePosition;
+    strokeWeight: Double;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TCircleLiteral = class(TCircleOptions)
+  public
+    center: JSValue;
+    radius: Double;
+  end;
+
+  TAddFeatureEvent = class
+  public
+    feature: TGoogle.TMaps.TData.TFeature;
+  end;
+
+  TDataOptions = class
+  public
+    controlPosition: TGoogle.TMaps.TControlPosition;
+    controls: TArray<String>;
+    drawingMode: String;
+    featureFactory: TFunc<TGoogle.TMaps.TData.TGeometry, TGoogle.TMaps.TData.TFeature>;
+    map: TGoogle.TMaps.TMap;
+    style: TStyleOptions;
+    styleFunction: TFunc<TGoogle.TMaps.TData.TFeature, TStyleOptions>; external name 'style';
+  end;
+
+  TFeatureOptions = class
+  public
+    geometry: JSValue;
+    id: Double;
+    properties: TJSObject;
+  end;
+
+  TGeoJsonOptions = class
+  public
+    idPropertyName: String;
+  end;
+
+  TMapMouseEvent = class external name 'MapMouseEvent'
+  public
+    domEvent: TJSEvent;
+    latLng: TGoogle.TMaps.TLatLng;
+    procedure stop;
+  end;
+
+  TMouseEvent = class(TMapMouseEvent)
+  public
+    feature: TGoogle.TMaps.TData.TFeature;
+  end;
+
+  TRemoveFeatureEvent = class
+  public
+    feature: TGoogle.TMaps.TData.TFeature;
+  end;
+
+  TRemovePropertyEvent = class
+  public
+    feature: TGoogle.TMaps.TData.TFeature;
+    name: String;
+    oldValue: JSValue;
+  end;
+
+  TSetGeometryEvent = class
+  public
+    feature: TGoogle.TMaps.TData.TFeature;
+    newGeometry: TGoogle.TMaps.TData.TGeometry;
+    oldGeometry: TGoogle.TMaps.TData.TGeometry;
+  end;
+
+  TSetPropertyEvent = class
+    feature: TGoogle.TMaps.TData.TFeature;
+    name: String;
+    newValue: JSValue;
+    oldValue: JSValue;
+  end;
+
+  TStyleOptions = class
+  public
+    clickable: Boolean;
+    cursor: String;
+    draggable: Boolean;
+    editable: Boolean;
+    fillColor: String;
+    fillOpacity: Double;
+    icon: JSValue;
+    shape: TMarkerShape;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokeWeight: Double;
+    title: String;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TDirectionsGeocodedWaypoint = class
+  public
+    partial_match: Boolean;
+    place_id: String;
+    types: TArray<String>;
+  end;
+
+  TDirectionsLeg = class
+  public
+    arrival_time: TTimeGoogle;
+    departure_time: TTimeGoogle;
+    distance: TDistance;
+    duration: TDuration;
+    duration_in_traffic: TDuration;
+    end_address: String;
+    end_location: TGoogle.TMaps.TLatLng;
+    start_address: String;
+    start_location: TGoogle.TMaps.TLatLng;
+    steps: TArray<TDirectionsStep>;
+    via_waypoints: TArray<TGoogle.TMaps.TLatLng>;
+  end;
+
+  TDirectionsRendererOptions = class
+  public
+    directions: TDirectionsResult;
+    draggable: Boolean;
+    hideRouteList: Boolean;
+    infoWindow: TGoogle.TMaps.TInfoWindow;
+    map: TGoogle.TMaps.TMap;
+    markerOptions: TMarkerOptions;
+    panel: TJSNode;
+    polylineOptions: google.maps.TPolylineOptions;
+    preserveViewport: Boolean;
+    routeIndex: Double;
+    suppressBicyclingLayer: Boolean;
+    suppressInfoWindows: Boolean;
+    suppressMarkers: Boolean;
+    suppressPolylines: Boolean;
+  end;
+
+  TDirectionsRequest = class
+  public
+    avoidFerries: Boolean;
+    avoidHighways: Boolean;
+    avoidTolls: Boolean;
+    destination: JSValue;
+    drivingOptions: TDrivingOptions;
+    optimizeWaypoints: Boolean;
+    origin: JSValue;
+    provideRouteAlternatives: Boolean;
+    region: String;
+    transitOptions: TTransitOptions;
+    travelMode: TGoogle.TMaps.TTravelMode;
+    unitSystem: TGoogle.TMaps.TUnitSystem;
+    waypoints: TArray<TDirectionsWaypoint>;
+  end;
+
+  TDirectionsResult = class
+  public
+    geocoded_waypoints: TArray<TDirectionsGeocodedWaypoint>;
+    routes: TArray<TDirectionsRoute>;
+  end;
+
+  TDirectionsRoute = class
+  public
+    bounds: TGoogle.TMaps.TLatLngBounds;
+    copyrights: String;
+    fare: TArray<TTransitFare>;
+    legs: TArray<TDirectionsLeg>;
+    overview_path: TArray<TGoogle.TMaps.TLatLng>;
+    overview_polyline: String;
+    warnings: TArray<String>;
+    waypoint_order: TArray<Double>;
+  end;
+
+  TDirectionsStep = class
+    distance: TDistance;
+    duration: TDuration;
+    end_location: TGoogle.TMaps.TLatLng;
+    instructions: String;
+    path: TArray<TGoogle.TMaps.TLatLng>;
+    start_location: TGoogle.TMaps.TLatLng;
+    steps: TArray<TDirectionsStep>;
+    transit: TTransitDetails;
+    travel_mode: TGoogle.TMaps.TTravelMode;
+  end;
+
+  TDirectionsWaypoint = class
+    location: JSValue;
+    stopover: Boolean;
+  end;
+
+  TDistance = class
+  public
+    text: String;
+    value: Double;
+  end;
+
+  TDistanceMatrixRequest = class
+  public
+    avoidFerries: Boolean;
+    avoidHighways: Boolean;
+    avoidTolls: Boolean;
+    destinations: TArray<JSValue>;
+    drivingOptions: TDrivingOptions;
+    origins: TArray<JSValue>;
+    region: String;
+    transitOptions: TTransitOptions;
+    travelMode: TGoogle.TMaps.TTravelMode;
+    unitSystem: TGoogle.TMaps.TUnitSystem;
+  end;
+
+  TDistanceMatrixResponse = class
+  public
+    destinationAddresses: TArray<String>;
+    originAddresses: TArray<String>;
+    rows: TArray<TDistanceMatrixResponseRow>;
+  end;
+
+  TDistanceMatrixResponseElement = class
+  public
+    distance: TDistance;
+    duration: TDuration;
+    duration_in_traffic: TDuration;
+    fare: TTransitFare;
+    status: TGoogle.TMaps.TDistanceMatrixElementStatus;
+  end;
+
+  TDistanceMatrixResponseRow = class
+  public
+    elements: TArray<TDistanceMatrixResponseElement>;
+  end;
+
+  TDrivingOptions = class
+  public
+    departureTime: String;
+    trafficModel: TGoogle.TMaps.TTrafficModel;
+  end;
+
+  TDuration = class
+  public
+    text: String;
+    value: Double;
+  end;
+
+  TElevationResult = class
+  public
+    elevation: Double;
+    location: TGoogle.TMaps.TLatLng;
+    resolution: Double;
+  end;
+
+  TFullscreenControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TGeocoderAddressComponent = class
+  public
+    long_name: String;
+    short_name: String;
+    types: TArray<String>;
+  end;
+
+  TGeocoderComponentRestrictions = class
+  public
+    administrativeArea: String;
+    country: String;
+    locality: String;
+    postalCode: String;
+    route: String;
+  end;
+
+  TGeocoderGeometry = class
+  public
+    bounds: TGoogle.TMaps.TLatLngBounds;
+    location: TGoogle.TMaps.TLatLng;
+    location_type: TGoogle.TMaps.TGeocoderLocationType;
+    viewport: TGoogle.TMaps.TLatLngBounds;
+  end;
+
+  TGeocoderRequest = class
+  public
+    address: String;
+    bounds: JSValue;
+    componentRestrictions: TGeocoderComponentRestrictions;
+    location: JSValue;
+    placeId: String;
+    region: String;
+  end;
+
+  TGeocoderResponse = class
+  public
+    results: TArray<TGeocoderResult>;
+  end;
+
+  TGeocoderResult = class
+  public
+    address_components: TArray<TGeocoderAddressComponent>;
+    formatted_address: String;
+    geometry: TGeocoderGeometry;
+    partial_match: Boolean;
+    place_id: String;
+    postcode_localities: TArray<String>;
+    types: TArray<String>;
+  end;
+
+  TGroundOverlayOptions = class
+  public
+    clickable: Boolean;
+    map: TGoogle.TMaps.TMap;
+    opacity: Double;
+  end;
+
+  TIcon = class
+  public
+    anchor: TGoogle.TMaps.TPoint;
+    labelOrigin: TGoogle.TMaps.TPoint;
+    origin: TGoogle.TMaps.TPoint;
+    scaledSize: TGoogle.TMaps.TSize;
+    size: TGoogle.TMaps.TSize;
+    url: String;
+  end;
+
+  TIconMouseEvent = class(TMapMouseEvent)
+  public
+    placeId: String;
+  end;
+
+  TIconSequence = class
+  public
+    fixedRotation: Boolean;
+    icon: TSymbol;
+    offset: String;
+    &repeat: String;
+  end;
+
+  TImageMapTypeOptions = class
+  public
+    alt: String;
+    getTileUrl: TFunc<TGoogle.TMaps.TPoint, Double, String>;
+    maxZoom: Double;
+    minZoom: Double;
+    name: String;
+    opacity: Double;
+    tileSize: TGoogle.TMaps.TSize;
+  end;
+
+  TInfoWindowOptions = class
+  public
+    content: JSValue;
+    disableAutoPan: Boolean;
+    maxWidth: Double;
+    minWidth: Double;
+    pixelOffset: TGoogle.TMaps.TSize;
+    position: JSValue;
+    zIndex: Double;
+  end;
+
+  TKmlAuthor = class
+  public
+    email: String;
+    name: String;
+    uri: String;
+  end;
+
+  TKmlFeatureData = class
+  public
+    author: TKmlAuthor;
+    description: String;
+    id: String;
+    infoWindowHtml: String;
+    name: String;
+    snippet: String;
+  end;
+
+  TKmlLayerMetadata = class
+  public
+    author: TKmlAuthor;
+    description: String;
+    hasScreenOverlays: Boolean;
+    name: String;
+    snippet: String;
+  end;
+
+  TKmlLayerOptions = class
+  public
+    clickable: Boolean;
+    map: TGoogle.TMaps.TMap;
+    preserveViewport: Boolean;
+    screenOverlays: Boolean;
+    suppressInfoWindows: Boolean;
+    url: String;
+    zIndex: Double;
+  end;
+
+  TKmlMouseEvent = class
+  public
+    featureData: TKmlFeatureData;
+    latLng: TGoogle.TMaps.TLatLng;
+    pixelOffset: TGoogle.TMaps.TSize;
+  end;
+
+  TLatLngBoundsLiteral = class
+  public
+    east: Double;
+    north: Double;
+    south: Double;
+    west: Double;
+  end;
+
+  TLatLngLiteral = class
+  public
+    lat: Double;
+    lng: Double;
+
+    constructor Create(Lat, Lng: Double);
+  end;
+
+  TLocationElevationRequest = class
+  public
+    locations: TArray<JSValue>;
+  end;
+
+  TLocationElevationResponse = class
+  public
+    results: TArray<TElevationResult>;
+  end;
+
+  TMapCanvasProjection = class external name 'MapCanvasProjection' abstract
+  public
+    function fromContainerPixelToLatLng(pixel: TGoogle.TMaps.TPoint; nowrap: Boolean): TGoogle.TMaps.TLatLng;
+    function fromDivPixelToLatLng(pixel: TGoogle.TMaps.TPoint; nowrap: Boolean): TGoogle.TMaps.TLatLng;
+    function fromLatLngToContainerPixel(latLng: TGoogle.TMaps.TLatLng): TGoogle.TMaps.TPoint;
+    function fromLatLngToDivPixel(latLng: TGoogle.TMaps.TLatLng): TGoogle.TMaps.TPoint;
+    function getWorldWidth: Double;
+  end;
+
+  TMapOptions = class
+  private
+    FFullscreenControlOptions: TFullscreenControlOptions; external name 'fullscreenControlOptions';
+    Frestriction: TMapRestriction; external name 'restriction';
+    FzoomControlOptions: TZoomControlOptions; external name 'zoomControlOptions';
+    FscaleControlOptions: TScaleControlOptions; external name 'scaleControlOptions';
+    FmapTypeControlOptions: TMapTypeControlOptions; external name 'mapTypeControlOptions';
+    FpanControlOptions: TPanControlOptions; external name 'panControlOptions';
+    FstreetViewControlOptions: TStreetViewControlOptions; external name 'streetViewControlOptions';
+    FrotateControlOptions: TRotateControlOptions; external name 'rotateControlOptions';
+
+    function GetRestriction: TMapRestriction;
+    function GetRotateControlOptions: TRotateControlOptions;
+    function GetScaleControlOptions: TScaleControlOptions;
+    function GetStreetViewControlOptions: TStreetViewControlOptions;
+    function GetZoomControlOptions: TZoomControlOptions;
+    function GetfullscreenControlOptions: TFullscreenControlOptions;
+    function GetmapTypeControlOptions: TMapTypeControlOptions;
+    function GetpanControlOptions: TPanControlOptions;
+  public
+    backgroundColor: String;
+    center: JSValue;
+    clickableIcons: Boolean;
+    controlSize: Double;
+    disableDefaultUI: Boolean;
+    disableDoubleClickZoom: Boolean;
+    draggableCursor: String;
+    draggingCursor: String;
+    fullscreenControl: Boolean;
+    gestureHandling: String;
+    heading: Double;
+    keyboardShortcuts: Boolean;
+    mapTypeControl: Boolean;
+    mapTypeId: String;
+    maxZoom: Double;
+    minZoom: Double;
+    noClear: Boolean;
+    panControl: Boolean;
+    rotateControl: Boolean;
+    scaleControl: Boolean;
+    scrollwheel: Boolean;
+    streetView: TGoogle.TMaps.TStreetViewPanorama;
+    streetViewControl: Boolean;
+    styles: TArray<TMapTypeStyle>;
+    tilt: Double;
+    zoom: Double;
+    zoomControl: Boolean;
+
+    property fullscreenControlOptions: TFullscreenControlOptions read GetfullscreenControlOptions write FfullscreenControlOptions;
+    property mapTypeControlOptions: TMapTypeControlOptions read GetmapTypeControlOptions write FmapTypeControlOptions;
+    property panControlOptions: TPanControlOptions read GetpanControlOptions write FpanControlOptions;
+    property rotateControlOptions: TRotateControlOptions read GetrotateControlOptions write FrotateControlOptions;
+    property streetViewControlOptions: TStreetViewControlOptions read GetstreetViewControlOptions write FstreetViewControlOptions;
+    property restriction: TMapRestriction read Getrestriction write Frestriction;
+    property scaleControlOptions: TScaleControlOptions read GetscaleControlOptions write FscaleControlOptions;
+    property zoomControlOptions: TZoomControlOptions read GetzoomControlOptions write FzoomControlOptions;
+  end;
+
+  TMapPanes = class
+  public
+    floatPane: TJSHTMLElement;
+    mapPane: TJSHTMLElement;
+    markerLayer: TJSHTMLElement;
+    overlayLayer: TJSHTMLElement;
+    overlayMouseTarget: TJSHTMLElement;
+  end;
+
+  TMapRestriction = class
+  public
+    latLngBounds: JSValue;
+    strictBounds: Boolean;
+  end;
+
+  TMapType = class external name 'MapType' abstract
+  public
+    alt: String;
+    maxZoom: Double;
+    minZoom: Double;
+    name: String;
+    projection: TProjection;
+    radius: Double;
+    tileSize: TGoogle.TMaps.TSize;
+    procedure releaseTile(tile: TJSNode);
+    function getTile(tileCoord: TGoogle.TMaps.TPoint; zoom: Double; ownerDocument: TJSDocument): TJSNode;
+  end;
+
+  TMapTypeControlOptions = class
+  public
+    mapTypeIds: TArray<String>;
+    position: TGoogle.TMaps.TControlPosition;
+    style: TGoogle.TMaps.TMapTypeControlStyle;
+  end;
+
+  TMapTypeStyle = class
+  public
+    elementType: String;
+    featureType: String;
+    stylers: TArray<TJSObject>;
+  end;
+
+  TMapsEventListener = class external name 'MapsEventListener' abstract
+  public
+    procedure remove;
+  end;
+
+  TPadding = class
+  public
+    bottom: Double;
+    left: Double;
+    right: Double;
+    top: Double;
+  end;
+
+  TPanControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TPanoProviderOptions = class
+  public
+    cors: Boolean;
+  end;
+
+  TPathElevationRequest = class
+  public
+    path: TArray<JSValue>;
+    samples: Double;
+  end;
+
+  TPathElevationResponse = class
+  public
+    results: TArray<TElevationResult>;
+  end;
+
+  TPlace = class
+  public
+    location: JSValue;
+    placeId: String;
+    query: String;
+  end;
+
+  TPolyMouseEvent = class(TMapMouseEvent)
+  public
+    edge: Double;
+    path: Double;
+    vertex: Double;
+  end;
+
+  TMarkerLabel = class
+  public
+    className: String;
+    color: String;
+    fontFamily: String;
+    fontSize: String;
+    fontWeight: String;
+    text: String;
+  end;
+
+  TMarkerOptions = class
+  public
+    anchorPoint: TGoogle.TMaps.TPoint;
+    animation: TGoogle.TMaps.TAnimation;
+    clickable: Boolean;
+    crossOnDrag: Boolean;
+    cursor: String;
+    draggable: Boolean;
+    icon: JSValue;
+    &label: JSValue;
+    map: TGoogle.TMaps.TMap;
+    mapStreetViewPanorama: TGoogle.TMaps.TStreetViewPanorama; external name 'map';
+    opacity: Double;
+    optimized: Boolean;
+    position: JSValue;
+    shape: TMarkerShape;
+    title: String;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TMarkerShape = class
+  public
+    coords: TArray<Double>;
+    &type: String;
+  end;
+
+  TMaxZoomResult = class
+  public
+    status: TGoogle.TMaps.TMaxZoomStatus;
+    zoom: Double;
+  end;
+
+  TPolygonOptions = class
+  public
+    clickable: Boolean;
+    draggable: Boolean;
+    editable: Boolean;
+    fillColor: String;
+    fillOpacity: Double;
+    geodesic: Boolean;
+    map: TGoogle.TMaps.TMap;
+    paths: JSValue;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokePosition: TGoogle.TMaps.TStrokePosition;
+    strokeWeight: Double;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TPolylineOptions = class
+  public
+    clickable: Boolean;
+    draggable: Boolean;
+    editable: Boolean;
+    geodesic: Boolean;
+    icons: TArray<TIconSequence>;
+    map: TGoogle.TMaps.TMap;
+    path: TArray<JSValue>;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokeWeight: Double;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TProjection = class external name 'Projection' abstract
+  public
+    function fromLatLngToPoint(latLng: TGoogle.TMaps.TLatLng; point: TGoogle.TMaps.TPoint): TGoogle.TMaps.TPoint;
+    function fromPointToLatLng(pixel: TGoogle.TMaps.TPoint; noWrap: Boolean): TGoogle.TMaps.TLatLng;
+  end;
+
+  TRectangleOptions = class
+  public
+    bounds: JSValue;
+    clickable: Boolean;
+    draggable: Boolean;
+    editable: Boolean;
+    fillColor: String;
+    fillOpacity: Double;
+    map: TGoogle.TMaps.TMap;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokePosition: TGoogle.TMaps.TStrokePosition;
+    strokeWeight: Double;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TRotateControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TScaleControlOptions = class
+  public type
+    TScaleControlStyle = (scDEFAULT);
+  public
+    style: TScaleControlStyle;
+  end;
+
+  TMotionTrackingControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TStreetViewAddressControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TStreetViewControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TStreetViewLink = class
+  public
+    description: String;
+    heading: Double;
+    pano: String;
+  end;
+
+  TStreetViewLocation = class
+  public
+    description: String;
+    latLng: TGoogle.TMaps.TLatLng;
+    pano: String;
+    shortDescription: String;
+  end;
+
+  TStreetViewLocationRequest = class
+  public
+    location: JSValue;
+    preference: TGoogle.TMaps.TStreetViewPreference;
+    radius: Double;
+    source: TGoogle.TMaps.TStreetViewSource;
+  end;
+
+  TStreetViewPanoRequest = class
+  public
+    pano: String;
+  end;
+
+  TStreetViewPanoramaData = class
+  public
+    copyright: String;
+    imageDate: String;
+    links: TArray<TStreetViewLink>;
+    location: TStreetViewLocation;
+    tiles: TStreetViewTileData;
+  end;
+
+  TStreetViewPanoramaOptions = class
+  public
+    addressControl: Boolean;
+    addressControlOptions: TStreetViewAddressControlOptions;
+    clickToGo: Boolean;
+    controlSize: Double;
+    disableDefaultUI: Boolean;
+    disableDoubleClickZoom: Boolean;
+    enableCloseButton: Boolean;
+    fullscreenControl: Boolean;
+    fullscreenControlOptions: TFullscreenControlOptions;
+    imageDateControl: Boolean;
+    linksControl: Boolean;
+    motionTracking: Boolean;
+    motionTrackingControl: Boolean;
+    motionTrackingControlOptions: TMotionTrackingControlOptions;
+    panControl: Boolean;
+    panControlOptions: TPanControlOptions;
+    pano: String;
+    position: JSValue;
+    pov: TStreetViewPov;
+    scrollwheel: Boolean;
+    showRoadLabels: Boolean;
+    visible: Boolean;
+    zoom: Double;
+    zoomControl: Boolean;
+    zoomControlOptions: TZoomControlOptions;
+  end;
+
+  TStreetViewPov = class
+  public
+    heading: Double;
+    pitch: Double;
+  end;
+
+  TStreetViewResponse = class
+  public
+    data: TStreetViewPanoramaData;
+  end;
+
+  TStreetViewTileData = class
+  public
+    centerHeading: Double;
+    tileSize: TGoogle.TMaps.TSize;
+    worldSize: TGoogle.TMaps.TSize;
+
+    function getTileUrl(pano: String; tileZoom: Double; tileX: Double; tileY: Double): String; virtual; abstract;
+  end;
+
+  TStyledMapTypeOptions = class
+  public
+    alt: String;
+    maxZoom: Double;
+    minZoom: Double;
+    name: String;
+  end;
+
+  TSymbol = class
+  public
+    anchor: TGoogle.TMaps.TPoint;
+    fillColor: String;
+    fillOpacity: Double;
+    labelOrigin: TGoogle.TMaps.TPoint;
+    path: JSValue;
+    rotation: Double;
+    scale: Double;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokeWeight: Double;
+  end;
+
+  TTimeGoogle = class
+  public
+    text: String;
+    time_zone: String;
+    value: String;
+  end;
+
+  TTrafficLayerOptions = class
+  public
+    autoRefresh: Boolean;
+    map: TGoogle.TMaps.TMap;
+  end;
+
+  TTransitAgency = class
+  public
+    name: String;
+    phone: String;
+    url: String;
+  end;
+
+  TTransitDetails = class
+  public
+    arrival_stop: TTransitStop;
+    arrival_time: TTimeGoogle;
+    departure_stop: TTransitStop;
+    departure_time: TTimeGoogle;
+    headsign: String;
+    headway: Double;
+    line: TTransitLine;
+    num_stops: Double;
+    trip_short_name: String;
+  end;
+
+  TTransitFare = class
+  public
+    currency: String;
+    value: Double;
+  end;
+
+  TTransitLine = class
+  public
+    agencies: TArray<TTransitAgency>;
+    color: String;
+    icon: String;
+    name: String;
+    short_name: String;
+    text_color: String;
+    url: String;
+    vehicle: TTransitVehicle;
+  end;
+
+  TTransitOptions = class
+  public
+    arrivalTime: String;
+    departureTime: String;
+    modes: TArray<TGoogle.TMaps.TTransitMode>;
+    routingPreference: TArray<TGoogle.TMaps.TTransitRoutePreference>;
+  end;
+
+  TTransitStop = class
+  public
+    location: TGoogle.TMaps.TLatLng;
+    name: String;
+  end;
+
+  TTransitVehicle = class
+  public
+    icon: String;
+    local_icon: String;
+    name: String;
+    &type: TGoogle.TMaps.TVehicleType;
+  end;
+
+  TZoomControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TDrawingControlOptions = class
+  public
+    drawingModes: TArray<TGoogle.TMaps.TOverlayType>;
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TDrawingManagerOptions = class
+  public
+    circleOptions: TCircleOptions;
+    drawingControl: Boolean;
+    drawingControlOptions: TDrawingControlOptions;
+    drawingMode: TGoogle.TMaps.TOverlayType;
+    map: TGoogle.TMaps.TMap;
+    markerOptions: TMarkerOptions;
+    polygonOptions: TPolygonOptions;
+    polylineOptions: TPolylineOptions;
+    rectangleOptions: TRectangleOptions;
+  end;
+
+  TOverlayCompleteEvent = class
+  public
+    overlay: JSValue;
+    &type: TGoogle.TMaps.TOverlayType;
+  end;
+
+  TPinOptions = class
+  public
+    background: String;
+    glyphColor: String;
+    scale: Double;
+  end;
+
+  TAutocompleteOptions = class
+  public
+    bounds: JSValue;
+    componentRestrictions: TComponentRestrictions;
+    fields: TArray<String>;
+    strictBounds: Boolean;
+    types: TArray<String>;
+  end;
+
+  TAutocompletePrediction = class
+  public
+    description: String;
+    distance_meters: Double;
+    matched_substrings: TArray<TPredictionSubstring>;
+    place_id: String;
+    structured_formatting: TStructuredFormatting;
+    terms: TArray<TPredictionTerm>;
+    types: TArray<String>;
+  end;
+
+  TAutocompleteResponse = class
+  public
+    predictions: TArray<TAutocompletePrediction>;
+  end;
+
+  TAutocompleteSessionToken = class
+  end;
+
+  TAutocompletionRequest = class
+  public
+    bounds: JSValue;
+    componentRestrictions: TComponentRestrictions;
+    input: String;
+    location: TGoogle.TMaps.TLatLng;
+    offset: Double;
+    origin: JSValue;
+    radius: Double;
+    sessionToken: TAutocompleteSessionToken;
+    types: TArray<String>;
+  end;
+
+  TComponentRestrictions = class
+  public
+    country: TArray<String>;
+  end;
+
+  TFindPlaceFromPhoneNumberRequest = class
+  public
+    fields: TArray<String>;
+    locationBias: JSValue;
+    phoneNumber: String;
+  end;
+
+  TFindPlaceFromQueryRequest = class
+  public
+    fields: TArray<String>;
+    locationBias: JSValue;
+    query: String;
+  end;
+
+  TPredictionSubstring = class
+  public
+    length: Double;
+    offset: Double;
+  end;
+
+  TPredictionTerm = class
+  public
+    offset: Double;
+    value: String;
+  end;
+
+  TQueryAutocompletionRequest = class
+  public
+    bounds: JSValue;
+    input: String;
+    location: TGoogle.TMaps.TLatLng;
+    offset: Double;
+    radius: Double;
+  end;
+
+  TSearchBoxOptions = class
+  public
+    bounds: JSValue;
+  end;
+
+  TStructuredFormatting = class
+  public
+    main_text: String;
+    main_text_matched_substrings: TArray<TPredictionSubstring>;
+    secondary_text: String;
+  end;
+
+  TTextSearchRequest = class
+  public
+    bounds: JSValue;
+    location: JSValue;
+    query: String;
+    radius: Double;
+    &type: String;
+  end;
+
+  THeatmapLayerOptions = class
+  public
+    data: JSValue;
+    dissipating: Boolean;
+    gradient: TArray<String>;
+    map: TGoogle.TMaps.TMap;
+    maxIntensity: Double;
+    opacity: Double;
+    radius: Double;
+  end;
+
+  TWeightedLocation = class
+  public
+    location: TGoogle.TMaps.TLatLng;
+    weight: Double;
+  end;
+
+function InitializeMap(Key: String): TJSPromise;
+
+implementation
+
+function InitializeMap(Key: String): TJSPromise;
+begin
+  Result := TJSPromise.New(
+    procedure(Resolve, Reject: TJSPromiseResolver)
+    var
+      Script: TJSHTMLScriptElement;
+
+    begin
+      Script := TJSHTMLScriptElement(document.createElement('script'));
+      Script.OnLoad :=
+        function(Event: TEventListenerEvent): Boolean
+        begin
+          Window.RequestIdleCallback(
+            procedure (idleDeadline: TJSIdleDeadline)
+            begin
+              Resolve(True);
+            end);
+
+          Result := True;
+        end;
+      Script.src := Format('https://maps.googleapis.com/maps/api/js?key=%s', [Key]);
+      Script.type_ := 'text/javascript';
+
+      document.head.appendChild(Script);
+    end);
+end;
+
+{ TLatLngLiteral }
+
+constructor TLatLngLiteral.Create(Lat, Lng: Double);
+begin
+  Self.Lat := Lat;
+  Self.Lng := Lng;
+end;
+
+{ TMapOptions }
+
+function TMapOptions.GetfullscreenControlOptions: TFullscreenControlOptions;
+begin
+  if not Assigned(FfullscreenControlOptions) then
+    FfullscreenControlOptions := TFullscreenControlOptions.Create;
+
+  Result := FfullscreenControlOptions;
+end;
+
+function TMapOptions.GetmapTypeControlOptions: TMapTypeControlOptions;
+begin
+  if not Assigned(FmapTypeControlOptions) then
+    FmapTypeControlOptions := TMapTypeControlOptions.Create;
+
+  Result := FmapTypeControlOptions;
+end;
+
+function TMapOptions.GetpanControlOptions: TPanControlOptions;
+begin
+  if not Assigned(FpanControlOptions) then
+    FpanControlOptions := TPanControlOptions.Create;
+
+  Result := FpanControlOptions;
+end;
+
+function TMapOptions.GetRestriction: TMapRestriction;
+begin
+  if not Assigned(FRestriction) then
+    FRestriction := TMapRestriction.Create;
+
+  Result := FRestriction;
+end;
+
+function TMapOptions.GetRotateControlOptions: TRotateControlOptions;
+begin
+  if not Assigned(FRotateControlOptions) then
+    FRotateControlOptions := TRotateControlOptions.Create;
+
+  Result := FRotateControlOptions;
+end;
+
+function TMapOptions.GetScaleControlOptions: TScaleControlOptions;
+begin
+  if not Assigned(FScaleControlOptions) then
+    FScaleControlOptions := TScaleControlOptions.Create;
+
+  Result := FScaleControlOptions;
+end;
+
+function TMapOptions.GetZoomControlOptions: TZoomControlOptions;
+begin
+  if not Assigned(FZoomControlOptions) then
+    FZoomControlOptions := TZoomControlOptions.Create;
+
+  Result := FZoomControlOptions;
+end;
+
+function TMapOptions.GetStreetViewControlOptions: TStreetViewControlOptions;
+begin
+  if not Assigned(FStreetViewControlOptions) then
+    FStreetViewControlOptions := TStreetViewControlOptions.Create;
+
+  Result := FStreetViewControlOptions;
+end;
+
+end.
+
diff --git a/packages/maps/Leaflet.Maps.pas b/packages/maps/Leaflet.Maps.pas
new file mode 100644
index 00000000..6ab74f3e
--- /dev/null
+++ b/packages/maps/Leaflet.Maps.pas
@@ -0,0 +1,1845 @@
+unit Leaflet.Maps;
+
+interface
+
+{$modeswitch externalclass}
+
+uses JS, Web, SysUtils, GeoJSON;
+
+type
+  TAttributionOptions = class;
+  TCircleMarkerOptions = class;
+  TControlOptions = class;
+  TDefaultMapPanes = class;
+  TDivIconOptions = class;
+  TDivOverlayOptions = class;
+  TDragEndEvent = class;
+  TError = class;
+  TErrorEvent = class;
+  TFitBoundsOptions = class;
+  TGeoJSONEvent = class;
+  TGeoJSONOptions = class;
+  TGridLayerOptions = class;
+  TIconOptions = class;
+  TImageOverlayOptions = class;
+  TInteractiveLayerOptions = class;
+  TInvalidateSizeOptions = class;
+  TLatLngLiteral = class;
+  TLayerEvent = class;
+  TLayerOptions = class;
+  TLayersControlEvent = class;
+  TLayersObject = class;
+  TLayersOptions = class;
+  TLeafletEvent = class;
+  TLeafletKeyboardEvent = class;
+  TLeafletMouseEvent = class;
+  TLocateOptions = class;
+  TLocationEvent = class;
+  TMapOptions = class;
+  TMarkerOptions = class;
+  TPanInsideOptions = class;
+  TPanOptions = class;
+  TPathOptions = class;
+  TPolylineOptions = class;
+  TPopupEvent = class;
+  TPopupOptions = class;
+  TRendererOptions = class;
+  TResizeEvent = class;
+  TScaleOptions = class;
+  TTileErrorEvent = class;
+  TTileEvent = class;
+  TTileLayerOptions = class;
+  TTooltipEvent = class;
+  TTooltipOptions = class;
+  TVideoOverlayOptions = class;
+  TWMSOptions = class;
+  TWMSParams = class;
+  TZoomAnimEvent = class;
+  TZoomControlOptions = class;
+  TZoomOptions = class;
+  TZoomPanOptions = class;
+
+  TLatLngTuple = array[0..1] of Double;
+  TPointTuple = array[0..1] of Double;
+
+  TBoundsLiteral = array[0..1] of TPointTuple;
+
+  TLeaflet = class external name 'L'
+  public type
+    TBounds = class;
+    TLatLng = class;
+    TLatLngBounds = class;
+    TLayerGroup = class;
+    TMap = class;
+    TPoint = class;
+    TPopup = class;
+    TTooltip = class;
+
+    TLatLngBoundsLiteral = TArray<TLatLngTuple>;
+
+    TClass = class external name 'Class'
+    public
+      class function addInitHook(initHookFn: TProc): TClass; overload;
+      class function addInitHook(methodName: String): TClass; varargs; overload;
+      class function extend(props: JSValue): TClass;
+      class function include(props: JSValue): TClass;
+      class function mergeOptions(props: JSValue): TClass;
+    end;
+
+    TTransformation = class external name 'Transformation'
+    public
+      constructor new(a, b, c, d: Double);
+
+      function transform(point: TPoint): TPoint; overload;
+      function transform(point: TPoint; scale: Double): TPoint; overload;
+      function untransform(point: TPoint): TPoint; overload;
+      function untransform(point: TPoint; scale: Double): TPoint; overload;
+    end;
+
+    TLineUtil = class external name 'LineUtil'
+    public
+      function simplify(points: TArray<TPoint>; tolerance: Double): TArray<TPoint>;
+      function pointToSegmentDistance(p, p1,p2: TPoint): Double;
+      function closestPointOnSegment(p, p1, p2: TPoint): TPoint;
+      function isFlat(latlngs: TArray<TLatLng>): Boolean; overload;
+      function isFlat(latlngs: TArray<TLatLngLiteral>): Boolean; overload;
+      function isFlat(latlngs: TArray<TLatLngTuple>): Boolean; overload;
+      function clipSegment(a, b: TPoint; bounds: TBounds): TArray<TPoint>; overload;
+      function clipSegment(a, b: TPoint; bounds: TBounds; useLastCode: Boolean): TArray<TPoint>; overload;
+      function clipSegment(a, b: TPoint; bounds: TBounds; useLastCode, round: Boolean): TArray<TPoint>; overload;
+    end;
+
+    TPolyUtil = class external name 'PolyUtil'
+    public
+      function clipPolygon(points: TArray<TPoint>; bounds: TBounds): TArray<TPoint>; overload;
+      function clipPolygon(points: TArray<TPoint>; bounds: TBoundsLiteral): TArray<TPoint>; overload;
+      function clipPolygon(points: TArray<TPoint>; bounds: TBounds; round: Boolean): TArray<TPoint>; overload;
+      function clipPolygon(points: TArray<TPoint>; bounds: TBoundsLiteral; round: Boolean): TArray<TPoint>; overload;
+    end;
+
+    TDomUtil = class external name 'DomUtil'
+    public
+      TRANSFORM: String;
+      TRANSITION: String;
+      TRANSITION_END: String;
+
+      function get(element: String): TJSHTMLElement; overload;
+      function get(element: TJSHTMLElement): TJSHTMLElement; overload;
+      function getStyle(el: TJSHTMLElement; styleAttrib: String): String;
+      function create(tagName: String): TJSHTMLElement; overload;
+      function create(tagName: String; className: String): TJSHTMLElement; overload;
+      function create(tagName: String; className: String; container: TJSHTMLElement): TJSHTMLElement; overload;
+      procedure remove(el: TJSHTMLElement);
+      procedure empty(el: TJSHTMLElement);
+      procedure toFront(el: TJSHTMLElement);
+      procedure toBack(el: TJSHTMLElement);
+      function hasClass(el: TJSHTMLElement; name: String): Boolean;
+      procedure addClass(el: TJSHTMLElement; name: String);
+      procedure removeClass(el: TJSHTMLElement; name: String);
+      procedure setClass(el: TJSHTMLElement; name: String);
+      function getClass(el: TJSHTMLElement): String;
+      procedure setOpacity(el: TJSHTMLElement; opacity: Double);
+      function testProp(props: TArray<String>): String;
+      procedure setTransform(el: TJSHTMLElement; offset: TPoint; scale: Double);
+      procedure setPosition(el: TJSHTMLElement; position: TPoint);
+      function getPosition(el: TJSHTMLElement): TPoint;
+      procedure disableTextSelection();
+      procedure enableTextSelection();
+      procedure disableImageDrag();
+      procedure enableImageDrag();
+      procedure preventOutline(el: TJSHTMLElement);
+      procedure restoreOutline();
+    end;
+
+    TCRS = class external name 'CRS'
+    public class var
+      EPSG3395: TCRS;
+      EPSG3857: TCRS;
+      EPSG4326: TCRS;
+      EPSG900913: TCRS;
+      Earth: TCRS;
+      Simple: TCRS;
+    public
+      code: String;
+      wrapLng: TArray<Double>;
+      wrapLat: TArray<Double>;
+      infinite: Boolean;
+
+      function latLngToPoint(latlng: TLatLng; zoom: Double): TPoint; overload;
+      function latLngToPoint(latlng: TLatLngLiteral; zoom: Double): TPoint; overload;
+      function latLngToPoint(latlng: TLatLngTuple; zoom: Double): TPoint; overload;
+      function pointToLatLng(point: TPoint; zoom: Double): TLatLng; overload;
+      function pointToLatLng(point: TPointTuple; zoom: Double): TLatLng; overload;
+      function project(latlng: TLatLng): TPoint; overload;
+      function project(latlng: TLatLngLiteral): TPoint; overload;
+      function unproject(point: TPoint): TLatLng; overload;
+      function unproject(point: TPointTuple): TLatLng; overload;
+      function scale(zoom: Double): Double;
+      function zoom(scale: Double): Double;
+      function getProjectedBounds(zoom: Double): TBounds;
+      function distance(latlng1, latlng2: TLatLng): Double; overload;
+      function distance(latlng1, latlng2: TLatLngLiteral): Double; overload;
+      function distance(latlng1, latlng2: TLatLngTuple): Double; overload;
+      function wrapLatLng(latlng: TLatLng): TLatLng; overload;
+      function wrapLatLng(latlng: TLatLngLiteral): TLatLng; overload;
+    end;
+
+    TProjection = class external name 'Projection'
+    public
+      bounds: TBounds;
+
+      const LonLat: TProjection;
+      const Mercator: TProjection;
+      const SphericalMercator: TProjection;
+
+      function project(latlng: TLatLng): TPoint; overload;
+      function project(latlng: TLatLngLiteral): TPoint; overload;
+      function unproject(point: TPoint): TLatLng; overload;
+      function unproject(point: TPointTuple): TLatLng; overload;
+    end;
+
+    TLatLng = class external name 'LatLng'
+    public
+      lat: Double;
+      lng: Double;
+      alt: Double;
+
+      constructor new(latitude, longitude: Double); overload;
+      constructor new(latitude, longitude, altitude: Double); overload;
+
+      function clone(): TLatLng;
+      function distanceTo(otherLatLng: TLatLng): Double; overload;
+      function distanceTo(otherLatLng: TLatLngLiteral): Double; overload;
+      function distanceTo(otherLatLng: TLatLngTuple): Double; overload;
+      function equals(otherLatLng: TLatLng): Boolean; overload;
+      function equals(otherLatLng: TLatLng; maxMargin: Double): Boolean; overload;
+      function equals(otherLatLng: TLatLngLiteral): Boolean; overload;
+      function equals(otherLatLng: TLatLngLiteral; maxMargin: Double): Boolean; overload;
+      function equals(otherLatLng: TLatLngTuple): Boolean; overload;
+      function equals(otherLatLng: TLatLngTuple; maxMargin: Double): Boolean; overload;
+      function toBounds(sizeInMeters: Double): TLatLngBounds;
+      function toString(): String;
+      function wrap(): TLatLng;
+    end;
+
+    TLatLngBounds = class external name 'LatLngBounds'
+    public
+      constructor new(southWest, northEast: TLatLng); overload;
+      constructor new(southWest, northEast: TLatLngLiteral); overload;
+      constructor new(southWest, northEast: TLatLngTuple); overload;
+      constructor new(latlngs: TLatLngBoundsLiteral); overload;
+
+      function extend(latlngOrBounds: TLatLng): TLatLngBounds; overload;
+      function extend(latlngOrBounds: TLatLngLiteral): TLatLngBounds; overload;
+      function extend(latlngOrBounds: TLatLngTuple): TLatLngBounds; overload;
+      function extend(latlngOrBounds: TLatLngBounds): TLatLngBounds; overload;
+      function extend(latlngOrBounds: TLatLngBoundsLiteral): TLatLngBounds; overload;
+      function pad(bufferRatio: Double): TLatLngBounds; // does this modify the current instance or does it return a new one?
+      function getCenter(): TLatLng;
+      function getSouthWest(): TLatLng;
+      function getNorthEast(): TLatLng;
+      function getNorthWest(): TLatLng;
+      function getSouthEast(): TLatLng;
+      function getWest(): Double;
+      function getSouth(): Double;
+      function getEast(): Double;
+      function getNorth(): Double;
+      function contains(otherBoundsOrLatLng: TLatLngBounds): Boolean; overload;
+      function contains(otherBoundsOrLatLng: TLatLngBoundsLiteral): Boolean; overload;
+      function contains(otherBoundsOrLatLng: TLatLng): Boolean; overload;
+      function contains(otherBoundsOrLatLng: TLatLngLiteral): Boolean; overload;
+      function contains(otherBoundsOrLatLng: TLatLngTuple): Boolean; overload;
+      function intersects(otherBounds: TLatLngBounds): Boolean; overload;
+      function intersects(otherBounds: TLatLngBoundsLiteral): Boolean; overload;
+      function overlaps(otherBounds: TLatLngBounds): Boolean; overload;
+      function overlaps(otherBounds: TLatLngBoundsLiteral): Boolean; overload;
+      function toBBoxString(): String;
+      function equals(otherBounds: TLatLngBounds): Boolean; overload;
+      function equals(otherBounds: TLatLngBoundsLiteral): Boolean; overload;
+      function isValid(): Boolean;
+    end;
+
+    TPoint = class external name 'TPoint'
+    public
+      x: Double;
+      y: Double;
+
+      constructor new(x, y: Double); overload;
+      constructor new(x, y: Double; round: Boolean); overload;
+      function clone(): TPoint;
+      function add(otherPoint: TPoint): TPoint; overload;
+      function add(otherPoint: TPointTuple): TPoint; overload;
+      function subtract(otherPoint: TPoint): TPoint; overload;
+      function subtract(otherPoint: TPointTuple): TPoint; overload;
+      function divideBy(num: Double): TPoint;
+      function multiplyBy(num: Double): TPoint;
+      function scaleBy(scale: TPoint): TPoint; overload;
+      function scaleBy(scale: TPointTuple): TPoint; overload;
+      function unscaleBy(scale: TPoint): TPoint; overload;
+      function unscaleBy(scale: TPointTuple): TPoint; overload;
+      function round(): TPoint;
+      function floor(): TPoint;
+      function ceil(): TPoint;
+      function distanceTo(otherPoint: TPoint): Double; overload;
+      function distanceTo(otherPoint: TPointTuple): Double; overload;
+      function equals(otherPoint: TPoint): Boolean; overload;
+      function equals(otherPoint: TPointTuple): Boolean; overload;
+      function contains(otherPoint: TPoint): Boolean; overload;
+      function contains(otherPoint: TPointTuple): Boolean; overload;
+      function toString(): String;
+    end;
+
+    TCoords = class external name 'Coords' (TPoint)
+    public
+      z: Double;
+    end;
+
+    TBounds = class external name 'Bounds'
+    public
+      min: TPoint;
+      max: TPoint;
+
+      constructor new(points: TArray<TPoint>); overload;
+      constructor new(points: TBoundsLiteral); overload;
+      constructor new(topLeft, bottomRight: TPoint); overload;
+      constructor new(topLeft, bottomRight: TPointTuple); overload;
+      function extend(point: TPoint): TBounds; overload;
+      function extend(point: TPointTuple): TBounds; overload;
+      function getCenter(round: Boolean): TPoint;
+      function getBottomLeft(): TPoint;
+      function getBottomRight(): TPoint;
+      function getTopLeft(): TPoint;
+      function getTopRight(): TPoint;
+      function getSize(): TPoint;
+      function contains(pointOrBounds: TBounds): Boolean; overload;
+      function contains(pointOrBounds: TBoundsLiteral): Boolean; overload;
+      function contains(pointOrBounds: TPoint): Boolean; overload;
+      function contains(pointOrBounds: TPointTuple): Boolean; overload;
+      function intersects(otherBounds: TBounds): Boolean; overload;
+      function intersects(otherBounds: TBoundsLiteral): Boolean; overload;
+      function overlaps(otherBounds: TBounds): Boolean; overload;
+      function overlaps(otherBounds: TBoundsLiteral): Boolean; overload;
+    end;
+
+    // Event handler types
+    TDragEndEventHandlerFn = TProc<TDragEndEvent>;
+    TErrorEventHandlerFn = TProc<TErrorEvent>;
+    TLayerEventHandlerFn = TProc<TLayerEvent>;
+    TLayersControlEventHandlerFn = TProc<TLayersControlEvent>;
+    TLeafletEventHandlerFn = TProc<TLeafletEvent>;
+    TLeafletKeyboardEventHandlerFn = TProc<TLeafletKeyboardEvent>;
+    TLeafletMouseEventHandlerFn = TProc<TLeafletMouseEvent>;
+    TLocationEventHandlerFn = TProc<TLocationEvent>;
+    TPopupEventHandlerFn = TProc<TPopupEvent>;
+    TResizeEventHandlerFn = TProc<TResizeEvent>;
+    TTileErrorEventHandlerFn = TProc<TTileErrorEvent>;
+    TTileEventHandlerFn = TProc<TTileEvent>;
+    TTooltipEventHandlerFn = TProc<TTooltipEvent>;
+    TZoomAnimEventHandlerFn = TProc<TZoomAnimEvent>;
+
+    TLeafletEventHandlerFnMap = class external name 'LeafletEventHandlerFnMap'
+    public
+      baselayerchange: TLayersControlEventHandlerFn;
+      overlayadd: TLayersControlEventHandlerFn;
+      overlayremove: TLayersControlEventHandlerFn;
+
+      layeradd: TLayerEventHandlerFn;
+      layerremove: TLayerEventHandlerFn;
+
+      zoomlevelschange: TLeafletEventHandlerFn;
+      unload: TLeafletEventHandlerFn;
+      viewreset: TLeafletEventHandlerFn;
+      load: TLeafletEventHandlerFn;
+      zoomstart: TLeafletEventHandlerFn;
+      movestart: TLeafletEventHandlerFn;
+      zoom: TLeafletEventHandlerFn;
+      move: TLeafletEventHandlerFn;
+      zoomend: TLeafletEventHandlerFn;
+      moveend: TLeafletEventHandlerFn;
+      autopanstart: TLeafletEventHandlerFn;
+      dragstart: TLeafletEventHandlerFn;
+      drag: TLeafletEventHandlerFn;
+      add: TLeafletEventHandlerFn;
+      remove: TLeafletEventHandlerFn;
+      loading: TLeafletEventHandlerFn;
+      error: TLeafletEventHandlerFn;
+      update: TLeafletEventHandlerFn;
+      down: TLeafletEventHandlerFn;
+      predrag: TLeafletEventHandlerFn;
+
+      resize: TResizeEventHandlerFn;
+
+      popupopen: TPopupEventHandlerFn;
+      popupclose: TPopupEventHandlerFn;
+
+      tooltipopen: TTooltipEventHandlerFn;
+      tooltipclose: TTooltipEventHandlerFn;
+
+      locationerror: TErrorEventHandlerFn;
+
+      locationfound: TLocationEventHandlerFn;
+
+      click: TLeafletMouseEventHandlerFn;
+      dblclick: TLeafletMouseEventHandlerFn;
+      mousedown: TLeafletMouseEventHandlerFn;
+      mouseup: TLeafletMouseEventHandlerFn;
+      mouseover: TLeafletMouseEventHandlerFn;
+      mouseout: TLeafletMouseEventHandlerFn;
+      mousemove: TLeafletMouseEventHandlerFn;
+      contextmenu: TLeafletMouseEventHandlerFn;
+      preclick: TLeafletMouseEventHandlerFn;
+
+      keypress: TLeafletKeyboardEventHandlerFn;
+      keydown: TLeafletKeyboardEventHandlerFn;
+      keyup: TLeafletKeyboardEventHandlerFn;
+
+      zoomanim: TZoomAnimEventHandlerFn;
+
+      dragend: TDragEndEventHandlerFn;
+
+      tileunload: TTileEventHandlerFn;
+      tileloadstart: TTileEventHandlerFn;
+      tileload: TTileEventHandlerFn;
+
+      tileerror: TTileErrorEventHandlerFn;
+    end;
+
+    TEvented = class external name 'Evented' (TClass)
+    public
+      function addEventListener(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TTileErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function addEventParent(obj: TEvented): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TTileErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function clearAllEventListeners(): TEvented; overload;
+      function fire(&type: String; data: JSValue): TEvented; overload;
+      function fire(&type: String; data: JSValue; propagate: Boolean): TEvented; overload;
+      function fireEvent(&type: String; data: JSValue): TEvented; overload;
+      function fireEvent(&type: String; data: JSValue; propagate: Boolean): TEvented; overload;
+      function hasEventListeners(&type: String): Boolean;
+      function listens(&type: String): Boolean; overload;
+      function off(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TTileErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(): TEvented; overload;
+      function off(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function &on(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TTileErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function once(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function removeEventListener(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TTileErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function removeEventParent(obj: TEvented): TEvented; overload;
+    end;
+
+    TDraggable = class external name 'Draggable' (TEvented)
+    public
+      constructor new(element, dragStartTarget: TJSHTMLElement; preventOutline: Boolean);
+
+      procedure enable();
+      procedure disable();
+      procedure finishDrag();
+    end;
+
+    TLayer = class external name 'Layer' (TEvented)
+    public
+      constructor new(options: TLayerOptions);
+
+      function addTo(map: TMap): TLayer; overload;
+      function addTo(map: TLayerGroup): TLayer; overload;
+      function remove(): TLayer;
+      function removeFrom(map: TMap): TLayer;
+      function getPane(name: String): TJSHTMLElement;
+
+      // Popup methods
+      function bindPopup(content: TFunc<TLayer, String>; options: TPopupOptions): TLayer; overload;
+      function bindPopup(content: TFunc<TLayer, TJSHTMLElement>; options: TPopupOptions): TLayer; overload;
+      function bindPopup(content: String; options: TPopupOptions): TLayer; overload;
+      function bindPopup(content: TJSHTMLElement; options: TPopupOptions): TLayer; overload;
+      function bindPopup(content: TPopup; options: TPopupOptions): TLayer; overload;
+      function unbindPopup(): TLayer;
+      function openPopup(latlng: TLatLng): TLayer; overload;
+      function openPopup(latlng: TLatLngLiteral): TLayer; overload;
+      function openPopup(latlng: TLatLngTuple): TLayer; overload;
+      function closePopup(): TLayer;
+      function togglePopup(): TLayer;
+      function isPopupOpen(): Boolean;
+      function setPopupContent(content: String): TLayer; overload;
+      function setPopupContent(content: TJSHTMLElement): TLayer; overload;
+      function setPopupContent(content: TPopup): TLayer; overload;
+      function getPopup(): TPopup;
+
+      // Tooltip methods
+      function bindTooltip(content: TFunc<TLayer, String>; options: TTooltipOptions): TLayer; overload;
+      function bindTooltip(content: TFunc<TLayer, TJSHTMLElement>; options: TTooltipOptions): TLayer; overload;
+      function bindTooltip(content: TTooltip; options: TTooltipOptions): TLayer; overload;
+      function bindTooltip(content: String; options: TTooltipOptions): TLayer; overload;
+      function bindTooltip(content: TJSHTMLElement; options: TTooltipOptions): TLayer; overload;
+      function unbindTooltip(): TLayer;
+      function openTooltip(latlng: TLatLng): TLayer; overload;
+      function openTooltip(latlng: TLatLngLiteral): TLayer; overload;
+      function openTooltip(latlng: TLatLngTuple): TLayer; overload;
+      function closeTooltip(): TLayer;
+      function toggleTooltip(): TLayer;
+      function isTooltipOpen(): Boolean;
+      function setTooltipContent(content: String): TLayer; overload;
+      function setTooltipContent(content: TJSHTMLElement): TLayer; overload;
+      function setTooltipContent(content: TTooltip): TLayer; overload;
+      function getTooltip(): TTooltip;
+
+      // Extension methods
+      function onAdd(map: TMap): TLayer;
+      function onRemove(map: TMap): TLayer;
+      function getEvents(): TJSObject;
+      function getAttribution(): String;
+      function beforeAdd(map: TMap): TLayer;
+    end;
+
+    TDoneCallback = TProc<TError, TJSHTMLElement>;
+
+    TGridLayer = class external name 'GridLayer' (TLayer)
+    public
+      constructor new(options: TGridLayerOptions);
+      function bringToFront(): TGridLayer;
+      function bringToBack(): TGridLayer;
+      function getContainer(): TJSHTMLElement;
+      function setOpacity(opacity: Double): TGridLayer;
+      function setZIndex(zIndex: Double): TGridLayer;
+      function isLoading(): Boolean;
+      function redraw(): TGridLayer;
+      function getTileSize(): TPoint;
+    end;
+
+    TTileLayer = class external name 'TileLayer' (TGridLayer)
+    public type
+      TWMS = class external name 'WMS' (TTileLayer)
+      public
+        wmsParams: TWMSParams;
+        options: TWMSOptions;
+
+        constructor new(baseUrl: String; options: TWMSOptions);
+        function setParams(params: TWMSParams; noRedraw: Boolean): TWMS;
+      end;
+    public
+      options: TTileLayerOptions;
+
+      constructor new(urlTemplate: String; options: TTileLayerOptions);
+      function setUrl(url: String; noRedraw: Boolean): TTileLayer;
+      function getTileUrl(coords: TCoords): String;
+      function wms(baseUrl: String; options: TWMSOptions): TWMS;
+    end;
+
+    TImageOverlay = class external name 'ImageOverlay' (TLayer)
+    public
+      options: TImageOverlayOptions;
+
+      constructor new(imageUrl: String; bounds: TLatLngBounds; options: TImageOverlayOptions); overload;
+      constructor new(imageUrl: String; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions); overload;
+      function setOpacity(opacity: Double): TImageOverlay;
+      function bringToFront(): TImageOverlay;
+      function bringToBack(): TImageOverlay;
+      function setUrl(url: String): TImageOverlay;
+
+      function setBounds(bounds: TLatLngBounds): TImageOverlay;
+
+      function setZIndex(value: Double): TImageOverlay;
+
+      function getBounds(): TLatLngBounds;
+
+      function getElement(): TJSHTMLImageElement;
+    end;
+
+    TSVGOverlay = class external name 'SVGOverlay' (TLayer)
+    public
+      options: TImageOverlayOptions;
+
+      constructor new(svgImage: String; bounds: TLatLngBounds; options: TImageOverlayOptions); overload;
+      constructor new(svgImage: String; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions); overload;
+      constructor new(svgImage: TJSHTMLElement; bounds: TLatLngBounds; options: TImageOverlayOptions); overload;
+      constructor new(svgImage: TJSHTMLElement; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions); overload;
+
+      function setOpacity(opacity: Double): TSVGOverlay;
+      function bringToFront(): TSVGOverlay;
+      function bringToBack(): TSVGOverlay;
+      function setUrl(url: String): TSVGOverlay;
+
+      function setBounds(bounds: TLatLngBounds): TSVGOverlay;
+
+      function setZIndex(value: Double): TSVGOverlay;
+
+      function getBounds(): TLatLngBounds;
+
+      function getElement(): TJSHTMLElement;
+    end;
+
+    TVideoOverlay = class external name 'VideoOverlay' (TLayer)
+    public
+      options: TVideoOverlayOptions;
+
+      constructor new(video: String; bounds: TLatLngBounds; options: TVideoOverlayOptions); overload;
+      constructor new(video: String; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions); overload;
+      constructor new(video: TArray<String>; bounds: TLatLngBounds; options: TVideoOverlayOptions); overload;
+      constructor new(video: TArray<String>; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions); overload;
+      constructor new(video: TJSHTMLVideoElement; bounds: TLatLngBounds; options: TVideoOverlayOptions); overload;
+      constructor new(video: TJSHTMLVideoElement; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions); overload;
+
+      function setOpacity(opacity: Double): TVideoOverlay;
+      function bringToFront(): TVideoOverlay;
+      function bringToBack(): TVideoOverlay;
+      function setUrl(url: String): TVideoOverlay;
+
+      function setBounds(bounds: TLatLngBounds): TVideoOverlay;
+
+      function getBounds(): TLatLngBounds;
+
+      function getElement(): TJSHTMLVideoElement;
+    end;
+
+    TPath = class external name 'Path' abstract (TLayer)
+    public
+      options: TPathOptions;
+
+      function redraw(): TPath;
+      function setStyle(style: TPathOptions): TPath;
+      function bringToFront(): TPath;
+      function bringToBack(): TPath;
+      function getElement(): TJSHTMLElement;
+    end;
+
+    TPolyline = class external name 'Polyline' (TPath)
+    public
+      feature: TFeature;
+      options: TPolylineOptions;
+
+      constructor new(latlngs: TArray<TLatLng>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TArray<TLatLng>>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TLatLngLiteral>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TArray<TLatLngLiteral>>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TLatLngTuple>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TArray<TLatLngTuple>>; options: TPolylineOptions); overload;
+
+      function toGeoJSON(precision: Double): TFeature;
+      function getLatLngs(): JSValue;
+      function setLatLngs(latlngs: TArray<TLatLng>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TLatLngLiteral>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TLatLngTuple>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TLatLng>>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TLatLngLiteral>>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TLatLngTuple>>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TArray<TLatLng>>>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TArray<TLatLngLiteral>>>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TArray<TLatLngTuple>>>): TPolyline; overload;
+      function isEmpty(): Boolean;
+      function getCenter(): TLatLng;
+      function getBounds(): TLatLngBounds;
+      function addLatLng(latlng: TLatLng): TPolyline; overload;
+      function addLatLng(latlng: TLatLngLiteral): TPolyline; overload;
+      function addLatLng(latlng: TLatLngTuple): TPolyline; overload;
+      function addLatLng(latlng: TLatLng; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TLatLngLiteral; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TLatLngTuple; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLngLiteral>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLngTuple>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLng>; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLngLiteral>; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLngTuple>; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function closestLayerPoint(p: TPoint): TPoint;
+    end;
+
+    TPolygon = class external name 'Polygon' (TPolyline)
+    public
+      constructor new(latlngs: TArray<TLatLng>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TArray<TLatLng>>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TLatLngLiteral>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TArray<TLatLngLiteral>>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TLatLngTuple>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TArray<TLatLngTuple>>; options: TPolylineOptions); overload;
+    end;
+
+    TRectangle = class external name 'Rectangle' (TPolygon)
+    public
+      constructor new(latLngBounds: TLatLngBounds; options: TPolylineOptions); overload;
+      constructor new(latLngBounds: TLatLngBoundsLiteral; options: TPolylineOptions); overload;
+
+      function setBounds(latLngBounds: TLatLngBounds): TRectangle; overload;
+      function setBounds(latLngBounds: TLatLngBoundsLiteral): TRectangle; overload;
+    end;
+
+    TCircleMarker = class external name 'CircleMarker' (TPath)
+    public
+      options: TCircleMarkerOptions;
+      feature: TFeature;
+
+      constructor new(latlng: TLatLng; options: TCircleMarkerOptions); overload;
+      constructor new(latlng: TLatLngLiteral; options: TCircleMarkerOptions); overload;
+      constructor new(latlng: TLatLngTuple; options: TCircleMarkerOptions); overload;
+
+      function toGeoJSON(precision: Double): TFeature;
+      function setLatLng(latLng: JSValue): TCircleMarker;
+      function getLatLng(): TLatLng;
+      function setRadius(radius: Double): TCircleMarker;
+      function getRadius(): Double;
+    end;
+
+    TCircle = class external name 'Circle' (TCircleMarker)
+    public
+      constructor new(latlng: TLatLng; options: TCircleMarkerOptions); overload;
+      constructor new(latlng: TLatLngLiteral; options: TCircleMarkerOptions); overload;
+      constructor new(latlng: TLatLngTuple; options: TCircleMarkerOptions); overload;
+
+      function getBounds(): TLatLngBounds;
+    end;
+
+    TRenderer = class external name 'Renderer' (TLayer)
+    public
+      options: TRendererOptions;
+
+      constructor new(options: TRendererOptions);
+    end;
+
+    TSVG = class external name 'SVG' (TRenderer)
+    public
+      class function create(name: String): TJSHTMLElement;
+      class function pointsToPath(rings: TPoint; close: Boolean): String; overload;
+      class function pointsToPath(rings: TArray<TPointTuple>; close: Boolean): String; overload;
+    end;
+
+    TCanvas = class external name 'Canvas' (TRenderer)
+    end;
+
+    TLayerGroup = class external name 'LayerGroup' (TLayer)
+    public
+      feature: JSValue;
+
+      constructor new(layers: TArray<TLayer>); overload;
+      constructor new(layers: TArray<TLayer>; options: TLayerOptions); overload;
+      constructor new; overload;
+
+      function addLayer(layer: TLayer): TLayerGroup;
+      function clearLayers(): TLayerGroup;
+      function eachLayer(fn: TProc<TLayer>; context: JSValue): TLayerGroup;
+      function getLayer(id: Double): TLayer;
+      function getLayerId(layer: TLayer): Double;
+      function getLayers(): TArray<TLayer>;
+      function hasLayer(layer: TLayer): Boolean;
+      function invoke(methodName: String): TLayerGroup; varargs;
+      function removeLayer(layer: TLayer): TLayerGroup;
+      function setZIndex(zIndex: Double): TLayerGroup;
+      function toGeoJSON(precision: Double): JSValue; overload;
+      function toGeoJSON: JSValue; overload;
+    end;
+
+    TFeatureGroup = class external name 'FeatureGroup' (TLayerGroup)
+    public
+      function bringToBack(): TFeatureGroup;
+      function bringToFront(): TFeatureGroup;
+      function getBounds(): TLatLngBounds;
+      function setStyle(style: TPathOptions): TFeatureGroup;
+    end;
+
+    TStyleFunction = TFunc<TFeature, TPathOptions>;
+
+    TGeoJSON = class external name 'GeoJSON' (TFeatureGroup)
+    public
+      options: TGeoJSONOptions;
+
+      constructor new(geojson: TGeoJsonObject; options: TGeoJSONOptions);
+
+      class function asFeature(geojson: TFeature): TFeature;
+      class function coordsToLatLng(coords: TArray<Double>): TLatLng;
+      class function coordsToLatLngs(coords: TArray<JSValue>; levelsDeep: Double; coordsToLatLng: TFunc<TArray<Double>, TLatLng>): TArray<JSValue>; // Using TArray<JSValue> to avoid artificially limiting valid calls
+      class function geometryToLayer(featureData: TFeature; options: TGeoJSONOptions): TLayer;
+      class function latLngToCoords(latlng: TLatLng): TArray<Double>;
+      class function latLngsToCoords(latlngs: TArray<JSValue>; levelsDeep: Double; closed: Boolean): TArray<JSValue>;  // Using TArray<JSValue> to avoid artificially limiting valid calls
+
+      function addData(data: TGeoJsonObject): TLayer;
+      function resetStyle(layer: TLayer): TLayer;
+      function setStyle(style: TPathOptions): TGeoJSON; overload;
+      function setStyle(style: TStyleFunction): TGeoJSON; overload;
+    end;
+
+    TControl = class external name 'Control' (TClass)
+    public type
+      TZoom = class external name 'Zoom' (TControl)
+      public
+        options: TZoomControlOptions;
+        constructor new(options: TZoomControlOptions);
+      end;
+
+      TAttribution = class external name 'Attribution' (TControl)
+      public
+        options: TAttributionOptions;
+
+        constructor new(options: TAttributionOptions);
+        function setPrefix(prefix: String): TAttribution;
+        function addAttribution(text: String): TAttribution;
+        function removeAttribution(text: String): TAttribution;
+      end;
+
+      TLayers = class external name 'Layers' (TControl)
+      public
+        options: TLayersOptions;
+
+        constructor new; overload;
+        constructor new(baseLayers: TLayersObject); overload;
+        constructor new(baseLayers, overlays: TLayersObject); overload;
+        constructor new(baseLayers, overlays: TLayersObject; options: TLayersOptions); overload;
+
+        function addBaseLayer(layer: TLayer; name: String): TLayers;
+        function addOverlay(layer: TLayer; name: String): TLayers;
+        function removeLayer(layer: TLayer): TLayers;
+        function expand(): TLayers;
+        function collapse(): TLayers;
+      end;
+
+      TScale = class external name 'Scale' (TControl)
+      public
+        options: TScaleOptions;
+        constructor new(options: TScaleOptions);
+      end;
+    public
+      // Extension methods
+      onAdd: TFunc<TMap, TJSHTMLElement>;
+      onRemove: TProc<TMap>;
+      options: TControlOptions;
+
+      constructor new(options: TControlOptions);
+      function getPosition(): String;
+      function setPosition(position: String): TControl;
+      function getContainer(): TJSHTMLElement;
+      function addTo(map: TMap): TControl;
+      function remove(): TControl;
+      function zoom(options: TZoomControlOptions): TZoom;
+      function attribution(options: TAttributionOptions): TAttribution;
+      function layers(baseLayers, overlays: TLayersObject; options: TLayersOptions): TLayers;
+      function scale(options: TScaleOptions): TScale;
+    end;
+
+    TDivOverlay = class external name 'DivOverlay' abstract (TLayer)
+    public
+      options: TDivOverlayOptions;
+
+      constructor new; overload;
+      constructor new(options: TDivOverlayOptions); overload;
+      constructor new(options: TDivOverlayOptions; source: TLayer); overload;
+      function getLatLng(): TLatLng;
+      function setLatLng(latlng: TLatLng): TDivOverlay; overload;
+      function setLatLng(latlng: TLatLngLiteral): TDivOverlay; overload;
+      function setLatLng(latlng: TLatLngTuple): TDivOverlay; overload;
+      function getContent(): JSValue;
+      function setContent(htmlContent: TFunc<TLayer, String>): TDivOverlay; overload;
+      function setContent(htmlContent: TFunc<TLayer, TJSHTMLElement>): TDivOverlay; overload;
+      function setContent(htmlContent: String): TDivOverlay; overload;
+      function setContent(htmlContent: TJSHTMLElement): TDivOverlay; overload;
+      function getElement(): TJSHTMLElement;
+      procedure update();
+      function isOpen(): Boolean;
+      function bringToFront(): TDivOverlay;
+      function bringToBack(): TDivOverlay;
+    end;
+
+    TPopup = class external name 'Popup' (TDivOverlay)
+    public
+      options: TPopupOptions;
+
+      constructor new; overload;
+      constructor new(options: TPopupOptions); overload;
+      constructor new(options: TPopupOptions; source: TLayer); overload;
+      function openOn(map: TMap): TPopup;
+    end;
+
+    TTooltip = class external name 'Tooltip' (TDivOverlay)
+    public
+      options: TTooltipOptions;
+
+      constructor new; overload;
+      constructor new(options: TTooltipOptions); overload;
+      constructor new(options: TTooltipOptions; source: TLayer); overload;
+
+      procedure setOpacity(val: Double);
+    end;
+
+    THandler = class external name 'Handler' (TClass)
+    public
+      // Extension methods
+      addHooks: TProc;
+      removeHooks: TProc;
+
+      constructor new(map: TMap);
+
+      function disable(): THandler;
+      function enable(): THandler;
+      function enabled(): Boolean;
+    end;
+
+    THandlerClass = class of THandler;
+
+    TDomEvent = class external name 'DomEvent'
+    public type
+      TEventHandlerFn = TProc<TLeafletEvent>;
+    public
+      function addListener(el: TJSHTMLElement; types: String; fn: TEventHandlerFn; context: JSValue): TDomEvent;
+      function disableClickPropagation(el: TJSHTMLElement): TDomEvent;
+      function disableScrollPropagation(el: TJSHTMLElement): TDomEvent;
+      function getMousePosition(ev: TLeafletMouseEvent; container: TJSHTMLElement): TPoint;
+      function getWheelDelta(ev: TLeafletEvent): Double;
+      function off(el: TJSHTMLElement; types: String; fn: TEventHandlerFn; context: JSValue): TDomEvent;
+      function &on(el: TJSHTMLElement; types: String; fn: TEventHandlerFn; context: JSValue): TDomEvent;
+      function preventDefault(ev: TLeafletEvent): TDomEvent;
+      function removeListener(el: TJSHTMLElement; types: String; fn: TEventHandlerFn; context: JSValue): TDomEvent;
+      function stop(ev: TLeafletEvent): TDomEvent;
+      function stopPropagation(ev: TLeafletEvent): TDomEvent;
+    end;
+
+    TMap = class external name 'Map' (TEvented)
+    public
+      // Properties
+      attributionControl: TLeaflet.TControl.TAttribution;
+      boxZoom: THandler;
+      doubleClickZoom: THandler;
+      dragging: THandler;
+      keyboard: THandler;
+      scrollWheelZoom: THandler;
+      tap: THandler;
+      touchZoom: THandler;
+      zoomControl: TControl.TZoom;
+
+      options: TMapOptions;
+
+      constructor new(element: String); overload;
+      constructor new(element: String; options: TMapOptions); overload;
+      constructor new(element: TJSHTMLElement); overload;
+      constructor new(element: TJSHTMLElement; options: TMapOptions); overload;
+
+      function getRenderer(layer: TPath): TRenderer;
+
+      // Methods for layers and controls
+      function addControl(control: TControl): TMap;
+      function addLayer(layer: TLayer): TMap;
+      function closePopup(popup: TPopup): TMap;
+      function closeTooltip(tooltip: TTooltip): TMap;
+      function eachLayer(fn: TProc<TLayer>; context: JSValue): TMap;
+      function hasLayer(layer: TLayer): Boolean;
+      function openPopup(content: String; latlng: TLatLng; options: TPopupOptions): TMap; overload;
+      function openPopup(content: String; latlng: TLatLngLiteral; options: TPopupOptions): TMap; overload;
+      function openPopup(content: String; latlng: TLatLngTuple; options: TPopupOptions): TMap; overload;
+      function openPopup(content: TJSHTMLElement; latlng: TLatLng; options: TPopupOptions): TMap; overload;
+      function openPopup(content: TJSHTMLElement; latlng: TLatLngLiteral; options: TPopupOptions): TMap; overload;
+      function openPopup(content: TJSHTMLElement; latlng: TLatLngTuple; options: TPopupOptions): TMap; overload;
+      function openPopup(popup: TPopup): TMap; overload;
+      function openTooltip(content: String; latlng: TLatLng; options: TTooltipOptions): TMap; overload;
+      function openTooltip(content: String; latlng: TLatLngLiteral; options: TTooltipOptions): TMap; overload;
+      function openTooltip(content: String; latlng: TLatLngTuple; options: TTooltipOptions): TMap; overload;
+      function openTooltip(content: TJSHTMLElement; latlng: TLatLng; options: TTooltipOptions): TMap; overload;
+      function openTooltip(content: TJSHTMLElement; latlng: TLatLngLiteral; options: TTooltipOptions): TMap; overload;
+      function openTooltip(content: TJSHTMLElement; latlng: TLatLngTuple; options: TTooltipOptions): TMap; overload;
+      function openTooltip(tooltip: TTooltip): TMap; overload;
+      function removeControl(control: TControl): TMap;
+      function removeLayer(layer: TLayer): TMap;
+
+      // Methods for modifying map state
+      function fitBounds(bounds: TLatLngBounds; options: TFitBoundsOptions): TMap; overload;
+      function fitBounds(bounds: TLatLngBoundsLiteral; options: TFitBoundsOptions): TMap; overload;
+      function fitWorld(options: TFitBoundsOptions): TMap;
+      function flyTo(latlng: TLatLng; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function flyTo(latlng: TLatLngLiteral; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function flyTo(latlng: TLatLngTuple; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function flyToBounds(bounds: TLatLngBounds): TMap; overload;
+      function flyToBounds(bounds: TLatLngBounds; options: TFitBoundsOptions): TMap; overload;
+      function flyToBounds(bounds: TLatLngBoundsLiteral): TMap; overload;
+      function flyToBounds(bounds: TLatLngBoundsLiteral; options: TFitBoundsOptions): TMap; overload;
+      function invalidateSize(options: Boolean): TMap; overload;
+      function invalidateSize(options: TInvalidateSizeOptions): TMap; overload;
+      function panBy(offset: TPoint; options: TPanOptions): TMap; overload;
+      function panBy(offset: TPointTuple; options: TPanOptions): TMap; overload;
+      function panInside(latLng: JSValue; options: TPanInsideOptions): TMap;
+      function panInsideBounds(bounds: TLatLngBounds; options: TPanOptions): TMap; overload;
+      function panInsideBounds(bounds: TLatLngBoundsLiteral; options: TPanOptions): TMap; overload;
+      function panTo(latlng: TLatLng; options: TPanOptions): TMap; overload;
+      function panTo(latlng: TLatLngLiteral; options: TPanOptions): TMap; overload;
+      function panTo(latlng: TLatLngTuple; options: TPanOptions): TMap; overload;
+      function setMaxBounds(bounds: TLatLngBounds): TMap; overload;
+      function setMaxBounds(bounds: TLatLngBoundsLiteral): TMap; overload;
+      function setMaxZoom(zoom: Double): TMap;
+      function setMinZoom(zoom: Double): TMap;
+      function setView(center: TLatLngLiteral; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function setView(center: TLatLngTuple; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function setView(center: TLatLng; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function setZoom(zoom: Double; options: TZoomPanOptions): TMap;
+      function setZoomAround(position: TLatLng; zoom: Double; options: TZoomOptions): TMap; overload;
+      function setZoomAround(position: TLatLngLiteral; zoom: Double; options: TZoomOptions): TMap; overload;
+      function setZoomAround(position: TLatLngTuple; zoom: Double; options: TZoomOptions): TMap; overload;
+      function setZoomAround(position: TPoint; zoom: Double; options: TZoomOptions): TMap; overload;
+      function stop(): TMap;
+      function zoomIn(delta: Double; options: TZoomOptions): TMap;
+      function zoomOut(delta: Double; options: TZoomOptions): TMap;
+
+      // Other methods
+      function addHandler(name: String; HandlerClass: THandlerClass): TMap; // Alternatively; HandlerClass: new(map: TMap) => THandler
+      function createPane(name: String; container: TJSHTMLElement): TJSHTMLElement;
+      function getContainer(): TJSHTMLElement;
+      function getPane(pane: String): TJSHTMLElement; overload;
+      function getPane(pane: TJSHTMLElement): TJSHTMLElement; overload;
+      function getPanes(): TDefaultMapPanes;
+      function remove(): TMap;
+      function whenReady(fn: TProc; context: JSValue): TMap;
+
+      // Methods for getting map state
+      function getBounds(): TLatLngBounds;
+      function getBoundsZoom(bounds: TLatLngBounds; inside: Boolean; padding: TPoint): Double; overload;
+      function getBoundsZoom(bounds: TLatLngBoundsLiteral; inside: Boolean; padding: TPoint): Double; overload;
+      function getCenter(): TLatLng;
+      function getMaxZoom(): Double;
+      function getMinZoom(): Double;
+      function getPixelBounds(): TBounds;
+      function getPixelOrigin(): TPoint;
+      function getPixelWorldBounds(zoom: Double): TBounds;
+      function getSize(): TPoint;
+      function getZoom(): Double;
+
+      // Conversion methods
+      function containerPointToLatLng(point: TPoint): TLatLng; overload;
+      function containerPointToLatLng(point: TPointTuple): TLatLng; overload;
+      function containerPointToLayerPoint(point: TPoint): TPoint; overload;
+      function containerPointToLayerPoint(point: TPointTuple): TPoint; overload;
+      function distance(latlng1, latlng2: TLatLng): Double; overload;
+      function distance(latlng1, latlng2: TLatLngLiteral): Double; overload;
+      function distance(latlng1, latlng2: TLatLngTuple): Double; overload;
+      function getScaleZoom(scale: Double; fromZoom: Double): Double;
+      function getZoomScale(toZoom: Double; fromZoom: Double): Double;
+      function latLngToContainerPoint(latlng: TLatLng): TPoint; overload;
+      function latLngToContainerPoint(latlng: TLatLngLiteral): TPoint; overload;
+      function latLngToContainerPoint(latlng: TLatLngTuple): TPoint; overload;
+      function latLngToLayerPoint(latlng: TLatLng): TPoint; overload;
+      function latLngToLayerPoint(latlng: TLatLngLiteral): TPoint; overload;
+      function latLngToLayerPoint(latlng: TLatLngTuple): TPoint; overload;
+      function layerPointToContainerPoint(point: TPoint): TPoint; overload;
+      function layerPointToContainerPoint(point: TPointTuple): TPoint; overload;
+      function layerPointToLatLng(point: TPoint): TLatLng; overload;
+      function layerPointToLatLng(point: TPointTuple): TLatLng; overload;
+      function mouseEventToContainerPoint(ev: TLeafletMouseEvent): TPoint;
+      function mouseEventToLatLng(ev: TLeafletMouseEvent): TLatLng;
+      function mouseEventToLayerPoint(ev: TLeafletMouseEvent): TPoint;
+      function project(latlng: TLatLng; zoom: Double): TPoint; overload;
+      function project(latlng: TLatLngLiteral; zoom: Double): TPoint; overload;
+      function project(latlng: TLatLngTuple; zoom: Double): TPoint; overload;
+      function unproject(point: TPoint; zoom: Double): TLatLng; overload;
+      function unproject(point: TPointTuple; zoom: Double): TLatLng; overload;
+      function wrapLatLng(latlng: TLatLng): TLatLng; overload;
+      function wrapLatLng(latlng: TLatLngLiteral): TLatLng; overload;
+      function wrapLatLng(latlng: TLatLngTuple): TLatLng; overload;
+      function wrapLatLngBounds(bounds: TLatLngBounds): TLatLngBounds;
+
+      // Geolocation methods
+      function locate(options: TLocateOptions): TMap;
+      function stopLocate(): TMap;
+    end;
+
+    TIcon = class external name 'Icon'
+    public
+      options: TIconOptions;
+
+      constructor new(options: TIconOptions);
+
+      function createIcon(oldIcon: TJSHTMLElement): TJSHTMLElement;
+      function createShadow(oldIcon: TJSHTMLElement): TJSHTMLElement;
+    end;
+
+    TDefaultIcon = class external name 'Icon.Default' (TIcon)
+    public
+      constructor new; overload;
+      constructor new(options: TIconOptions); overload;
+    end;
+
+    TDivIcon = class external name 'DivIcon' (TIcon)
+    public
+      options: TDivIconOptions;
+
+      constructor new(options: TDivIconOptions);
+    end;
+
+    TMarker = class external name 'Marker' (TLayer)
+    public
+      // Properties
+      options: TMarkerOptions;
+      dragging: THandler;
+      feature: TFeature;
+
+      constructor new(latlng: TLatLng; options: TMarkerOptions); overload;
+      constructor new(latlng: TLatLngLiteral; options: TMarkerOptions); overload;
+      constructor new(latlng: TLatLngTuple; options: TMarkerOptions); overload;
+
+      function toGeoJSON(precision: Double): TFeature;
+      function getLatLng(): TLatLng;
+      function setLatLng(latlng: TLatLng): TMarker; overload;
+      function setLatLng(latlng: TLatLngLiteral): TMarker; overload;
+      function setLatLng(latlng: TLatLngTuple): TMarker; overload;
+      function setZIndexOffset(offset: Double): TMarker;
+      function getIcon(): JSValue;
+      function setIcon(icon: JSValue): TMarker;
+      function setOpacity(opacity: Double): TMarker;
+      function getElement(): TJSHTMLElement;
+    end;
+
+    TBrowser = class external name 'Browser'
+    public const
+      ie: Boolean;
+      ielt9: Boolean;
+      edge: Boolean;
+      webkit: Boolean;
+      android: Boolean;
+      android23: Boolean;
+      androidStock: Boolean;
+      opera: Boolean;
+      chrome: Boolean;
+      gecko: Boolean;
+      safari: Boolean;
+      opera12: Boolean;
+      win: Boolean;
+      ie3d: Boolean;
+      webkit3d: Boolean;
+      gecko3d: Boolean;
+      any3d: Boolean;
+      mobile: Boolean;
+      mobileWebkit: Boolean;
+      mobileWebkit3d: Boolean;
+      msPointer: Boolean;
+      pointer: Boolean;
+      touch: Boolean;
+      mobileOpera: Boolean;
+      mobileGecko: Boolean;
+      retina: Boolean;
+      canvas: Boolean;
+      svg: Boolean;
+      vml: Boolean;
+    end;
+
+    TUtil = class external name 'Util'
+    public
+      function extend(dest: JSValue): JSValue; varargs;
+
+      function stamp(obj: JSValue): Double;
+      function throttle(fn: TProc; time: Double; context: JSValue): TProc;
+      function wrapNum(num: Double; range: TArray<Double>; includeMax: Boolean): Double;
+      function falseFn(): Boolean;
+      function formatNum(num: Double; digits: Double): Double;
+      function trim(str: String): String;
+      function splitWords(str: String): TArray<String>;
+      function setOptions(obj: JSValue; options: JSValue): JSValue;
+      function getParamString(obj: JSValue; existingUrl: String; uppercase: Boolean): String;
+      function template(str: String; data: JSValue): String;
+      function isArray(obj: JSValue): Boolean;
+      function indexOf(&array: TArray<JSValue>; el: JSValue): Double;
+      function requestAnimFrame(fn: TProc<Double>; context: JSValue; immediate: Boolean): Double;
+      procedure cancelAnimFrame(id: Double);
+    end;
+  public
+    lastId: Double;
+    emptyImageUrl: String;
+
+    function bounds(topLeft, bottomRight: TPoint): TBounds; overload;
+    function bounds(topLeft, bottomRight: TPointTuple): TBounds; overload;
+    function bounds(points: TArray<TPoint>): TBounds; overload;
+    function bounds(points: TBoundsLiteral): TBounds; overload;
+    function canvas(options: TRendererOptions): TCanvas;
+    function circle(latlng: TLatLng; options: TCircleMarkerOptions): TCircle; overload;
+    function circle(latlng: TLatLngLiteral; options: TCircleMarkerOptions): TCircle; overload;
+    function circle(latlng: TLatLngTuple; options: TCircleMarkerOptions): TCircle; overload;
+    function circleMarker(latlng: TLatLng; options: TCircleMarkerOptions): TCircleMarker; overload;
+    function circleMarker(latlng: TLatLngLiteral; options: TCircleMarkerOptions): TCircleMarker; overload;
+    function circleMarker(latlng: TLatLngTuple; options: TCircleMarkerOptions): TCircleMarker; overload;
+    function divIcon(options: TDivIconOptions): TDivIcon;
+    function featureGroup(layers: TArray<TLayer>): TFeatureGroup;
+    function geoJSON(geojson: TGeoJsonObject; options: TGeoJSONOptions): TGeoJSON;
+    function gridLayer(options: TGridLayerOptions): TGridLayer;
+    function icon(options: TIconOptions): TIcon;
+    function imageOverlay(imageUrl: String; bounds: TLatLngBounds; options: TImageOverlayOptions): TImageOverlay; overload;
+    function imageOverlay(imageUrl: String; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions): TImageOverlay; overload;
+    function latLng(coords: TArray<Double>): TLatLng; overload;
+    function latLng(latitude, longitude: Double): TLatLng; overload;
+    function latLng(latitude, longitude, altitude: Double): TLatLng; overload;
+    function latLngBounds(southWest, northEast: TLatLng): TLatLngBounds; overload;
+    function latLngBounds(southWest, northEast: TLatLngLiteral): TLatLngBounds; overload;
+    function latLngBounds(southWest, northEast: TLatLngTuple): TLatLngBounds; overload;
+    function latLngBounds(latlngs: TArray<TLatLng>): TLatLngBounds; overload;
+    function latLngBounds(latlngs: TArray<TLatLngLiteral>): TLatLngBounds; overload;
+    function latLngBounds(latlngs: TArray<TLatLngTuple>): TLatLngBounds; overload;
+    function layerGroup: TLayerGroup; overload;
+    function layerGroup(layers: TArray<TLayer>): TLayerGroup; overload;
+    function layerGroup(layers: TArray<TLayer>; options: TLayerOptions): TLayerGroup; overload;
+    function map(element: String; options: TMapOptions): TMap; overload;
+    function map(element: TJSHTMLElement; options: TMapOptions): TMap; overload;
+    function marker(latlng: TLatLng; options: TMarkerOptions): TMarker; overload;
+    function marker(latlng: TLatLngLiteral; options: TMarkerOptions): TMarker; overload;
+    function marker(latlng: TLatLngTuple; options: TMarkerOptions): TMarker; overload;
+    function point(x, y: Double): TPoint; overload;
+    function point(x, y: Double; round: Boolean): TPoint; overload;
+    function point(coords: TPointTuple): TPoint; overload;
+    function polyline(latlngs: TArray<TLatLng>; options: TPolylineOptions): TPolyline; overload;
+    function polyline(latlngs: TArray<TArray<TLatLng>>; options: TPolylineOptions): TPolyline; overload;
+    function polyline(latlngs: TArray<TLatLngLiteral>; options: TPolylineOptions): TPolyline; overload;
+    function polyline(latlngs: TArray<TArray<TLatLngLiteral>>; options: TPolylineOptions): TPolyline; overload;
+    function polyline(latlngs: TArray<TLatLngTuple>; options: TPolylineOptions): TPolyline; overload;
+    function polyline(latlngs: TArray<TArray<TLatLngTuple>>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TLatLng>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TArray<TLatLng>>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TLatLngLiteral>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TArray<TLatLngLiteral>>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TLatLngTuple>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TArray<TLatLngTuple>>; options: TPolylineOptions): TPolyline; overload;
+    function popup: TPopup; overload;
+    function popup(options: TPopupOptions): TPopup; overload;
+    function popup(options: TPopupOptions; source: TLayer): TPopup; overload;
+    function rectangle(latLngBounds: TLatLngBounds; options: TPolylineOptions): TRectangle; overload;
+    function rectangle(latLngBounds: TLatLngBoundsLiteral; options: TPolylineOptions): TRectangle; overload;
+    function svg(options: TRendererOptions): TSVG;
+    function svgOverlay(svgImage: String; bounds: TLatLngBounds; options: TImageOverlayOptions): TSVGOverlay; overload;
+    function svgOverlay(svgImage: String; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions): TSVGOverlay; overload;
+    function svgOverlay(svgImage: TJSHTMLElement; bounds: TLatLngBounds; options: TImageOverlayOptions): TSVGOverlay; overload;
+    function svgOverlay(svgImage: TJSHTMLElement; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions): TSVGOverlay; overload;
+    function tileLayer(urlTemplate: String; options: TTileLayerOptions): TTileLayer;
+    function tooltip: TTooltip; overload;
+    function tooltip(options: TTooltipOptions): TTooltip; overload;
+    function tooltip(options: TTooltipOptions; source: TLayer): TTooltip; overload;
+    function videoOverlay(video: String; bounds: TLatLngBounds; options: TVideoOverlayOptions): TVideoOverlay; overload;
+    function videoOverlay(video: String; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions): TVideoOverlay; overload;
+    function videoOverlay(video: TArray<String>; bounds: TLatLngBounds; options: TVideoOverlayOptions): TVideoOverlay; overload;
+    function videoOverlay(video: TArray<String>; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions): TVideoOverlay; overload;
+    function videoOverlay(video: TJSHTMLVideoElement; bounds: TLatLngBounds; options: TVideoOverlayOptions): TVideoOverlay; overload;
+    function videoOverlay(video: TJSHTMLVideoElement; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions): TVideoOverlay; overload;
+  end;
+
+  TLatLngLiteral = class
+  public
+    lat: Double;
+    lng: Double;
+  end;
+
+  TLayerOptions = class
+  public
+    pane: String;
+    attribution: String;
+  end;
+
+  TInteractiveLayerOptions = class(TLayerOptions)
+  public
+    interactive: Boolean;
+    bubblingMouseEvents: Boolean;
+  end;
+
+  TGridLayerOptions = class(TLayerOptions)
+  public
+    tileSize: TPoint;
+    tileSizeNumber: Double; external name 'tileSize';
+    opacity: Double;
+    updateWhenIdle: Boolean;
+    updateWhenZooming: Boolean;
+    updateInterval: Double;
+    attribution: String;
+    zIndex: Double;
+    bounds: JSValue;
+    minZoom: Double;
+    maxZoom: Double;
+    noWrap: Boolean;
+    pane: String;
+    className: String;
+    keepBuffer: Double;
+  end;
+
+  TTileLayerOptions = class(TGridLayerOptions)
+  public
+    id: String;
+    accessToken: String;
+    minZoom: Double;
+    maxZoom: Double;
+    maxNativeZoom: Double;
+    minNativeZoom: Double;
+    subdomains: TArray<String>;
+    errorTileUrl: String;
+    zoomOffset: Double;
+    tms: Boolean;
+    zoomReverse: Boolean;
+    detectRetina: Boolean;
+    crossOrigin: String;
+  end;
+
+  TWMSOptions = class(TTileLayerOptions)
+  public
+    layers: String;
+    styles: String;
+    format: String;
+    transparent: Boolean;
+    version: String;
+    crs: TLeaflet.TCRS;
+    uppercase: Boolean;
+  end;
+
+  TWMSParams = class
+  public
+    format: String;
+    layers: String;
+    request: String;
+    service: String;
+    styles: String;
+    version: String;
+    transparent: Boolean;
+    width: Double;
+    height: Double;
+  end;
+
+  TImageOverlayOptions = class(TInteractiveLayerOptions)
+  public
+    opacity: Double;
+    alt: String;
+    interactive: Boolean;
+    attribution: String;
+    crossOrigin: String;
+    errorOverlayUrl: String;
+    zIndex: Double;
+    className: String;
+  end;
+
+  TVideoOverlayOptions = class(TImageOverlayOptions)
+  public
+    autoplay: Boolean;
+    loop: Boolean;
+    keepAspectRatio: Boolean;
+  end;
+
+  TPathOptions = class(TInteractiveLayerOptions)
+  public
+    stroke: Boolean;
+    color: String;
+    weight: Double;
+    opacity: Double;
+    lineCap: String;
+    lineJoin: String;
+    dashArray: TArray<Double>;
+    dashOffset: String;
+    fill: Boolean;
+    fillColor: String;
+    fillOpacity: Double;
+    fillRule: String;
+    renderer: TLeaflet.TRenderer;
+    className: String;
+  end;
+
+  TPolylineOptions = class(TPathOptions)
+  public
+    smoothFactor: Double;
+    noClip: Boolean;
+  end;
+
+  TCircleMarkerOptions = class(TPathOptions)
+  public
+    radius: Double;
+  end;
+
+  TRendererOptions = class (TLayerOptions)
+  public
+    padding: Double;
+    tolerance: Double;
+  end;
+
+  TGeoJSONOptions = class(TInteractiveLayerOptions)
+  public
+    coordsToLatLng: TFunc<TArray<Double>, TLeaflet.TLatLng>;
+    filter: TFunc<TFeature, Boolean>;
+    onEachFeature: TProc<TFeature, TLeaflet.TLayer>;
+    pointToLayer: TFunc<TFeature, TLeaflet.TLatLng, TLeaflet.TLayer>;
+    style: TPathOptions;
+    styleFunction: TLeaflet.TStyleFunction; external name 'style';
+  end;
+
+  TMapOptions = class
+  private
+    FCRS: TLeaflet.TCRS; external name 'crs';
+
+    function GetCRS: TLeaflet.TCRS;
+
+    procedure SetCRS(Value: TLeaflet.TCRS);
+  public
+    preferCanvas: Boolean;
+
+    // Control options
+    attributionControl: Boolean;
+    zoomControl: Boolean;
+
+    // Interaction options
+    closePopupOnClick: Boolean;
+    zoomSnap: Double;
+    zoomDelta: Double;
+    trackResize: Boolean;
+    boxZoom: Boolean;
+    doubleClickZoom: String;
+    dragging: Boolean;
+
+    // Map state options
+    center: JSValue;
+    zoom: Double;
+    minZoom: Double;
+    maxZoom: Double;
+    layers: TArray<TLeaflet.TLayer>;
+    maxBounds: JSValue;
+    renderer: TLeaflet.TRenderer;
+
+    // Animation options
+    fadeAnimation: Boolean;
+    markerZoomAnimation: Boolean;
+    transform3DLimit: Double;
+    zoomAnimation: Boolean;
+    zoomAnimationThreshold: Double;
+
+    // Panning inertia options
+    inertia: Boolean;
+    inertiaDeceleration: Double;
+    inertiaMaxSpeed: Double;
+    easeLinearity: Double;
+    worldCopyJump: Boolean;
+    maxBoundsViscosity: Double;
+
+    // Keyboard navigation options
+    keyboard: Boolean;
+    keyboardPanDelta: Double;
+
+    // Mousewheel options
+    scrollWheelZoom: TLeaflet.TControl.TZoom;
+    wheelDebounceTime: Double;
+    wheelPxPerZoomLevel: Double;
+
+    // Touch interaction options
+    tap: Boolean;
+    tapTolerance: Double;
+    touchZoom: TLeaflet.TControl.TZoom;
+    bounceAtZoomLimits: Boolean;
+
+    property crs: TLeaflet.TCRS read GetCRS write SetCRS;
+  end;
+
+  TControlOptions = class
+  public
+    position: String;
+  end;
+
+  TZoomControlOptions = class(TControlOptions)
+  public
+    zoomInText: String;
+    zoomInTitle: String;
+    zoomOutText: String;
+    zoomOutTitle: String;
+  end;
+
+  TAttributionOptions = class(TControlOptions)
+  public
+    prefix: String;
+  end;
+
+  TLayersOptions = class(TControlOptions)
+  public
+    collapsed: Boolean;
+    autoZIndex: Boolean;
+    hideSingleBase: Boolean;
+  end;
+
+  TLayersObject = class
+  private
+    function GetLayers(name: String): TLeaflet.TLayer; external name '[]';
+
+    procedure SetLayers(name: String; Value: TLeaflet.TLayer); external name '[]';
+  public
+    property Layers[name: String]: TLeaflet.TLayer read GetLayers write SetLayers;
+  end;
+
+  TScaleOptions = class(TControlOptions)
+  public
+    maxWidth: Double;
+    metric: Boolean;
+    imperial: Boolean;
+    updateWhenIdle: Boolean;
+  end;
+
+  TDivOverlayOptions = class
+  public
+    offset: TPoint;
+    zoomAnimation: Boolean;
+    className: String;
+    pane: String;
+  end;
+
+  TPopupOptions = class(TDivOverlayOptions)
+  public
+    maxWidth: Double;
+    minWidth: Double;
+    maxHeight: Double;
+    keepInView: Boolean;
+    closeButton: Boolean;
+    autoPan: Boolean;
+    autoPanPaddingTopLeft: TPoint;
+    autoPanPaddingBottomRight: TPoint;
+    autoPanPadding: TPoint;
+    autoClose: Boolean;
+    closeOnClick: Boolean;
+    closeOnEscapeKey: Boolean;
+  end;
+
+  TTooltipOptions = class(TDivOverlayOptions)
+  public
+    pane: String;
+    offset: TPoint;
+    direction: String;
+    permanent: Boolean;
+    sticky: Boolean;
+    interactive: Boolean;
+    opacity: Double;
+  end;
+
+  TZoomOptions = class
+  public
+    animate: Boolean;
+  end;
+
+  TPanOptions = class(TZoomOptions)
+  public
+    duration: Double;
+    easeLinearity: Double;
+    noMoveStart: Boolean;
+  end;
+
+  TZoomPanOptions = class(TZoomOptions)
+  end;
+
+  TInvalidateSizeOptions = class(TZoomPanOptions)
+  public
+    debounceMoveend: Boolean;
+    pan: Boolean;
+  end;
+
+  TFitBoundsOptions = class(TZoomPanOptions)
+  public
+    paddingTopLeft: TPoint;
+    paddingBottomRight: TPoint;
+    padding: TPoint;
+    maxZoom: Double;
+  end;
+
+  TPanInsideOptions = class
+  public
+    paddingTopLeft: TPoint;
+    paddingBottomRight: TPoint;
+    padding: TPoint;
+  end;
+
+  TLocateOptions = class
+  public
+    watch: Boolean;
+    setView: Boolean;
+    maxZoom: Double;
+    timeout: Double;
+    maximumAge: Double;
+    enableHighAccuracy: Boolean;
+  end;
+
+  TLeafletEvent = class
+  public
+    &type: String;
+    target: JSValue;
+    sourceTarget: JSValue;
+    propagatedFrom: JSValue;
+  end;
+
+  TLeafletMouseEvent = class(TLeafletEvent)
+  public
+    latlng: TLeaflet.TLatLng;
+    layerPoint: TPoint;
+    containerPoint: TPoint;
+    originalEvent: TLeafletMouseEvent;
+  end;
+
+  TLeafletKeyboardEvent = class(TLeafletEvent)
+  public
+    originalEvent: TLeafletKeyboardEvent;
+  end;
+
+  TLocationEvent = class(TLeafletEvent)
+  public
+    latlng: TLeaflet.TLatLng;
+    bounds: TLeaflet.TLatLngBounds;
+    accuracy: Double;
+    altitude: Double;
+    altitudeAccuracy: Double;
+    heading: Double;
+    speed: Double;
+    timestamp: Double;
+  end;
+
+  TErrorEvent = class(TLeafletEvent)
+  public
+    message: String;
+    code: Double;
+  end;
+
+  TLayerEvent = class(TLeafletEvent)
+  public
+    layer: TLeaflet.TLayer;
+  end;
+
+  TLayersControlEvent = class(TLayerEvent)
+  public
+    name: String;
+  end;
+
+  TTileEvent = class(TLeafletEvent)
+  public
+    tile: TJSHTMLImageElement;
+    coords: TLeaflet.TCoords;
+  end;
+
+  TTileErrorEvent = class(TTileEvent)
+  public
+    error: TError;
+  end;
+
+  TResizeEvent = class(TLeafletEvent)
+  public
+    oldSize: TPoint;
+    newSize: TPoint;
+  end;
+
+  TGeoJSONEvent = class(TLeafletEvent)
+  public
+    layer: TLeaflet.TLayer;
+    properties: JSValue;
+    geometryType: String;
+    id: String;
+  end;
+
+  TPopupEvent = class(TLeafletEvent)
+  public
+    popup: TLeaflet.TPopup;
+  end;
+
+  TTooltipEvent = class(TLeafletEvent)
+  public
+    tooltip: TLeaflet.TTooltip;
+  end;
+
+  TDragEndEvent = class(TLeafletEvent)
+  public
+    distance: Double;
+  end;
+
+  TZoomAnimEvent = class(TLeafletEvent)
+  public
+    center: TLeaflet.TLatLng;
+    zoom: Double;
+    noUpdate: Boolean;
+  end;
+
+  TDefaultMapPanes = class
+  public
+    mapPane: TJSHTMLElement;
+    tilePane: TJSHTMLElement;
+    overlayPane: TJSHTMLElement;
+    shadowPane: TJSHTMLElement;
+    markerPane: TJSHTMLElement;
+    tooltipPane: TJSHTMLElement;
+    popupPane: TJSHTMLElement;
+  end;
+
+  TIconOptions = class(TLayerOptions)
+  public
+    iconUrl: String;
+    iconRetinaUrl: String;
+    iconSize: TPoint;
+    iconAnchor: TPoint;
+    popupAnchor: TPoint;
+    tooltipAnchor: TPoint;
+    shadowUrl: String;
+    shadowRetinaUrl: String;
+    shadowSize: TPoint;
+    shadowAnchor: TPoint;
+    className: String;
+  end;
+
+  TDivIconOptions = class (TIconOptions)
+  public
+    html: JSValue;
+    bgPos: TPoint;
+    iconSize: TPoint;
+    iconAnchor: TPoint;
+    popupAnchor: TPoint;
+    className: String;
+  end;
+
+  TMarkerOptions = class(TInteractiveLayerOptions)
+  public
+    icon: JSValue;
+    draggable: Boolean;
+    keyboard: Boolean;
+    title: String;
+    alt: String;
+    zIndexOffset: Double;
+    opacity: Double;
+    riseOnHover: Boolean;
+    riseOffset: Double;
+    shadowPane: String;
+    autoPan: Boolean;
+    autoPanPadding: TPoint;
+    autoPanSpeed: Double;
+  end;
+
+  TError = class
+  end;
+
+  TMapboxLayerOptions = class(TTileLayerOptions)
+  public
+    AccessToken: String; external name 'accessToken';
+    Style: String; external name 'style';
+
+    constructor Create(Style, AccessToken: String);
+  end;
+
+var
+  Leaflet: TLeaflet; external name 'L';
+
+function InitializeMap: TJSPromise;
+
+implementation
+
+function InitializeMap: TJSPromise;
+begin
+  Result := TJSPromise.New(
+    procedure(Resolve, Reject: TJSPromiseResolver)
+    var
+      Script: TJSHTMLScriptElement;
+
+      Link: TJSHTMLLinkElement;
+
+    begin
+      Link := TJSHTMLLinkElement(document.createElement('link'));
+      Link.HRef := 'https://unpkg.com/leaflet/dist/leaflet.css';
+      Link.Rel := 'stylesheet';
+
+      document.head.appendChild(Link);
+
+      Script := TJSHTMLScriptElement(document.createElement('script'));
+      Script.OnLoad :=
+        function (Event: TEventListenerEvent): Boolean
+        begin
+          Resolve(True);
+
+          Result := True;
+        end;
+      Script.src := 'https://unpkg.com/leaflet/dist/leaflet.js';
+      Script.type_ := 'text/javascript';
+
+      document.head.appendChild(Script);
+    end);
+end;
+
+{ TMapOptions }
+
+function TMapOptions.GetCRS: TLeaflet.TCRS;
+begin
+  if not Assigned(FCRS) then
+    FCRS := TLeaflet.TCRS.EPSG3857;
+
+  Result := FCRS;
+end;
+
+procedure TMapOptions.SetCRS(Value: TLeaflet.TCRS);
+begin
+  FCRS := Value;
+end;
+
+{ TMapboxLayerOptions }
+
+constructor TMapboxLayerOptions.Create(Style, AccessToken: String);
+begin
+  inherited Create;
+
+  Attribution := 'Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>';
+  Self.AccessToken := AccessToken;
+  Self.Style := Style;
+  TileSizeNumber := 512;
+  ZoomOffset := -1;
+end;
+
+end.
+
-- 
2.31.1.windows.1

henrique

2021-05-20 13:17

reporter   ~0130970

It is important to note that to work these implementations need only fix the 0038883 bug and apply the statements I made in the 0038912 task.

henrique

2021-05-27 13:16

reporter   ~0131052

Some fixes.
0001-Implementa-o-da-base-dos-mapas-4.patch (182,710 bytes)   
From 9aae83d53c956161a59741ea98ae68a6623948eb Mon Sep 17 00:00:00 2001
From: Henrique Gottardi Werlang <henriquewerlang@hotmail.com>
Date: Thu, 27 May 2021 10:14:43 -0300
Subject: [PATCH] =?UTF-8?q?Implementa=C3=A7=C3=A3o=20da=20base=20dos=20map?=
 =?UTF-8?q?as.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 packages/maps/Bing.Maps.pas    |  873 +++++++++++++
 packages/maps/GeoJSON.pas      |  166 +++
 packages/maps/Google.Maps.pas  | 2156 ++++++++++++++++++++++++++++++++
 packages/maps/Leaflet.Maps.pas | 1845 +++++++++++++++++++++++++++
 4 files changed, 5040 insertions(+)
 create mode 100644 packages/maps/Bing.Maps.pas
 create mode 100644 packages/maps/GeoJSON.pas
 create mode 100644 packages/maps/Google.Maps.pas
 create mode 100644 packages/maps/Leaflet.Maps.pas

diff --git a/packages/maps/Bing.Maps.pas b/packages/maps/Bing.Maps.pas
new file mode 100644
index 00000000..89f2b0c9
--- /dev/null
+++ b/packages/maps/Bing.Maps.pas
@@ -0,0 +1,873 @@
+unit Bing.Maps;
+
+interface
+
+{$modeswitch externalclass}
+
+uses Web, JS, SysUtils;
+
+type
+  TAddress = class;
+  TAnimatedFrameEventArgs = class;
+  TAnimatedTileLayerOptions  = class;
+  TBorderedMapElementStyle = class;
+  TCustomMapStyle = class;
+  TCustomOverlayOptions = class;
+  TGroundOverlayOptions = class;
+  THandlerId = class;
+  TInfoboxEventArgs = class;
+  TInfoboxOptions  = class;
+  TMapElementStyle = class;
+  TMapElements = class;
+  TMapOptions = class;
+  TMapTypeChangeEventArgs = class;
+  TModuleOptions = class;
+  TMouseEventArgs = class;
+  TPanoramaInfo = class;
+  TPolygonOptions = class;
+  TPolylineOptions = class;
+  TPrimitiveChangedEventArgs = class;
+  TPrimitiveOptions = class;
+  TPushpinOptions = class;
+  TRange = class;
+  TSettingsStyle = class;
+  TStreetsideOptions  = class;
+  TStyleUrl = class;
+  TStylesOptions = class;
+  TTileLayerOptions = class;
+  TTileSourceOptions = class;
+  TViewOptions = class;
+
+  TMicrosoft = class external name 'Microsoft'
+  public type
+    TMaps = class external name 'Maps'
+    public type
+      TCustomOverlay = class;
+      TInfobox = class;
+      TLayer = class;
+      TLocation = class;
+      TLocationRect = class;
+      TMap = class;
+      TPoint = class;
+      TPolygon = class;
+      TPolyline = class;
+      TPushpin = class;
+      TTileSource = class;
+
+      TLabelOverlay = (loHidden, loVisible);
+      TMapTypeId = (mtAerial, mtBirdseye, mtCanvasDark, mtCanvasLight, mtGrayscale, mtMercator, mtOrdnanceSurvey, mtRoad, mtStreetside);
+      TNavigationBarMode = (nbCompact, nbDefault, nbMinified);
+      TNavigationBarOrientation = (nboHorizontal, nboVertical);
+      TOverviewMapMode = (omExpanded, omHidden, omMinimized);
+      TPixelReference = (prControl, prPage, prViewport);
+
+      TPrimitive = class external name 'Primitive' abstract
+      public
+        function getCursor: String;
+        function getVisible: Boolean;
+        procedure setOptions(options: TPrimitiveOptions);
+      end;
+
+      TAnimatedTileLayer = class external name 'AnimatedTileLayer'
+      public
+        constructor new(options: TAnimatedTileLayerOptions);
+
+        function getFrameRate: Double;
+        function getLoadingScreen: TCustomOverlay;
+        function getMaxTotalLoadTime: Double;
+        function getTileSources: TArray<TTileSource>;
+        function getVisible: Boolean;
+
+        procedure pause;
+        procedure play;
+        procedure setOptions(options: TAnimatedTileLayerOptions);
+        procedure stop;
+      end;
+
+      TColor = class external name 'Color'
+      public
+        a: Double;
+        r: Double;
+        g: Double;
+        b: Double;
+
+        constructor new(a: Double; r: Double; g: Double; b: Double);
+
+        class function clone(color: TColor): TColor; overload;
+        class function fromHex(hex: String): TColor;
+
+        function clone: TColor; overload;
+        function getOpacity: Double;
+        function toHex: String;
+        function toRgba: String;
+      end;
+
+      TLayer = class external name 'Layer'
+      public
+        metadata: JSValue;
+
+        constructor new; overload;
+        constructor new(id: String); overload;
+
+        function getId: String;
+        function getPrimitives: TArray<TPrimitive>;
+        function getVisible: Boolean;
+        function getZIndex: Double;
+        function remove(primitive: TPrimitive): TPrimitive;
+        function removeAt(index: Double): TPrimitive;
+
+        procedure add(primitive: TPrimitive); overload;
+        procedure add(primitive: TPrimitive; index: Double); overload;
+        procedure add(primitive: TArray<TPrimitive>); overload;
+        procedure add(primitive: TArray<TPrimitive>; index: Double); overload;
+        procedure clear;
+        procedure dispose;
+        procedure setPrimitives(primitives: TArray<TPrimitive>);
+        procedure setVisible(value: Boolean);
+        procedure setZIndex(zIndex: Double);
+      end;
+
+      TCustomOverlay = class external name 'CustomOverlay' (TLayer)
+      public
+        _map: TMap;
+
+        constructor new(options: TCustomOverlayOptions);
+
+        function getHtmlElement: TJSHTMLElement;
+        function getMap: TMap;
+
+        procedure onAdd;
+        procedure onLoad;
+        procedure onRemove;
+        procedure setHtmlElement(htmlElement: TJSHTMLElement);
+      end;
+
+      TEvents = class external name 'Events'
+      public
+        function addHandler(target: JSValue; eventName: String; handler: TProc<JSValue>): THandlerId; overload;
+        function addHandler(target: TInfobox; eventName: String; handler: TProc<TInfoboxEventArgs>): THandlerId; overload;
+        function addHandler(target: TLayer; eventName: String; handler: TProc<TMouseEventArgs>): THandlerId; overload;
+        function addHandler(target: TMap; eventName: String; handler: TProc<TMapTypeChangeEventArgs>): THandlerId; overload;
+        function addHandler(target: TMap; eventName: String; handler: TProc<TMouseEventArgs>): THandlerId; overload;
+        function addHandler(target: TPolygon; eventName: String; handler: TProc<TMouseEventArgs>): THandlerId; overload;
+        function addHandler(target: TPolygon; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>): THandlerId; overload;
+        function addHandler(target: TPolyline; eventName: String; handler: TProc<TMouseEventArgs>): THandlerId; overload;
+        function addHandler(target: TPolyline; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>): THandlerId; overload;
+        function addHandler(target: TPushpin; eventName: String; handler: TProc<TMouseEventArgs>): THandlerId; overload;
+        function addHandler(target: TPushpin; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>): THandlerId; overload;
+        function addThrottledHandler(target: JSValue; eventName: String; handler: TProc<JSValue>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TInfobox; eventName: String; handler: TProc<TInfoboxEventArgs>): THandlerId; overload;
+        function addThrottledHandler(target: TLayer; eventName: String; handler: TProc<TMouseEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TMap; eventName: String; handler: TProc<TMapTypeChangeEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TMap; eventName: String; handler: TProc<TMouseEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPolygon; eventName: String; handler: TProc<TMouseEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPolygon; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPolyline; eventName: String; handler: TProc<TMouseEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPolyline; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPushpin; eventName: String; handler: TProc<TMouseEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function addThrottledHandler(target: TPushpin; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>; throttleInterval: Double): THandlerId; overload;
+        function hasHandler(target: JSValue; eventName: String): Boolean;
+
+        procedure addOne(target: JSValue; eventName: String; handler: TProc<JSValue>); overload;
+        procedure addOne(target: TInfobox; eventName: String; handler: TProc<TInfoboxEventArgs>); overload;
+        procedure addOne(target: TLayer; eventName: String; handler: TProc<TMouseEventArgs>); overload;
+        procedure addOne(target: TMap; eventName: String; handler: TProc<TMapTypeChangeEventArgs>); overload;
+        procedure addOne(target: TMap; eventName: String; handler: TProc<TMouseEventArgs>); overload;
+        procedure addOne(target: TPolygon; eventName: String; handler: TProc<TMouseEventArgs>); overload;
+        procedure addOne(target: TPolygon; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>); overload;
+        procedure addOne(target: TPolyline; eventName: String; handler: TProc<TMouseEventArgs>); overload;
+        procedure addOne(target: TPolyline; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>); overload;
+        procedure addOne(target: TPushpin; eventName: String; handler: TProc<TMouseEventArgs>); overload;
+        procedure addOne(target: TPushpin; eventName: String; handler: TProc<TPrimitiveChangedEventArgs>); overload;
+        procedure invoke(target: JSValue; evenName: String; args: JSValue);
+        procedure removeHandler(handlerId: THandlerId);
+      end;
+
+      TGroundOverlay = class external name 'GroundOverlay' (TCustomOverlay)
+      public
+        metadata: JSValue; external name 'metadata';
+
+        constructor new(options: TGroundOverlayOptions);
+
+        function getBackgroundColor: TColor;
+        function getBounds: TLocationRect;
+        function getImageUrl: String;
+        function getMap: TMap;
+        function getOpacity: Double;
+        function getRotation: Double;
+        function getVisible: Boolean;
+
+        procedure setOptions(options: TGroundOverlayOptions);
+        procedure setVisible(visible: Boolean);
+      end;
+
+      THeading = class external name 'Heading'
+      public
+        class var East: Double;
+        class var North: Double;
+        class var South: Double;
+        class var West: Double;
+      end;
+
+      TInfobox = class external name 'Infobox'
+      public
+        constructor new(location: TLocation; options: TInfoboxOptions);
+
+        function getAnchor: TPoint;
+        function getDescription: String;
+        function getHeight: Double;
+        function getHtmlContent: String;
+        function getLocation: TLocation;
+        function getMaxHeight: Double;
+        function getMaxWidth: Double;
+        function getOffset: TPoint;
+        function getOptions: TInfoboxOptions;
+        function getShowCloseButton: Boolean;
+        function getShowPointer: Boolean;
+        function getTitle: String;
+        function getVisible: Boolean;
+        function getWidth: Double;
+        function getZIndex: Double;
+
+        procedure setHtmlContent(content: String);
+        procedure setLocation(loc: TLocation);
+        procedure setMap(Map: TMap);
+        procedure setOptions(options: TInfoboxOptions; ignoreDelay: Boolean);
+      end;
+
+      TLayerCollection = class external name 'LayerCollection'
+      public
+        length: Double;
+
+        function indexOf(layer: TLayer): Double;
+
+        procedure clear;
+        procedure insert(layer: TLayer);
+        procedure insertAll(layers: TArray<TLayer>);
+        procedure remove(layer: TLayer);
+        procedure removeAt(idx: Double);
+      end;
+
+      TLocation = class external name 'Location'
+      public
+        latitude: Double;
+        longitude: Double;
+
+        constructor new(latitude, longitude: Double);
+
+        class function areEqual(location1: TLocation; location2: TLocation): Boolean;
+        class function cloneFrom(source: TLocation): TLocation;
+        class function normalizeLongitude(longitude: Double): Double;
+        class function parseLatLong(str: String): TLocation;
+
+        function clone: TLocation;
+        function toString: String;
+      end;
+
+      TLocationRect = class external name 'LocationRect'
+      public
+        center: TLocation;
+        height: Double;
+        width: Double;
+
+        constructor new(center: TLocation; width: Double; height: Double);
+
+        class function fromCorners(northwest: TLocation; southeast: TLocation): TLocationRect;
+        class function fromEdges(north: Double; west: Double; south: Double; east: Double): TLocationRect;
+        class function fromLocations(locations: TArray<TLocation>): TLocationRect;
+        class function fromShapes(shapes: TArray<TArray<TPrimitive>>): TLocationRect; overload;
+        class function fromShapes(shapes: TArray<TPrimitive>): TLocationRect; overload;
+        class function fromString(str: String): TLocationRect;
+        class function merge(rect1: TLocationRect; rect2: TLocationRect): TLocationRect;
+
+        function clone: TLocationRect;
+        function contains(location: TLocation): Boolean;
+        function crossesInternationalDateLine: Boolean;
+        function getEast: Double;
+        function getNorth: Double;
+        function getNorthwest: TLocation;
+        function getSouth: Double;
+        function getSoutheast: TLocation;
+        function getWest: Double;
+        function intersects(rect: TLocationRect): Boolean;
+        function splitByInternationalDateLine: TArray<TLocationRect>;
+        function toString: String;
+
+        procedure buffer(percentage: Double);
+      end;
+
+      TMap = class external name 'Map'
+      public
+        layers: TLayerCollection;
+
+        constructor new(parentElement: String); overload;
+        constructor new(parentElement: String; options: TMapOptions); overload;
+        constructor new(parentElement: String; options: TViewOptions); overload;
+        constructor new(parentElement: TJSHTMLElement); overload;
+        constructor new(parentElement: TJSHTMLElement; options: TMapOptions); overload;
+        constructor new(parentElement: TJSHTMLElement; options: TViewOptions); overload;
+
+        class function getVersion: String;
+
+        function getBounds: TLocationRect;
+        function getCenter: TLocation;
+        function getCulture: String;
+        function getHeading: Double;
+        function getHeight: Double;
+        function getImageryId: String;
+        function getMapTypeId: TMapTypeId;
+        function getMetersPerPixel: Double;
+        function getOptions: TMapOptions;
+        function getPageX: Double;
+        function getPageY: Double;
+        function getPitch: Double;
+        function getRootElement: TJSHTMLElement;
+        function getUserRegion: String;
+        function getWidth: Double;
+        function getZoom: Double;
+        function getZoomRange: TRange;
+        function isMercator: Boolean;
+        function isRotationEnabled: Boolean;
+        function tryLocationToPixel(location: TArray<TLocation>; reference: JSValue): TArray<TPoint>;
+        function tryPixelToLocation(point: TArray<TPoint>; reference: JSValue): TArray<TLocation>;
+
+        class procedure getClosestPanorama(bounds: TLocationRect; success: TProc<TPanoramaInfo>; missingCoverage: TProc);
+
+        procedure dispose;
+        procedure getCopyrights(callback: TProc<TArray<String>>);
+        procedure getCredentials(callback: TProc<String>);
+        procedure setMapType(mapTypeId: TMapTypeId);
+        procedure setOptions(options: TMapOptions);
+        procedure setView(viewOptions: TViewOptions);
+      end;
+
+      TPoint = class external name 'Point'
+      public
+        x: Double;
+        y: Double;
+
+        constructor new(x: Double; y: Double);
+
+        function add(point: TPoint): TPoint;
+        function clone: TPoint;
+        function equals(point: TPoint; tolerance: Double): Boolean;
+        function subtract(point: TPoint): TPoint;
+        function toString: String;
+      end;
+
+      TPointCompression = class external name 'ointCompression'
+      public
+        class function decode(value: String): TArray<TLocation>;
+        class function encode(locations: TArray<TLocation>): String;
+      end;
+
+      TPolygon = class external name 'Polygon' (TPrimitive)
+      public
+        metadata: JSValue;
+
+        constructor new(rings: TArray<TArray<TLocation>>; options: TPolygonOptions); overload;
+        constructor new(rings: TArray<TLocation>; options: TPolygonOptions); overload;
+
+        function getCursor: String;
+        function getFillColor: TColor;
+        function getGeneralizable: Boolean;
+        function getLocations: TArray<TLocation>;
+        function getRings: TArray<TArray<TLocation>>;
+        function getStrokeColor: TColor;
+        function getStrokeDashArray: TArray<Double>;
+        function getStrokeDashArrayString: String; external name 'getStrokeDashArray';
+        function getStrokeThickness: Double;
+        function getVisible: Boolean;
+
+        procedure setLocations(locations: TArray<TLocation>);
+        procedure setOptions(options: TPolygonOptions);
+        procedure setRings(rings: TArray<TArray<TLocation>>); overload;
+        procedure setRings(rings: TArray<TLocation>); overload;
+      end;
+
+      TPolyline = class external name 'Polyline' (TPrimitive)
+      public
+        metadata: JSValue;
+
+        constructor new(locations: TArray<TLocation>; options: TPolylineOptions);
+
+        function getCursor: String;
+        function getGeneralizable: Boolean;
+        function getLocations: TArray<TLocation>;
+        function getStrokeColor: TColor;
+        function getStrokeDashArray: TArray<Double>;
+        function getStrokeDashArrayString: String; external name 'getStrokeDashArray';
+        function getStrokeThickness: Double;
+        function getVisible: Boolean;
+
+        procedure setLocations(locations: TArray<TLocation>);
+        procedure setOptions(options: TPolylineOptions);
+      end;
+
+      TPushpin = class external name 'Pushpin' (TPrimitive)
+      public
+        metadata: JSValue;
+
+        constructor new(location: TLocation; options: TPushpinOptions);
+
+        function getAnchor: TPoint;
+        function getClickedStyleEnabled: Boolean;
+        function getColor: TColor;
+        function getCursor: String;
+        function getDraggable: Boolean;
+        function getHoverStyleEnabled: Boolean;
+        function getIcon: String;
+        function getLocation: TLocation;
+        function getRoundClickableArea: Boolean;
+        function getSubTitle: String;
+        function getText: String;
+        function getTextOffset: TPoint;
+        function getTitle: String;
+        function getVisible: Boolean;
+
+        procedure setLocation(location: TLocation);
+        procedure setOptions(options: TPushpinOptions);
+      end;
+
+      TPyramidTileId = class external name 'PyramidTileId'
+      public
+        pixelHeight: Double;
+        pixelWidth: Double;
+        quadKey: String;
+        x: Double;
+        y: Double;
+        zoom: Double;
+
+        constructor new(x: Double; y: Double; zoom: Double; width: Double; height: Double);
+
+        class function areEqual(tileId1: TPyramidTileId; tileId2: TPyramidTileId): Boolean;
+        class function fromQuadKey(quadkey: String; width: Double; height: Double): TPyramidTileId;
+      end;
+
+      TTileLayer = class external name 'TileLayer' (TLayer)
+      public
+        metadata: JSValue;
+
+        constructor new(options: TTileLayerOptions);
+
+        function getOpacity: Double;
+        function getTileSource: TTileSource;
+        function getVisible: Boolean;
+        function getZIndex: Double;
+
+        procedure setOpacity(opacity: Double);
+        procedure setOptions(options: TTileLayerOptions);
+        procedure setVisible(show: Boolean);
+        procedure setZIndex(idx: Double);
+      end;
+
+      TTileSource = class external name 'TileSource'
+      public
+        constructor new(options: TTileSourceOptions);
+
+        function getBounds: TLocationRect;
+        function getHeight: Double;
+        function getMaxZoom: Double;
+        function getMinZoom: Double;
+        function getUriConstructor(tile: TPyramidTileId): String; overload;
+        function getUriConstructor: String; overload;
+        function getWidth: Double;
+      end;
+    public
+      class var Credentials: String;
+
+      procedure getIsBirdseyeAvailable(loc: TLocation; heading: Double; callback: TProc<Boolean>); overload;
+      procedure getIsBirdseyeAvailable(loc: TLocation; heading: THeading; callback: TProc<Boolean>); overload;
+      procedure loadModule(moduleName: TArray<String>; options: TModuleOptions); overload;
+      procedure loadModule(moduleName: TArray<String>; options: TProc); overload;
+      procedure moduleLoaded(moduleName: String);
+      procedure registerModule(moduleName: String; url: String; styles: TStyleUrl);
+    end;
+  end;
+
+  TAddress = class
+  public
+    addressLine: String;
+    adminDistrict: String;
+    countryRegion: String;
+    countryRegionISO2: String;
+    district: String;
+    formattedAddress: String;
+    locality: String;
+    postalCode: String;
+  end;
+
+  TAnimatedFrameEventArgs = class
+  public
+    animatedTileLayer: TMicrosoft.TMaps.TAnimatedTileLayer;
+    index: Double;
+  end;
+
+  TAnimatedTileLayerOptions = class
+  public
+    autoPlay: Boolean;
+    frameRate: Double;
+    loadingScreen: TMicrosoft.TMaps.TCustomOverlay;
+    maxTotalLoadTime: Double;
+    mercator: TArray<TMicrosoft.TMaps.TTileSource>;
+    visible: Boolean;
+  end;
+
+  TCustomOverlayOptions = class
+  public
+    beneathLabels: Boolean;
+  end;
+
+  TGroundOverlayOptions = class(TCustomOverlayOptions)
+  public
+    backgroundColor: TMicrosoft.TMaps.TColor;
+    bounds: TMicrosoft.TMaps.TLocationRect;
+    imageUrl: String;
+    opacity: Double;
+    rotation: Double;
+    visible: Boolean;
+  end;
+
+  THandlerId = class
+  end;
+
+  TInfoboxOptions  = class
+  public
+    description: String;
+    closeDelayTime: Double;
+    htmlContent: String;
+    location: TMicrosoft.TMaps.TLocation;
+    maxHeight: Double;
+    maxWidth: Double;
+    offset: TMicrosoft.TMaps.TPoint;
+    showCloseButton: Boolean;
+    showPointer: Boolean;
+    title: String;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TInfoboxEventArgs = class
+  public
+    eventName: String;
+    pageX: Double;
+    pageY: Double;
+    target: TMicrosoft.TMaps.TInfobox;
+    targetType: String;
+    originalEvent: TJSMouseEvent;
+  end;
+
+  TMapOptions = class
+  public
+    allowHidingLabelsOfRoad: Boolean;
+    allowInfoboxOverflow: Boolean;
+    backgroundColor: TMicrosoft.TMaps.TColor;
+    customMapStyle: TCustomMapStyle;
+    disableBirdseye: Boolean;
+    disableKeyboardInput: Boolean;
+    disableMapTypeSelectorMouseOver: Boolean;
+    disablePanning: Boolean;
+    disableScrollWheelZoom: Boolean;
+    disableStreetside: Boolean;
+    disableStreetsideAutoCoverage: Boolean;
+    disableZooming: Boolean;
+    enableClickableLogo: Boolean;
+    enableCORS: Boolean;
+    enableHighDpi: Boolean;
+    enableInertia: Boolean;
+    liteMode: Boolean;
+    maxBounds: TMicrosoft.TMaps.TLocationRect;
+    maxZoom: Double;
+    minZoom: Double;
+    navigationBarMode: TMicrosoft.TMaps.TNavigationBarMode;
+    navigationBarOrientation: TMicrosoft.TMaps.TNavigationBarOrientation;
+    showBreadcrumb: Boolean;
+    showDashboard: Boolean;
+    showLocateMeButton: Boolean;
+    showLogo: Boolean;
+    showMapTypeSelector: Boolean;
+    showScalebar: Boolean;
+    showTrafficButton: Boolean;
+    showTermsLink: Boolean;
+    showZoomButtons: Boolean;
+    streetsideOptions: TStreetsideOptions;
+    supportedMapTypes: TArray<TMicrosoft.TMaps.TMapTypeId>;
+  end;
+
+  TMapTypeChangeEventArgs = class
+  public
+    newMapTypeId: TMicrosoft.TMaps.TMapTypeId;
+    oldMapTypeId: TMicrosoft.TMaps.TMapTypeId;
+    target: TMicrosoft.TMaps.TMap;
+    targetType: String;
+  end;
+
+  TModuleOptions = class
+  public
+    errorCallback: TProc;
+    credentials: String;
+  end;
+
+  TMouseEventArgs = class
+  public
+    eventName: String;
+    isPrimary: Boolean;
+    isSecondary: Boolean;
+    layer: TMicrosoft.TMaps.TLayer;
+    location: TMicrosoft.TMaps.TLocation;
+    pageX: Double;
+    pageY: Double;
+    point: TMicrosoft.TMaps.TPoint;
+    target: TMicrosoft.TMaps.TMap;
+    targetPrimitive: TMicrosoft.TMaps.TPrimitive; external name 'target';
+    targetType: String;
+    wheelDelta: Double;
+  end;
+
+  TPanoramaInfo = class
+  public
+    cd: String;
+  end;
+
+  TPrimitiveChangedEventArgs = class
+  public
+    sender: TMicrosoft.TMaps.TPrimitive;
+    name: String;
+  end;
+
+  TPrimitiveOptions = class
+  public
+    cursor: String;
+    visible: Boolean;
+  end;
+
+  TPolylineOptions = class(TPrimitiveOptions)
+  public
+    generalizable: Boolean;
+    strokeColor: TMicrosoft.TMaps.TColor;
+    strokeDashArray: TArray<Double>;
+    strokeDashArrayString: String; external name 'strokeDashArray';
+    strokeThickness: Double;
+  end;
+
+  TPolygonOptions = class(TPolylineOptions)
+  public
+    fillColor: TMicrosoft.TMaps.TColor;
+  end;
+
+  TPushpinOptions = class(TPrimitiveOptions)
+  public
+    anchor: TMicrosoft.TMaps.TPoint;
+    color: TMicrosoft.TMaps.TColor;
+    draggable: Boolean;
+    enableClickedStyle: Boolean;
+    enableHoverStyle: Boolean;
+    icon: String;
+    roundClickableArea: Boolean;
+    subTitle: String;
+    title: String;
+    text: String;
+    textOffset: TMicrosoft.TMaps.TPoint;
+  end;
+
+  TRange = class
+  public
+    min: Double;
+    max: Double;
+  end;
+
+  TStreetsideOptions  = class
+  public
+    disablePanoramaNavigation: Boolean;
+    locationToLookAt: TMicrosoft.TMaps.TLocation;
+    onErrorLoading: TProc;
+    onSuccessLoading: TProc;
+    overviewMapMode: TMicrosoft.TMaps.TOverviewMapMode;
+    panoramaInfo: TPanoramaInfo;
+    panoramaLookupRadius: Double;
+    showCurrentAddress: Boolean;
+    showExitButton: Boolean;
+    showHeadingCompass: Boolean;
+    showProblemReporting: Boolean;
+    showZoomButtons: Boolean;
+  end;
+
+  TStylesOptions = class
+  public
+    pushpinOptions: TPushpinOptions;
+    polylineOptions: TPolylineOptions;
+    polygonOptions: TPolygonOptions;
+  end;
+
+  TStyleUrl = class
+  public
+    styleURLs: TArray<String>;
+  end;
+
+  TTileLayerOptions = class
+  public
+    enableCORS: Boolean;
+    downloadTimeout: Double;
+    mercator: TMicrosoft.TMaps.TTileSource;
+    opacity: Double;
+    useCredentialsForCORS: Boolean;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TTileSourceOptions = class
+  public
+    bounds: TMicrosoft.TMaps.TLocationRect;
+    maxZoom: Double;
+    minZoom: Double;
+    uriConstructor: String;
+    uriConstructorFunction: TFunc<TMicrosoft.TMaps.TPyramidTileId, String>; external name 'uriConstructor';
+  end;
+
+  TViewOptions = class
+  public
+    bounds: TMicrosoft.TMaps.TLocationRect;
+    center: TMicrosoft.TMaps.TLocation;
+    centerOffset: TMicrosoft.TMaps.TPoint;
+    heading: Double;
+    labelOverlay: TMicrosoft.TMaps.TLabelOverlay;
+    mapTypeId: TMicrosoft.TMaps.TMapTypeId;
+    padding: Double;
+    pitch: Double;
+    zoom: Double;
+  end;
+
+  TMapElementStyle = class
+  public
+    fillColor: String;
+    labelColor: String;
+    labelOutlineColor: String;
+    labelVisible: boolean;
+    strokeColor: String;
+    visible: Boolean;
+  end;
+
+  TBorderedMapElementStyle = class(TMapElementStyle)
+  public
+    borderOutlineColor: String;
+    borderStrokeColor: String;
+    borderVisible: Boolean;
+  end;
+
+  TSettingsStyle = class
+  public
+    landColor: String;
+    shadedReliefVisible: Boolean;
+  end;
+
+  TMapElements = class
+  public
+    adminDistrict: TBorderedMapElementStyle;
+    adminDistrictCapital: TMapElementStyle;
+    airport: TMapElementStyle;
+    area: TMapElementStyle;
+    arterialRoad: TMapElementStyle;
+    building: TMapElementStyle;
+    business: TMapElementStyle;
+    capital: TMapElementStyle;
+    cemetery: TMapElementStyle;
+    continent: TMapElementStyle;
+    controlledAccessHighway: TMapElementStyle;
+    countryRegion: TBorderedMapElementStyle;
+    countryRegionCapital: TMapElementStyle;
+    district: TBorderedMapElementStyle;
+    education: TMapElementStyle;
+    educationBuilding: TMapElementStyle;
+    foodPoint: TMapElementStyle;
+    forest: TMapElementStyle;
+    golfCourse: TMapElementStyle;
+    highSpeedRamp: TMapElementStyle;
+    highway: TMapElementStyle;
+    indigenousPeoplesReserve: TMapElementStyle;
+    island: TMapElementStyle;
+    majorRoad: TMapElementStyle;
+    mapElement: TMapElementStyle;
+    medical: TMapElementStyle;
+    medicalBuilding: TMapElementStyle;
+    military: TMapElementStyle;
+    naturalPoint: TMapElementStyle;
+    nautical: TMapElementStyle;
+    neighborhood: TMapElementStyle;
+    park: TMapElementStyle;
+    peak: TMapElementStyle;
+    playingField: TMapElementStyle;
+    point: TMapElementStyle;
+    pointOfInterest: TMapElementStyle;
+    political: TBorderedMapElementStyle;
+    populatedPlace: TMapElementStyle;
+    railway: TMapElementStyle;
+    ramp: TMapElementStyle;
+    reserve: TMapElementStyle;
+    river: TMapElementStyle;
+    road: TMapElementStyle;
+    roadExit: TMapElementStyle;
+    runway: TMapElementStyle;
+    sand: TMapElementStyle;
+    shoppingCenter: TMapElementStyle;
+    stadium: TMapElementStyle;
+    street: TMapElementStyle;
+    structure: TMapElementStyle;
+    tollRoad: TMapElementStyle;
+    trail: TMapElementStyle;
+    transit: TMapElementStyle;
+    transitBuilding: TMapElementStyle;
+    transportation: TMapElementStyle;
+    unpavedStreet: TMapElementStyle;
+    vegetation: TMapElementStyle;
+    volcanicPeak: TMapElementStyle;
+    water: TMapElementStyle;
+    waterPoint: TMapElementStyle;
+    waterRoute: TMapElementStyle;
+  end;
+
+  TCustomMapStyle = class
+  public
+    elements: TMapElements;
+    settings: TSettingsStyle;
+    version: String;
+  end;
+
+function InitializeMap(Key: String): TJSPromise;
+
+implementation
+
+function InitializeMap(Key: String): TJSPromise;
+begin
+  Result := TJSPromise.New(
+    procedure(Resolve, Reject: TJSPromiseResolver)
+    var
+      Script: TJSHTMLScriptElement;
+
+    begin
+      Script := TJSHTMLScriptElement(document.createElement('script'));
+      Script.async := False;
+      Script.src := Format('https://www.bing.com/maps/sdk/mapcontrol?key=%s', [Key]);
+      Script.onload :=
+        function(Event: TEventListenerEvent): Boolean
+        var
+          Options: TJSIdleCallbackOptions;
+
+        begin
+          Options := TJSIdleCallbackOptions.Create;
+          Options.timeOut := 100;
+
+          Window.requestIdleCallback(
+            procedure (idleDeadline: TJSIdleDeadline)
+            begin
+              Resolve(True);
+            end, Options);
+
+          Result := True;
+        end;
+
+      document.head.appendChild(Script);
+    end);
+end;
+
+end.
+
diff --git a/packages/maps/GeoJSON.pas b/packages/maps/GeoJSON.pas
new file mode 100644
index 00000000..ca5ad2cc
--- /dev/null
+++ b/packages/maps/GeoJSON.pas
@@ -0,0 +1,166 @@
+unit GeoJSON;
+
+interface
+
+{$modeswitch externalclass}
+
+uses JS;
+
+type
+  TBBox = TArray<Double>;
+  TPosition = TArray<Double>;
+
+  TGeoJsonObject = class
+  private
+    function GetForeignMember(name: String): JSValue; external name '[]';
+
+    procedure SetForeignMember(name: String; value: JSValue); external name '[]';
+  public
+    &type: String;
+    bbox: TBBox;
+
+    constructor Create(&type: String);
+
+    property ForeignMember[name: String]: JSValue read GetForeignMember write SetForeignMember; default;
+  end;
+
+  TGeometryObject = class(TGeoJsonObject)
+
+  end;
+
+  TPoint = class (TGeometryObject)
+  public
+    coordinates: TPosition;
+
+    constructor Create;
+  end;
+
+  TMultiPoint = class (TGeometryObject)
+  public
+    coordinates: TArray<TPosition>;
+    constructor Create;
+  end;
+
+  TLineString = class (TGeometryObject)
+  public
+    coordinates: TArray<TPosition>;
+
+    constructor Create;
+  end;
+
+  TMultiLineString = class (TGeometryObject)
+  public
+    coordinates: TArray<TArray<TPosition>>;
+
+    constructor Create;
+  end;
+
+  TPolygon = class(TGeometryObject)
+  public
+    coordinates: TArray<TArray<TPosition>>;
+
+    constructor Create;
+  end;
+
+  TMultiPolygon = class(TGeometryObject)
+  public
+    coordinates: TArray<TArray<TArray<TPosition>>>;
+
+    constructor Create;
+  end;
+
+  TGeometryCollection = class(TGeoJsonObject)
+  public
+    geometries: TArray<TGeometryObject>;
+
+    constructor Create;
+  end;
+
+  TFeature = class (TGeoJsonObject)
+    geometry: TGeometryObject;
+    id: String;
+    properties: TJSObject;
+
+    constructor Create;
+  end;
+
+  TFeatureCollection = class (TGeoJsonObject)
+  public
+    features: TArray<TGeoJsonObject>;
+
+    constructor Create;
+  end;
+
+implementation
+
+{ TGeoJsonObject }
+
+constructor TGeoJsonObject.Create(&type: String);
+begin
+  Self.&type := &type;
+end;
+
+{ TPoint }
+
+constructor TPoint.Create;
+begin
+  inherited Create('Point');
+end;
+
+{ TMultiPoint }
+
+constructor TMultiPoint.Create;
+begin
+  inherited Create('MultiPoint');
+end;
+
+{ TLineString }
+
+constructor TLineString.Create;
+begin
+  inherited Create('LineString');
+end;
+
+{ TMultiLineString }
+
+constructor TMultiLineString.Create;
+begin
+  inherited Create('MultiLineString');
+end;
+
+{ TPolygon }
+
+constructor TPolygon.Create;
+begin
+  inherited Create('Polygon');
+end;
+
+{ TMultiPolygon }
+
+constructor TMultiPolygon.Create;
+begin
+  inherited Create('MultiPolygon');
+end;
+
+{ TGeometryCollection }
+
+constructor TGeometryCollection.Create;
+begin
+  inherited Create('GeometryCollection');
+end;
+
+{ TFeature }
+
+constructor TFeature.Create;
+begin
+  inherited Create('Feature');
+end;
+
+{ TFeatureCollection }
+
+constructor TFeatureCollection.Create;
+begin
+  inherited Create('FeatureCollection');
+end;
+
+end.
diff --git a/packages/maps/Google.Maps.pas b/packages/maps/Google.Maps.pas
new file mode 100644
index 00000000..050675e2
--- /dev/null
+++ b/packages/maps/Google.Maps.pas
@@ -0,0 +1,2156 @@
+unit Google.Maps;
+
+interface
+
+{$modeswitch externalclass}
+
+uses JS, SysUtils, GeoJSON, Web;
+
+type
+  TAddFeatureEvent = class;
+  TAutocompleteOptions = class;
+  TAutocompletePrediction = class;
+  TAutocompleteResponse = class;
+  TAutocompleteSessionToken = class;
+  TAutocompletionRequest = class;
+  TCircleLiteral = class;
+  TCircleOptions = class;
+  TComponentRestrictions = class;
+  TDataOptions = class;
+  TDirectionsGeocodedWaypoint = class;
+  TDirectionsLeg = class;
+  TDirectionsRendererOptions = class;
+  TDirectionsRequest = class;
+  TDirectionsResult = class;
+  TDirectionsRoute = class;
+  TDirectionsStep = class;
+  TDirectionsWaypoint = class;
+  TDistance = class;
+  TDistanceMatrixRequest = class;
+  TDistanceMatrixResponse = class;
+  TDistanceMatrixResponseElement = class;
+  TDistanceMatrixResponseRow = class;
+  TDrawingControlOptions = class;
+  TDrawingManagerOptions = class;
+  TDrivingOptions = class;
+  TDuration = class;
+  TElevationResult = class;
+  TFeatureOptions = class;
+  TFindPlaceFromPhoneNumberRequest = class;
+  TFindPlaceFromQueryRequest = class;
+  TFullscreenControlOptions = class;
+  TGeoJsonOptions = class;
+  TGeocoderAddressComponent = class;
+  TGeocoderComponentRestrictions = class;
+  TGeocoderGeometry = class;
+  TGeocoderRequest = class;
+  TGeocoderResponse = class;
+  TGeocoderResult = class;
+  TGroundOverlayOptions = class;
+  THeatmapLayerOptions = class;
+  TIcon = class;
+  TIconMouseEvent = class;
+  TIconSequence = class;
+  TImageMapTypeOptions = class;
+  TInfoWindowOptions = class;
+  TKmlAuthor = class;
+  TKmlFeatureData = class;
+  TKmlLayerMetadata = class;
+  TKmlLayerOptions = class;
+  TKmlMouseEvent = class;
+  TLatLngBoundsLiteral = class;
+  TLatLngLiteral = class;
+  TLocationElevationRequest = class;
+  TLocationElevationResponse = class;
+  TMapCanvasProjection = class;
+  TMapMouseEvent = class;
+  TMapOptions = class;
+  TMapPanes = class;
+  TMapRestriction = class;
+  TMapType = class;
+  TMapTypeControlOptions = class;
+  TMapTypeStyle = class;
+  TMapsEventListener = class;
+  TMarkerLabel = class;
+  TMarkerOptions = class;
+  TMarkerShape = class;
+  TMaxZoomResult = class;
+  TMotionTrackingControlOptions = class;
+  TMouseEvent = class;
+  TOverlayCompleteEvent = class;
+  TPadding = class;
+  TPanControlOptions = class;
+  TPanoProviderOptions = class;
+  TPathElevationRequest = class;
+  TPathElevationResponse = class;
+  TPinOptions = class;
+  TPlace = class;
+  TPolyMouseEvent = class;
+  TPolygonOptions = class;
+  TPolylineOptions = class;
+  TPredictionSubstring = class;
+  TPredictionTerm = class;
+  TProjection = class;
+  TQueryAutocompletionRequest = class;
+  TRectangleOptions = class;
+  TRemoveFeatureEvent = class;
+  TRemovePropertyEvent = class;
+  TRotateControlOptions = class;
+  TScaleControlOptions = class;
+  TSearchBoxOptions = class;
+  TSetGeometryEvent = class;
+  TSetPropertyEvent = class;
+  TStreetViewAddressControlOptions = class;
+  TStreetViewControlOptions = class;
+  TStreetViewLink = class;
+  TStreetViewLocation = class;
+  TStreetViewLocationRequest = class;
+  TStreetViewPanoRequest = class;
+  TStreetViewPanoramaData = class;
+  TStreetViewPanoramaOptions = class;
+  TStreetViewPov = class;
+  TStreetViewResponse = class;
+  TStreetViewTileData = class;
+  TStructuredFormatting = class;
+  TStyleOptions = class;
+  TStyledMapTypeOptions = class;
+  TSymbol = class;
+  TTextSearchRequest = class;
+  TTimeGoogle = class;
+  TTrafficLayerOptions = class;
+  TTransitAgency = class;
+  TTransitDetails = class;
+  TTransitFare = class;
+  TTransitLine = class;
+  TTransitOptions = class;
+  TTransitStop = class;
+  TTransitVehicle = class;
+  TWeightedLocation = class;
+  TZoomControlOptions = class;
+
+  TGoogle = class external name 'google'
+  public type
+    TMaps = class external name 'maps'
+    public type
+      TLatLng = class;
+      TLatLngBounds = class;
+      TMap = class;
+      TMapTypeRegistry = class;
+      TOverlayType = class;
+      TPlacesServiceStatus = class;
+      TPoint = class;
+      TSize = class;
+      TStreetViewPanorama = class;
+
+      TAnimation = (BOUNCE, DROP);
+      TControlPosition = (BOTTOM_CENTER, BOTTOM_LEFT, BOTTOM_RIGHT, LEFT_BOTTOM, LEFT_CENTER, LEFT_TOP, RIGHT_BOTTOM, RIGHT_CENTER, RIGHT_TOP, TOP_CENTER, TOP_LEFT, TOP_RIGHT);
+      TMapTypeControlStyle = (DEFAULT, DROPDOWN_MENU, HORIZONTAL_BAR);
+      TStrokePosition = (CENTER, INSIDE, OUTSIDE);
+      TSymbolPath = (BACKWARD_CLOSED_ARROW, BACKWARD_OPEN_ARROW, CIRCLE, FORWARD_CLOSED_ARROW, FORWARD_OPEN_ARROW);
+      TUnitSystem = (IMPERIAL, METRIC);
+      TRankBy = (DISTANCE, PROMINENCE);
+
+      TMVCObject = class external name 'MVCObject'
+      public
+        function addListener(eventName: String; handler: TProc): TMapsEventListener;
+        procedure bindTo(key: String; target: TMVCObject; targetKey: String; noNotify: Boolean);
+        function get(key: String): JSValue;
+        procedure notify(key: String);
+        procedure &set(key: String; value: JSValue);
+        procedure setValues(values: TJSObject);
+        procedure unbind(key: String);
+        procedure unbindAll;
+      end;
+
+      TBicyclingLayer = class external name 'BicyclingLayer' (TMVCObject)
+      public
+        function getMap: TMap;
+        procedure setMap(map: TMap);
+      end;
+
+      TCircle = class external name 'Circle' (TMVCObject)
+      public
+        constructor new(opts: TCircleOptions);
+        function getBounds: TLatLngBounds;
+        function getCenter: TLatLng;
+        function getDraggable: Boolean;
+        function getEditable: Boolean;
+        function getMap: TMap;
+        function getRadius: Double;
+        function getVisible: Boolean;
+        procedure setCenter(center: TLatLng); overload;
+        procedure setCenter(center: TLatLngLiteral); overload;
+        procedure setDraggable(draggable: Boolean);
+        procedure setEditable(editable: Boolean);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TCircleOptions);
+        procedure setRadius(radius: Double);
+        procedure setVisible(visible: Boolean);
+      end;
+
+      TData = class external name 'Data' (TMVCObject)
+      public type
+        TGeometry = class;
+        TPolygon = class;
+
+        TFeature = class external name 'Feature'
+        public
+          constructor new(options: TFeatureOptions);
+
+          procedure forEachProperty(callback: TProc<JSValue, String>);
+          function getGeometry: TGeometry;
+          function getId: Double;
+          function getIdString: String; external name 'getId';
+          function getProperty(name: String): JSValue;
+          procedure removeProperty(name: String);
+          procedure setGeometry(newGeometry: TGeometry); overload;
+          procedure setGeometry(newGeometry: TLatLng); overload;
+          procedure setGeometry(newGeometry: TLatLngLiteral); overload;
+          procedure setProperty(name: String; newValue: JSValue);
+          procedure toGeoJson(callback: TProc<TJSObject>);
+        end;
+
+        TGeometry = class external name 'Geometry'
+        public
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getType: String;
+        end;
+
+        TGeometryCollection = class external name 'GeometryCollection' (TGeometry)
+        public
+          constructor new(elements: TArray<TGeometry>); overload;
+          constructor new(elements: TArray<TLatLng>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TGeometry>;
+          function getAt(n: Double): TGeometry;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TLineString = class external name 'LineString' (TGeometry)
+        public
+          constructor new(elements: TArray<TLatLng>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TLatLng>;
+          function getAt(n: Double): TLatLng;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TLinearRing = class external name 'LinearRing' (TGeometry)
+        public
+          constructor new(elements: TArray<TLatLng>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TLatLng>;
+          function getAt(n: Double): TLatLng;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TMultiLineString = class external name 'MultiLineString' (TGeometry)
+        public
+          constructor new(elements: TArray<TLatLng>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TLineString>;
+          function getAt(n: Double): TLineString;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TMultiPoint = class external name 'MultiPoint' (TGeometry)
+        public
+          constructor new(elements: TArray<TLatLng>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TLatLng>;
+          function getAt(n: Double): TLatLng;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TMultiPolygon = class external name 'MultiPolygon' (TGeometry)
+        public
+          constructor new(elements: TArray<TLatLng>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+          constructor new(elements: TArray<TLinearRing>); overload;
+          constructor new(elements: TArray<TPolygon>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+
+          function getArray: TArray<TPolygon>;
+          function getAt(n: Double): TPolygon;
+          function getLength: Double;
+          function getType: String;
+        end;
+
+        TPoint = class external name 'Point' (TGeometry)
+        public
+          constructor new(elements: TArray<TLatLng>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function get: TLatLng;
+          function getType: String;
+        end;
+
+        TPolygon = class external name 'Polygon' (TGeometry)
+        public
+          constructor new(elements: TArray<TArray<TLatLng>>); overload;
+          constructor new(elements: TArray<TLatLngLiteral>); overload;
+
+          procedure forEachLatLng(callback: TProc<TLatLng>);
+          function getArray: TArray<TLinearRing>;
+          function getAt(n: Double): TLinearRing;
+          function getLength: Double;
+          function getType: String;
+        end;
+      public
+        constructor new(options: TDataOptions);
+        function add(feature: TFeature): TFeature; overload;
+        function add(feature: TFeatureOptions): TFeature; overload;
+        function addGeoJson(geoJson: TGeoJSONObject; options: TGeoJsonOptions): TArray<TFeature>;
+        function contains(feature: TFeature): Boolean;
+        procedure forEach(callback: TProc<TFeature>);
+        function getControlPosition: TControlPosition;
+        function getControls: TArray<String>;
+        function getDrawingMode: String;
+        function getFeatureById(id: Double): TFeature; overload;
+        function getFeatureById(id: String): TFeature; overload;
+        function getMap: TMap;
+        function getStyle: TStyleOptions;
+        function getStyleFunction: TFunc<TFeature, TStyleOptions>; external name 'getStyle';
+        procedure loadGeoJson(url: String; options: TGeoJsonOptions; callback: TProc<TArray<TFeature>>);
+        procedure overrideStyle(feature: TFeature; style: TStyleOptions);
+        procedure remove(feature: TFeature);
+        procedure revertStyle(feature: TFeature);
+        procedure setControlPosition(controlPosition: TControlPosition);
+        procedure setControls(controls: TArray<String>);
+        procedure setDrawingMode(drawingMode: String);
+        procedure setMap(map: TMap);
+        procedure setStyle(style: TStyleOptions); overload;
+        procedure setStyle(style: TFunc<TFeature, TStyleOptions>); overload;
+        procedure toGeoJson(callback: TProc<TGeoJSONObject>);
+      end;
+
+      TDirectionsRenderer = class external name 'DirectionsRenderer' (TMVCObject)
+      public
+        constructor new(opts: TDirectionsRendererOptions);
+        function getDirections: TDirectionsResult;
+        function getMap: TMap;
+        function getPanel: TJSNode;
+        function getRouteIndex: Double;
+        procedure setDirections(directions: TDirectionsResult);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TDirectionsRendererOptions);
+        procedure setPanel(panel: TJSNode);
+        procedure setRouteIndex(routeIndex: Double);
+      end;
+
+      TDirectionsStatus = class
+      public const
+        INVALID_REQUEST = 'INVALID_REQUEST';
+        MAX_WAYPOINTS_EXCEEDED = 'MAX_WAYPOINTS_EXCEEDED';
+        NOT_FOUND = 'NOT_FOUND';
+        OK = 'OK';
+        OVER_QUERY_LIMIT = 'OVER_QUERY_LIMIT';
+        REQUEST_DENIED = 'REQUEST_DENIED';
+        UNKNOWN_ERROR = 'UNKNOWN_ERROR';
+        ZERO_RESULTS = 'ZERO_RESULTS';
+      end;
+
+      TDirectionsService = class external name 'DirectionsService'
+      public
+        function route(request: TDirectionsRequest; callback: TProc<TDirectionsResult, TDirectionsStatus>): TJSPromise;
+      end;
+
+      TDistanceMatrixService = class external name 'DistanceMatrixService'
+      public type
+        TDistanceMatrixStatus = (INVALID_REQUEST, MAX_DIMENSIONS_EXCEEDED, MAX_ELEMENTS_EXCEEDED, OK, OVER_QUERY_LIMIT, REQUEST_DENIED, UNKNOWN_ERROR);
+      public
+        function getDistanceMatrix(request: TDistanceMatrixRequest; callback: TProc<TDistanceMatrixResponse, TDistanceMatrixStatus>): TJSPromise;
+      end;
+
+      TElevationStatus = class
+      public const
+        INVALID_REQUEST = 'INVALID_REQUEST';
+        OK = 'OK';
+        OVER_QUERY_LIMIT = 'OVER_QUERY_LIMIT';
+        REQUEST_DENIED = 'REQUEST_DENIED';
+        UNKNOWN_ERROR = 'UNKNOWN_ERROR';
+      end;
+
+      TElevationService = class external name 'ElevationService'
+      public
+        function getElevationAlongPath(request: TPathElevationRequest; callback: TProc<TArray<TElevationResult>, TElevationStatus>): TJSPromise;
+        function getElevationForLocations(request: TLocationElevationRequest; callback: TProc<TArray<TElevationResult>, TElevationStatus>): TJSPromise;
+      end;
+
+      TGeocoderStatus = class
+      public const
+        ERROR = 'ERROR';
+        INVALID_REQUEST = 'INVALID_REQUEST';
+        OK = 'OK';
+        OVER_QUERY_LIMIT = 'OVER_QUERY_LIMIT';
+        REQUEST_DENIED = 'REQUEST_DENIED';
+        UNKNOWN_ERROR = 'UNKNOWN_ERROR';
+        ZERO_RESULTS = 'ZERO_RESULTS';
+      end;
+
+      TGeocoder = class external name 'Geocoder'
+      public
+        function geocode(request: TGeocoderRequest; callback: TProc<TArray<TGeocoderResult>, TGeocoderStatus>): TJSPromise;
+      end;
+
+      TGroundOverlay = class external name 'GroundOverlay' (TMVCObject)
+      public
+        constructor new(url: String; bounds: TLatLngBounds; opts: TGroundOverlayOptions); overload;
+        constructor new(url: String; bounds: TLatLngBoundsLiteral; opts: TGroundOverlayOptions); overload;
+        function getBounds: TLatLngBounds;
+        function getMap: TMap;
+        function getOpacity: Double;
+        function getUrl: String;
+        procedure setMap(map: TMap);
+        procedure setOpacity(opacity: Double);
+      end;
+
+      TImageMapType = class external name 'ImageMapType' (TMVCObject)
+      public
+        alt: String;
+        maxZoom: Double;
+        minZoom: Double;
+        name: String;
+        projection: TProjection;
+        radius: Double;
+        tileSize: TSize;
+
+        constructor new(opts: TImageMapTypeOptions);
+
+        function getOpacity: Double;
+        function getTile(tileCoord: TPoint; zoom: Double; ownerDocument: TJSDocument): TJSNode;
+        procedure releaseTile(tileDiv: TJSNode);
+        procedure setOpacity(opacity: Double);
+      end;
+
+      TInfoWindow = class external name 'InfoWindow' (TMVCObject)
+      public
+        constructor new(opts: TInfoWindowOptions);
+        procedure close;
+        function getContent: TJSNode;
+        function getContentString: String; external name 'getContent';
+        function getPosition: TLatLng;
+        function getZIndex: Double;
+        procedure open(map: TMap; anchor: TMVCObject); overload;
+        procedure open(map: TStreetViewPanorama; anchor: TMVCObject); overload;
+        procedure setContent(content: TJSNode); overload;
+        procedure setContent(content: String); overload;
+        procedure setOptions(options: TInfoWindowOptions);
+        procedure setPosition(position: TLatLng); overload;
+        procedure setPosition(position: TLatLngLiteral); overload;
+        procedure setZIndex(zIndex: Double);
+      end;
+
+      TKmlLayerStatus = class external name 'KmlLayerStatus'
+      public const
+        DOCUMENT_NOT_FOUND = 'DOCUMENT_NOT_FOUND';
+        DOCUMENT_TOO_LARGE = 'DOCUMENT_TOO_LARGE';
+        FETCH_ERROR = 'FETCH_ERROR';
+        INVALID_DOCUMENT = 'INVALID_DOCUMENT';
+        INVALID_REQUEST = 'INVALID_REQUEST';
+        LIMITS_EXCEEDED = 'LIMITS_EXCEEDED';
+        OK = 'OK';
+        TIMED_OUT = 'TIMED_OUT';
+        UNKNOWN = 'UNKNOWN';
+      end;
+
+      TKmlLayer = class external name 'KmlLayer' (TMVCObject)
+      public
+        constructor new(opts: TKmlLayerOptions);
+        function getDefaultViewport: TLatLngBounds;
+        function getMap: TMap;
+        function getMetadata: TKmlLayerMetadata;
+        function getStatus: TKmlLayerStatus;
+        function getUrl: String;
+        function getZIndex: Double;
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TKmlLayerOptions);
+        procedure setUrl(url: String);
+        procedure setZIndex(zIndex: Double);
+      end;
+
+      TLatLng = class external name 'LatLng'
+      public
+        constructor new(lat, lng: Double); overload;
+        constructor new(lat, lng: Double; lngOrNoWrap, noWrap: Boolean); overload;
+        constructor new(latLngLiteral: TLatLngLiteral); overload;
+        constructor new(latLngLiteral: TLatLngLiteral; lngOrNoWrap, noWrap: Boolean); overload;
+        function equals(other: TLatLng): Boolean;
+        function lat: Double;
+        function lng: Double;
+        function toJSON: TLatLngLiteral;
+        function toString: String;
+        function toUrlValue(precision: Double): String;
+      end;
+
+      TLatLngBounds = class external name 'LatLngBounds'
+      public
+        constructor new(sw, ne: TLatLng); overload;
+        constructor new(sw, ne: TLatLngLiteral); overload;
+        function contains(latLng: TLatLng): Boolean; overload;
+        function contains(latLng: TLatLngLiteral): Boolean; overload;
+        function equals(other: TLatLng): Boolean; overload;
+        function equals(other: TLatLngBounds): Boolean; overload;
+        function extend(point: TLatLng): TLatLngBounds; overload;
+        function extend(point: TLatLngLiteral): TLatLngBounds; overload;
+        function getCenter: TLatLng;
+        function getNorthEast: TLatLng;
+        function getSouthWest: TLatLng;
+        function intersects(other: TLatLngBounds): Boolean; overload;
+        function intersects(other: TLatLngBoundsLiteral): Boolean; overload;
+        function isEmpty: Boolean;
+        function toJSON: TLatLngBoundsLiteral;
+        function toSpan: TLatLng;
+        function toString: String;
+        function toUrlValue(precision: Double): String;
+        function union(other: TLatLngBounds): TLatLngBounds; overload;
+        function union(other: TLatLngBoundsLiteral): TLatLngBounds; overload;
+      end;
+
+      TMVCArray<T> = class external name 'MVCArray' (TMVCObject)
+      public
+        constructor new(&array: TArray<T>);
+        procedure clear;
+        procedure forEach(callback: TProc<T, Double>);
+        function getArray: TArray<T>;
+        function getAt(i: Double): T;
+        function getLength: Double;
+        procedure insertAt(i: Double; elem: T);
+        function pop: T;
+        function push(elem: T): Double;
+        function removeAt(i: Double): T;
+        procedure setAt(i: Double; elem: T);
+      end;
+
+      TMapTypeId = class external name 'MapTypeId'
+      public const
+        HYBRID = 'HYBRID';
+        ROADMAP = 'ROADMAP';
+        SATELLITE = 'SATELLITE';
+        TERRAIN = 'TERRAIN';
+      end;
+
+      TMap = class external name 'Map' (TMVCObject)
+      public
+        controls: TArray<TMVCArray<JSValue>>;
+        data: TData;
+        mapTypes: TMapTypeRegistry;
+        overlayMapTypes: TMVCArray<JSValue>;
+
+        constructor new(mapDiv: TJSHTMLElement; opts: TMapOptions);
+
+        function getBounds: TLatLngBounds;
+        function getCenter: TLatLng;
+        function getClickableIcons: Boolean;
+        function getDiv: TJSHTMLElement;
+        function getHeading: Double;
+        function getMapTypeId: String;
+        function getProjection: TProjection;
+        function getStreetView: TStreetViewPanorama;
+        function getTilt: Double;
+        function getZoom: Double;
+
+        procedure fitBounds(bounds: TLatLngBounds; padding: Double); overload;
+        procedure fitBounds(bounds: TLatLngBounds; padding: TPadding); overload;
+        procedure fitBounds(bounds: TLatLngBoundsLiteral; padding: Double); overload;
+        procedure fitBounds(bounds: TLatLngBoundsLiteral; padding: TPadding); overload;
+        procedure panBy(x, y: Double);
+        procedure panTo(latLng: TLatLng); overload;
+        procedure panTo(latLng: TLatLngLiteral); overload;
+        procedure panToBounds(bounds: TLatLngBounds; padding: Double); overload;
+        procedure panToBounds(bounds: TLatLngBounds; padding: TPadding); overload;
+        procedure panToBounds(bounds: TLatLngBoundsLiteral; padding: Double); overload;
+        procedure panToBounds(bounds: TLatLngBoundsLiteral; padding: TPadding); overload;
+        procedure setCenter(latlng: TLatLng); overload;
+        procedure setCenter(latlng: TLatLngLiteral); overload;
+        procedure setClickableIcons(value: Boolean);
+        procedure setHeading(heading: Double);
+        procedure setMapTypeId(mapTypeId: String);
+        procedure setOptions(options: TMapOptions);
+        procedure setStreetView(panorama: TStreetViewPanorama);
+        procedure setTilt(tilt: Double);
+        procedure setZoom(zoom: Double);
+      end;
+
+      TMapTypeRegistry = class external name 'MapTypeRegistry' (TMVCObject)
+      public
+        procedure &set(id: String; mapType: JSValue);
+      end;
+
+      TMarker = class external name 'Marker' (TMVCObject)
+      public
+        constructor new(opts: TMarkerOptions);
+        function getAnimation: TAnimation;
+        function getClickable: Boolean;
+        function getCursor: String;
+        function getDraggable: Boolean;
+        function getIcon: JSValue;
+        function getLabel: TMarkerLabel;
+        function getMap: TMap;
+        function getStreetViewPanorama: TStreetViewPanorama; external name 'getMap';
+        function getOpacity: Double;
+        function getPosition: TLatLng;
+        function getShape: TMarkerShape;
+        function getTitle: String;
+        function getVisible: Boolean;
+        function getZIndex: Double;
+        procedure setAnimation(animation: TAnimation);
+        procedure setClickable(flag: Boolean);
+        procedure setCursor(cursor: String);
+        procedure setDraggable(flag: Boolean);
+        procedure setIcon(icon: String); overload;
+        procedure setIcon(icon: TIcon); overload;
+        procedure setIcon(icon: TSymbol); overload;
+        procedure setLabel(&label: String); overload;
+        procedure setLabel(&label: TMarkerLabel); overload;
+        procedure setMap(map: TMap); overload;
+        procedure setMap(map: TStreetViewPanorama); overload;
+        procedure setOpacity(opacity: Double);
+        procedure setOptions(options: TMarkerOptions);
+        procedure setPosition(latlng: TLatLng); overload;
+        procedure setPosition(latlng: TLatLngLiteral); overload;
+        procedure setShape(shape: TMarkerShape);
+        procedure setTitle(title: String);
+        procedure setVisible(visible: Boolean);
+        procedure setZIndex(zIndex: Double);
+
+        class var MAX_ZINDEX: Double;
+      end;
+
+      TMaxZoomService = class external name 'MaxZoomService'
+      public
+        function getMaxZoomAtLatLng(latlng: TLatLng; callback: TProc<TMaxZoomResult>): TJSPromise; overload;
+        function getMaxZoomAtLatLng(latlng: TLatLngLiteral; callback: TProc<TMaxZoomResult>): TJSPromise; overload;
+      end;
+
+      TOverlayView = class external name 'OverlayView' (TMVCObject)
+      public
+        procedure draw;
+        function getMap: TMap;
+        function getMapStreetViewPanorama: TStreetViewPanorama; external name 'getMap';
+        function getPanes: TMapPanes;
+        function getProjection: TMapCanvasProjection;
+        procedure onAdd;
+        procedure onRemove;
+        procedure setMap(map: TMap); overload;
+        procedure setMap(map: TStreetViewPanorama); overload;
+        class procedure preventMapHitsAndGesturesFrom(this: JSValue; element: TJSHTMLElement);
+        class procedure preventMapHitsFrom(this: JSValue; element: TJSHTMLElement);
+      end;
+
+      TPoint = class external name 'Point'
+      public
+        x: Double;
+        y: Double;
+
+        constructor new(x, y: Double);
+        function equals(other: TPoint): Boolean;
+        function toString: String;
+      end;
+
+      TPolygon = class external name 'Polygon' (TMVCObject)
+      public
+        constructor new(opts: TPolygonOptions);
+        function getDraggable: Boolean;
+        function getEditable: Boolean;
+        function getMap: TMap;
+        function getPath: TMVCArray<JSValue>;
+        function getPaths: TMVCArray<JSValue>;
+        function getVisible: Boolean;
+        procedure setDraggable(draggable: Boolean);
+        procedure setEditable(editable: Boolean);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TPolygonOptions);
+        procedure setPath(path: TMVCArray<JSValue>); overload;
+        procedure setPath(path: TArray<TLatLng>); overload;
+        procedure setPath(path: TArray<TLatLngLiteral>); overload;
+        procedure setPaths(paths: TMVCArray<JSValue>); overload;
+        procedure setPaths(paths: TArray<JSValue>); overload;
+        procedure setVisible(visible: Boolean);
+      end;
+
+      TPolyline = class external name 'Polyline' (TMVCObject)
+      public
+        constructor new(opts: TPolylineOptions);
+        function getDraggable: Boolean;
+        function getEditable: Boolean;
+        function getMap: TMap;
+        function getPath: TMVCArray<JSValue>;
+        function getVisible: Boolean;
+        procedure setDraggable(draggable: Boolean);
+        procedure setEditable(editable: Boolean);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TPolylineOptions);
+        procedure setPath(path: TMVCArray<JSValue>); overload;
+        procedure setPath(path: TArray<TLatLng>); overload;
+        procedure setPath(path: TArray<TLatLngLiteral>); overload;
+        procedure setVisible(visible: Boolean);
+      end;
+
+      TRectangle = class external name 'Rectangle' (TMVCObject)
+      public
+        constructor new(opts: TRectangleOptions);
+        function getBounds: TLatLngBounds;
+        function getDraggable: Boolean;
+        function getEditable: Boolean;
+        function getMap: TMap;
+        function getVisible: Boolean;
+        procedure setBounds(bounds: TLatLngBounds); overload;
+        procedure setBounds(bounds: TLatLngBoundsLiteral); overload;
+        procedure setDraggable(draggable: Boolean);
+        procedure setEditable(editable: Boolean);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TRectangleOptions);
+        procedure setVisible(visible: Boolean);
+      end;
+
+      TSize = class external name 'Size'
+      public
+        height: Double;
+        width: Double;
+
+        constructor new(width, height: Double; widthUnit, heightUnit: String);
+        function equals(other: TSize): Boolean;
+        function toString: String;
+      end;
+
+      TStreetViewCoverageLayer = class external name 'StreetViewCoverageLayer' (TMVCObject)
+      public
+        function getMap: TMap;
+        procedure setMap(map: TMap);
+      end;
+
+      TStreetViewStatus = class external name 'StreetViewStatus'
+      public const
+        OK = 'OK';
+        UNKNOWN_ERROR = 'UNKNOWN_ERROR';
+        ZERO_RESULTS = 'ZERO_RESULTS';
+      end;
+
+      TStreetViewPanorama = class external name 'StreetViewPanorama' (TMVCObject)
+      public
+        controls: TArray<TMVCArray<JSValue>>;
+
+        constructor new(container: TJSHTMLElement; opts: TStreetViewPanoramaOptions);
+        function getLinks: TArray<TStreetViewLink>;
+        function getLocation: TStreetViewLocation;
+        function getMotionTracking: Boolean;
+        function getPano: String;
+        function getPhotographerPov: TStreetViewPov;
+        function getPosition: TLatLng;
+        function getPov: TStreetViewPov;
+        function getStatus: TStreetViewStatus;
+        function getVisible: Boolean;
+        function getZoom: Double;
+        procedure registerPanoProvider(provider: TFunc<String, TStreetViewPanoramaData>; opt_options: TPanoProviderOptions);
+        procedure setLinks(links: TArray<TStreetViewLink>);
+        procedure setMotionTracking(motionTracking: Boolean);
+        procedure setOptions(options: TStreetViewPanoramaOptions);
+        procedure setPano(pano: String);
+        procedure setPosition(latLng: TLatLng); overload;
+        procedure setPosition(latLng: TLatLngLiteral); overload;
+        procedure setPov(pov: TStreetViewPov);
+        procedure setVisible(flag: Boolean);
+        procedure setZoom(zoom: Double);
+      end;
+
+      TStreetViewService = class external name 'StreetViewService'
+      public
+        function getPanorama(request: TStreetViewLocationRequest; callback: TProc<TStreetViewPanoramaData, TStreetViewStatus>): TJSPromise; overload;
+        function getPanorama(request: TStreetViewPanoRequest; callback: TProc<TStreetViewPanoramaData, TStreetViewStatus>): TJSPromise; overload;
+      end;
+
+      TStyledMapType = class external name 'StyledMapType' (TMVCObject)
+      public
+        alt: String;
+        maxZoom: Double;
+        minZoom: Double;
+        name: String;
+        projection: TProjection;
+        radius: Double;
+        tileSize: TSize;
+        constructor new(styles: TArray<TMapTypeStyle>; options: TStyledMapTypeOptions);
+        function getTile(tileCoord: TPoint; zoom: Double; ownerDocument: TJSDocument): TJSNode;
+        procedure releaseTile(tile: TJSNode);
+      end;
+
+      TTrafficLayer = class external name 'TrafficLayer' (TMVCObject)
+      public
+        constructor new(opts: TTrafficLayerOptions);
+        function getMap: TMap;
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TTrafficLayerOptions);
+      end;
+
+      TTransitLayer = class external name 'TransitLayer' (TMVCObject)
+      public
+        function getMap: TMap;
+        procedure setMap(map: TMap);
+      end;
+
+      TDrawingManager = class external name 'DrawingManager' (TMVCObject)
+      public
+        constructor new(options: TDrawingManagerOptions);
+        function getDrawingMode: TOverlayType;
+        function getMap: TMap;
+        procedure setDrawingMode(drawingMode: TOverlayType);
+        procedure setMap(map: TMap);
+        procedure setOptions(options: TDrawingManagerOptions);
+      end;
+
+      TEvent = class external name 'event'
+      public
+        function addDomListener(instance: TJSObject; eventName: String; handler: TProc; capture: Boolean): TMapsEventListener;
+        function addDomListenerOnce(instance: TJSObject; eventName: String; handler: TProc; capture: Boolean): TMapsEventListener;
+        function addListener(instance: TJSObject; eventName: String; handler: TProc): TMapsEventListener;
+        function addListenerOnce(instance: TJSObject; eventName: String; handler: TProc): TMapsEventListener;
+        procedure clearInstanceListeners(instance: TJSObject);
+        procedure clearListeners(instance: TJSObject; eventName: String);
+        procedure removeListener(listener: TMapsEventListener);
+        procedure trigger(instance: TJSObject; eventName: String); varargs;
+      end;
+
+      TGeometry = class external name 'geometry'
+      public type
+        TEncoding = class external name 'encoding'
+        public
+          function decodePath(encodedPath: String): TArray<TLatLng>;
+          function encodePath(path: TArray<TLatLng>): String; overload;
+          function encodePath(path: TMVCArray<JSValue>): String; overload;
+        end;
+
+        TPoly = class external name 'poly'
+        public
+          function containsLocation(point: TLatLng; polygon: TGoogle.TMaps.TPolygon): Boolean;
+          function isLocationOnEdge(point: TLatLng; poly: TGoogle.TMaps.TPolygon; tolerance: Double): Boolean; overload;
+          function isLocationOnEdge(point: TLatLng; poly: TGoogle.TMaps.TPolyline; tolerance: Double): Boolean; overload;
+        end;
+
+        TSpherical = class external name 'spherical'
+        public
+          function computeArea(path: TArray<TLatLng>; radius: Double): Double; overload;
+          function computeArea(path: TMVCArray<JSValue>; radius: Double): Double; overload;
+          function computeDistanceBetween(from: TLatLng; &to: TLatLng; radius: Double): Double;
+          function computeHeading(from: TLatLng; &to: TLatLng): Double;
+          function computeLength(path: TArray<TLatLng>; radius: Double): Double; overload;
+          function computeLength(path: TMVCArray<JSValue>; radius: Double): Double; overload;
+          function computeOffset(from: TLatLng; distance, heading, radius: Double): TLatLng;
+          function computeOffsetOrigin(&to: TLatLng; distance, heading, radius: Double): TLatLng;
+          function computeSignedArea(loop: TArray<TLatLng>; radius: Double): Double; overload;
+          function computeSignedArea(loop: TMVCArray<JSValue>; radius: Double): Double; overload;
+          function interpolate(from, &to: TLatLng; fraction: Double): TLatLng;
+        end;
+      end;
+
+      TVisualization = class external name 'visualization'
+      public type
+        THeatmapLayer = class external name 'HeatmapLayer' (TMVCObject)
+        public
+          constructor new(opts: THeatmapLayerOptions);
+          function getData: TMVCArray<JSValue>;
+          function getMap: TMaps;
+          procedure setData(data: TMVCArray<JSValue>); overload;
+          procedure setData(data: TArray<TLatLng>); overload;
+          procedure setData(data: TArray<TWeightedLocation>); overload;
+          procedure setMap(map: TMap);
+          procedure setOptions(options: THeatmapLayerOptions);
+        end;
+      end;
+
+      TStreetViewPreference = class external name 'StreetViewPreference'
+      public const
+        BEST = 'BEST';
+        NEAREST = 'NEAREST';
+      end;
+
+      TMaxZoomStatus = class external name 'MaxZoomStatus'
+      public const
+        ERROR = 'ERROR';
+        OK = 'OK';
+      end;
+
+      TGeocoderLocationType = class external name 'GeocoderLocationType'
+      public const
+        APPROXIMATE = 'APPROXIMATE';
+        GEOMETRIC_CENTER = 'GEOMETRIC_CENTER';
+        RANGE_INTERPOLATED = 'RANGE_INTERPOLATED';
+        ROOFTOP = 'ROOFTOP';
+      end;
+
+      TTrafficModel = class external name 'TrafficModel'
+      public const
+        BEST_GUESS = 'BEST_GUESS';
+        OPTIMISTIC = 'OPTIMISTIC';
+        PESSIMISTIC = 'PESSIMISTIC';
+      end;
+
+      TTransitMode = class external name 'TransitMode'
+      public const
+        BUS = 'BUS';
+        RAIL = 'RAIL';
+        SUBWAY = 'SUBWAY';
+        TRAIN = 'TRAIN';
+        TRAM = 'TRAM';
+      end;
+
+      TTransitRoutePreference = class external name 'TransitRoutePreference'
+      public const
+        FEWER_TRANSFERS = 'FEWER_TRANSFERS';
+        LESS_WALKING = 'LESS_WALKING';
+      end;
+
+      TTravelMode = class external name 'TravelMode'
+      public const
+        BICYCLING = 'BICYCLING';
+        DRIVING = 'DRIVING';
+        TRANSIT = 'TRANSIT';
+        WALKING = 'WALKING';
+      end;
+
+      TOverlayType = class external name 'OverlayType'
+      public const
+        CIRCLE = 'CIRCLE';
+        MARKER = 'MARKER';
+        POLYGON = 'POLYGON';
+        POLYLINE = 'POLYLINE';
+        RECTANGLE = 'RECTANGLE';
+      end;
+
+      TBusinessStatus = class external name 'BusinessStatus'
+      public const
+        CLOSED_PERMANENTLY = 'CLOSED_PERMANENTLY';
+        CLOSED_TEMPORARILY = 'CLOSED_TEMPORARILY';
+        OPERATIONAL = 'OPERATIONAL';
+      end;
+
+      TPlacesServiceStatus = class external name 'PlacesServiceStatus'
+      public const
+        INVALID_REQUEST = 'INVALID_REQUEST';
+        NOT_FOUND = 'NOT_FOUND';
+        OK = 'OK';
+        OVER_QUERY_LIMIT = 'OVER_QUERY_LIMIT';
+        REQUEST_DENIED = 'REQUEST_DENIED';
+        UNKNOWN_ERROR = 'UNKNOWN_ERROR';
+        ZERO_RESULTS = 'ZERO_RESULTS';
+      end;
+
+      TDistanceMatrixElementStatus = class
+      public const
+        NOT_FOUND = 'NOT_FOUND';
+        OK = 'OK';
+        ZERO_RESULTS = 'ZERO_RESULTS';
+      end;
+
+      TStreetViewSource = class
+      public const
+        DEFAULT = 'DEFAULT';
+        OUTDOOR = 'OUTDOOR';
+      end;
+
+      TVehicleType = class
+      public const
+        BUS = 'BUS';
+        CABLE_CAR = 'CABLE_CAR';
+        COMMUTER_TRAIN = 'COMMUTER_TRAIN';
+        COMMUTER_TRAINCOMMUTER_TRAINCOMMUTER_TRAINCOMMUTER_TRAINFERRY = 'COMMUTER_TRAINCOMMUTER_TRAINCOMMUTER_TRAINCOMMUTER_TRAINFERRY';
+        FUNICULAR = 'FUNICULAR';
+        GONDOLA_LIFT = 'GONDOLA_LIFT';
+        HEAVY_RAIL = 'HEAVY_RAIL';
+        HIGH_SPEED_TRAIN = 'HIGH_SPEED_TRAIN';
+        INTERCITY_BUS = 'INTERCITY_BUS';
+        METRO_RAIL = 'METRO_RAIL';
+        MONORAIL = 'MONORAIL';
+        OTHER = 'OTHER';
+        RAIL = 'RAIL';
+        SHARE_TAXI = 'SHARE_TAXI';
+        SUBWAY = 'SUBWAY';
+        TRAM = 'TRAM';
+        TROLLEYBUS = 'TROLLEYBUS';
+      end;
+    public
+      version: String;
+    end;
+  end;
+
+  TCircleOptions = class
+  public
+    center: JSValue;
+    clickable: Boolean;
+    draggable: Boolean;
+    editable: Boolean;
+    fillColor: String;
+    fillOpacity: Double;
+    map: TGoogle.TMaps.TMap;
+    radius: Double;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokePosition: TGoogle.TMaps.TStrokePosition;
+    strokeWeight: Double;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TCircleLiteral = class(TCircleOptions)
+  public
+    center: JSValue;
+    radius: Double;
+  end;
+
+  TAddFeatureEvent = class
+  public
+    feature: TGoogle.TMaps.TData.TFeature;
+  end;
+
+  TDataOptions = class
+  public
+    controlPosition: TGoogle.TMaps.TControlPosition;
+    controls: TArray<String>;
+    drawingMode: String;
+    featureFactory: TFunc<TGoogle.TMaps.TData.TGeometry, TGoogle.TMaps.TData.TFeature>;
+    map: TGoogle.TMaps.TMap;
+    style: TStyleOptions;
+    styleFunction: TFunc<TGoogle.TMaps.TData.TFeature, TStyleOptions>; external name 'style';
+  end;
+
+  TFeatureOptions = class
+  public
+    geometry: JSValue;
+    id: Double;
+    properties: TJSObject;
+  end;
+
+  TGeoJsonOptions = class
+  public
+    idPropertyName: String;
+  end;
+
+  TMapMouseEvent = class external name 'MapMouseEvent'
+  public
+    domEvent: TJSEvent;
+    latLng: TGoogle.TMaps.TLatLng;
+    procedure stop;
+  end;
+
+  TMouseEvent = class(TMapMouseEvent)
+  public
+    feature: TGoogle.TMaps.TData.TFeature;
+  end;
+
+  TRemoveFeatureEvent = class
+  public
+    feature: TGoogle.TMaps.TData.TFeature;
+  end;
+
+  TRemovePropertyEvent = class
+  public
+    feature: TGoogle.TMaps.TData.TFeature;
+    name: String;
+    oldValue: JSValue;
+  end;
+
+  TSetGeometryEvent = class
+  public
+    feature: TGoogle.TMaps.TData.TFeature;
+    newGeometry: TGoogle.TMaps.TData.TGeometry;
+    oldGeometry: TGoogle.TMaps.TData.TGeometry;
+  end;
+
+  TSetPropertyEvent = class
+    feature: TGoogle.TMaps.TData.TFeature;
+    name: String;
+    newValue: JSValue;
+    oldValue: JSValue;
+  end;
+
+  TStyleOptions = class
+  public
+    clickable: Boolean;
+    cursor: String;
+    draggable: Boolean;
+    editable: Boolean;
+    fillColor: String;
+    fillOpacity: Double;
+    icon: JSValue;
+    shape: TMarkerShape;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokeWeight: Double;
+    title: String;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TDirectionsGeocodedWaypoint = class
+  public
+    partial_match: Boolean;
+    place_id: String;
+    types: TArray<String>;
+  end;
+
+  TDirectionsLeg = class
+  public
+    arrival_time: TTimeGoogle;
+    departure_time: TTimeGoogle;
+    distance: TDistance;
+    duration: TDuration;
+    duration_in_traffic: TDuration;
+    end_address: String;
+    end_location: TGoogle.TMaps.TLatLng;
+    start_address: String;
+    start_location: TGoogle.TMaps.TLatLng;
+    steps: TArray<TDirectionsStep>;
+    via_waypoints: TArray<TGoogle.TMaps.TLatLng>;
+  end;
+
+  TDirectionsRendererOptions = class
+  public
+    directions: TDirectionsResult;
+    draggable: Boolean;
+    hideRouteList: Boolean;
+    infoWindow: TGoogle.TMaps.TInfoWindow;
+    map: TGoogle.TMaps.TMap;
+    markerOptions: TMarkerOptions;
+    panel: TJSNode;
+    polylineOptions: google.maps.TPolylineOptions;
+    preserveViewport: Boolean;
+    routeIndex: Double;
+    suppressBicyclingLayer: Boolean;
+    suppressInfoWindows: Boolean;
+    suppressMarkers: Boolean;
+    suppressPolylines: Boolean;
+  end;
+
+  TDirectionsRequest = class
+  public
+    avoidFerries: Boolean;
+    avoidHighways: Boolean;
+    avoidTolls: Boolean;
+    destination: JSValue;
+    drivingOptions: TDrivingOptions;
+    optimizeWaypoints: Boolean;
+    origin: JSValue;
+    provideRouteAlternatives: Boolean;
+    region: String;
+    transitOptions: TTransitOptions;
+    travelMode: TGoogle.TMaps.TTravelMode;
+    unitSystem: TGoogle.TMaps.TUnitSystem;
+    waypoints: TArray<TDirectionsWaypoint>;
+  end;
+
+  TDirectionsResult = class
+  public
+    geocoded_waypoints: TArray<TDirectionsGeocodedWaypoint>;
+    routes: TArray<TDirectionsRoute>;
+  end;
+
+  TDirectionsRoute = class
+  public
+    bounds: TGoogle.TMaps.TLatLngBounds;
+    copyrights: String;
+    fare: TArray<TTransitFare>;
+    legs: TArray<TDirectionsLeg>;
+    overview_path: TArray<TGoogle.TMaps.TLatLng>;
+    overview_polyline: String;
+    warnings: TArray<String>;
+    waypoint_order: TArray<Double>;
+  end;
+
+  TDirectionsStep = class
+    distance: TDistance;
+    duration: TDuration;
+    end_location: TGoogle.TMaps.TLatLng;
+    instructions: String;
+    path: TArray<TGoogle.TMaps.TLatLng>;
+    start_location: TGoogle.TMaps.TLatLng;
+    steps: TArray<TDirectionsStep>;
+    transit: TTransitDetails;
+    travel_mode: TGoogle.TMaps.TTravelMode;
+  end;
+
+  TDirectionsWaypoint = class
+    location: JSValue;
+    stopover: Boolean;
+  end;
+
+  TDistance = class
+  public
+    text: String;
+    value: Double;
+  end;
+
+  TDistanceMatrixRequest = class
+  public
+    avoidFerries: Boolean;
+    avoidHighways: Boolean;
+    avoidTolls: Boolean;
+    destinations: TArray<JSValue>;
+    drivingOptions: TDrivingOptions;
+    origins: TArray<JSValue>;
+    region: String;
+    transitOptions: TTransitOptions;
+    travelMode: TGoogle.TMaps.TTravelMode;
+    unitSystem: TGoogle.TMaps.TUnitSystem;
+  end;
+
+  TDistanceMatrixResponse = class
+  public
+    destinationAddresses: TArray<String>;
+    originAddresses: TArray<String>;
+    rows: TArray<TDistanceMatrixResponseRow>;
+  end;
+
+  TDistanceMatrixResponseElement = class
+  public
+    distance: TDistance;
+    duration: TDuration;
+    duration_in_traffic: TDuration;
+    fare: TTransitFare;
+    status: TGoogle.TMaps.TDistanceMatrixElementStatus;
+  end;
+
+  TDistanceMatrixResponseRow = class
+  public
+    elements: TArray<TDistanceMatrixResponseElement>;
+  end;
+
+  TDrivingOptions = class
+  public
+    departureTime: String;
+    trafficModel: TGoogle.TMaps.TTrafficModel;
+  end;
+
+  TDuration = class
+  public
+    text: String;
+    value: Double;
+  end;
+
+  TElevationResult = class
+  public
+    elevation: Double;
+    location: TGoogle.TMaps.TLatLng;
+    resolution: Double;
+  end;
+
+  TFullscreenControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TGeocoderAddressComponent = class
+  public
+    long_name: String;
+    short_name: String;
+    types: TArray<String>;
+  end;
+
+  TGeocoderComponentRestrictions = class
+  public
+    administrativeArea: String;
+    country: String;
+    locality: String;
+    postalCode: String;
+    route: String;
+  end;
+
+  TGeocoderGeometry = class
+  public
+    bounds: TGoogle.TMaps.TLatLngBounds;
+    location: TGoogle.TMaps.TLatLng;
+    location_type: TGoogle.TMaps.TGeocoderLocationType;
+    viewport: TGoogle.TMaps.TLatLngBounds;
+  end;
+
+  TGeocoderRequest = class
+  public
+    address: String;
+    bounds: JSValue;
+    componentRestrictions: TGeocoderComponentRestrictions;
+    location: JSValue;
+    placeId: String;
+    region: String;
+  end;
+
+  TGeocoderResponse = class
+  public
+    results: TArray<TGeocoderResult>;
+  end;
+
+  TGeocoderResult = class
+  public
+    address_components: TArray<TGeocoderAddressComponent>;
+    formatted_address: String;
+    geometry: TGeocoderGeometry;
+    partial_match: Boolean;
+    place_id: String;
+    postcode_localities: TArray<String>;
+    types: TArray<String>;
+  end;
+
+  TGroundOverlayOptions = class
+  public
+    clickable: Boolean;
+    map: TGoogle.TMaps.TMap;
+    opacity: Double;
+  end;
+
+  TIcon = class
+  public
+    anchor: TGoogle.TMaps.TPoint;
+    labelOrigin: TGoogle.TMaps.TPoint;
+    origin: TGoogle.TMaps.TPoint;
+    scaledSize: TGoogle.TMaps.TSize;
+    size: TGoogle.TMaps.TSize;
+    url: String;
+  end;
+
+  TIconMouseEvent = class(TMapMouseEvent)
+  public
+    placeId: String;
+  end;
+
+  TIconSequence = class
+  public
+    fixedRotation: Boolean;
+    icon: TSymbol;
+    offset: String;
+    &repeat: String;
+  end;
+
+  TImageMapTypeOptions = class
+  public
+    alt: String;
+    getTileUrl: TFunc<TGoogle.TMaps.TPoint, Double, String>;
+    maxZoom: Double;
+    minZoom: Double;
+    name: String;
+    opacity: Double;
+    tileSize: TGoogle.TMaps.TSize;
+  end;
+
+  TInfoWindowOptions = class
+  public
+    content: JSValue;
+    disableAutoPan: Boolean;
+    maxWidth: Double;
+    minWidth: Double;
+    pixelOffset: TGoogle.TMaps.TSize;
+    position: JSValue;
+    zIndex: Double;
+  end;
+
+  TKmlAuthor = class
+  public
+    email: String;
+    name: String;
+    uri: String;
+  end;
+
+  TKmlFeatureData = class
+  public
+    author: TKmlAuthor;
+    description: String;
+    id: String;
+    infoWindowHtml: String;
+    name: String;
+    snippet: String;
+  end;
+
+  TKmlLayerMetadata = class
+  public
+    author: TKmlAuthor;
+    description: String;
+    hasScreenOverlays: Boolean;
+    name: String;
+    snippet: String;
+  end;
+
+  TKmlLayerOptions = class
+  public
+    clickable: Boolean;
+    map: TGoogle.TMaps.TMap;
+    preserveViewport: Boolean;
+    screenOverlays: Boolean;
+    suppressInfoWindows: Boolean;
+    url: String;
+    zIndex: Double;
+  end;
+
+  TKmlMouseEvent = class
+  public
+    featureData: TKmlFeatureData;
+    latLng: TGoogle.TMaps.TLatLng;
+    pixelOffset: TGoogle.TMaps.TSize;
+  end;
+
+  TLatLngBoundsLiteral = class
+  public
+    east: Double;
+    north: Double;
+    south: Double;
+    west: Double;
+  end;
+
+  TLatLngLiteral = class
+  public
+    lat: Double;
+    lng: Double;
+
+    constructor Create(Lat, Lng: Double);
+  end;
+
+  TLocationElevationRequest = class
+  public
+    locations: TArray<JSValue>;
+  end;
+
+  TLocationElevationResponse = class
+  public
+    results: TArray<TElevationResult>;
+  end;
+
+  TMapCanvasProjection = class external name 'MapCanvasProjection' abstract
+  public
+    function fromContainerPixelToLatLng(pixel: TGoogle.TMaps.TPoint; nowrap: Boolean): TGoogle.TMaps.TLatLng;
+    function fromDivPixelToLatLng(pixel: TGoogle.TMaps.TPoint; nowrap: Boolean): TGoogle.TMaps.TLatLng;
+    function fromLatLngToContainerPixel(latLng: TGoogle.TMaps.TLatLng): TGoogle.TMaps.TPoint;
+    function fromLatLngToDivPixel(latLng: TGoogle.TMaps.TLatLng): TGoogle.TMaps.TPoint;
+    function getWorldWidth: Double;
+  end;
+
+  TMapOptions = class
+  private
+    FFullscreenControlOptions: TFullscreenControlOptions; external name 'fullscreenControlOptions';
+    Frestriction: TMapRestriction; external name 'restriction';
+    FzoomControlOptions: TZoomControlOptions; external name 'zoomControlOptions';
+    FscaleControlOptions: TScaleControlOptions; external name 'scaleControlOptions';
+    FmapTypeControlOptions: TMapTypeControlOptions; external name 'mapTypeControlOptions';
+    FpanControlOptions: TPanControlOptions; external name 'panControlOptions';
+    FstreetViewControlOptions: TStreetViewControlOptions; external name 'streetViewControlOptions';
+    FrotateControlOptions: TRotateControlOptions; external name 'rotateControlOptions';
+
+    function GetRestriction: TMapRestriction;
+    function GetRotateControlOptions: TRotateControlOptions;
+    function GetScaleControlOptions: TScaleControlOptions;
+    function GetStreetViewControlOptions: TStreetViewControlOptions;
+    function GetZoomControlOptions: TZoomControlOptions;
+    function GetfullscreenControlOptions: TFullscreenControlOptions;
+    function GetmapTypeControlOptions: TMapTypeControlOptions;
+    function GetpanControlOptions: TPanControlOptions;
+  public
+    backgroundColor: String;
+    center: JSValue;
+    clickableIcons: Boolean;
+    controlSize: Double;
+    disableDefaultUI: Boolean;
+    disableDoubleClickZoom: Boolean;
+    draggableCursor: String;
+    draggingCursor: String;
+    fullscreenControl: Boolean;
+    gestureHandling: String;
+    heading: Double;
+    keyboardShortcuts: Boolean;
+    mapTypeControl: Boolean;
+    mapTypeId: String;
+    maxZoom: Double;
+    minZoom: Double;
+    noClear: Boolean;
+    panControl: Boolean;
+    rotateControl: Boolean;
+    scaleControl: Boolean;
+    scrollwheel: Boolean;
+    streetView: TGoogle.TMaps.TStreetViewPanorama;
+    streetViewControl: Boolean;
+    styles: TArray<TMapTypeStyle>;
+    tilt: Double;
+    zoom: Double;
+    zoomControl: Boolean;
+
+    property fullscreenControlOptions: TFullscreenControlOptions read GetfullscreenControlOptions write FfullscreenControlOptions;
+    property mapTypeControlOptions: TMapTypeControlOptions read GetmapTypeControlOptions write FmapTypeControlOptions;
+    property panControlOptions: TPanControlOptions read GetpanControlOptions write FpanControlOptions;
+    property rotateControlOptions: TRotateControlOptions read GetrotateControlOptions write FrotateControlOptions;
+    property streetViewControlOptions: TStreetViewControlOptions read GetstreetViewControlOptions write FstreetViewControlOptions;
+    property restriction: TMapRestriction read Getrestriction write Frestriction;
+    property scaleControlOptions: TScaleControlOptions read GetscaleControlOptions write FscaleControlOptions;
+    property zoomControlOptions: TZoomControlOptions read GetzoomControlOptions write FzoomControlOptions;
+  end;
+
+  TMapPanes = class
+  public
+    floatPane: TJSHTMLElement;
+    mapPane: TJSHTMLElement;
+    markerLayer: TJSHTMLElement;
+    overlayLayer: TJSHTMLElement;
+    overlayMouseTarget: TJSHTMLElement;
+  end;
+
+  TMapRestriction = class
+  public
+    latLngBounds: JSValue;
+    strictBounds: Boolean;
+  end;
+
+  TMapType = class external name 'MapType' abstract
+  public
+    alt: String;
+    maxZoom: Double;
+    minZoom: Double;
+    name: String;
+    projection: TProjection;
+    radius: Double;
+    tileSize: TGoogle.TMaps.TSize;
+    procedure releaseTile(tile: TJSNode);
+    function getTile(tileCoord: TGoogle.TMaps.TPoint; zoom: Double; ownerDocument: TJSDocument): TJSNode;
+  end;
+
+  TMapTypeControlOptions = class
+  public
+    mapTypeIds: TArray<String>;
+    position: TGoogle.TMaps.TControlPosition;
+    style: TGoogle.TMaps.TMapTypeControlStyle;
+  end;
+
+  TMapTypeStyle = class
+  public
+    elementType: String;
+    featureType: String;
+    stylers: TArray<TJSObject>;
+  end;
+
+  TMapsEventListener = class external name 'MapsEventListener' abstract
+  public
+    procedure remove;
+  end;
+
+  TPadding = class
+  public
+    bottom: Double;
+    left: Double;
+    right: Double;
+    top: Double;
+  end;
+
+  TPanControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TPanoProviderOptions = class
+  public
+    cors: Boolean;
+  end;
+
+  TPathElevationRequest = class
+  public
+    path: TArray<JSValue>;
+    samples: Double;
+  end;
+
+  TPathElevationResponse = class
+  public
+    results: TArray<TElevationResult>;
+  end;
+
+  TPlace = class
+  public
+    location: JSValue;
+    placeId: String;
+    query: String;
+  end;
+
+  TPolyMouseEvent = class(TMapMouseEvent)
+  public
+    edge: Double;
+    path: Double;
+    vertex: Double;
+  end;
+
+  TMarkerLabel = class
+  public
+    className: String;
+    color: String;
+    fontFamily: String;
+    fontSize: String;
+    fontWeight: String;
+    text: String;
+  end;
+
+  TMarkerOptions = class
+  public
+    anchorPoint: TGoogle.TMaps.TPoint;
+    animation: TGoogle.TMaps.TAnimation;
+    clickable: Boolean;
+    crossOnDrag: Boolean;
+    cursor: String;
+    draggable: Boolean;
+    icon: JSValue;
+    &label: JSValue;
+    map: TGoogle.TMaps.TMap;
+    mapStreetViewPanorama: TGoogle.TMaps.TStreetViewPanorama; external name 'map';
+    opacity: Double;
+    optimized: Boolean;
+    position: JSValue;
+    shape: TMarkerShape;
+    title: String;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TMarkerShape = class
+  public
+    coords: TArray<Double>;
+    &type: String;
+  end;
+
+  TMaxZoomResult = class
+  public
+    status: TGoogle.TMaps.TMaxZoomStatus;
+    zoom: Double;
+  end;
+
+  TPolygonOptions = class
+  public
+    clickable: Boolean;
+    draggable: Boolean;
+    editable: Boolean;
+    fillColor: String;
+    fillOpacity: Double;
+    geodesic: Boolean;
+    map: TGoogle.TMaps.TMap;
+    paths: JSValue;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokePosition: TGoogle.TMaps.TStrokePosition;
+    strokeWeight: Double;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TPolylineOptions = class
+  public
+    clickable: Boolean;
+    draggable: Boolean;
+    editable: Boolean;
+    geodesic: Boolean;
+    icons: TArray<TIconSequence>;
+    map: TGoogle.TMaps.TMap;
+    path: TArray<JSValue>;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokeWeight: Double;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TProjection = class external name 'Projection' abstract
+  public
+    function fromLatLngToPoint(latLng: TGoogle.TMaps.TLatLng; point: TGoogle.TMaps.TPoint): TGoogle.TMaps.TPoint;
+    function fromPointToLatLng(pixel: TGoogle.TMaps.TPoint; noWrap: Boolean): TGoogle.TMaps.TLatLng;
+  end;
+
+  TRectangleOptions = class
+  public
+    bounds: JSValue;
+    clickable: Boolean;
+    draggable: Boolean;
+    editable: Boolean;
+    fillColor: String;
+    fillOpacity: Double;
+    map: TGoogle.TMaps.TMap;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokePosition: TGoogle.TMaps.TStrokePosition;
+    strokeWeight: Double;
+    visible: Boolean;
+    zIndex: Double;
+  end;
+
+  TRotateControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TScaleControlOptions = class
+  public type
+    TScaleControlStyle = (scDEFAULT);
+  public
+    style: TScaleControlStyle;
+  end;
+
+  TMotionTrackingControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TStreetViewAddressControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TStreetViewControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TStreetViewLink = class
+  public
+    description: String;
+    heading: Double;
+    pano: String;
+  end;
+
+  TStreetViewLocation = class
+  public
+    description: String;
+    latLng: TGoogle.TMaps.TLatLng;
+    pano: String;
+    shortDescription: String;
+  end;
+
+  TStreetViewLocationRequest = class
+  public
+    location: JSValue;
+    preference: TGoogle.TMaps.TStreetViewPreference;
+    radius: Double;
+    source: TGoogle.TMaps.TStreetViewSource;
+  end;
+
+  TStreetViewPanoRequest = class
+  public
+    pano: String;
+  end;
+
+  TStreetViewPanoramaData = class
+  public
+    copyright: String;
+    imageDate: String;
+    links: TArray<TStreetViewLink>;
+    location: TStreetViewLocation;
+    tiles: TStreetViewTileData;
+  end;
+
+  TStreetViewPanoramaOptions = class
+  public
+    addressControl: Boolean;
+    addressControlOptions: TStreetViewAddressControlOptions;
+    clickToGo: Boolean;
+    controlSize: Double;
+    disableDefaultUI: Boolean;
+    disableDoubleClickZoom: Boolean;
+    enableCloseButton: Boolean;
+    fullscreenControl: Boolean;
+    fullscreenControlOptions: TFullscreenControlOptions;
+    imageDateControl: Boolean;
+    linksControl: Boolean;
+    motionTracking: Boolean;
+    motionTrackingControl: Boolean;
+    motionTrackingControlOptions: TMotionTrackingControlOptions;
+    panControl: Boolean;
+    panControlOptions: TPanControlOptions;
+    pano: String;
+    position: JSValue;
+    pov: TStreetViewPov;
+    scrollwheel: Boolean;
+    showRoadLabels: Boolean;
+    visible: Boolean;
+    zoom: Double;
+    zoomControl: Boolean;
+    zoomControlOptions: TZoomControlOptions;
+  end;
+
+  TStreetViewPov = class
+  public
+    heading: Double;
+    pitch: Double;
+  end;
+
+  TStreetViewResponse = class
+  public
+    data: TStreetViewPanoramaData;
+  end;
+
+  TStreetViewTileData = class
+  public
+    centerHeading: Double;
+    tileSize: TGoogle.TMaps.TSize;
+    worldSize: TGoogle.TMaps.TSize;
+
+    function getTileUrl(pano: String; tileZoom: Double; tileX: Double; tileY: Double): String; virtual; abstract;
+  end;
+
+  TStyledMapTypeOptions = class
+  public
+    alt: String;
+    maxZoom: Double;
+    minZoom: Double;
+    name: String;
+  end;
+
+  TSymbol = class
+  public
+    anchor: TGoogle.TMaps.TPoint;
+    fillColor: String;
+    fillOpacity: Double;
+    labelOrigin: TGoogle.TMaps.TPoint;
+    path: JSValue;
+    rotation: Double;
+    scale: Double;
+    strokeColor: String;
+    strokeOpacity: Double;
+    strokeWeight: Double;
+  end;
+
+  TTimeGoogle = class
+  public
+    text: String;
+    time_zone: String;
+    value: String;
+  end;
+
+  TTrafficLayerOptions = class
+  public
+    autoRefresh: Boolean;
+    map: TGoogle.TMaps.TMap;
+  end;
+
+  TTransitAgency = class
+  public
+    name: String;
+    phone: String;
+    url: String;
+  end;
+
+  TTransitDetails = class
+  public
+    arrival_stop: TTransitStop;
+    arrival_time: TTimeGoogle;
+    departure_stop: TTransitStop;
+    departure_time: TTimeGoogle;
+    headsign: String;
+    headway: Double;
+    line: TTransitLine;
+    num_stops: Double;
+    trip_short_name: String;
+  end;
+
+  TTransitFare = class
+  public
+    currency: String;
+    value: Double;
+  end;
+
+  TTransitLine = class
+  public
+    agencies: TArray<TTransitAgency>;
+    color: String;
+    icon: String;
+    name: String;
+    short_name: String;
+    text_color: String;
+    url: String;
+    vehicle: TTransitVehicle;
+  end;
+
+  TTransitOptions = class
+  public
+    arrivalTime: String;
+    departureTime: String;
+    modes: TArray<TGoogle.TMaps.TTransitMode>;
+    routingPreference: TArray<TGoogle.TMaps.TTransitRoutePreference>;
+  end;
+
+  TTransitStop = class
+  public
+    location: TGoogle.TMaps.TLatLng;
+    name: String;
+  end;
+
+  TTransitVehicle = class
+  public
+    icon: String;
+    local_icon: String;
+    name: String;
+    &type: TGoogle.TMaps.TVehicleType;
+  end;
+
+  TZoomControlOptions = class
+  public
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TDrawingControlOptions = class
+  public
+    drawingModes: TArray<TGoogle.TMaps.TOverlayType>;
+    position: TGoogle.TMaps.TControlPosition;
+  end;
+
+  TDrawingManagerOptions = class
+  public
+    circleOptions: TCircleOptions;
+    drawingControl: Boolean;
+    drawingControlOptions: TDrawingControlOptions;
+    drawingMode: TGoogle.TMaps.TOverlayType;
+    map: TGoogle.TMaps.TMap;
+    markerOptions: TMarkerOptions;
+    polygonOptions: TPolygonOptions;
+    polylineOptions: TPolylineOptions;
+    rectangleOptions: TRectangleOptions;
+  end;
+
+  TOverlayCompleteEvent = class
+  public
+    overlay: JSValue;
+    &type: TGoogle.TMaps.TOverlayType;
+  end;
+
+  TPinOptions = class
+  public
+    background: String;
+    glyphColor: String;
+    scale: Double;
+  end;
+
+  TAutocompleteOptions = class
+  public
+    bounds: JSValue;
+    componentRestrictions: TComponentRestrictions;
+    fields: TArray<String>;
+    strictBounds: Boolean;
+    types: TArray<String>;
+  end;
+
+  TAutocompletePrediction = class
+  public
+    description: String;
+    distance_meters: Double;
+    matched_substrings: TArray<TPredictionSubstring>;
+    place_id: String;
+    structured_formatting: TStructuredFormatting;
+    terms: TArray<TPredictionTerm>;
+    types: TArray<String>;
+  end;
+
+  TAutocompleteResponse = class
+  public
+    predictions: TArray<TAutocompletePrediction>;
+  end;
+
+  TAutocompleteSessionToken = class
+  end;
+
+  TAutocompletionRequest = class
+  public
+    bounds: JSValue;
+    componentRestrictions: TComponentRestrictions;
+    input: String;
+    location: TGoogle.TMaps.TLatLng;
+    offset: Double;
+    origin: JSValue;
+    radius: Double;
+    sessionToken: TAutocompleteSessionToken;
+    types: TArray<String>;
+  end;
+
+  TComponentRestrictions = class
+  public
+    country: TArray<String>;
+  end;
+
+  TFindPlaceFromPhoneNumberRequest = class
+  public
+    fields: TArray<String>;
+    locationBias: JSValue;
+    phoneNumber: String;
+  end;
+
+  TFindPlaceFromQueryRequest = class
+  public
+    fields: TArray<String>;
+    locationBias: JSValue;
+    query: String;
+  end;
+
+  TPredictionSubstring = class
+  public
+    length: Double;
+    offset: Double;
+  end;
+
+  TPredictionTerm = class
+  public
+    offset: Double;
+    value: String;
+  end;
+
+  TQueryAutocompletionRequest = class
+  public
+    bounds: JSValue;
+    input: String;
+    location: TGoogle.TMaps.TLatLng;
+    offset: Double;
+    radius: Double;
+  end;
+
+  TSearchBoxOptions = class
+  public
+    bounds: JSValue;
+  end;
+
+  TStructuredFormatting = class
+  public
+    main_text: String;
+    main_text_matched_substrings: TArray<TPredictionSubstring>;
+    secondary_text: String;
+  end;
+
+  TTextSearchRequest = class
+  public
+    bounds: JSValue;
+    location: JSValue;
+    query: String;
+    radius: Double;
+    &type: String;
+  end;
+
+  THeatmapLayerOptions = class
+  public
+    data: JSValue;
+    dissipating: Boolean;
+    gradient: TArray<String>;
+    map: TGoogle.TMaps.TMap;
+    maxIntensity: Double;
+    opacity: Double;
+    radius: Double;
+  end;
+
+  TWeightedLocation = class
+  public
+    location: TGoogle.TMaps.TLatLng;
+    weight: Double;
+  end;
+
+function InitializeMap(Key: String): TJSPromise;
+
+implementation
+
+function InitializeMap(Key: String): TJSPromise;
+begin
+  Result := TJSPromise.New(
+    procedure(Resolve, Reject: TJSPromiseResolver)
+    var
+      Script: TJSHTMLScriptElement;
+
+    begin
+      Script := TJSHTMLScriptElement(document.createElement('script'));
+      Script.OnLoad :=
+        function(Event: TEventListenerEvent): Boolean
+        begin
+          Window.RequestIdleCallback(
+            procedure (idleDeadline: TJSIdleDeadline)
+            begin
+              Resolve(True);
+            end);
+
+          Result := True;
+        end;
+      Script.src := Format('https://maps.googleapis.com/maps/api/js?key=%s', [Key]);
+      Script.type_ := 'text/javascript';
+
+      document.head.appendChild(Script);
+    end);
+end;
+
+{ TLatLngLiteral }
+
+constructor TLatLngLiteral.Create(Lat, Lng: Double);
+begin
+  Self.Lat := Lat;
+  Self.Lng := Lng;
+end;
+
+{ TMapOptions }
+
+function TMapOptions.GetfullscreenControlOptions: TFullscreenControlOptions;
+begin
+  if not Assigned(FfullscreenControlOptions) then
+    FfullscreenControlOptions := TFullscreenControlOptions.Create;
+
+  Result := FfullscreenControlOptions;
+end;
+
+function TMapOptions.GetmapTypeControlOptions: TMapTypeControlOptions;
+begin
+  if not Assigned(FmapTypeControlOptions) then
+    FmapTypeControlOptions := TMapTypeControlOptions.Create;
+
+  Result := FmapTypeControlOptions;
+end;
+
+function TMapOptions.GetpanControlOptions: TPanControlOptions;
+begin
+  if not Assigned(FpanControlOptions) then
+    FpanControlOptions := TPanControlOptions.Create;
+
+  Result := FpanControlOptions;
+end;
+
+function TMapOptions.GetRestriction: TMapRestriction;
+begin
+  if not Assigned(FRestriction) then
+    FRestriction := TMapRestriction.Create;
+
+  Result := FRestriction;
+end;
+
+function TMapOptions.GetRotateControlOptions: TRotateControlOptions;
+begin
+  if not Assigned(FRotateControlOptions) then
+    FRotateControlOptions := TRotateControlOptions.Create;
+
+  Result := FRotateControlOptions;
+end;
+
+function TMapOptions.GetScaleControlOptions: TScaleControlOptions;
+begin
+  if not Assigned(FScaleControlOptions) then
+    FScaleControlOptions := TScaleControlOptions.Create;
+
+  Result := FScaleControlOptions;
+end;
+
+function TMapOptions.GetZoomControlOptions: TZoomControlOptions;
+begin
+  if not Assigned(FZoomControlOptions) then
+    FZoomControlOptions := TZoomControlOptions.Create;
+
+  Result := FZoomControlOptions;
+end;
+
+function TMapOptions.GetStreetViewControlOptions: TStreetViewControlOptions;
+begin
+  if not Assigned(FStreetViewControlOptions) then
+    FStreetViewControlOptions := TStreetViewControlOptions.Create;
+
+  Result := FStreetViewControlOptions;
+end;
+
+end.
+
diff --git a/packages/maps/Leaflet.Maps.pas b/packages/maps/Leaflet.Maps.pas
new file mode 100644
index 00000000..6ab74f3e
--- /dev/null
+++ b/packages/maps/Leaflet.Maps.pas
@@ -0,0 +1,1845 @@
+unit Leaflet.Maps;
+
+interface
+
+{$modeswitch externalclass}
+
+uses JS, Web, SysUtils, GeoJSON;
+
+type
+  TAttributionOptions = class;
+  TCircleMarkerOptions = class;
+  TControlOptions = class;
+  TDefaultMapPanes = class;
+  TDivIconOptions = class;
+  TDivOverlayOptions = class;
+  TDragEndEvent = class;
+  TError = class;
+  TErrorEvent = class;
+  TFitBoundsOptions = class;
+  TGeoJSONEvent = class;
+  TGeoJSONOptions = class;
+  TGridLayerOptions = class;
+  TIconOptions = class;
+  TImageOverlayOptions = class;
+  TInteractiveLayerOptions = class;
+  TInvalidateSizeOptions = class;
+  TLatLngLiteral = class;
+  TLayerEvent = class;
+  TLayerOptions = class;
+  TLayersControlEvent = class;
+  TLayersObject = class;
+  TLayersOptions = class;
+  TLeafletEvent = class;
+  TLeafletKeyboardEvent = class;
+  TLeafletMouseEvent = class;
+  TLocateOptions = class;
+  TLocationEvent = class;
+  TMapOptions = class;
+  TMarkerOptions = class;
+  TPanInsideOptions = class;
+  TPanOptions = class;
+  TPathOptions = class;
+  TPolylineOptions = class;
+  TPopupEvent = class;
+  TPopupOptions = class;
+  TRendererOptions = class;
+  TResizeEvent = class;
+  TScaleOptions = class;
+  TTileErrorEvent = class;
+  TTileEvent = class;
+  TTileLayerOptions = class;
+  TTooltipEvent = class;
+  TTooltipOptions = class;
+  TVideoOverlayOptions = class;
+  TWMSOptions = class;
+  TWMSParams = class;
+  TZoomAnimEvent = class;
+  TZoomControlOptions = class;
+  TZoomOptions = class;
+  TZoomPanOptions = class;
+
+  TLatLngTuple = array[0..1] of Double;
+  TPointTuple = array[0..1] of Double;
+
+  TBoundsLiteral = array[0..1] of TPointTuple;
+
+  TLeaflet = class external name 'L'
+  public type
+    TBounds = class;
+    TLatLng = class;
+    TLatLngBounds = class;
+    TLayerGroup = class;
+    TMap = class;
+    TPoint = class;
+    TPopup = class;
+    TTooltip = class;
+
+    TLatLngBoundsLiteral = TArray<TLatLngTuple>;
+
+    TClass = class external name 'Class'
+    public
+      class function addInitHook(initHookFn: TProc): TClass; overload;
+      class function addInitHook(methodName: String): TClass; varargs; overload;
+      class function extend(props: JSValue): TClass;
+      class function include(props: JSValue): TClass;
+      class function mergeOptions(props: JSValue): TClass;
+    end;
+
+    TTransformation = class external name 'Transformation'
+    public
+      constructor new(a, b, c, d: Double);
+
+      function transform(point: TPoint): TPoint; overload;
+      function transform(point: TPoint; scale: Double): TPoint; overload;
+      function untransform(point: TPoint): TPoint; overload;
+      function untransform(point: TPoint; scale: Double): TPoint; overload;
+    end;
+
+    TLineUtil = class external name 'LineUtil'
+    public
+      function simplify(points: TArray<TPoint>; tolerance: Double): TArray<TPoint>;
+      function pointToSegmentDistance(p, p1,p2: TPoint): Double;
+      function closestPointOnSegment(p, p1, p2: TPoint): TPoint;
+      function isFlat(latlngs: TArray<TLatLng>): Boolean; overload;
+      function isFlat(latlngs: TArray<TLatLngLiteral>): Boolean; overload;
+      function isFlat(latlngs: TArray<TLatLngTuple>): Boolean; overload;
+      function clipSegment(a, b: TPoint; bounds: TBounds): TArray<TPoint>; overload;
+      function clipSegment(a, b: TPoint; bounds: TBounds; useLastCode: Boolean): TArray<TPoint>; overload;
+      function clipSegment(a, b: TPoint; bounds: TBounds; useLastCode, round: Boolean): TArray<TPoint>; overload;
+    end;
+
+    TPolyUtil = class external name 'PolyUtil'
+    public
+      function clipPolygon(points: TArray<TPoint>; bounds: TBounds): TArray<TPoint>; overload;
+      function clipPolygon(points: TArray<TPoint>; bounds: TBoundsLiteral): TArray<TPoint>; overload;
+      function clipPolygon(points: TArray<TPoint>; bounds: TBounds; round: Boolean): TArray<TPoint>; overload;
+      function clipPolygon(points: TArray<TPoint>; bounds: TBoundsLiteral; round: Boolean): TArray<TPoint>; overload;
+    end;
+
+    TDomUtil = class external name 'DomUtil'
+    public
+      TRANSFORM: String;
+      TRANSITION: String;
+      TRANSITION_END: String;
+
+      function get(element: String): TJSHTMLElement; overload;
+      function get(element: TJSHTMLElement): TJSHTMLElement; overload;
+      function getStyle(el: TJSHTMLElement; styleAttrib: String): String;
+      function create(tagName: String): TJSHTMLElement; overload;
+      function create(tagName: String; className: String): TJSHTMLElement; overload;
+      function create(tagName: String; className: String; container: TJSHTMLElement): TJSHTMLElement; overload;
+      procedure remove(el: TJSHTMLElement);
+      procedure empty(el: TJSHTMLElement);
+      procedure toFront(el: TJSHTMLElement);
+      procedure toBack(el: TJSHTMLElement);
+      function hasClass(el: TJSHTMLElement; name: String): Boolean;
+      procedure addClass(el: TJSHTMLElement; name: String);
+      procedure removeClass(el: TJSHTMLElement; name: String);
+      procedure setClass(el: TJSHTMLElement; name: String);
+      function getClass(el: TJSHTMLElement): String;
+      procedure setOpacity(el: TJSHTMLElement; opacity: Double);
+      function testProp(props: TArray<String>): String;
+      procedure setTransform(el: TJSHTMLElement; offset: TPoint; scale: Double);
+      procedure setPosition(el: TJSHTMLElement; position: TPoint);
+      function getPosition(el: TJSHTMLElement): TPoint;
+      procedure disableTextSelection();
+      procedure enableTextSelection();
+      procedure disableImageDrag();
+      procedure enableImageDrag();
+      procedure preventOutline(el: TJSHTMLElement);
+      procedure restoreOutline();
+    end;
+
+    TCRS = class external name 'CRS'
+    public class var
+      EPSG3395: TCRS;
+      EPSG3857: TCRS;
+      EPSG4326: TCRS;
+      EPSG900913: TCRS;
+      Earth: TCRS;
+      Simple: TCRS;
+    public
+      code: String;
+      wrapLng: TArray<Double>;
+      wrapLat: TArray<Double>;
+      infinite: Boolean;
+
+      function latLngToPoint(latlng: TLatLng; zoom: Double): TPoint; overload;
+      function latLngToPoint(latlng: TLatLngLiteral; zoom: Double): TPoint; overload;
+      function latLngToPoint(latlng: TLatLngTuple; zoom: Double): TPoint; overload;
+      function pointToLatLng(point: TPoint; zoom: Double): TLatLng; overload;
+      function pointToLatLng(point: TPointTuple; zoom: Double): TLatLng; overload;
+      function project(latlng: TLatLng): TPoint; overload;
+      function project(latlng: TLatLngLiteral): TPoint; overload;
+      function unproject(point: TPoint): TLatLng; overload;
+      function unproject(point: TPointTuple): TLatLng; overload;
+      function scale(zoom: Double): Double;
+      function zoom(scale: Double): Double;
+      function getProjectedBounds(zoom: Double): TBounds;
+      function distance(latlng1, latlng2: TLatLng): Double; overload;
+      function distance(latlng1, latlng2: TLatLngLiteral): Double; overload;
+      function distance(latlng1, latlng2: TLatLngTuple): Double; overload;
+      function wrapLatLng(latlng: TLatLng): TLatLng; overload;
+      function wrapLatLng(latlng: TLatLngLiteral): TLatLng; overload;
+    end;
+
+    TProjection = class external name 'Projection'
+    public
+      bounds: TBounds;
+
+      const LonLat: TProjection;
+      const Mercator: TProjection;
+      const SphericalMercator: TProjection;
+
+      function project(latlng: TLatLng): TPoint; overload;
+      function project(latlng: TLatLngLiteral): TPoint; overload;
+      function unproject(point: TPoint): TLatLng; overload;
+      function unproject(point: TPointTuple): TLatLng; overload;
+    end;
+
+    TLatLng = class external name 'LatLng'
+    public
+      lat: Double;
+      lng: Double;
+      alt: Double;
+
+      constructor new(latitude, longitude: Double); overload;
+      constructor new(latitude, longitude, altitude: Double); overload;
+
+      function clone(): TLatLng;
+      function distanceTo(otherLatLng: TLatLng): Double; overload;
+      function distanceTo(otherLatLng: TLatLngLiteral): Double; overload;
+      function distanceTo(otherLatLng: TLatLngTuple): Double; overload;
+      function equals(otherLatLng: TLatLng): Boolean; overload;
+      function equals(otherLatLng: TLatLng; maxMargin: Double): Boolean; overload;
+      function equals(otherLatLng: TLatLngLiteral): Boolean; overload;
+      function equals(otherLatLng: TLatLngLiteral; maxMargin: Double): Boolean; overload;
+      function equals(otherLatLng: TLatLngTuple): Boolean; overload;
+      function equals(otherLatLng: TLatLngTuple; maxMargin: Double): Boolean; overload;
+      function toBounds(sizeInMeters: Double): TLatLngBounds;
+      function toString(): String;
+      function wrap(): TLatLng;
+    end;
+
+    TLatLngBounds = class external name 'LatLngBounds'
+    public
+      constructor new(southWest, northEast: TLatLng); overload;
+      constructor new(southWest, northEast: TLatLngLiteral); overload;
+      constructor new(southWest, northEast: TLatLngTuple); overload;
+      constructor new(latlngs: TLatLngBoundsLiteral); overload;
+
+      function extend(latlngOrBounds: TLatLng): TLatLngBounds; overload;
+      function extend(latlngOrBounds: TLatLngLiteral): TLatLngBounds; overload;
+      function extend(latlngOrBounds: TLatLngTuple): TLatLngBounds; overload;
+      function extend(latlngOrBounds: TLatLngBounds): TLatLngBounds; overload;
+      function extend(latlngOrBounds: TLatLngBoundsLiteral): TLatLngBounds; overload;
+      function pad(bufferRatio: Double): TLatLngBounds; // does this modify the current instance or does it return a new one?
+      function getCenter(): TLatLng;
+      function getSouthWest(): TLatLng;
+      function getNorthEast(): TLatLng;
+      function getNorthWest(): TLatLng;
+      function getSouthEast(): TLatLng;
+      function getWest(): Double;
+      function getSouth(): Double;
+      function getEast(): Double;
+      function getNorth(): Double;
+      function contains(otherBoundsOrLatLng: TLatLngBounds): Boolean; overload;
+      function contains(otherBoundsOrLatLng: TLatLngBoundsLiteral): Boolean; overload;
+      function contains(otherBoundsOrLatLng: TLatLng): Boolean; overload;
+      function contains(otherBoundsOrLatLng: TLatLngLiteral): Boolean; overload;
+      function contains(otherBoundsOrLatLng: TLatLngTuple): Boolean; overload;
+      function intersects(otherBounds: TLatLngBounds): Boolean; overload;
+      function intersects(otherBounds: TLatLngBoundsLiteral): Boolean; overload;
+      function overlaps(otherBounds: TLatLngBounds): Boolean; overload;
+      function overlaps(otherBounds: TLatLngBoundsLiteral): Boolean; overload;
+      function toBBoxString(): String;
+      function equals(otherBounds: TLatLngBounds): Boolean; overload;
+      function equals(otherBounds: TLatLngBoundsLiteral): Boolean; overload;
+      function isValid(): Boolean;
+    end;
+
+    TPoint = class external name 'TPoint'
+    public
+      x: Double;
+      y: Double;
+
+      constructor new(x, y: Double); overload;
+      constructor new(x, y: Double; round: Boolean); overload;
+      function clone(): TPoint;
+      function add(otherPoint: TPoint): TPoint; overload;
+      function add(otherPoint: TPointTuple): TPoint; overload;
+      function subtract(otherPoint: TPoint): TPoint; overload;
+      function subtract(otherPoint: TPointTuple): TPoint; overload;
+      function divideBy(num: Double): TPoint;
+      function multiplyBy(num: Double): TPoint;
+      function scaleBy(scale: TPoint): TPoint; overload;
+      function scaleBy(scale: TPointTuple): TPoint; overload;
+      function unscaleBy(scale: TPoint): TPoint; overload;
+      function unscaleBy(scale: TPointTuple): TPoint; overload;
+      function round(): TPoint;
+      function floor(): TPoint;
+      function ceil(): TPoint;
+      function distanceTo(otherPoint: TPoint): Double; overload;
+      function distanceTo(otherPoint: TPointTuple): Double; overload;
+      function equals(otherPoint: TPoint): Boolean; overload;
+      function equals(otherPoint: TPointTuple): Boolean; overload;
+      function contains(otherPoint: TPoint): Boolean; overload;
+      function contains(otherPoint: TPointTuple): Boolean; overload;
+      function toString(): String;
+    end;
+
+    TCoords = class external name 'Coords' (TPoint)
+    public
+      z: Double;
+    end;
+
+    TBounds = class external name 'Bounds'
+    public
+      min: TPoint;
+      max: TPoint;
+
+      constructor new(points: TArray<TPoint>); overload;
+      constructor new(points: TBoundsLiteral); overload;
+      constructor new(topLeft, bottomRight: TPoint); overload;
+      constructor new(topLeft, bottomRight: TPointTuple); overload;
+      function extend(point: TPoint): TBounds; overload;
+      function extend(point: TPointTuple): TBounds; overload;
+      function getCenter(round: Boolean): TPoint;
+      function getBottomLeft(): TPoint;
+      function getBottomRight(): TPoint;
+      function getTopLeft(): TPoint;
+      function getTopRight(): TPoint;
+      function getSize(): TPoint;
+      function contains(pointOrBounds: TBounds): Boolean; overload;
+      function contains(pointOrBounds: TBoundsLiteral): Boolean; overload;
+      function contains(pointOrBounds: TPoint): Boolean; overload;
+      function contains(pointOrBounds: TPointTuple): Boolean; overload;
+      function intersects(otherBounds: TBounds): Boolean; overload;
+      function intersects(otherBounds: TBoundsLiteral): Boolean; overload;
+      function overlaps(otherBounds: TBounds): Boolean; overload;
+      function overlaps(otherBounds: TBoundsLiteral): Boolean; overload;
+    end;
+
+    // Event handler types
+    TDragEndEventHandlerFn = TProc<TDragEndEvent>;
+    TErrorEventHandlerFn = TProc<TErrorEvent>;
+    TLayerEventHandlerFn = TProc<TLayerEvent>;
+    TLayersControlEventHandlerFn = TProc<TLayersControlEvent>;
+    TLeafletEventHandlerFn = TProc<TLeafletEvent>;
+    TLeafletKeyboardEventHandlerFn = TProc<TLeafletKeyboardEvent>;
+    TLeafletMouseEventHandlerFn = TProc<TLeafletMouseEvent>;
+    TLocationEventHandlerFn = TProc<TLocationEvent>;
+    TPopupEventHandlerFn = TProc<TPopupEvent>;
+    TResizeEventHandlerFn = TProc<TResizeEvent>;
+    TTileErrorEventHandlerFn = TProc<TTileErrorEvent>;
+    TTileEventHandlerFn = TProc<TTileEvent>;
+    TTooltipEventHandlerFn = TProc<TTooltipEvent>;
+    TZoomAnimEventHandlerFn = TProc<TZoomAnimEvent>;
+
+    TLeafletEventHandlerFnMap = class external name 'LeafletEventHandlerFnMap'
+    public
+      baselayerchange: TLayersControlEventHandlerFn;
+      overlayadd: TLayersControlEventHandlerFn;
+      overlayremove: TLayersControlEventHandlerFn;
+
+      layeradd: TLayerEventHandlerFn;
+      layerremove: TLayerEventHandlerFn;
+
+      zoomlevelschange: TLeafletEventHandlerFn;
+      unload: TLeafletEventHandlerFn;
+      viewreset: TLeafletEventHandlerFn;
+      load: TLeafletEventHandlerFn;
+      zoomstart: TLeafletEventHandlerFn;
+      movestart: TLeafletEventHandlerFn;
+      zoom: TLeafletEventHandlerFn;
+      move: TLeafletEventHandlerFn;
+      zoomend: TLeafletEventHandlerFn;
+      moveend: TLeafletEventHandlerFn;
+      autopanstart: TLeafletEventHandlerFn;
+      dragstart: TLeafletEventHandlerFn;
+      drag: TLeafletEventHandlerFn;
+      add: TLeafletEventHandlerFn;
+      remove: TLeafletEventHandlerFn;
+      loading: TLeafletEventHandlerFn;
+      error: TLeafletEventHandlerFn;
+      update: TLeafletEventHandlerFn;
+      down: TLeafletEventHandlerFn;
+      predrag: TLeafletEventHandlerFn;
+
+      resize: TResizeEventHandlerFn;
+
+      popupopen: TPopupEventHandlerFn;
+      popupclose: TPopupEventHandlerFn;
+
+      tooltipopen: TTooltipEventHandlerFn;
+      tooltipclose: TTooltipEventHandlerFn;
+
+      locationerror: TErrorEventHandlerFn;
+
+      locationfound: TLocationEventHandlerFn;
+
+      click: TLeafletMouseEventHandlerFn;
+      dblclick: TLeafletMouseEventHandlerFn;
+      mousedown: TLeafletMouseEventHandlerFn;
+      mouseup: TLeafletMouseEventHandlerFn;
+      mouseover: TLeafletMouseEventHandlerFn;
+      mouseout: TLeafletMouseEventHandlerFn;
+      mousemove: TLeafletMouseEventHandlerFn;
+      contextmenu: TLeafletMouseEventHandlerFn;
+      preclick: TLeafletMouseEventHandlerFn;
+
+      keypress: TLeafletKeyboardEventHandlerFn;
+      keydown: TLeafletKeyboardEventHandlerFn;
+      keyup: TLeafletKeyboardEventHandlerFn;
+
+      zoomanim: TZoomAnimEventHandlerFn;
+
+      dragend: TDragEndEventHandlerFn;
+
+      tileunload: TTileEventHandlerFn;
+      tileloadstart: TTileEventHandlerFn;
+      tileload: TTileEventHandlerFn;
+
+      tileerror: TTileErrorEventHandlerFn;
+    end;
+
+    TEvented = class external name 'Evented' (TClass)
+    public
+      function addEventListener(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TTileErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function addEventListener(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function addEventParent(obj: TEvented): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TTileErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function addOneTimeEventListener(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function clearAllEventListeners(): TEvented; overload;
+      function fire(&type: String; data: JSValue): TEvented; overload;
+      function fire(&type: String; data: JSValue; propagate: Boolean): TEvented; overload;
+      function fireEvent(&type: String; data: JSValue): TEvented; overload;
+      function fireEvent(&type: String; data: JSValue; propagate: Boolean): TEvented; overload;
+      function hasEventListeners(&type: String): Boolean;
+      function listens(&type: String): Boolean; overload;
+      function off(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TTileErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function off(): TEvented; overload;
+      function off(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function &on(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TTileErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function &on(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function once(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function once(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function removeEventListener(&type: String; fn: TDragEndEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLayerEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLayersControlEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLeafletEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLeafletKeyboardEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLeafletMouseEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TLocationEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TPopupEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TResizeEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TTileErrorEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TTileEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TTooltipEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(&type: String; fn: TZoomAnimEventHandlerFn; context: JSValue): TEvented; overload;
+      function removeEventListener(eventMap: TLeafletEventHandlerFnMap): TEvented; overload;
+      function removeEventParent(obj: TEvented): TEvented; overload;
+    end;
+
+    TDraggable = class external name 'Draggable' (TEvented)
+    public
+      constructor new(element, dragStartTarget: TJSHTMLElement; preventOutline: Boolean);
+
+      procedure enable();
+      procedure disable();
+      procedure finishDrag();
+    end;
+
+    TLayer = class external name 'Layer' (TEvented)
+    public
+      constructor new(options: TLayerOptions);
+
+      function addTo(map: TMap): TLayer; overload;
+      function addTo(map: TLayerGroup): TLayer; overload;
+      function remove(): TLayer;
+      function removeFrom(map: TMap): TLayer;
+      function getPane(name: String): TJSHTMLElement;
+
+      // Popup methods
+      function bindPopup(content: TFunc<TLayer, String>; options: TPopupOptions): TLayer; overload;
+      function bindPopup(content: TFunc<TLayer, TJSHTMLElement>; options: TPopupOptions): TLayer; overload;
+      function bindPopup(content: String; options: TPopupOptions): TLayer; overload;
+      function bindPopup(content: TJSHTMLElement; options: TPopupOptions): TLayer; overload;
+      function bindPopup(content: TPopup; options: TPopupOptions): TLayer; overload;
+      function unbindPopup(): TLayer;
+      function openPopup(latlng: TLatLng): TLayer; overload;
+      function openPopup(latlng: TLatLngLiteral): TLayer; overload;
+      function openPopup(latlng: TLatLngTuple): TLayer; overload;
+      function closePopup(): TLayer;
+      function togglePopup(): TLayer;
+      function isPopupOpen(): Boolean;
+      function setPopupContent(content: String): TLayer; overload;
+      function setPopupContent(content: TJSHTMLElement): TLayer; overload;
+      function setPopupContent(content: TPopup): TLayer; overload;
+      function getPopup(): TPopup;
+
+      // Tooltip methods
+      function bindTooltip(content: TFunc<TLayer, String>; options: TTooltipOptions): TLayer; overload;
+      function bindTooltip(content: TFunc<TLayer, TJSHTMLElement>; options: TTooltipOptions): TLayer; overload;
+      function bindTooltip(content: TTooltip; options: TTooltipOptions): TLayer; overload;
+      function bindTooltip(content: String; options: TTooltipOptions): TLayer; overload;
+      function bindTooltip(content: TJSHTMLElement; options: TTooltipOptions): TLayer; overload;
+      function unbindTooltip(): TLayer;
+      function openTooltip(latlng: TLatLng): TLayer; overload;
+      function openTooltip(latlng: TLatLngLiteral): TLayer; overload;
+      function openTooltip(latlng: TLatLngTuple): TLayer; overload;
+      function closeTooltip(): TLayer;
+      function toggleTooltip(): TLayer;
+      function isTooltipOpen(): Boolean;
+      function setTooltipContent(content: String): TLayer; overload;
+      function setTooltipContent(content: TJSHTMLElement): TLayer; overload;
+      function setTooltipContent(content: TTooltip): TLayer; overload;
+      function getTooltip(): TTooltip;
+
+      // Extension methods
+      function onAdd(map: TMap): TLayer;
+      function onRemove(map: TMap): TLayer;
+      function getEvents(): TJSObject;
+      function getAttribution(): String;
+      function beforeAdd(map: TMap): TLayer;
+    end;
+
+    TDoneCallback = TProc<TError, TJSHTMLElement>;
+
+    TGridLayer = class external name 'GridLayer' (TLayer)
+    public
+      constructor new(options: TGridLayerOptions);
+      function bringToFront(): TGridLayer;
+      function bringToBack(): TGridLayer;
+      function getContainer(): TJSHTMLElement;
+      function setOpacity(opacity: Double): TGridLayer;
+      function setZIndex(zIndex: Double): TGridLayer;
+      function isLoading(): Boolean;
+      function redraw(): TGridLayer;
+      function getTileSize(): TPoint;
+    end;
+
+    TTileLayer = class external name 'TileLayer' (TGridLayer)
+    public type
+      TWMS = class external name 'WMS' (TTileLayer)
+      public
+        wmsParams: TWMSParams;
+        options: TWMSOptions;
+
+        constructor new(baseUrl: String; options: TWMSOptions);
+        function setParams(params: TWMSParams; noRedraw: Boolean): TWMS;
+      end;
+    public
+      options: TTileLayerOptions;
+
+      constructor new(urlTemplate: String; options: TTileLayerOptions);
+      function setUrl(url: String; noRedraw: Boolean): TTileLayer;
+      function getTileUrl(coords: TCoords): String;
+      function wms(baseUrl: String; options: TWMSOptions): TWMS;
+    end;
+
+    TImageOverlay = class external name 'ImageOverlay' (TLayer)
+    public
+      options: TImageOverlayOptions;
+
+      constructor new(imageUrl: String; bounds: TLatLngBounds; options: TImageOverlayOptions); overload;
+      constructor new(imageUrl: String; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions); overload;
+      function setOpacity(opacity: Double): TImageOverlay;
+      function bringToFront(): TImageOverlay;
+      function bringToBack(): TImageOverlay;
+      function setUrl(url: String): TImageOverlay;
+
+      function setBounds(bounds: TLatLngBounds): TImageOverlay;
+
+      function setZIndex(value: Double): TImageOverlay;
+
+      function getBounds(): TLatLngBounds;
+
+      function getElement(): TJSHTMLImageElement;
+    end;
+
+    TSVGOverlay = class external name 'SVGOverlay' (TLayer)
+    public
+      options: TImageOverlayOptions;
+
+      constructor new(svgImage: String; bounds: TLatLngBounds; options: TImageOverlayOptions); overload;
+      constructor new(svgImage: String; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions); overload;
+      constructor new(svgImage: TJSHTMLElement; bounds: TLatLngBounds; options: TImageOverlayOptions); overload;
+      constructor new(svgImage: TJSHTMLElement; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions); overload;
+
+      function setOpacity(opacity: Double): TSVGOverlay;
+      function bringToFront(): TSVGOverlay;
+      function bringToBack(): TSVGOverlay;
+      function setUrl(url: String): TSVGOverlay;
+
+      function setBounds(bounds: TLatLngBounds): TSVGOverlay;
+
+      function setZIndex(value: Double): TSVGOverlay;
+
+      function getBounds(): TLatLngBounds;
+
+      function getElement(): TJSHTMLElement;
+    end;
+
+    TVideoOverlay = class external name 'VideoOverlay' (TLayer)
+    public
+      options: TVideoOverlayOptions;
+
+      constructor new(video: String; bounds: TLatLngBounds; options: TVideoOverlayOptions); overload;
+      constructor new(video: String; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions); overload;
+      constructor new(video: TArray<String>; bounds: TLatLngBounds; options: TVideoOverlayOptions); overload;
+      constructor new(video: TArray<String>; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions); overload;
+      constructor new(video: TJSHTMLVideoElement; bounds: TLatLngBounds; options: TVideoOverlayOptions); overload;
+      constructor new(video: TJSHTMLVideoElement; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions); overload;
+
+      function setOpacity(opacity: Double): TVideoOverlay;
+      function bringToFront(): TVideoOverlay;
+      function bringToBack(): TVideoOverlay;
+      function setUrl(url: String): TVideoOverlay;
+
+      function setBounds(bounds: TLatLngBounds): TVideoOverlay;
+
+      function getBounds(): TLatLngBounds;
+
+      function getElement(): TJSHTMLVideoElement;
+    end;
+
+    TPath = class external name 'Path' abstract (TLayer)
+    public
+      options: TPathOptions;
+
+      function redraw(): TPath;
+      function setStyle(style: TPathOptions): TPath;
+      function bringToFront(): TPath;
+      function bringToBack(): TPath;
+      function getElement(): TJSHTMLElement;
+    end;
+
+    TPolyline = class external name 'Polyline' (TPath)
+    public
+      feature: TFeature;
+      options: TPolylineOptions;
+
+      constructor new(latlngs: TArray<TLatLng>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TArray<TLatLng>>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TLatLngLiteral>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TArray<TLatLngLiteral>>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TLatLngTuple>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TArray<TLatLngTuple>>; options: TPolylineOptions); overload;
+
+      function toGeoJSON(precision: Double): TFeature;
+      function getLatLngs(): JSValue;
+      function setLatLngs(latlngs: TArray<TLatLng>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TLatLngLiteral>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TLatLngTuple>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TLatLng>>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TLatLngLiteral>>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TLatLngTuple>>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TArray<TLatLng>>>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TArray<TLatLngLiteral>>>): TPolyline; overload;
+      function setLatLngs(latlngs: TArray<TArray<TArray<TLatLngTuple>>>): TPolyline; overload;
+      function isEmpty(): Boolean;
+      function getCenter(): TLatLng;
+      function getBounds(): TLatLngBounds;
+      function addLatLng(latlng: TLatLng): TPolyline; overload;
+      function addLatLng(latlng: TLatLngLiteral): TPolyline; overload;
+      function addLatLng(latlng: TLatLngTuple): TPolyline; overload;
+      function addLatLng(latlng: TLatLng; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TLatLngLiteral; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TLatLngTuple; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLngLiteral>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLngTuple>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLng>; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLngLiteral>; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function addLatLng(latlng: TArray<TLatLngTuple>; latlngs: TArray<TLatLng>): TPolyline; overload;
+      function closestLayerPoint(p: TPoint): TPoint;
+    end;
+
+    TPolygon = class external name 'Polygon' (TPolyline)
+    public
+      constructor new(latlngs: TArray<TLatLng>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TArray<TLatLng>>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TLatLngLiteral>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TArray<TLatLngLiteral>>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TLatLngTuple>; options: TPolylineOptions); overload;
+      constructor new(latlngs: TArray<TArray<TLatLngTuple>>; options: TPolylineOptions); overload;
+    end;
+
+    TRectangle = class external name 'Rectangle' (TPolygon)
+    public
+      constructor new(latLngBounds: TLatLngBounds; options: TPolylineOptions); overload;
+      constructor new(latLngBounds: TLatLngBoundsLiteral; options: TPolylineOptions); overload;
+
+      function setBounds(latLngBounds: TLatLngBounds): TRectangle; overload;
+      function setBounds(latLngBounds: TLatLngBoundsLiteral): TRectangle; overload;
+    end;
+
+    TCircleMarker = class external name 'CircleMarker' (TPath)
+    public
+      options: TCircleMarkerOptions;
+      feature: TFeature;
+
+      constructor new(latlng: TLatLng; options: TCircleMarkerOptions); overload;
+      constructor new(latlng: TLatLngLiteral; options: TCircleMarkerOptions); overload;
+      constructor new(latlng: TLatLngTuple; options: TCircleMarkerOptions); overload;
+
+      function toGeoJSON(precision: Double): TFeature;
+      function setLatLng(latLng: JSValue): TCircleMarker;
+      function getLatLng(): TLatLng;
+      function setRadius(radius: Double): TCircleMarker;
+      function getRadius(): Double;
+    end;
+
+    TCircle = class external name 'Circle' (TCircleMarker)
+    public
+      constructor new(latlng: TLatLng; options: TCircleMarkerOptions); overload;
+      constructor new(latlng: TLatLngLiteral; options: TCircleMarkerOptions); overload;
+      constructor new(latlng: TLatLngTuple; options: TCircleMarkerOptions); overload;
+
+      function getBounds(): TLatLngBounds;
+    end;
+
+    TRenderer = class external name 'Renderer' (TLayer)
+    public
+      options: TRendererOptions;
+
+      constructor new(options: TRendererOptions);
+    end;
+
+    TSVG = class external name 'SVG' (TRenderer)
+    public
+      class function create(name: String): TJSHTMLElement;
+      class function pointsToPath(rings: TPoint; close: Boolean): String; overload;
+      class function pointsToPath(rings: TArray<TPointTuple>; close: Boolean): String; overload;
+    end;
+
+    TCanvas = class external name 'Canvas' (TRenderer)
+    end;
+
+    TLayerGroup = class external name 'LayerGroup' (TLayer)
+    public
+      feature: JSValue;
+
+      constructor new(layers: TArray<TLayer>); overload;
+      constructor new(layers: TArray<TLayer>; options: TLayerOptions); overload;
+      constructor new; overload;
+
+      function addLayer(layer: TLayer): TLayerGroup;
+      function clearLayers(): TLayerGroup;
+      function eachLayer(fn: TProc<TLayer>; context: JSValue): TLayerGroup;
+      function getLayer(id: Double): TLayer;
+      function getLayerId(layer: TLayer): Double;
+      function getLayers(): TArray<TLayer>;
+      function hasLayer(layer: TLayer): Boolean;
+      function invoke(methodName: String): TLayerGroup; varargs;
+      function removeLayer(layer: TLayer): TLayerGroup;
+      function setZIndex(zIndex: Double): TLayerGroup;
+      function toGeoJSON(precision: Double): JSValue; overload;
+      function toGeoJSON: JSValue; overload;
+    end;
+
+    TFeatureGroup = class external name 'FeatureGroup' (TLayerGroup)
+    public
+      function bringToBack(): TFeatureGroup;
+      function bringToFront(): TFeatureGroup;
+      function getBounds(): TLatLngBounds;
+      function setStyle(style: TPathOptions): TFeatureGroup;
+    end;
+
+    TStyleFunction = TFunc<TFeature, TPathOptions>;
+
+    TGeoJSON = class external name 'GeoJSON' (TFeatureGroup)
+    public
+      options: TGeoJSONOptions;
+
+      constructor new(geojson: TGeoJsonObject; options: TGeoJSONOptions);
+
+      class function asFeature(geojson: TFeature): TFeature;
+      class function coordsToLatLng(coords: TArray<Double>): TLatLng;
+      class function coordsToLatLngs(coords: TArray<JSValue>; levelsDeep: Double; coordsToLatLng: TFunc<TArray<Double>, TLatLng>): TArray<JSValue>; // Using TArray<JSValue> to avoid artificially limiting valid calls
+      class function geometryToLayer(featureData: TFeature; options: TGeoJSONOptions): TLayer;
+      class function latLngToCoords(latlng: TLatLng): TArray<Double>;
+      class function latLngsToCoords(latlngs: TArray<JSValue>; levelsDeep: Double; closed: Boolean): TArray<JSValue>;  // Using TArray<JSValue> to avoid artificially limiting valid calls
+
+      function addData(data: TGeoJsonObject): TLayer;
+      function resetStyle(layer: TLayer): TLayer;
+      function setStyle(style: TPathOptions): TGeoJSON; overload;
+      function setStyle(style: TStyleFunction): TGeoJSON; overload;
+    end;
+
+    TControl = class external name 'Control' (TClass)
+    public type
+      TZoom = class external name 'Zoom' (TControl)
+      public
+        options: TZoomControlOptions;
+        constructor new(options: TZoomControlOptions);
+      end;
+
+      TAttribution = class external name 'Attribution' (TControl)
+      public
+        options: TAttributionOptions;
+
+        constructor new(options: TAttributionOptions);
+        function setPrefix(prefix: String): TAttribution;
+        function addAttribution(text: String): TAttribution;
+        function removeAttribution(text: String): TAttribution;
+      end;
+
+      TLayers = class external name 'Layers' (TControl)
+      public
+        options: TLayersOptions;
+
+        constructor new; overload;
+        constructor new(baseLayers: TLayersObject); overload;
+        constructor new(baseLayers, overlays: TLayersObject); overload;
+        constructor new(baseLayers, overlays: TLayersObject; options: TLayersOptions); overload;
+
+        function addBaseLayer(layer: TLayer; name: String): TLayers;
+        function addOverlay(layer: TLayer; name: String): TLayers;
+        function removeLayer(layer: TLayer): TLayers;
+        function expand(): TLayers;
+        function collapse(): TLayers;
+      end;
+
+      TScale = class external name 'Scale' (TControl)
+      public
+        options: TScaleOptions;
+        constructor new(options: TScaleOptions);
+      end;
+    public
+      // Extension methods
+      onAdd: TFunc<TMap, TJSHTMLElement>;
+      onRemove: TProc<TMap>;
+      options: TControlOptions;
+
+      constructor new(options: TControlOptions);
+      function getPosition(): String;
+      function setPosition(position: String): TControl;
+      function getContainer(): TJSHTMLElement;
+      function addTo(map: TMap): TControl;
+      function remove(): TControl;
+      function zoom(options: TZoomControlOptions): TZoom;
+      function attribution(options: TAttributionOptions): TAttribution;
+      function layers(baseLayers, overlays: TLayersObject; options: TLayersOptions): TLayers;
+      function scale(options: TScaleOptions): TScale;
+    end;
+
+    TDivOverlay = class external name 'DivOverlay' abstract (TLayer)
+    public
+      options: TDivOverlayOptions;
+
+      constructor new; overload;
+      constructor new(options: TDivOverlayOptions); overload;
+      constructor new(options: TDivOverlayOptions; source: TLayer); overload;
+      function getLatLng(): TLatLng;
+      function setLatLng(latlng: TLatLng): TDivOverlay; overload;
+      function setLatLng(latlng: TLatLngLiteral): TDivOverlay; overload;
+      function setLatLng(latlng: TLatLngTuple): TDivOverlay; overload;
+      function getContent(): JSValue;
+      function setContent(htmlContent: TFunc<TLayer, String>): TDivOverlay; overload;
+      function setContent(htmlContent: TFunc<TLayer, TJSHTMLElement>): TDivOverlay; overload;
+      function setContent(htmlContent: String): TDivOverlay; overload;
+      function setContent(htmlContent: TJSHTMLElement): TDivOverlay; overload;
+      function getElement(): TJSHTMLElement;
+      procedure update();
+      function isOpen(): Boolean;
+      function bringToFront(): TDivOverlay;
+      function bringToBack(): TDivOverlay;
+    end;
+
+    TPopup = class external name 'Popup' (TDivOverlay)
+    public
+      options: TPopupOptions;
+
+      constructor new; overload;
+      constructor new(options: TPopupOptions); overload;
+      constructor new(options: TPopupOptions; source: TLayer); overload;
+      function openOn(map: TMap): TPopup;
+    end;
+
+    TTooltip = class external name 'Tooltip' (TDivOverlay)
+    public
+      options: TTooltipOptions;
+
+      constructor new; overload;
+      constructor new(options: TTooltipOptions); overload;
+      constructor new(options: TTooltipOptions; source: TLayer); overload;
+
+      procedure setOpacity(val: Double);
+    end;
+
+    THandler = class external name 'Handler' (TClass)
+    public
+      // Extension methods
+      addHooks: TProc;
+      removeHooks: TProc;
+
+      constructor new(map: TMap);
+
+      function disable(): THandler;
+      function enable(): THandler;
+      function enabled(): Boolean;
+    end;
+
+    THandlerClass = class of THandler;
+
+    TDomEvent = class external name 'DomEvent'
+    public type
+      TEventHandlerFn = TProc<TLeafletEvent>;
+    public
+      function addListener(el: TJSHTMLElement; types: String; fn: TEventHandlerFn; context: JSValue): TDomEvent;
+      function disableClickPropagation(el: TJSHTMLElement): TDomEvent;
+      function disableScrollPropagation(el: TJSHTMLElement): TDomEvent;
+      function getMousePosition(ev: TLeafletMouseEvent; container: TJSHTMLElement): TPoint;
+      function getWheelDelta(ev: TLeafletEvent): Double;
+      function off(el: TJSHTMLElement; types: String; fn: TEventHandlerFn; context: JSValue): TDomEvent;
+      function &on(el: TJSHTMLElement; types: String; fn: TEventHandlerFn; context: JSValue): TDomEvent;
+      function preventDefault(ev: TLeafletEvent): TDomEvent;
+      function removeListener(el: TJSHTMLElement; types: String; fn: TEventHandlerFn; context: JSValue): TDomEvent;
+      function stop(ev: TLeafletEvent): TDomEvent;
+      function stopPropagation(ev: TLeafletEvent): TDomEvent;
+    end;
+
+    TMap = class external name 'Map' (TEvented)
+    public
+      // Properties
+      attributionControl: TLeaflet.TControl.TAttribution;
+      boxZoom: THandler;
+      doubleClickZoom: THandler;
+      dragging: THandler;
+      keyboard: THandler;
+      scrollWheelZoom: THandler;
+      tap: THandler;
+      touchZoom: THandler;
+      zoomControl: TControl.TZoom;
+
+      options: TMapOptions;
+
+      constructor new(element: String); overload;
+      constructor new(element: String; options: TMapOptions); overload;
+      constructor new(element: TJSHTMLElement); overload;
+      constructor new(element: TJSHTMLElement; options: TMapOptions); overload;
+
+      function getRenderer(layer: TPath): TRenderer;
+
+      // Methods for layers and controls
+      function addControl(control: TControl): TMap;
+      function addLayer(layer: TLayer): TMap;
+      function closePopup(popup: TPopup): TMap;
+      function closeTooltip(tooltip: TTooltip): TMap;
+      function eachLayer(fn: TProc<TLayer>; context: JSValue): TMap;
+      function hasLayer(layer: TLayer): Boolean;
+      function openPopup(content: String; latlng: TLatLng; options: TPopupOptions): TMap; overload;
+      function openPopup(content: String; latlng: TLatLngLiteral; options: TPopupOptions): TMap; overload;
+      function openPopup(content: String; latlng: TLatLngTuple; options: TPopupOptions): TMap; overload;
+      function openPopup(content: TJSHTMLElement; latlng: TLatLng; options: TPopupOptions): TMap; overload;
+      function openPopup(content: TJSHTMLElement; latlng: TLatLngLiteral; options: TPopupOptions): TMap; overload;
+      function openPopup(content: TJSHTMLElement; latlng: TLatLngTuple; options: TPopupOptions): TMap; overload;
+      function openPopup(popup: TPopup): TMap; overload;
+      function openTooltip(content: String; latlng: TLatLng; options: TTooltipOptions): TMap; overload;
+      function openTooltip(content: String; latlng: TLatLngLiteral; options: TTooltipOptions): TMap; overload;
+      function openTooltip(content: String; latlng: TLatLngTuple; options: TTooltipOptions): TMap; overload;
+      function openTooltip(content: TJSHTMLElement; latlng: TLatLng; options: TTooltipOptions): TMap; overload;
+      function openTooltip(content: TJSHTMLElement; latlng: TLatLngLiteral; options: TTooltipOptions): TMap; overload;
+      function openTooltip(content: TJSHTMLElement; latlng: TLatLngTuple; options: TTooltipOptions): TMap; overload;
+      function openTooltip(tooltip: TTooltip): TMap; overload;
+      function removeControl(control: TControl): TMap;
+      function removeLayer(layer: TLayer): TMap;
+
+      // Methods for modifying map state
+      function fitBounds(bounds: TLatLngBounds; options: TFitBoundsOptions): TMap; overload;
+      function fitBounds(bounds: TLatLngBoundsLiteral; options: TFitBoundsOptions): TMap; overload;
+      function fitWorld(options: TFitBoundsOptions): TMap;
+      function flyTo(latlng: TLatLng; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function flyTo(latlng: TLatLngLiteral; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function flyTo(latlng: TLatLngTuple; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function flyToBounds(bounds: TLatLngBounds): TMap; overload;
+      function flyToBounds(bounds: TLatLngBounds; options: TFitBoundsOptions): TMap; overload;
+      function flyToBounds(bounds: TLatLngBoundsLiteral): TMap; overload;
+      function flyToBounds(bounds: TLatLngBoundsLiteral; options: TFitBoundsOptions): TMap; overload;
+      function invalidateSize(options: Boolean): TMap; overload;
+      function invalidateSize(options: TInvalidateSizeOptions): TMap; overload;
+      function panBy(offset: TPoint; options: TPanOptions): TMap; overload;
+      function panBy(offset: TPointTuple; options: TPanOptions): TMap; overload;
+      function panInside(latLng: JSValue; options: TPanInsideOptions): TMap;
+      function panInsideBounds(bounds: TLatLngBounds; options: TPanOptions): TMap; overload;
+      function panInsideBounds(bounds: TLatLngBoundsLiteral; options: TPanOptions): TMap; overload;
+      function panTo(latlng: TLatLng; options: TPanOptions): TMap; overload;
+      function panTo(latlng: TLatLngLiteral; options: TPanOptions): TMap; overload;
+      function panTo(latlng: TLatLngTuple; options: TPanOptions): TMap; overload;
+      function setMaxBounds(bounds: TLatLngBounds): TMap; overload;
+      function setMaxBounds(bounds: TLatLngBoundsLiteral): TMap; overload;
+      function setMaxZoom(zoom: Double): TMap;
+      function setMinZoom(zoom: Double): TMap;
+      function setView(center: TLatLngLiteral; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function setView(center: TLatLngTuple; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function setView(center: TLatLng; zoom: Double; options: TZoomPanOptions): TMap; overload;
+      function setZoom(zoom: Double; options: TZoomPanOptions): TMap;
+      function setZoomAround(position: TLatLng; zoom: Double; options: TZoomOptions): TMap; overload;
+      function setZoomAround(position: TLatLngLiteral; zoom: Double; options: TZoomOptions): TMap; overload;
+      function setZoomAround(position: TLatLngTuple; zoom: Double; options: TZoomOptions): TMap; overload;
+      function setZoomAround(position: TPoint; zoom: Double; options: TZoomOptions): TMap; overload;
+      function stop(): TMap;
+      function zoomIn(delta: Double; options: TZoomOptions): TMap;
+      function zoomOut(delta: Double; options: TZoomOptions): TMap;
+
+      // Other methods
+      function addHandler(name: String; HandlerClass: THandlerClass): TMap; // Alternatively; HandlerClass: new(map: TMap) => THandler
+      function createPane(name: String; container: TJSHTMLElement): TJSHTMLElement;
+      function getContainer(): TJSHTMLElement;
+      function getPane(pane: String): TJSHTMLElement; overload;
+      function getPane(pane: TJSHTMLElement): TJSHTMLElement; overload;
+      function getPanes(): TDefaultMapPanes;
+      function remove(): TMap;
+      function whenReady(fn: TProc; context: JSValue): TMap;
+
+      // Methods for getting map state
+      function getBounds(): TLatLngBounds;
+      function getBoundsZoom(bounds: TLatLngBounds; inside: Boolean; padding: TPoint): Double; overload;
+      function getBoundsZoom(bounds: TLatLngBoundsLiteral; inside: Boolean; padding: TPoint): Double; overload;
+      function getCenter(): TLatLng;
+      function getMaxZoom(): Double;
+      function getMinZoom(): Double;
+      function getPixelBounds(): TBounds;
+      function getPixelOrigin(): TPoint;
+      function getPixelWorldBounds(zoom: Double): TBounds;
+      function getSize(): TPoint;
+      function getZoom(): Double;
+
+      // Conversion methods
+      function containerPointToLatLng(point: TPoint): TLatLng; overload;
+      function containerPointToLatLng(point: TPointTuple): TLatLng; overload;
+      function containerPointToLayerPoint(point: TPoint): TPoint; overload;
+      function containerPointToLayerPoint(point: TPointTuple): TPoint; overload;
+      function distance(latlng1, latlng2: TLatLng): Double; overload;
+      function distance(latlng1, latlng2: TLatLngLiteral): Double; overload;
+      function distance(latlng1, latlng2: TLatLngTuple): Double; overload;
+      function getScaleZoom(scale: Double; fromZoom: Double): Double;
+      function getZoomScale(toZoom: Double; fromZoom: Double): Double;
+      function latLngToContainerPoint(latlng: TLatLng): TPoint; overload;
+      function latLngToContainerPoint(latlng: TLatLngLiteral): TPoint; overload;
+      function latLngToContainerPoint(latlng: TLatLngTuple): TPoint; overload;
+      function latLngToLayerPoint(latlng: TLatLng): TPoint; overload;
+      function latLngToLayerPoint(latlng: TLatLngLiteral): TPoint; overload;
+      function latLngToLayerPoint(latlng: TLatLngTuple): TPoint; overload;
+      function layerPointToContainerPoint(point: TPoint): TPoint; overload;
+      function layerPointToContainerPoint(point: TPointTuple): TPoint; overload;
+      function layerPointToLatLng(point: TPoint): TLatLng; overload;
+      function layerPointToLatLng(point: TPointTuple): TLatLng; overload;
+      function mouseEventToContainerPoint(ev: TLeafletMouseEvent): TPoint;
+      function mouseEventToLatLng(ev: TLeafletMouseEvent): TLatLng;
+      function mouseEventToLayerPoint(ev: TLeafletMouseEvent): TPoint;
+      function project(latlng: TLatLng; zoom: Double): TPoint; overload;
+      function project(latlng: TLatLngLiteral; zoom: Double): TPoint; overload;
+      function project(latlng: TLatLngTuple; zoom: Double): TPoint; overload;
+      function unproject(point: TPoint; zoom: Double): TLatLng; overload;
+      function unproject(point: TPointTuple; zoom: Double): TLatLng; overload;
+      function wrapLatLng(latlng: TLatLng): TLatLng; overload;
+      function wrapLatLng(latlng: TLatLngLiteral): TLatLng; overload;
+      function wrapLatLng(latlng: TLatLngTuple): TLatLng; overload;
+      function wrapLatLngBounds(bounds: TLatLngBounds): TLatLngBounds;
+
+      // Geolocation methods
+      function locate(options: TLocateOptions): TMap;
+      function stopLocate(): TMap;
+    end;
+
+    TIcon = class external name 'Icon'
+    public
+      options: TIconOptions;
+
+      constructor new(options: TIconOptions);
+
+      function createIcon(oldIcon: TJSHTMLElement): TJSHTMLElement;
+      function createShadow(oldIcon: TJSHTMLElement): TJSHTMLElement;
+    end;
+
+    TDefaultIcon = class external name 'Icon.Default' (TIcon)
+    public
+      constructor new; overload;
+      constructor new(options: TIconOptions); overload;
+    end;
+
+    TDivIcon = class external name 'DivIcon' (TIcon)
+    public
+      options: TDivIconOptions;
+
+      constructor new(options: TDivIconOptions);
+    end;
+
+    TMarker = class external name 'Marker' (TLayer)
+    public
+      // Properties
+      options: TMarkerOptions;
+      dragging: THandler;
+      feature: TFeature;
+
+      constructor new(latlng: TLatLng; options: TMarkerOptions); overload;
+      constructor new(latlng: TLatLngLiteral; options: TMarkerOptions); overload;
+      constructor new(latlng: TLatLngTuple; options: TMarkerOptions); overload;
+
+      function toGeoJSON(precision: Double): TFeature;
+      function getLatLng(): TLatLng;
+      function setLatLng(latlng: TLatLng): TMarker; overload;
+      function setLatLng(latlng: TLatLngLiteral): TMarker; overload;
+      function setLatLng(latlng: TLatLngTuple): TMarker; overload;
+      function setZIndexOffset(offset: Double): TMarker;
+      function getIcon(): JSValue;
+      function setIcon(icon: JSValue): TMarker;
+      function setOpacity(opacity: Double): TMarker;
+      function getElement(): TJSHTMLElement;
+    end;
+
+    TBrowser = class external name 'Browser'
+    public const
+      ie: Boolean;
+      ielt9: Boolean;
+      edge: Boolean;
+      webkit: Boolean;
+      android: Boolean;
+      android23: Boolean;
+      androidStock: Boolean;
+      opera: Boolean;
+      chrome: Boolean;
+      gecko: Boolean;
+      safari: Boolean;
+      opera12: Boolean;
+      win: Boolean;
+      ie3d: Boolean;
+      webkit3d: Boolean;
+      gecko3d: Boolean;
+      any3d: Boolean;
+      mobile: Boolean;
+      mobileWebkit: Boolean;
+      mobileWebkit3d: Boolean;
+      msPointer: Boolean;
+      pointer: Boolean;
+      touch: Boolean;
+      mobileOpera: Boolean;
+      mobileGecko: Boolean;
+      retina: Boolean;
+      canvas: Boolean;
+      svg: Boolean;
+      vml: Boolean;
+    end;
+
+    TUtil = class external name 'Util'
+    public
+      function extend(dest: JSValue): JSValue; varargs;
+
+      function stamp(obj: JSValue): Double;
+      function throttle(fn: TProc; time: Double; context: JSValue): TProc;
+      function wrapNum(num: Double; range: TArray<Double>; includeMax: Boolean): Double;
+      function falseFn(): Boolean;
+      function formatNum(num: Double; digits: Double): Double;
+      function trim(str: String): String;
+      function splitWords(str: String): TArray<String>;
+      function setOptions(obj: JSValue; options: JSValue): JSValue;
+      function getParamString(obj: JSValue; existingUrl: String; uppercase: Boolean): String;
+      function template(str: String; data: JSValue): String;
+      function isArray(obj: JSValue): Boolean;
+      function indexOf(&array: TArray<JSValue>; el: JSValue): Double;
+      function requestAnimFrame(fn: TProc<Double>; context: JSValue; immediate: Boolean): Double;
+      procedure cancelAnimFrame(id: Double);
+    end;
+  public
+    lastId: Double;
+    emptyImageUrl: String;
+
+    function bounds(topLeft, bottomRight: TPoint): TBounds; overload;
+    function bounds(topLeft, bottomRight: TPointTuple): TBounds; overload;
+    function bounds(points: TArray<TPoint>): TBounds; overload;
+    function bounds(points: TBoundsLiteral): TBounds; overload;
+    function canvas(options: TRendererOptions): TCanvas;
+    function circle(latlng: TLatLng; options: TCircleMarkerOptions): TCircle; overload;
+    function circle(latlng: TLatLngLiteral; options: TCircleMarkerOptions): TCircle; overload;
+    function circle(latlng: TLatLngTuple; options: TCircleMarkerOptions): TCircle; overload;
+    function circleMarker(latlng: TLatLng; options: TCircleMarkerOptions): TCircleMarker; overload;
+    function circleMarker(latlng: TLatLngLiteral; options: TCircleMarkerOptions): TCircleMarker; overload;
+    function circleMarker(latlng: TLatLngTuple; options: TCircleMarkerOptions): TCircleMarker; overload;
+    function divIcon(options: TDivIconOptions): TDivIcon;
+    function featureGroup(layers: TArray<TLayer>): TFeatureGroup;
+    function geoJSON(geojson: TGeoJsonObject; options: TGeoJSONOptions): TGeoJSON;
+    function gridLayer(options: TGridLayerOptions): TGridLayer;
+    function icon(options: TIconOptions): TIcon;
+    function imageOverlay(imageUrl: String; bounds: TLatLngBounds; options: TImageOverlayOptions): TImageOverlay; overload;
+    function imageOverlay(imageUrl: String; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions): TImageOverlay; overload;
+    function latLng(coords: TArray<Double>): TLatLng; overload;
+    function latLng(latitude, longitude: Double): TLatLng; overload;
+    function latLng(latitude, longitude, altitude: Double): TLatLng; overload;
+    function latLngBounds(southWest, northEast: TLatLng): TLatLngBounds; overload;
+    function latLngBounds(southWest, northEast: TLatLngLiteral): TLatLngBounds; overload;
+    function latLngBounds(southWest, northEast: TLatLngTuple): TLatLngBounds; overload;
+    function latLngBounds(latlngs: TArray<TLatLng>): TLatLngBounds; overload;
+    function latLngBounds(latlngs: TArray<TLatLngLiteral>): TLatLngBounds; overload;
+    function latLngBounds(latlngs: TArray<TLatLngTuple>): TLatLngBounds; overload;
+    function layerGroup: TLayerGroup; overload;
+    function layerGroup(layers: TArray<TLayer>): TLayerGroup; overload;
+    function layerGroup(layers: TArray<TLayer>; options: TLayerOptions): TLayerGroup; overload;
+    function map(element: String; options: TMapOptions): TMap; overload;
+    function map(element: TJSHTMLElement; options: TMapOptions): TMap; overload;
+    function marker(latlng: TLatLng; options: TMarkerOptions): TMarker; overload;
+    function marker(latlng: TLatLngLiteral; options: TMarkerOptions): TMarker; overload;
+    function marker(latlng: TLatLngTuple; options: TMarkerOptions): TMarker; overload;
+    function point(x, y: Double): TPoint; overload;
+    function point(x, y: Double; round: Boolean): TPoint; overload;
+    function point(coords: TPointTuple): TPoint; overload;
+    function polyline(latlngs: TArray<TLatLng>; options: TPolylineOptions): TPolyline; overload;
+    function polyline(latlngs: TArray<TArray<TLatLng>>; options: TPolylineOptions): TPolyline; overload;
+    function polyline(latlngs: TArray<TLatLngLiteral>; options: TPolylineOptions): TPolyline; overload;
+    function polyline(latlngs: TArray<TArray<TLatLngLiteral>>; options: TPolylineOptions): TPolyline; overload;
+    function polyline(latlngs: TArray<TLatLngTuple>; options: TPolylineOptions): TPolyline; overload;
+    function polyline(latlngs: TArray<TArray<TLatLngTuple>>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TLatLng>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TArray<TLatLng>>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TLatLngLiteral>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TArray<TLatLngLiteral>>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TLatLngTuple>; options: TPolylineOptions): TPolyline; overload;
+    function polygon(latlngs: TArray<TArray<TLatLngTuple>>; options: TPolylineOptions): TPolyline; overload;
+    function popup: TPopup; overload;
+    function popup(options: TPopupOptions): TPopup; overload;
+    function popup(options: TPopupOptions; source: TLayer): TPopup; overload;
+    function rectangle(latLngBounds: TLatLngBounds; options: TPolylineOptions): TRectangle; overload;
+    function rectangle(latLngBounds: TLatLngBoundsLiteral; options: TPolylineOptions): TRectangle; overload;
+    function svg(options: TRendererOptions): TSVG;
+    function svgOverlay(svgImage: String; bounds: TLatLngBounds; options: TImageOverlayOptions): TSVGOverlay; overload;
+    function svgOverlay(svgImage: String; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions): TSVGOverlay; overload;
+    function svgOverlay(svgImage: TJSHTMLElement; bounds: TLatLngBounds; options: TImageOverlayOptions): TSVGOverlay; overload;
+    function svgOverlay(svgImage: TJSHTMLElement; bounds: TLatLngBoundsLiteral; options: TImageOverlayOptions): TSVGOverlay; overload;
+    function tileLayer(urlTemplate: String; options: TTileLayerOptions): TTileLayer;
+    function tooltip: TTooltip; overload;
+    function tooltip(options: TTooltipOptions): TTooltip; overload;
+    function tooltip(options: TTooltipOptions; source: TLayer): TTooltip; overload;
+    function videoOverlay(video: String; bounds: TLatLngBounds; options: TVideoOverlayOptions): TVideoOverlay; overload;
+    function videoOverlay(video: String; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions): TVideoOverlay; overload;
+    function videoOverlay(video: TArray<String>; bounds: TLatLngBounds; options: TVideoOverlayOptions): TVideoOverlay; overload;
+    function videoOverlay(video: TArray<String>; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions): TVideoOverlay; overload;
+    function videoOverlay(video: TJSHTMLVideoElement; bounds: TLatLngBounds; options: TVideoOverlayOptions): TVideoOverlay; overload;
+    function videoOverlay(video: TJSHTMLVideoElement; bounds: TLatLngBoundsLiteral; options: TVideoOverlayOptions): TVideoOverlay; overload;
+  end;
+
+  TLatLngLiteral = class
+  public
+    lat: Double;
+    lng: Double;
+  end;
+
+  TLayerOptions = class
+  public
+    pane: String;
+    attribution: String;
+  end;
+
+  TInteractiveLayerOptions = class(TLayerOptions)
+  public
+    interactive: Boolean;
+    bubblingMouseEvents: Boolean;
+  end;
+
+  TGridLayerOptions = class(TLayerOptions)
+  public
+    tileSize: TPoint;
+    tileSizeNumber: Double; external name 'tileSize';
+    opacity: Double;
+    updateWhenIdle: Boolean;
+    updateWhenZooming: Boolean;
+    updateInterval: Double;
+    attribution: String;
+    zIndex: Double;
+    bounds: JSValue;
+    minZoom: Double;
+    maxZoom: Double;
+    noWrap: Boolean;
+    pane: String;
+    className: String;
+    keepBuffer: Double;
+  end;
+
+  TTileLayerOptions = class(TGridLayerOptions)
+  public
+    id: String;
+    accessToken: String;
+    minZoom: Double;
+    maxZoom: Double;
+    maxNativeZoom: Double;
+    minNativeZoom: Double;
+    subdomains: TArray<String>;
+    errorTileUrl: String;
+    zoomOffset: Double;
+    tms: Boolean;
+    zoomReverse: Boolean;
+    detectRetina: Boolean;
+    crossOrigin: String;
+  end;
+
+  TWMSOptions = class(TTileLayerOptions)
+  public
+    layers: String;
+    styles: String;
+    format: String;
+    transparent: Boolean;
+    version: String;
+    crs: TLeaflet.TCRS;
+    uppercase: Boolean;
+  end;
+
+  TWMSParams = class
+  public
+    format: String;
+    layers: String;
+    request: String;
+    service: String;
+    styles: String;
+    version: String;
+    transparent: Boolean;
+    width: Double;
+    height: Double;
+  end;
+
+  TImageOverlayOptions = class(TInteractiveLayerOptions)
+  public
+    opacity: Double;
+    alt: String;
+    interactive: Boolean;
+    attribution: String;
+    crossOrigin: String;
+    errorOverlayUrl: String;
+    zIndex: Double;
+    className: String;
+  end;
+
+  TVideoOverlayOptions = class(TImageOverlayOptions)
+  public
+    autoplay: Boolean;
+    loop: Boolean;
+    keepAspectRatio: Boolean;
+  end;
+
+  TPathOptions = class(TInteractiveLayerOptions)
+  public
+    stroke: Boolean;
+    color: String;
+    weight: Double;
+    opacity: Double;
+    lineCap: String;
+    lineJoin: String;
+    dashArray: TArray<Double>;
+    dashOffset: String;
+    fill: Boolean;
+    fillColor: String;
+    fillOpacity: Double;
+    fillRule: String;
+    renderer: TLeaflet.TRenderer;
+    className: String;
+  end;
+
+  TPolylineOptions = class(TPathOptions)
+  public
+    smoothFactor: Double;
+    noClip: Boolean;
+  end;
+
+  TCircleMarkerOptions = class(TPathOptions)
+  public
+    radius: Double;
+  end;
+
+  TRendererOptions = class (TLayerOptions)
+  public
+    padding: Double;
+    tolerance: Double;
+  end;
+
+  TGeoJSONOptions = class(TInteractiveLayerOptions)
+  public
+    coordsToLatLng: TFunc<TArray<Double>, TLeaflet.TLatLng>;
+    filter: TFunc<TFeature, Boolean>;
+    onEachFeature: TProc<TFeature, TLeaflet.TLayer>;
+    pointToLayer: TFunc<TFeature, TLeaflet.TLatLng, TLeaflet.TLayer>;
+    style: TPathOptions;
+    styleFunction: TLeaflet.TStyleFunction; external name 'style';
+  end;
+
+  TMapOptions = class
+  private
+    FCRS: TLeaflet.TCRS; external name 'crs';
+
+    function GetCRS: TLeaflet.TCRS;
+
+    procedure SetCRS(Value: TLeaflet.TCRS);
+  public
+    preferCanvas: Boolean;
+
+    // Control options
+    attributionControl: Boolean;
+    zoomControl: Boolean;
+
+    // Interaction options
+    closePopupOnClick: Boolean;
+    zoomSnap: Double;
+    zoomDelta: Double;
+    trackResize: Boolean;
+    boxZoom: Boolean;
+    doubleClickZoom: String;
+    dragging: Boolean;
+
+    // Map state options
+    center: JSValue;
+    zoom: Double;
+    minZoom: Double;
+    maxZoom: Double;
+    layers: TArray<TLeaflet.TLayer>;
+    maxBounds: JSValue;
+    renderer: TLeaflet.TRenderer;
+
+    // Animation options
+    fadeAnimation: Boolean;
+    markerZoomAnimation: Boolean;
+    transform3DLimit: Double;
+    zoomAnimation: Boolean;
+    zoomAnimationThreshold: Double;
+
+    // Panning inertia options
+    inertia: Boolean;
+    inertiaDeceleration: Double;
+    inertiaMaxSpeed: Double;
+    easeLinearity: Double;
+    worldCopyJump: Boolean;
+    maxBoundsViscosity: Double;
+
+    // Keyboard navigation options
+    keyboard: Boolean;
+    keyboardPanDelta: Double;
+
+    // Mousewheel options
+    scrollWheelZoom: TLeaflet.TControl.TZoom;
+    wheelDebounceTime: Double;
+    wheelPxPerZoomLevel: Double;
+
+    // Touch interaction options
+    tap: Boolean;
+    tapTolerance: Double;
+    touchZoom: TLeaflet.TControl.TZoom;
+    bounceAtZoomLimits: Boolean;
+
+    property crs: TLeaflet.TCRS read GetCRS write SetCRS;
+  end;
+
+  TControlOptions = class
+  public
+    position: String;
+  end;
+
+  TZoomControlOptions = class(TControlOptions)
+  public
+    zoomInText: String;
+    zoomInTitle: String;
+    zoomOutText: String;
+    zoomOutTitle: String;
+  end;
+
+  TAttributionOptions = class(TControlOptions)
+  public
+    prefix: String;
+  end;
+
+  TLayersOptions = class(TControlOptions)
+  public
+    collapsed: Boolean;
+    autoZIndex: Boolean;
+    hideSingleBase: Boolean;
+  end;
+
+  TLayersObject = class
+  private
+    function GetLayers(name: String): TLeaflet.TLayer; external name '[]';
+
+    procedure SetLayers(name: String; Value: TLeaflet.TLayer); external name '[]';
+  public
+    property Layers[name: String]: TLeaflet.TLayer read GetLayers write SetLayers;
+  end;
+
+  TScaleOptions = class(TControlOptions)
+  public
+    maxWidth: Double;
+    metric: Boolean;
+    imperial: Boolean;
+    updateWhenIdle: Boolean;
+  end;
+
+  TDivOverlayOptions = class
+  public
+    offset: TPoint;
+    zoomAnimation: Boolean;
+    className: String;
+    pane: String;
+  end;
+
+  TPopupOptions = class(TDivOverlayOptions)
+  public
+    maxWidth: Double;
+    minWidth: Double;
+    maxHeight: Double;
+    keepInView: Boolean;
+    closeButton: Boolean;
+    autoPan: Boolean;
+    autoPanPaddingTopLeft: TPoint;
+    autoPanPaddingBottomRight: TPoint;
+    autoPanPadding: TPoint;
+    autoClose: Boolean;
+    closeOnClick: Boolean;
+    closeOnEscapeKey: Boolean;
+  end;
+
+  TTooltipOptions = class(TDivOverlayOptions)
+  public
+    pane: String;
+    offset: TPoint;
+    direction: String;
+    permanent: Boolean;
+    sticky: Boolean;
+    interactive: Boolean;
+    opacity: Double;
+  end;
+
+  TZoomOptions = class
+  public
+    animate: Boolean;
+  end;
+
+  TPanOptions = class(TZoomOptions)
+  public
+    duration: Double;
+    easeLinearity: Double;
+    noMoveStart: Boolean;
+  end;
+
+  TZoomPanOptions = class(TZoomOptions)
+  end;
+
+  TInvalidateSizeOptions = class(TZoomPanOptions)
+  public
+    debounceMoveend: Boolean;
+    pan: Boolean;
+  end;
+
+  TFitBoundsOptions = class(TZoomPanOptions)
+  public
+    paddingTopLeft: TPoint;
+    paddingBottomRight: TPoint;
+    padding: TPoint;
+    maxZoom: Double;
+  end;
+
+  TPanInsideOptions = class
+  public
+    paddingTopLeft: TPoint;
+    paddingBottomRight: TPoint;
+    padding: TPoint;
+  end;
+
+  TLocateOptions = class
+  public
+    watch: Boolean;
+    setView: Boolean;
+    maxZoom: Double;
+    timeout: Double;
+    maximumAge: Double;
+    enableHighAccuracy: Boolean;
+  end;
+
+  TLeafletEvent = class
+  public
+    &type: String;
+    target: JSValue;
+    sourceTarget: JSValue;
+    propagatedFrom: JSValue;
+  end;
+
+  TLeafletMouseEvent = class(TLeafletEvent)
+  public
+    latlng: TLeaflet.TLatLng;
+    layerPoint: TPoint;
+    containerPoint: TPoint;
+    originalEvent: TLeafletMouseEvent;
+  end;
+
+  TLeafletKeyboardEvent = class(TLeafletEvent)
+  public
+    originalEvent: TLeafletKeyboardEvent;
+  end;
+
+  TLocationEvent = class(TLeafletEvent)
+  public
+    latlng: TLeaflet.TLatLng;
+    bounds: TLeaflet.TLatLngBounds;
+    accuracy: Double;
+    altitude: Double;
+    altitudeAccuracy: Double;
+    heading: Double;
+    speed: Double;
+    timestamp: Double;
+  end;
+
+  TErrorEvent = class(TLeafletEvent)
+  public
+    message: String;
+    code: Double;
+  end;
+
+  TLayerEvent = class(TLeafletEvent)
+  public
+    layer: TLeaflet.TLayer;
+  end;
+
+  TLayersControlEvent = class(TLayerEvent)
+  public
+    name: String;
+  end;
+
+  TTileEvent = class(TLeafletEvent)
+  public
+    tile: TJSHTMLImageElement;
+    coords: TLeaflet.TCoords;
+  end;
+
+  TTileErrorEvent = class(TTileEvent)
+  public
+    error: TError;
+  end;
+
+  TResizeEvent = class(TLeafletEvent)
+  public
+    oldSize: TPoint;
+    newSize: TPoint;
+  end;
+
+  TGeoJSONEvent = class(TLeafletEvent)
+  public
+    layer: TLeaflet.TLayer;
+    properties: JSValue;
+    geometryType: String;
+    id: String;
+  end;
+
+  TPopupEvent = class(TLeafletEvent)
+  public
+    popup: TLeaflet.TPopup;
+  end;
+
+  TTooltipEvent = class(TLeafletEvent)
+  public
+    tooltip: TLeaflet.TTooltip;
+  end;
+
+  TDragEndEvent = class(TLeafletEvent)
+  public
+    distance: Double;
+  end;
+
+  TZoomAnimEvent = class(TLeafletEvent)
+  public
+    center: TLeaflet.TLatLng;
+    zoom: Double;
+    noUpdate: Boolean;
+  end;
+
+  TDefaultMapPanes = class
+  public
+    mapPane: TJSHTMLElement;
+    tilePane: TJSHTMLElement;
+    overlayPane: TJSHTMLElement;
+    shadowPane: TJSHTMLElement;
+    markerPane: TJSHTMLElement;
+    tooltipPane: TJSHTMLElement;
+    popupPane: TJSHTMLElement;
+  end;
+
+  TIconOptions = class(TLayerOptions)
+  public
+    iconUrl: String;
+    iconRetinaUrl: String;
+    iconSize: TPoint;
+    iconAnchor: TPoint;
+    popupAnchor: TPoint;
+    tooltipAnchor: TPoint;
+    shadowUrl: String;
+    shadowRetinaUrl: String;
+    shadowSize: TPoint;
+    shadowAnchor: TPoint;
+    className: String;
+  end;
+
+  TDivIconOptions = class (TIconOptions)
+  public
+    html: JSValue;
+    bgPos: TPoint;
+    iconSize: TPoint;
+    iconAnchor: TPoint;
+    popupAnchor: TPoint;
+    className: String;
+  end;
+
+  TMarkerOptions = class(TInteractiveLayerOptions)
+  public
+    icon: JSValue;
+    draggable: Boolean;
+    keyboard: Boolean;
+    title: String;
+    alt: String;
+    zIndexOffset: Double;
+    opacity: Double;
+    riseOnHover: Boolean;
+    riseOffset: Double;
+    shadowPane: String;
+    autoPan: Boolean;
+    autoPanPadding: TPoint;
+    autoPanSpeed: Double;
+  end;
+
+  TError = class
+  end;
+
+  TMapboxLayerOptions = class(TTileLayerOptions)
+  public
+    AccessToken: String; external name 'accessToken';
+    Style: String; external name 'style';
+
+    constructor Create(Style, AccessToken: String);
+  end;
+
+var
+  Leaflet: TLeaflet; external name 'L';
+
+function InitializeMap: TJSPromise;
+
+implementation
+
+function InitializeMap: TJSPromise;
+begin
+  Result := TJSPromise.New(
+    procedure(Resolve, Reject: TJSPromiseResolver)
+    var
+      Script: TJSHTMLScriptElement;
+
+      Link: TJSHTMLLinkElement;
+
+    begin
+      Link := TJSHTMLLinkElement(document.createElement('link'));
+      Link.HRef := 'https://unpkg.com/leaflet/dist/leaflet.css';
+      Link.Rel := 'stylesheet';
+
+      document.head.appendChild(Link);
+
+      Script := TJSHTMLScriptElement(document.createElement('script'));
+      Script.OnLoad :=
+        function (Event: TEventListenerEvent): Boolean
+        begin
+          Resolve(True);
+
+          Result := True;
+        end;
+      Script.src := 'https://unpkg.com/leaflet/dist/leaflet.js';
+      Script.type_ := 'text/javascript';
+
+      document.head.appendChild(Script);
+    end);
+end;
+
+{ TMapOptions }
+
+function TMapOptions.GetCRS: TLeaflet.TCRS;
+begin
+  if not Assigned(FCRS) then
+    FCRS := TLeaflet.TCRS.EPSG3857;
+
+  Result := FCRS;
+end;
+
+procedure TMapOptions.SetCRS(Value: TLeaflet.TCRS);
+begin
+  FCRS := Value;
+end;
+
+{ TMapboxLayerOptions }
+
+constructor TMapboxLayerOptions.Create(Style, AccessToken: String);
+begin
+  inherited Create;
+
+  Attribution := 'Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>';
+  Self.AccessToken := AccessToken;
+  Self.Style := Style;
+  TileSizeNumber := 512;
+  ZoomOffset := -1;
+end;
+
+end.
+
-- 
2.31.1.windows.1

Issue History

Date Modified Username Field Change
2021-05-11 19:21 henrique New Issue
2021-05-11 19:21 henrique File Added: 0001-Implementa-o-da-base-dos-mapas.patch
2021-05-11 20:43 Michael Van Canneyt Assigned To => Michael Van Canneyt
2021-05-11 20:43 Michael Van Canneyt Status new => assigned
2021-05-12 07:00 Michael Van Canneyt Status assigned => feedback
2021-05-12 07:00 Michael Van Canneyt Note Added: 0130824
2021-05-12 07:02 Michael Van Canneyt Relationship added related to 0038858
2021-05-12 17:44 henrique Note Added: 0130835
2021-05-12 17:44 henrique Status feedback => assigned
2021-05-12 18:02 Michael Van Canneyt Note Added: 0130837
2021-05-13 11:02 henrique Note Added: 0130851
2021-05-13 11:02 henrique File Added: 0001-Implementa-o-da-base-dos-mapas-2.patch
2021-05-20 13:13 henrique Note Added: 0130969
2021-05-20 13:13 henrique File Added: 0001-Implementa-o-da-base-dos-mapas-3.patch
2021-05-20 13:17 henrique Note Added: 0130970
2021-05-27 13:16 henrique Note Added: 0131052
2021-05-27 13:16 henrique File Added: 0001-Implementa-o-da-base-dos-mapas-4.patch