export = arkmap;
export as namespace arkmap;

declare namespace arkmap {
  export let version: string;

  type PluginStatus = "unavailable" | "loading" | "loaded" | "error";

  type LngLatLike =
    | [number, number]
    | LngLat
    | { lng: number; lat: number }
    | { lon: number; lat: number };

  type LngLatBoundsLike =
    | LngLatBounds
    | [LngLatLike, LngLatLike]
    | [number, number, number, number]
    | LngLatLike;
  type PointLike = Point | [number, number];
  type Offset = number | PointLike | { [_: string]: PointLike };

  type ExpressionName =
    // Types
    | "array"
    | "boolean"
    | "collator"
    | "format"
    | "literal"
    | "number"
    | "number-format"
    | "object"
    | "string"
    | "image"
    | "to-boolean"
    | "to-color"
    | "to-number"
    | "to-string"
    | "typeof"
    // Feature data
    | "feature-state"
    | "geometry-type"
    | "id"
    | "line-progress"
    | "properties"
    // Lookup
    | "at"
    | "get"
    | "has"
    | "in"
    | "index-of"
    | "length"
    | "slice"
    // Decision
    | "!"
    | "!="
    | "<"
    | "<="
    | "=="
    | ">"
    | ">="
    | "all"
    | "any"
    | "case"
    | "match"
    | "coalesce"
    | "within"
    // Ramps, scales, curves
    | "interpolate"
    | "interpolate-hcl"
    | "interpolate-lab"
    | "step"
    // Variable binding
    | "let"
    | "var"
    // String
    | "concat"
    | "downcase"
    | "is-supported-script"
    | "resolved-locale"
    | "upcase"
    // Color
    | "rgb"
    | "rgba"
    | "to-rgba"
    // Math
    | "-"
    | "*"
    | "/"
    | "%"
    | "^"
    | "+"
    | "abs"
    | "acos"
    | "asin"
    | "atan"
    | "ceil"
    | "cos"
    | "e"
    | "floor"
    | "ln"
    | "ln2"
    | "log10"
    | "log2"
    | "max"
    | "min"
    | "pi"
    | "round"
    | "sin"
    | "sqrt"
    | "tan"
    // Zoom, Heatmap
    | "zoom"
    | "heatmap-density";

  type Expression = [ExpressionName, ...any[]];

  type Anchor =
    | "center"
    | "left"
    | "right"
    | "top"
    | "bottom"
    | "top-left"
    | "top-right"
    | "bottom-left"
    | "bottom-right";

  type DragPanOptions = {
    linearity?: number;
    easing?: (t: number) => number;
    deceleration?: number;
    maxSpeed?: number;
  };

  type InteractiveOptions = { around?: "center" };

  class MapboxMap extends Evented {
    constructor(options: MapboxOptions, config: any);

    addControl(
      control: Control | IControl,
      position?: "top-right" | "top-left" | "bottom-right" | "bottom-left"
    ): this;

    removeControl(control: Control | IControl): this;

    hasControl(control: IControl): boolean;

    resize(eventData?: EventData): this;

    getBounds(): LngLatBounds;

    getMaxBounds(): LngLatBounds | null;

    setMaxBounds(lnglatbounds?: LngLatBoundsLike): this;

    setMinZoom(minZoom?: number | null): this;

    getMinZoom(): number;

    setMaxZoom(maxZoom?: number | null): this;

    getMaxZoom(): number;

    setMinPitch(minPitch?: number | null): this;

    getMinPitch(): number;

    setMaxPitch(maxPitch?: number | null): this;

    getMaxPitch(): number;

    getRenderWorldCopies(): boolean;

    setRenderWorldCopies(renderWorldCopies?: boolean): this;

    project(lnglat: LngLatLike): Point;

    unproject(point: PointLike): LngLat;

    isMoving(): boolean;

    isZooming(): boolean;

    isRotating(): boolean;

    queryRenderedFeatures(
      pointOrBox?: PointLike | [PointLike, PointLike],
      options?: {
        layers?: string[] | undefined;
        filter?: any[] | undefined;
      } & FilterOptions
    ): MapboxGeoJSONFeature[];

    querySourceFeatures(
      sourceID: string,
      parameters?: {
        sourceLayer?: string | undefined;
        filter?: any[] | undefined;
      } & FilterOptions
    ): MapboxGeoJSONFeature[];

    setStyle(
      style: Style | string,
      options?: {
        diff?: boolean | undefined;
        localIdeographFontFamily?: string | undefined;
      }
    ): this;

    getStyle(): Style;

    isStyleLoaded(): boolean;

    addSource(id: string, source: AnySourceData): this;

    isSourceLoaded(id: string): boolean;

    areTilesLoaded(): boolean;

    removeSource(id: string): this;

    getSource(id: string): AnySourceImpl;

    addImage(
      name: string,
      image:
        | HTMLImageElement
        | ArrayBufferView
        | {
            width: number;
            height: number;
            data: Uint8Array | Uint8ClampedArray;
          }
        | ImageData
        | ImageBitmap,
      options?: {
        pixelRatio?: number | undefined;
        sdf?: boolean | undefined;
        stretchX?: [number, number][] | undefined;
        stretchY?: [number, number][] | undefined;
        content?: [number, number, number, number] | undefined;
      }
    ): void;

    updateImage(
      name: string,
      image:
        | HTMLImageElement
        | ArrayBufferView
        | {
            width: number;
            height: number;
            data: Uint8Array | Uint8ClampedArray;
          }
        | ImageData
        | ImageBitmap
    ): void;

    hasImage(name: string): boolean;

    removeImage(name: string): void;

    loadImage(
      url: string,
      callback: (error?: Error, result?: HTMLImageElement | ImageBitmap) => void
    ): void;

    listImages(): string[];

    addLayer(layer: AnyLayer, before?: string): this;

    moveLayer(id: string, beforeId?: string): this;

    removeLayer(id: string): this;

    getLayer(id: string): AnyLayer;

    setFilter(
      layer: string,
      filter?: any[] | boolean | null,
      options?: FilterOptions | null
    ): this;

    setLayerZoomRange(layerId: string, minzoom: number, maxzoom: number): this;

    getFilter(layer: string): any[];

    setPaintProperty(
      layer: string,
      name: string,
      value: any,
      options?: FilterOptions
    ): this;

    getPaintProperty(layer: string, name: string): any;

    setLayoutProperty(
      layer: string,
      name: string,
      value: any,
      options?: FilterOptions
    ): this;

    getLayoutProperty(layer: string, name: string): any;

    setLight(light: Light, options?: FilterOptions): this;

    getLight(): Light;

    setTerrain(terrain?: TerrainSpecification | null): this;

    getTerrain(): TerrainSpecification | null;

    showTerrainWireframe: boolean;

    queryTerrainElevation(
      lngLat: LngLatLike,
      options?: ElevationQueryOptions
    ): number | null;

    setFeatureState(
      feature: FeatureIdentifier | MapboxGeoJSONFeature,
      state: { [key: string]: any }
    ): void;

    getFeatureState(feature: FeatureIdentifier | MapboxGeoJSONFeature): {
      [key: string]: any;
    };

    removeFeatureState(
      target: FeatureIdentifier | MapboxGeoJSONFeature,
      key?: string
    ): void;

    getContainer(): HTMLElement;

    getCanvasContainer(): HTMLElement;

    getCanvas(): HTMLCanvasElement;

    loaded(): boolean;

    remove(): void;

    triggerRepaint(): void;

    showTileBoundaries: boolean;

    showCollisionBoxes: boolean;

    showPadding: boolean;

    repaint: boolean;

    getCenter(): LngLat;

    setCenter(center: LngLatLike, eventData?: EventData): this;

    panBy(
      offset: PointLike,
      options?: AnimationOptions,
      eventData?: EventData
    ): this;

    panTo(
      lnglat: LngLatLike,
      options?: AnimationOptions,
      eventdata?: EventData
    ): this;

    getZoom(): number;

    setZoom(zoom: number, eventData?: EventData): this;

    zoomTo(
      zoom: number,
      options?: AnimationOptions,
      eventData?: EventData
    ): this;

    zoomIn(options?: AnimationOptions, eventData?: EventData): this;

    zoomOut(options?: AnimationOptions, eventData?: EventData): this;

    getBearing(): number;

    setBearing(bearing: number, eventData?: EventData): this;

    getPadding(): PaddingOptions;

    setPadding(padding: PaddingOptions, eventData?: EventData): this;

    rotateTo(
      bearing: number,
      options?: AnimationOptions,
      eventData?: EventData
    ): this;

    resetNorth(options?: AnimationOptions, eventData?: EventData): this;

    resetNorthPitch(
      options?: AnimationOptions | null,
      eventData?: EventData | null
    ): this;

    snapToNorth(options?: AnimationOptions, eventData?: EventData): this;

    getPitch(): number;

    setPitch(pitch: number, eventData?: EventData): this;

    cameraForBounds(
      bounds: LngLatBoundsLike,
      options?: CameraForBoundsOptions
    ): CameraForBoundsResult | undefined;

    fitBounds(
      bounds: LngLatBoundsLike,
      options?: FitBoundsOptions,
      eventData?: EventData
    ): this;

    fitScreenCoordinates(
      p0: PointLike,
      p1: PointLike,
      bearing: number,
      options?: AnimationOptions & CameraOptions,
      eventData?: EventData
    ): this;

    jumpTo(options: CameraOptions, eventData?: EventData): this;

    getFreeCameraOptions(): FreeCameraOptions;

    setFreeCameraOptions(options: FreeCameraOptions, eventData?: Object): this;

    easeTo(options: EaseToOptions, eventData?: EventData): this;

    flyTo(options: FlyToOptions, eventData?: EventData): this;

    isEasing(): boolean;

    stop(): this;

    on<T extends keyof MapLayerEventType>(
      type: T,
      layer: string | ReadonlyArray<string>,
      listener: (ev: MapLayerEventType[T] & EventData) => void
    ): this;
    on<T extends keyof MapEventType>(
      type: T,
      listener: (ev: MapEventType[T] & EventData) => void
    ): this;
    on(type: string, listener: (ev: any) => void): this;

    once<T extends keyof MapLayerEventType>(
      type: T,
      layer: string | ReadonlyArray<string>,
      listener: (ev: MapLayerEventType[T] & EventData) => void
    ): this;
    once<T extends keyof MapEventType>(
      type: T,
      listener: (ev: MapEventType[T] & EventData) => void
    ): this;
    once(type: string, listener: (ev: any) => void): this;
    once<T extends keyof MapEventType>(type: T): Promise<MapEventType[T]>;

    off<T extends keyof MapLayerEventType>(
      type: T,
      layer: string | ReadonlyArray<string>,
      listener: (ev: MapLayerEventType[T] & EventData) => void
    ): this;
    off<T extends keyof MapEventType>(
      type: T,
      listener: (ev: MapEventType[T] & EventData) => void
    ): this;
    off(type: string, listener: (ev: any) => void): this;

    scrollZoom: ScrollZoomHandler;

    boxZoom: BoxZoomHandler;

    dragRotate: DragRotateHandler;

    dragPan: DragPanHandler;

    keyboard: KeyboardHandler;

    doubleClickZoom: DoubleClickZoomHandler;

    touchZoomRotate: TouchZoomRotateHandler;

    touchPitch: TouchPitchHandler;

    getFog(): Fog | null;
    setFog(fog: Fog): this;

    getProjection(): Projection;
    setProjection(projection: Projection | string): this;

    stageConfig: Config;

    transform: any;

    _canvas: HTMLElement;

    painter: any;

    _container: HTMLElement;

    _canvasContainer: HTMLElement;
  }

  interface MapboxOptions {
    antialias?: boolean | undefined;

    attributionControl?: boolean | undefined;

    bearing?: number | undefined;

    bearingSnap?: number | undefined;

    bounds?: LngLatBoundsLike | undefined;

    boxZoom?: boolean | undefined;

    center?: LngLatLike | undefined;

    clickTolerance?: number | undefined;

    collectResourceTiming?: boolean | undefined;

    crossSourceCollisions?: boolean | undefined;

    container: string | HTMLElement;

    cooperativeGestures?: boolean;

    customAttribution?: string | string[] | undefined;

    dragPan?: boolean | DragPanOptions | undefined;

    dragRotate?: boolean | undefined;

    doubleClickZoom?: boolean | undefined;

    hash?: boolean | string | undefined;

    fadeDuration?: number | undefined;

    failIfMajorPerformanceCaveat?: boolean | undefined;

    fitBoundsOptions?: FitBoundsOptions | undefined;

    interactive?: boolean | undefined;

    keyboard?: boolean | undefined;

    locale?: { [key: string]: string } | undefined;

    localFontFamily?: string | undefined;

    localIdeographFontFamily?: string | undefined;

    logoPosition?:
      | "top-left"
      | "top-right"
      | "bottom-left"
      | "bottom-right"
      | undefined;

    maxBounds?: LngLatBoundsLike | undefined;

    maxPitch?: number | undefined;

    maxZoom?: number | undefined;

    minPitch?: number | undefined;

    minZoom?: number | undefined;

    optimizeForTerrain?: boolean | undefined;

    preserveDrawingBuffer?: boolean | undefined;

    pitch?: number | undefined;

    projection?: Projection;

    pitchWithRotate?: boolean | undefined;

    refreshExpiredTiles?: boolean | undefined;

    renderWorldCopies?: boolean | undefined;

    scrollZoom?: boolean | InteractiveOptions | undefined;

    style?: any | string | undefined;

    trackResize?: boolean | undefined;

    transformRequest?: TransformRequestFunction | undefined;

    touchZoomRotate?: boolean | InteractiveOptions | undefined;

    touchPitch?: boolean | InteractiveOptions | undefined;

    zoom?: number | undefined;

    maxTileCacheSize?: number | undefined;

    accessToken?: string | undefined;

    testMode?: boolean | undefined;

    worldview?: string | undefined;
  }

  type quat = number[];
  type vec3 = number[];

  export class FreeCameraOptions {
    constructor(position?: MercatorCoordinate, orientation?: quat);

    position: MercatorCoordinate | undefined;

    lookAtPoint(location: LngLatLike, up?: vec3): void;

    setPitchBearing(pitch: number, bearing: number): void;
  }

  export type ResourceType =
    | "Unknown"
    | "Style"
    | "Source"
    | "Tile"
    | "Glyphs"
    | "SpriteImage"
    | "SpriteJSON"
    | "Image";

  export interface RequestParameters {
    url: string;
    credentials?: "same-origin" | "include" | undefined;
    headers?: { [header: string]: any } | undefined;
    method?: "GET" | "POST" | "PUT" | undefined;
    collectResourceTiming?: boolean | undefined;
  }

  export type TransformRequestFunction = (
    url: string,
    resourceType: ResourceType
  ) => RequestParameters;

  export interface PaddingOptions {
    top: number;
    bottom: number;
    left: number;
    right: number;
  }

  export interface FeatureIdentifier {
    id?: string | number | undefined;
    source: string;
    sourceLayer?: string | undefined;
  }

  export class BoxZoomHandler {
    constructor(map: MapboxMap);

    isEnabled(): boolean;

    isActive(): boolean;

    enable(): void;

    disable(): void;
  }

  export class ScrollZoomHandler {
    constructor(map: MapboxMap);

    isEnabled(): boolean;

    enable(options?: InteractiveOptions): void;

    disable(): void;

    setZoomRate(zoomRate: number): void;

    setWheelZoomRate(wheelZoomRate: number): void;
  }

  export class DragPanHandler {
    constructor(map: MapboxMap);

    isEnabled(): boolean;

    isActive(): boolean;

    enable(options?: DragPanOptions): void;

    disable(): void;
  }

  export class DragRotateHandler {
    constructor(
      map: MapboxMap,
      options?: {
        bearingSnap?: number | undefined;
        pitchWithRotate?: boolean | undefined;
      }
    );

    isEnabled(): boolean;

    isActive(): boolean;

    enable(): void;

    disable(): void;
  }

  export class KeyboardHandler {
    constructor(map: MapboxMap);

    isEnabled(): boolean;

    enable(): void;

    disable(): void;

    isActive(): boolean;

    disableRotation(): void;

    enableRotation(): void;
  }

  export class DoubleClickZoomHandler {
    constructor(map: MapboxMap);

    isEnabled(): boolean;

    enable(): void;

    disable(): void;
  }

  export class TouchZoomRotateHandler {
    constructor(map: MapboxMap);

    isEnabled(): boolean;

    enable(options?: InteractiveOptions): void;

    disable(): void;

    disableRotation(): void;

    enableRotation(): void;
  }

  export class TouchPitchHandler {
    constructor(map: MapboxMap);

    enable(options?: InteractiveOptions): void;

    isActive(): boolean;

    isEnabled(): boolean;

    disable(): void;
  }

  export interface IControl {
    onAdd(map: MapboxMap): HTMLElement;

    onRemove(map: MapboxMap): void;

    getDefaultPosition?: (() => string) | undefined;
  }

  export class Control extends Evented implements IControl {
    onAdd(map: MapboxMap): HTMLElement;
    onRemove(map: MapboxMap): void;
    getDefaultPosition?: (() => string) | undefined;
  }

  export class NavigationControl extends Control {
    constructor(options?: {
      showCompass?: boolean | undefined;
      showZoom?: boolean | undefined;
      visualizePitch?: boolean | undefined;
    });
  }

  export class PositionOptions {
    enableHighAccuracy?: boolean | undefined;
    timeout?: number | undefined;
    maximumAge?: number | undefined;
  }

  export class GeolocateControl extends Control {
    constructor(options?: {
      positionOptions?: PositionOptions | undefined;
      fitBoundsOptions?: FitBoundsOptions | undefined;
      trackUserLocation?: boolean | undefined;
      showAccuracyCircle?: boolean | undefined;
      showUserLocation?: boolean | undefined;
      showUserHeading?: boolean | undefined;
      geolocation?: Geolocation | undefined;
    });
    trigger(): boolean;
  }

  export class AttributionControl extends Control {
    constructor(options?: {
      compact?: boolean | undefined;
      customAttribution?: string | string[] | undefined;
    });
  }

  export class ScaleControl extends Control {
    constructor(options?: {
      maxWidth?: number | undefined;
      unit?: string | undefined;
    });

    setUnit(unit: "imperial" | "metric" | "nautical"): void;
  }

  export class FullscreenControl extends Control {
    constructor(options?: FullscreenControlOptions | null);
  }

  export interface FullscreenControlOptions {
    container?: HTMLElement | null | undefined;
  }

  export interface Style {
    layers: AnyLayer[];
    sources: Sources;

    bearing?: number | undefined;
    center?: number[] | undefined;
    fog?: Fog | undefined;
    glyphs?: string | undefined;
    metadata?: any;
    name?: string | undefined;
    pitch?: number | undefined;
    light?: Light | undefined;
    sprite?: string | undefined;
    terrain?: TerrainSpecification | undefined;
    transition?: Transition | undefined;
    version: number;
    zoom?: number | undefined;
  }

  export interface Transition {
    delay?: number | undefined;
    duration?: number | undefined;
  }

  export interface Light {
    anchor?: "map" | "viewport" | undefined;
    position?: number[] | undefined;
    "position-transition"?: Transition | undefined;
    color?: string | undefined;
    "color-transition"?: Transition | undefined;
    intensity?: number | undefined;
    "intensity-transition"?: Transition | undefined;
  }

  export interface Fog {
    color?: string | Expression | undefined;
    "horizon-blend"?: number | Expression | undefined;
    range?: number[] | Expression | undefined;
  }

  export interface Sources {
    [sourceName: string]: AnySourceData;
  }

  export type PromoteIdSpecification = { [key: string]: string } | string;

  export type AnySourceData =
    | GeoJSONSourceRaw
    | VideoSourceRaw
    | ImageSourceRaw
    | CanvasSourceRaw
    | VectorSource
    | RasterSource
    | RasterDemSource
    | CustomSourceInterface<HTMLImageElement | ImageData | ImageBitmap>;

  interface VectorSourceImpl extends VectorSource {
    setTiles(tiles: ReadonlyArray<string>): VectorSourceImpl;

    setUrl(url: string): VectorSourceImpl;
  }

  export type AnySourceImpl =
    | GeoJSONSource
    | VideoSource
    | ImageSource
    | CanvasSource
    | VectorSourceImpl
    | RasterSource
    | RasterDemSource
    | CustomSource<HTMLImageElement | ImageData | ImageBitmap>;

  export interface Source {
    type:
      | "vector"
      | "raster"
      | "raster-dem"
      | "geojson"
      | "image"
      | "video"
      | "canvas"
      | "custom";
  }

  export interface GeoJSONSourceRaw extends Source, GeoJSONSourceOptions {
    type: "geojson";
  }

  export class GeoJSONSource implements GeoJSONSourceRaw {
    type: "geojson";

    constructor(options?: GeoJSONSourceOptions);

    setData(
      data:
        | GeoJSON.Feature<GeoJSON.Geometry>
        | GeoJSON.FeatureCollection<GeoJSON.Geometry>
        | String
    ): this;

    getClusterExpansionZoom(
      clusterId: number,
      callback: (error: any, zoom: number) => void
    ): this;

    getClusterChildren(
      clusterId: number,
      callback: (
        error: any,
        features: GeoJSON.Feature<GeoJSON.Geometry>[]
      ) => void
    ): this;

    getClusterLeaves(
      cluserId: number,
      limit: number,
      offset: number,
      callback: (
        error: any,
        features: GeoJSON.Feature<GeoJSON.Geometry>[]
      ) => void
    ): this;
  }

  export interface GeoJSONSourceOptions {
    data?:
      | GeoJSON.Feature<GeoJSON.Geometry>
      | GeoJSON.FeatureCollection<GeoJSON.Geometry>
      | GeoJSON.Geometry
      | string
      | undefined;

    maxzoom?: number | undefined;

    attribution?: string | undefined;

    buffer?: number | undefined;

    tolerance?: number | undefined;

    cluster?: number | boolean | undefined;

    clusterRadius?: number | undefined;

    clusterMaxZoom?: number | undefined;

    clusterMinPoints?: number | undefined;

    clusterProperties?: object | undefined;

    lineMetrics?: boolean | undefined;

    generateId?: boolean | undefined;

    promoteId?: PromoteIdSpecification | undefined;

    filter?: any;
  }

  export interface VideoSourceRaw extends Source, VideoSourceOptions {
    type: "video";
  }

  export class VideoSource implements VideoSourceRaw {
    type: "video";

    constructor(options?: VideoSourceOptions);

    getVideo(): HTMLVideoElement;

    setCoordinates(coordinates: number[][]): this;
  }

  export interface VideoSourceOptions {
    urls?: string[] | undefined;

    coordinates?: number[][] | undefined;
  }

  export interface ImageSourceRaw extends Source, ImageSourceOptions {
    type: "image";
  }

  export class ImageSource implements ImageSourceRaw {
    type: "image";

    constructor(options?: ImageSourceOptions);

    updateImage(options: ImageSourceOptions): this;

    setCoordinates(coordinates: number[][]): this;
  }

  export interface ImageSourceOptions {
    url?: string | undefined;

    coordinates?: number[][] | undefined;
  }

  export interface CanvasSourceRaw extends Source, CanvasSourceOptions {
    type: "canvas";
  }

  export class CanvasSource implements CanvasSourceRaw {
    type: "canvas";

    coordinates: number[][];

    canvas: string | HTMLCanvasElement;

    play(): void;

    pause(): void;

    getCanvas(): HTMLCanvasElement;

    setCoordinates(coordinates: number[][]): this;
  }

  export interface CanvasSourceOptions {
    coordinates: number[][];

    animate?: boolean | undefined;

    canvas: string | HTMLCanvasElement;
  }

  export type CameraFunctionSpecification<T> =
    | { type: "exponential"; stops: Array<[number, T]> }
    | { type: "interval"; stops: Array<[number, T]> };

  export type ExpressionSpecification = Array<unknown>;

  export type PropertyValueSpecification<T> =
    | T
    | CameraFunctionSpecification<T>
    | ExpressionSpecification;

  export interface TerrainSpecification {
    source: string;
    exaggeration?: PropertyValueSpecification<number> | undefined;
  }

  type SourceVectorLayer = {
    id: string;
    fields?: Record<string, string>;
    description?: string;
    minzoom?: number;
    maxzoom?: number;
    source?: string;
    source_name?: string;
  };

  interface VectorSource extends Source {
    type: "vector";
    format?: "pbf";

    url?: string | undefined;
    id?: string;
    name?: string;

    tiles?: string[] | undefined;
    bounds?: number[] | undefined;
    scheme?: "xyz" | "tms" | undefined;
    minzoom?: number | undefined;
    maxzoom?: number | undefined;
    attribution?: string | undefined;
    promoteId?: PromoteIdSpecification | undefined;

    vector_layers?: SourceVectorLayer[];
  }

  interface RasterSource extends Source {
    name?: string;
    type: "raster";
    id?: string;
    format?: "webp" | string;

    url?: string | undefined;
    tiles?: string[] | undefined;
    bounds?: number[] | undefined;
    minzoom?: number | undefined;
    maxzoom?: number | undefined;
    tileSize?: number | undefined;
    scheme?: "xyz" | "tms" | undefined;
    attribution?: string | undefined;
  }

  interface RasterDemSource extends Source {
    name?: string;
    type: "raster-dem";
    id?: string;

    url?: string | undefined;
    tiles?: string[] | undefined;
    bounds?: number[] | undefined;
    minzoom?: number | undefined;
    maxzoom?: number | undefined;
    tileSize?: number | undefined;
    attribution?: string | undefined;
    encoding?: "terrarium" | "mapbox" | undefined;
  }

  interface CustomSourceInterface<T> {
    id: string;
    type: "custom";
    dataType: "raster";
    minzoom?: number;
    maxzoom?: number;
    scheme?: string;
    tileSize?: number;
    attribution?: string;
    bounds?: [number, number, number, number];
    hasTile?: (tileID: { z: number; x: number; y: number }) => boolean;
    loadTile: (
      tileID: { z: number; x: number; y: number },
      options: { signal: AbortSignal }
    ) => Promise<T>;
    prepareTile?: (tileID: {
      z: number;
      x: number;
      y: number;
    }) => T | undefined;
    unloadTile?: (tileID: { z: number; x: number; y: number }) => void;
    onAdd?: (map: MapboxMap) => void;
    onRemove?: (map: MapboxMap) => void;
  }

  interface CustomSource<T> extends Source {
    id: string;
    type: "custom";
    scheme: string;
    minzoom: number;
    maxzoom: number;
    tileSize: number;
    attribution: string;

    _implementation: CustomSourceInterface<T>;
  }

  export class LngLat {
    lng: number;
    lat: number;

    constructor(lng: number, lat: number);

    wrap(): LngLat;

    toArray(): number[];

    toString(): string;

    distanceTo(lngLat: LngLat): number;

    toBounds(radius: number): LngLatBounds;

    static convert(input: LngLatLike): LngLat;
  }

  export class LngLatBounds {
    sw: LngLatLike;
    ne: LngLatLike;

    constructor(
      boundsLike?: [LngLatLike, LngLatLike] | [number, number, number, number]
    );
    constructor(sw: LngLatLike, ne: LngLatLike);

    setNorthEast(ne: LngLatLike): this;

    setSouthWest(sw: LngLatLike): this;

    contains(lnglat: LngLatLike): boolean;

    extend(obj: LngLatLike | LngLatBoundsLike): this;

    getCenter(): LngLat;

    getSouthWest(): LngLat;

    getNorthEast(): LngLat;

    getNorthWest(): LngLat;

    getSouthEast(): LngLat;

    getWest(): number;

    getSouth(): number;

    getEast(): number;

    getNorth(): number;

    toArray(): number[][];

    toString(): string;

    isEmpty(): boolean;

    static convert(input: LngLatBoundsLike): LngLatBounds;
  }

  export class Point {
    x: number;
    y: number;

    constructor(x: number, y: number);

    clone(): Point;

    add(p: Point): Point;

    sub(p: Point): Point;

    mult(k: number): Point;

    div(k: number): Point;

    rotate(a: number): Point;

    matMult(m: number): Point;

    unit(): Point;

    perp(): Point;

    round(): Point;

    mag(): number;

    equals(p: Point): boolean;

    dist(p: Point): number;

    distSqr(p: Point): number;

    angle(): number;

    angleTo(p: Point): number;

    angleWidth(p: Point): number;

    angleWithSep(x: number, y: number): number;

    static convert(a: PointLike): Point;
  }

  export class MercatorCoordinate {
    x: number;

    y: number;

    z?: number | undefined;

    constructor(x: number, y: number, z?: number);

    toAltitude(): number;

    toLngLat(): LngLat;

    meterInMercatorCoordinateUnits(): number;

    static fromLngLat(
      lngLatLike: LngLatLike,
      altitude?: number
    ): MercatorCoordinate;
  }

  type EventedListener = (object?: Object) => any;

  export class Evented {
    on(type: string, listener: EventedListener): this;

    off(type?: string | any, listener?: EventedListener): this;

    once(type: string, listener: EventedListener): this;

    fire(type: string, properties?: { [key: string]: any }): this;
  }

  export interface StyleOptions {
    transition?: boolean | undefined;
  }

  export type MapboxGeoJSONFeature = GeoJSON.Feature<GeoJSON.Geometry> & {
    layer: any;
    source: string;
    sourceLayer: string;
    state: { [key: string]: any };
  };

  export type EventData = { [key: string]: any };

  export class MapboxEvent<TOrig = undefined> {
    type: string;
    target: MapboxMap;
    originalEvent: TOrig;
  }

  export class MapMouseEvent extends MapboxEvent<MouseEvent> {
    type:
      | "mousedown"
      | "mouseup"
      | "click"
      | "dblclick"
      | "mousemove"
      | "mouseover"
      | "mouseenter"
      | "mouseleave"
      | "mouseout"
      | "contextmenu";

    point: Point;
    lngLat: LngLat;

    preventDefault(): void;
    defaultPrevented: boolean;
  }

  export type MapLayerMouseEvent = MapMouseEvent & {
    features?: MapboxGeoJSONFeature[] | undefined;
  };

  export class MapTouchEvent extends MapboxEvent<TouchEvent> {
    type: "touchstart" | "touchend" | "touchcancel";

    point: Point;
    lngLat: LngLat;
    points: Point[];
    lngLats: LngLat[];

    preventDefault(): void;
    defaultPrevented: boolean;
  }

  export type MapLayerTouchEvent = MapTouchEvent & {
    features?: MapboxGeoJSONFeature[] | undefined;
  };

  export class MapWheelEvent extends MapboxEvent<WheelEvent> {
    type: "wheel";

    preventDefault(): void;
    defaultPrevented: boolean;
  }

  export interface MapBoxZoomEvent extends MapboxEvent<MouseEvent> {
    type: "boxzoomstart" | "boxzoomend" | "boxzoomcancel";

    boxZoomBounds: LngLatBounds;
  }

  export type MapDataEvent = MapSourceDataEvent | MapStyleDataEvent;

  export interface MapStyleDataEvent extends MapboxEvent {
    dataType: "style";
  }

  export interface MapSourceDataEvent extends MapboxEvent {
    dataType: "source";
    isSourceLoaded: boolean;
    source: Source;
    sourceId: string;
    sourceDataType: "metadata" | "content";
    tile: any;
    coord: Coordinate;
  }

  export interface Coordinate {
    canonical: CanonicalCoordinate;
    wrap: number;
    key: number;
  }

  export interface CanonicalCoordinate {
    x: number;
    y: number;
    z: number;
    key: number;
    equals(coord: CanonicalCoordinate): boolean;
  }

  export interface MapContextEvent extends MapboxEvent<WebGLContextEvent> {
    type: "webglcontextlost" | "webglcontextrestored";
  }

  export class ErrorEvent extends MapboxEvent {
    type: "error";
    error: Error;
  }

  export interface FilterOptions {
    validate?: boolean | null | undefined;
  }

  export interface AnimationOptions {
    duration?: number | undefined;
    easing?: ((time: number) => number) | undefined;
    offset?: PointLike | undefined;
    animate?: boolean | undefined;
    essential?: boolean | undefined;
  }

  export interface CameraOptions {
    center?: LngLatLike | undefined;
    zoom?: number | undefined;
    bearing?: number | undefined;
    pitch?: number | undefined;
    around?: LngLatLike | undefined;
    padding?: number | PaddingOptions | undefined;
  }

  export interface CameraForBoundsOptions extends CameraOptions {
    offset?: PointLike | undefined;
    maxZoom?: number | undefined;
  }

  export type CameraForBoundsResult = Required<
    Pick<CameraOptions, "zoom" | "bearing">
  > & {
    center: { lng: number; lat: number };
  };

  export interface FlyToOptions extends AnimationOptions, CameraOptions {
    curve?: number | undefined;
    minZoom?: number | undefined;
    speed?: number | undefined;
    screenSpeed?: number | undefined;
    maxDuration?: number | undefined;
  }

  export interface EaseToOptions extends AnimationOptions, CameraOptions {
    delayEndEvents?: number | undefined;
  }

  export interface FitBoundsOptions extends FlyToOptions {
    linear?: boolean | undefined;
    offset?: PointLike | undefined;
    maxZoom?: number | undefined;
    maxDuration?: number | undefined;
  }

  export type MapEventType = {
    error: ErrorEvent;

    load: MapboxEvent;
    idle: MapboxEvent;
    remove: MapboxEvent;
    render: MapboxEvent;
    resize: MapboxEvent;

    webglcontextlost: MapContextEvent;
    webglcontextrestored: MapContextEvent;

    dataloading: MapDataEvent;
    data: MapDataEvent;
    tiledataloading: MapDataEvent;
    sourcedataloading: MapSourceDataEvent;
    styledataloading: MapStyleDataEvent;
    sourcedata: MapSourceDataEvent;
    styledata: MapStyleDataEvent;

    boxzoomcancel: MapBoxZoomEvent;
    boxzoomstart: MapBoxZoomEvent;
    boxzoomend: MapBoxZoomEvent;

    touchcancel: MapTouchEvent;
    touchmove: MapTouchEvent;
    touchend: MapTouchEvent;
    touchstart: MapTouchEvent;

    click: MapMouseEvent;
    contextmenu: MapMouseEvent;
    dblclick: MapMouseEvent;
    mousemove: MapMouseEvent;
    mouseup: MapMouseEvent;
    mousedown: MapMouseEvent;
    mouseout: MapMouseEvent;
    mouseover: MapMouseEvent;

    movestart: MapboxEvent<MouseEvent | TouchEvent | WheelEvent | undefined>;
    move: MapboxEvent<MouseEvent | TouchEvent | WheelEvent | undefined>;
    moveend: MapboxEvent<MouseEvent | TouchEvent | WheelEvent | undefined>;

    zoomstart: MapboxEvent<MouseEvent | TouchEvent | WheelEvent | undefined>;
    zoom: MapboxEvent<MouseEvent | TouchEvent | WheelEvent | undefined>;
    zoomend: MapboxEvent<MouseEvent | TouchEvent | WheelEvent | undefined>;

    rotatestart: MapboxEvent<MouseEvent | TouchEvent | undefined>;
    rotate: MapboxEvent<MouseEvent | TouchEvent | undefined>;
    rotateend: MapboxEvent<MouseEvent | TouchEvent | undefined>;

    dragstart: MapboxEvent<MouseEvent | TouchEvent | undefined>;
    drag: MapboxEvent<MouseEvent | TouchEvent | undefined>;
    dragend: MapboxEvent<MouseEvent | TouchEvent | undefined>;

    pitchstart: MapboxEvent<MouseEvent | TouchEvent | undefined>;
    pitch: MapboxEvent<MouseEvent | TouchEvent | undefined>;
    pitchend: MapboxEvent<MouseEvent | TouchEvent | undefined>;

    wheel: MapWheelEvent;
  };

  export type MapLayerEventType = {
    click: MapLayerMouseEvent;
    dblclick: MapLayerMouseEvent;
    mousedown: MapLayerMouseEvent;
    mouseup: MapLayerMouseEvent;
    mousemove: MapLayerMouseEvent;
    mouseenter: MapLayerMouseEvent;
    mouseleave: MapLayerMouseEvent;
    mouseover: MapLayerMouseEvent;
    mouseout: MapLayerMouseEvent;
    contextmenu: MapLayerMouseEvent;

    touchstart: MapLayerTouchEvent;
    touchend: MapLayerTouchEvent;
    touchcancel: MapLayerTouchEvent;
  };

  export type AnyLayer = any;
  export interface CustomLayerInterface {
    id: string;

    type: "custom";

    renderingMode?: "2d" | "3d" | undefined;

    onRemove?(map: MapboxMap, gl: WebGLRenderingContext): void;

    onAdd?(map: MapboxMap, gl: WebGLRenderingContext): void;

    prerender?(gl: WebGLRenderingContext, matrix: number[]): void;

    render(gl: WebGLRenderingContext, matrix: number[]): void;
  }

  export interface StyleFunction {
    stops?: any[][] | undefined;
    property?: string | undefined;
    base?: number | undefined;
    type?: "identity" | "exponential" | "interval" | "categorical" | undefined;
    default?: any;
    colorSpace?: "rgb" | "lab" | "hcl" | undefined;
  }

  type Visibility = "visible" | "none";

  export interface Layout {
    visibility?: Visibility | undefined;
  }

  export interface BackgroundLayout extends Layout {}

  export interface BackgroundPaint {
    "background-color"?: string | Expression | undefined;
    "background-color-transition"?: Transition | undefined;
    "background-pattern"?: string | undefined;
    "background-pattern-transition"?: Transition | undefined;
    "background-opacity"?: number | Expression | undefined;
    "background-opacity-transition"?: Transition | undefined;
  }

  export interface FillLayout extends Layout {
    "fill-sort-key"?: number | Expression | undefined;
  }

  export interface FillPaint {
    "fill-antialias"?: boolean | Expression | undefined;
    "fill-opacity"?: number | StyleFunction | Expression | undefined;
    "fill-opacity-transition"?: Transition | undefined;
    "fill-color"?: string | StyleFunction | Expression | undefined;
    "fill-color-transition"?: Transition | undefined;
    "fill-outline-color"?: string | StyleFunction | Expression | undefined;
    "fill-outline-color-transition"?: Transition | undefined;
    "fill-translate"?: number[] | undefined;
    "fill-translate-transition"?: Transition | undefined;
    "fill-translate-anchor"?: "map" | "viewport" | undefined;
    "fill-pattern"?: string | Expression | undefined;
    "fill-pattern-transition"?: Transition | undefined;
  }

  export interface FillExtrusionLayout extends Layout {}

  export interface FillExtrusionPaint {
    "fill-extrusion-opacity"?: number | Expression | undefined;
    "fill-extrusion-opacity-transition"?: Transition | undefined;
    "fill-extrusion-color"?: string | StyleFunction | Expression | undefined;
    "fill-extrusion-color-transition"?: Transition | undefined;
    "fill-extrusion-translate"?: number[] | Expression | undefined;
    "fill-extrusion-translate-transition"?: Transition | undefined;
    "fill-extrusion-translate-anchor"?: "map" | "viewport" | undefined;
    "fill-extrusion-pattern"?: string | Expression | undefined;
    "fill-extrusion-pattern-transition"?: Transition | undefined;
    "fill-extrusion-height"?: number | StyleFunction | Expression | undefined;
    "fill-extrusion-height-transition"?: Transition | undefined;
    "fill-extrusion-base"?: number | StyleFunction | Expression | undefined;
    "fill-extrusion-base-transition"?: Transition | undefined;
    "fill-extrusion-vertical-gradient"?: boolean | undefined;
  }

  export interface LineLayout extends Layout {
    "line-cap"?: "butt" | "round" | "square" | Expression | undefined;
    "line-join"?: "bevel" | "round" | "miter" | Expression | undefined;
    "line-miter-limit"?: number | Expression | undefined;
    "line-round-limit"?: number | Expression | undefined;
    "line-sort-key"?: number | Expression | undefined;
  }

  export interface LinePaint {
    "line-opacity"?: number | StyleFunction | Expression | undefined;
    "line-opacity-transition"?: Transition | undefined;
    "line-color"?: string | StyleFunction | Expression | undefined;
    "line-color-transition"?: Transition | undefined;
    "line-translate"?: number[] | Expression | undefined;
    "line-translate-transition"?: Transition | undefined;
    "line-translate-anchor"?: "map" | "viewport" | undefined;
    "line-width"?: number | StyleFunction | Expression | undefined;
    "line-width-transition"?: Transition | undefined;
    "line-gap-width"?: number | StyleFunction | Expression | undefined;
    "line-gap-width-transition"?: Transition | undefined;
    "line-offset"?: number | StyleFunction | Expression | undefined;
    "line-offset-transition"?: Transition | undefined;
    "line-blur"?: number | StyleFunction | Expression | undefined;
    "line-blur-transition"?: Transition | undefined;
    "line-dasharray"?: number[] | Expression | undefined;
    "line-dasharray-transition"?: Transition | undefined;
    "line-pattern"?: string | Expression | undefined;
    "line-pattern-transition"?: Transition | undefined;
    "line-gradient"?: Expression | undefined;
  }

  export interface SymbolLayout extends Layout {
    "symbol-placement"?: "point" | "line" | "line-center" | undefined;
    "symbol-spacing"?: number | Expression | undefined;
    "symbol-avoid-edges"?: boolean | undefined;
    "symbol-z-order"?: "viewport-y" | "source" | undefined;
    "icon-allow-overlap"?: boolean | StyleFunction | Expression | undefined;
    "icon-ignore-placement"?: boolean | Expression | undefined;
    "icon-optional"?: boolean | undefined;
    "icon-rotation-alignment"?: "map" | "viewport" | "auto" | undefined;
    "icon-size"?: number | StyleFunction | Expression | undefined;
    "icon-text-fit"?: "none" | "both" | "width" | "height" | undefined;
    "icon-text-fit-padding"?: number[] | Expression | undefined;
    "icon-image"?: string | StyleFunction | Expression | undefined;
    "icon-rotate"?: number | StyleFunction | Expression | undefined;
    "icon-padding"?: number | Expression | undefined;
    "icon-keep-upright"?: boolean | undefined;
    "icon-offset"?: number[] | StyleFunction | Expression | undefined;
    "icon-anchor"?: Anchor | StyleFunction | Expression | undefined;
    "icon-pitch-alignment"?: "map" | "viewport" | "auto" | undefined;
    "text-pitch-alignment"?: "map" | "viewport" | "auto" | undefined;
    "text-rotation-alignment"?: "map" | "viewport" | "auto" | undefined;
    "text-field"?: string | StyleFunction | Expression | undefined;
    "text-font"?: string[] | Expression | undefined;
    "text-size"?: number | StyleFunction | Expression | undefined;
    "text-max-width"?: number | StyleFunction | Expression | undefined;
    "text-line-height"?: number | Expression | undefined;
    "text-letter-spacing"?: number | Expression | undefined;
    "text-justify"?:
      | "auto"
      | "left"
      | "center"
      | "right"
      | Expression
      | undefined;
    "text-anchor"?: Anchor | StyleFunction | Expression | undefined;
    "text-max-angle"?: number | Expression | undefined;
    "text-rotate"?: number | StyleFunction | Expression | undefined;
    "text-padding"?: number | Expression | undefined;
    "text-keep-upright"?: boolean | undefined;
    "text-transform"?:
      | "none"
      | "uppercase"
      | "lowercase"
      | StyleFunction
      | Expression
      | undefined;
    "text-offset"?: number[] | Expression | undefined;
    "text-allow-overlap"?: boolean | undefined;
    "text-ignore-placement"?: boolean | undefined;
    "text-optional"?: boolean | undefined;
    "text-radial-offset"?: number | Expression | undefined;
    "text-variable-anchor"?: Anchor[] | undefined;
    "text-writing-mode"?: ("horizontal" | "vertical")[] | undefined;
    "symbol-sort-key"?: number | Expression | undefined;
  }

  export interface SymbolPaint {
    "icon-opacity"?: number | StyleFunction | Expression | undefined;
    "icon-opacity-transition"?: Transition | undefined;
    "icon-color"?: string | StyleFunction | Expression | undefined;
    "icon-color-transition"?: Transition | undefined;
    "icon-halo-color"?: string | StyleFunction | Expression | undefined;
    "icon-halo-color-transition"?: Transition | undefined;
    "icon-halo-width"?: number | StyleFunction | Expression | undefined;
    "icon-halo-width-transition"?: Transition | undefined;
    "icon-halo-blur"?: number | StyleFunction | Expression | undefined;
    "icon-halo-blur-transition"?: Transition | undefined;
    "icon-translate"?: number[] | Expression | undefined;
    "icon-translate-transition"?: Transition | undefined;
    "icon-translate-anchor"?: "map" | "viewport" | undefined;
    "text-opacity"?: number | StyleFunction | Expression | undefined;
    "text-opacity-transition"?: Transition | undefined;
    "text-color"?: string | StyleFunction | Expression | undefined;
    "text-color-transition"?: Transition | undefined;
    "text-halo-color"?: string | StyleFunction | Expression | undefined;
    "text-halo-color-transition"?: Transition | undefined;
    "text-halo-width"?: number | StyleFunction | Expression | undefined;
    "text-halo-width-transition"?: Transition | undefined;
    "text-halo-blur"?: number | StyleFunction | Expression | undefined;
    "text-halo-blur-transition"?: Transition | undefined;
    "text-translate"?: number[] | Expression | undefined;
    "text-translate-transition"?: Transition | undefined;
    "text-translate-anchor"?: "map" | "viewport" | undefined;
  }

  export interface RasterLayout extends Layout {}

  export interface RasterPaint {
    "raster-opacity"?: number | Expression | undefined;
    "raster-opacity-transition"?: Transition | undefined;
    "raster-hue-rotate"?: number | Expression | undefined;
    "raster-hue-rotate-transition"?: Transition | undefined;
    "raster-brightness-min"?: number | Expression | undefined;
    "raster-brightness-min-transition"?: Transition | undefined;
    "raster-brightness-max"?: number | Expression | undefined;
    "raster-brightness-max-transition"?: Transition | undefined;
    "raster-saturation"?: number | Expression | undefined;
    "raster-saturation-transition"?: Transition | undefined;
    "raster-contrast"?: number | Expression | undefined;
    "raster-contrast-transition"?: Transition | undefined;
    "raster-fade-duration"?: number | Expression | undefined;
    "raster-resampling"?: "linear" | "nearest" | undefined;
  }

  export interface CircleLayout extends Layout {
    "circle-sort-key"?: number | Expression | undefined;
  }

  export interface CirclePaint {
    "circle-radius"?: number | StyleFunction | Expression | undefined;
    "circle-radius-transition"?: Transition | undefined;
    "circle-color"?: string | StyleFunction | Expression | undefined;
    "circle-color-transition"?: Transition | undefined;
    "circle-blur"?: number | StyleFunction | Expression | undefined;
    "circle-blur-transition"?: Transition | undefined;
    "circle-opacity"?: number | StyleFunction | Expression | undefined;
    "circle-opacity-transition"?: Transition | undefined;
    "circle-translate"?: number[] | Expression | undefined;
    "circle-translate-transition"?: Transition | undefined;
    "circle-translate-anchor"?: "map" | "viewport" | undefined;
    "circle-pitch-scale"?: "map" | "viewport" | undefined;
    "circle-pitch-alignment"?: "map" | "viewport" | undefined;
    "circle-stroke-width"?: number | StyleFunction | Expression | undefined;
    "circle-stroke-width-transition"?: Transition | undefined;
    "circle-stroke-color"?: string | StyleFunction | Expression | undefined;
    "circle-stroke-color-transition"?: Transition | undefined;
    "circle-stroke-opacity"?: number | StyleFunction | Expression | undefined;
    "circle-stroke-opacity-transition"?: Transition | undefined;
  }

  export interface HeatmapLayout extends Layout {}

  export interface HeatmapPaint {
    "heatmap-radius"?: number | StyleFunction | Expression | undefined;
    "heatmap-radius-transition"?: Transition | undefined;
    "heatmap-weight"?: number | StyleFunction | Expression | undefined;
    "heatmap-intensity"?: number | StyleFunction | Expression | undefined;
    "heatmap-intensity-transition"?: Transition | undefined;
    "heatmap-color"?: string | StyleFunction | Expression | undefined;
    "heatmap-opacity"?: number | StyleFunction | Expression | undefined;
    "heatmap-opacity-transition"?: Transition | undefined;
  }

  export interface HillshadeLayout extends Layout {}

  export interface HillshadePaint {
    "hillshade-illumination-direction"?: number | Expression | undefined;
    "hillshade-illumination-anchor"?: "map" | "viewport" | undefined;
    "hillshade-exaggeration"?: number | Expression | undefined;
    "hillshade-exaggeration-transition"?: Transition | undefined;
    "hillshade-shadow-color"?: string | Expression | undefined;
    "hillshade-shadow-color-transition"?: Transition | undefined;
    "hillshade-highlight-color"?: string | Expression | undefined;
    "hillshade-highlight-color-transition"?: Transition | undefined;
    "hillshade-accent-color"?: string | Expression | undefined;
    "hillshade-accent-color-transition"?: Transition | undefined;
  }

  export interface SkyLayout extends Layout {}

  export interface SkyPaint {
    "sky-atmosphere-color"?: string | Expression | undefined;
    "sky-atmosphere-halo-color"?: string | Expression | undefined;
    "sky-atmosphere-sun"?: number[] | Expression | undefined;
    "sky-atmosphere-sun-intensity"?: number | Expression | undefined;
    "sky-gradient"?: string | Expression | undefined;
    "sky-gradient-center"?: number[] | Expression | undefined;
    "sky-gradient-radius"?: number | Expression | undefined;
    "sky-opacity"?: number | Expression | undefined;
    "sky-type"?: "gradient" | "atmosphere" | "texture" | undefined;
    "sky-map": (string | undefined)[];
  }

  export type ElevationQueryOptions = {
    exaggerated: boolean;
  };

  export interface Projection {
    name:
      | "albers"
      | "equalEarth"
      | "equirectangular"
      | "lambertConformalConic"
      | "mercator"
      | "naturalEarth"
      | "winkelTripel"
      | "globe";
    center?: [number, number];
    parallels?: [number, number];
  }

  /**
   * ArkMap Types
   */

  /********************物件对象**************************/

  class StageObject {
    map: Map;
    uuid: string;
    isDestroyed: boolean;
  }

  class DirectionalLight extends StageObject {
    rawLight: THREE.DirectionalLight;
  }

  class Model extends StageObject {
    reset(
      coord?: [number, number],
      altitude?: number,
      rotation?: TModelRotation,
      translation?: TModelPosition,
      sacle?: number
    ): void;
  }

  class Marker extends StageObject {
    setPosition(lng: number, lat: number, altitude?: number): void;
    setZIndex(zIndex: number): void;
    updateHeaderFragment(fragment: string): void;
    setVisible(visible: boolean): void;
  }

  class PathMoving extends StageObject {
    changeStatus(isPlay: boolean): void;
  }

  class FlyLine extends StageObject {}

  class Cover extends StageObject {}

  class Popup extends StageObject {}

  class MeshLineObject extends StageObject {}

  class Streamer extends StageObject {
    changeStatic(isStatic: boolean): void;
  }

  class Wall extends StageObject {}

  /********************配置项**************************/

  export interface IUserDirectionalLightOptions {
    position?: number[];
  }

  export interface IUserPathMovingOptions {
    path?: [number, number][];
    duration?: number;
    speed?: number;
    loop?: boolean;
    onRender?: (coord: number[]) => any;
    onEnd?: (coord: number[]) => any;
  }
  export type TModelRotation = { axis: string; angle: number }[];
  export type TModelPosition = { axis: string; offset: number }[];
  export interface IUserModelOptions {
    texture?: HTMLImageElement;
    color?: string;
    rotation?: TModelRotation;
    translation?: TModelPosition;
    scale?: number;
    coord?: number[];
    altitude?: number;
    type?: string;
    animate?: (delta: number, obj: THREE.Object3D) => any;
    onClick?: (e: MapMouseEvent) => any;
  }

  export type TBuildingLight = {
    enable?: boolean;
    color?: string;
    strength?: number;
  };
  export interface IUserBuildingOptions {
    layerId?: string;
    textures?: HTMLImageElement[];
    roofcolor?: string;
    minzoom?: number;
    maxzoom?: number;
    buildingColor?: string;
    opacity?: number;
    source?: string;
    sourceLayer?: string;
    heightField?: string;
    before?: string;
    mixinStrength?: number;
    vignetting?: boolean;
    light?: TBuildingLight;
  }

  export interface IUserLightupOptions {
    coord?: number[];
    raduis?: number;
    color?: string;
  }

  export type TExtendCameraOptions = {
    rotation?: boolean;
    meta?: any;
  };
  export interface IUserCameraOptions
    extends TExtendCameraOptions,
      CameraOptions {}

  export type TMarkerHeader = {
    show?: boolean;
    fragment?: string;
    scale?: number[][];
    style?: Partial<CSSStyleDeclaration>;
    translate?: string;
  };
  export type TMarkerBody = {
    show?: boolean;
    color?: string;
    width?: number;
    depthTest?: boolean;
  };
  export type TMarkerBase = {
    show?: boolean;
    image?: HTMLImageElement;
    size?: number[];
    depthTest?: boolean;
  };
  export interface IMarkerClickCallbackEvent {
    event: MouseEvent;
  }
  export interface IUserMarkerOptions {
    id: string;
    minzoom?: number;
    maxzoom?: number;
    header?: TMarkerHeader;
    body?: TMarkerBody;
    base?: TMarkerBase;
    coord?: number[];
    height?: number;
    altitude?: number;
    zIndex?: number;
    onclick?: (event: IMarkerClickCallbackEvent) => any;
  }

  export interface IUserSkyBoxOptions {
    textures?: HTMLImageElement[];
  }

  export interface IUserFlyLineOptions {
    src?: number[];
    dest?: number[];
    lineColor?: string;
    backgroundColor?: string;
    backgroundOpacity?: number;
    size?: number;
    altitude?: number;
    points?: number;
  }

  export interface IUserDofOptions {
    enable?: boolean;
    blurRadius?: number;
    near?: number;
    nearRange?: number;
    far?: number;
    farRange?: number;
  }

  export interface IUserFlotsamOptions {
    coord?: number[];
    texture?: HTMLImageElement[];
    altitude?: number;
    raduis?: number;
    deathAge?: number;
    perSecond?: number;
    sizeRange?: number[];
    speedRange?: number[];
  }

  export type TPositionRange = {
    center?: number[];
    radius?: number;
    phiLimit?: number[];
    thetaLimit?: number[];
  };
  export type TDirectionRange = {
    phiLimit?: number[];
    thetaLimit?: number[];
  };
  export interface IUserParticleEmitterOptions {
    coord?: number[];
    altitude?: number;
    texture?: HTMLImageElement;
    particlesPerSecond?: number;
    particleDeathAge?: number;
    positionRange?: TPositionRange;
    directionRange?: TDirectionRange;
    speedRange?: number[];
    color?: string;
    colorRangeRadius?: number;
    colorTween?: [number[], string[]];
    sizeRange?: number[];
    sizeTween?: [number[], number[]];
    opacityRange?: number[];
    opacityTween?: [number[], number[]];
    depthTest?: boolean;
    premultipliedAlpha?: boolean;
  }

  export interface IUserPopupOptions {
    coord?: number[];
    altitude?: number;
    content?: string;
    style?: Partial<CSSStyleDeclaration>;
    scale?: number[][];
    maxzoom?: number;
    minzoom?: number;
  }

  export interface IUserCoverOptions {
    bounds?: LngLat[];
    coverColor?: string;
    coverOpacity?: number;
    scanColor?: string;
    scanOpacity?: number;
    scanWidthFactor?: number;
    speed?: number;
  }

  export interface IUserMeshLineOptions {
    lineWidth?: number;
    color?: string;
    opacity?: number;
    height?: number;
    altitude?: number;
  }

  export interface IUserStreamerOptions {
    lineWidth?: number;
    length?: number;
    lineColor?: string;
    blurRadius?: number;
    blurStrength?: number;
    minLength?: number;
    speed?: number;
  }

  export interface IUserWallOptions {
    path?: number[][];
    color?: string;
    opacity?: number;
    height?: number;
    flowSpeed?: number;
    flowTexture?: HTMLImageElement;
    altitude?: number;
  }
  /*******************************************/

  export interface IArkMapOptions {
    sourceDebug?: boolean;
    passiveRendering?: boolean;
    fps?: number;
    stageAntialias?: boolean;
    buildingAntialias?: boolean;
    offscreenAntialias?: boolean;
    canvasPixelRatio?: number;
    shadowEnable?: boolean;
    qualityPreset?: string;
  }
  class Config implements IArkMapOptions {
    sourceDebug?: boolean;
    passiveRendering?: boolean;
    fps?: number;
    stageAntialias?: boolean;
    buildingAntialias?: boolean;
    offscreenAntialias?: boolean;
    canvasPixelRatio?: number;
    shadowEnable?: boolean;
    qualityPreset?: string;

    set(options: Partial<IArkMapOptions & MapboxOptions>);
  }
  export interface MapOptions extends IArkMapOptions, MapboxOptions {}

  export interface ICustomStage {
    id: string;
    onAdd: (
      map?: Map,
      renderer?: THREE.WebGLRenderer,
      world?: THREE.Group,
      scene?: THREE.Scene,
      camera?: THREE.Camera
    ) => void;
    render?: (delta: number) => void;
    destroy?: () => void;
  }

  type TAngleLimit = [number, number];
  class Tween {}
  class Particle {}
  export interface IParticleEmitterParams {
    sizeTween?: Tween;
    colorTween?: Tween;
    opacityTween?: Tween;
    particlesPerSecond?: number;
    particleDeathAge?: number;
    directionRange?: [TAngleLimit, TAngleLimit];
    positionRange: [THREE.Vector3, number, TAngleLimit, TAngleLimit];
    speedRange?: [number, number];
    sizeRange?: [number, number];
    colorRange?: [THREE.Vector3, number];
    opacityRange?: [number, number];
    blendMode?: THREE.Blending;
    premultipliedAlpha?: boolean;
    texture?: THREE.Texture;
    depthTest?: boolean;
    particleCount: number;
    particles: Particle[];
  }
  export class Emitter implements IParticleEmitterParams {
    uuid: string;
    sizeTween?: Tween;
    colorTween?: Tween;
    opacityTween?: Tween;
    particlesPerSecond?: number;
    particleDeathAge?: number;
    directionRange?: [TAngleLimit, TAngleLimit];
    positionRange: [THREE.Vector3, number, TAngleLimit, TAngleLimit];
    speedRange?: [number, number];
    sizeRange?: [number, number];
    colorRange?: [THREE.Vector3, number];
    opacityRange?: [number, number];
    blendMode?: THREE.Blending;
    premultipliedAlpha?: boolean;
    texture?: THREE.Texture;
    depthTest?: boolean;
    particleCount: number;
    particles: Particle[];

    fire(): void;
  }

  export class Map extends MapboxMap {
    destroyed: boolean;

    constructor(options: MapOptions);

    addDirectionalLight(
      options: IUserDirectionalLightOptions
    ): DirectionalLight;

    addCustomStage(stage: ICustomStage): void;
    removeCustomStage(id: string): void;

    pathMoving(
      model: Model | Marker,
      options: IUserPathMovingOptions
    ): PathMoving;
    removePathMoving(pm: PathMoving): void;

    setPassiveRendering(passiveRendering: boolean): void;
    setFps(fps: number): void;

    addBuildings(options: IUserBuildingOptions): void;
    removeBuilding(): void;

    lightUpBuilding(options: IUserLightupOptions): Promise<Emitter>;
    setFlotsam(options: IUserFlotsamOptions): Emitter;
    getParticleEmitter(options: IUserParticleEmitterOptions): Emitter;
    removeEmitter(emitter: Emitter): void;

    focus(options: IUserCameraOptions, cb: () => void): void;
    unfocus(): void;

    addMarker(options: IUserMarkerOptions): Marker;
    removeMarker(marker: Marker): void;

    add3DModel(obj: any, options: IUserModelOptions): Model;
    remove3DModel(model: Model): void;

    addSkyBox(options: IUserSkyBoxOptions): void;

    addFlyLine(options: IUserFlyLineOptions): FlyLine;
    removeFlyLine(fl: FlyLine): void;

    setDOF(options: IUserDofOptions): void;

    addCover(options: IUserCoverOptions): Cover;
    removeCover(cover: Cover): void;

    addPopup(options: IUserPopupOptions): Popup;
    removePopup(popup: Popup);

    addMeshLine(
      source: GeoJSON.FeatureCollection<GeoJSON.MultiLineString>,
      options: IUserMeshLineOptions
    ): MeshLineObject;
    removeMeshLine(ml: MeshLineObject): void;

    addStreamer(
      source: GeoJSON.FeatureCollection<GeoJSON.MultiLineString>,
      options: IUserStreamerOptions
    ): Streamer;
    removeStreamer(sm: Streamer): void;

    addWall(options: IUserWallOptions): Wall;
    removeWall(wall: Wall): void;

    destroy(): void;
  }

  export function loadObj(src: string): Promise<any>;

  export function loadGLTF(src: string): Promise<any>;

  export type TDrivingInfo = {
    dist: number;
    bearing: number;
    coord: GeoJSON.Position;
  };

  export class Navigation {
    constructor(routeNetwork: GeoJSON.FeatureCollection<GeoJSON.LineString>);

    static genDrivingInfo(path: [number, number][]): TDrivingInfo[];

    findWayFuzzy(
      point1: number[],
      point2: number[]
    ): Promise<undefined | { path: number[][] }>;

    findWay(point1: number[], point2: number[]): undefined | number[][];
  }

  export interface IMouseEventCallback {
    (e: MouseEvent, intersects: THREE.Intersection<THREE.Object3D>[]): void;
  }
  export type TMouseEventType = "click" | "hover";
  class ThreeMouseEvent {
    constructor(map: Map, camera: THREE.PerspectiveCamera);

    onClick(obj: THREE.Object3D, callback: IMouseEventCallback): void;
    onHover(obj: THREE.Object3D, callback: IMouseEventCallback): void;
    off(type: TMouseEventType, obj: THREE.Object3D);
  }
  export type TConvertLnglatToWorldResult =
    | THREE.Vector3
    | {
        vertices: THREE.Vector3[];
        position: THREE.Vector3;
      };
  type TCustomStageUtils = {
    StageMouseEvent: ThreeMouseEvent;
    convertLnglatToWorld: (
      lnglat: number[] | number[][]
    ) => TConvertLnglatToWorldResult;
  };

  export let CustomStageUtils: TCustomStageUtils;
}
